Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,9 @@ class Sliver_perturber
#ifdef CGAL_MESH_3_USE_RELAXED_HEAP
typedef boost::relaxed_heap<PVertex, less_PVertex, PVertex_id> PQueue;
#else
typedef ::CGAL::internal::mutable_queue_with_remove<PVertex,std::vector<PVertex>, less_PVertex, PVertex_id> PQueue;
typedef CGAL::Modifiable_priority_queue<PVertex,less_PVertex,PVertex_id> PQueue;
#endif //CGAL_MESH_3_USE_RELAXED_HEAP
typedef typename boost::unordered_map<std::size_t,typename PQueue::handle> Handle_map;

public:
/**
Expand Down Expand Up @@ -725,6 +726,7 @@ class Sliver_perturber
SliverCriterion sliver_criterion_;
Perturbation_vector perturbation_vector_;
C3T3_helpers helper_;
mutable Handle_map h;

// Internal perturbation ordering
int next_perturbation_order_;
Expand Down Expand Up @@ -785,8 +787,7 @@ operator()(Visitor visitor)
#endif

// Build priority queue (we use one queue for all steps)
PQueue pqueue(tr_.number_of_vertices());

PQueue pqueue(0,less_PVertex(),PVertex_id());
// Initialize vertices ids
initialize_vertices_id();

Expand Down Expand Up @@ -942,10 +943,11 @@ perturb(const FT& sliver_bound, PQueue& pqueue, Visitor& visitor) const
{
this->create_task_group();

while (pqueue.size() > 0)
while (! pqueue.empty() )
{
PVertex pv = pqueue.top();
pqueue.pop();
h.erase(pv.id());
enqueue_task(pv, sliver_bound,
visitor, bad_vertices);
}
Expand Down Expand Up @@ -979,6 +981,7 @@ perturb(const FT& sliver_bound, PQueue& pqueue, Visitor& visitor) const
// Get pqueue head
PVertex pv = pqueue.top();
pqueue.pop();
h.erase(pv.id());
--pqueue_size;

CGAL_assertion(pv.is_perturbable());
Expand Down Expand Up @@ -1236,24 +1239,29 @@ int
Sliver_perturber<C3T3,Md,Sc,V_>::
update_priority_queue(const PVertex& pv, PQueue& pqueue) const
{
if ( pqueue.contains(pv) )
typename Handle_map::iterator pvh =
h.find(pv.id());
if ( pvh != h.end() )
{
if ( pv.is_perturbable() )
{
pqueue.update(pv);
typename PQueue::handle ex_h = pvh->second;
pqueue.update(pv, ex_h);
pvh->second = ex_h;
return 0;
}
else
{
pqueue.remove(pv);
pqueue.erase(pv, pvh->second);
h.erase(pv.id());
return -1;
}
}
else
{
if ( pv.is_perturbable() )
{
pqueue.push(pv);
h[pv.id()] = pqueue.push(pv);
return 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <CGAL/Polyline_simplification_2/Stop_below_count_threshold.h>
#include <CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h>
#include <CGAL/Modifiable_priority_queue.h>
#include <boost/unordered_map.hpp>
#include <CGAL/algorithm.h>

// Needed for Polygon_2
Expand Down Expand Up @@ -112,7 +113,7 @@ class Polyline_simplification_2
typedef CGAL::Modifiable_priority_queue<Vertex_handle,Compare_cost,Id_map> MPQ ;

MPQ* mpq;

boost::unordered_map<int,typename MPQ::handle> h;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now std::unordered_map can be used

Polyline_simplification_2(PCT& pct, CostFunction cost, StopFunction stop)
: pct(pct), cost(cost), stop(stop), pct_initial_number_of_vertices(pct.number_of_vertices()), number_of_unremovable_vertices(0)
{
Expand Down Expand Up @@ -214,9 +215,10 @@ class Polyline_simplification_2
boost::optional<FT> dist = cost(pct, it);
if(dist){
(*it)->set_cost(*dist);
if(! (*mpq).contains(*it)){
(*mpq).push(*it);
}
auto ir = h.insert(std::make_pair((*it)->ID, mpq->null_handle()));
if(ir.second){
ir.first->second = mpq->push(*it);
}
++n;
} else {
// no need to set the costs as this vertex is not in the priority queue
Expand Down Expand Up @@ -316,6 +318,7 @@ operator()()
}
Vertex_handle v = (*mpq).top();
(*mpq).pop();
h.erase(v->ID);
if(stop(pct, v, v->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){
return false;
}
Expand All @@ -327,36 +330,48 @@ operator()()

if((*u)->is_removable()){
boost::optional<FT> dist = cost(pct, u);
typename boost::unordered_map<int,typename MPQ::handle>::iterator find_result_u =
h.find((*u)->ID);
if(! dist){
// cost is undefined
if( mpq->contains(*u) ){
mpq->erase(*u);
if( find_result_u != h.end()){
mpq->erase(*u, find_result_u->second);
h.erase((*u)->ID);
}
} else {
if(find_result_u != h.end()){
typename MPQ::handle ex_h = find_result_u->second;
(*u)->set_cost(*dist);
if(mpq->contains(*u)){
mpq->update(*u, true);
mpq->update(*u, ex_h);
find_result_u->second = ex_h;
}
else{
mpq->push(*u);
(*u)->set_cost(*dist);
h[(*u)->ID]=mpq->push(*u);
}
}
}

if((*w)->is_removable()){
boost::optional<FT> dist = cost(pct, w);
typename boost::unordered_map<int,typename MPQ::handle>::iterator find_result_w =
h.find((*w)->ID);
if(! dist){
// cost is undefined
if( mpq->contains(*w) ){
mpq->erase(*w);
if(find_result_w != h.end()){
mpq->erase(*w, find_result_w->second);
h.erase((*w)->ID);
}
} else {
if(find_result_w != h.end()){
typename MPQ::handle ex_h = find_result_w->second;
(*w)->set_cost(*dist);
if(mpq->contains(*w)){
mpq->update(*w, true);
mpq->update(*w, ex_h);
find_result_w->second=ex_h;
}
else{
mpq->push(*w);
(*w)->set_cost(*dist);
h[(*w)->ID]=mpq->push(*w);
}

}
Expand Down
84 changes: 31 additions & 53 deletions STL_Extension/include/CGAL/Modifiable_priority_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,8 @@
#ifdef CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP
#include <boost/pending/relaxed_heap.hpp>
#else
#include <CGAL/STL_Extension/internal/boost/mutable_queue.hpp>


namespace CGAL {
namespace internal {
template <class IndexedType,
class RandomAccessContainer = std::vector<IndexedType>,
class Comp = std::less<typename RandomAccessContainer::value_type>,
class ID = ::boost::identity_property_map >
class mutable_queue_with_remove : public internal::boost_::mutable_queue<IndexedType,RandomAccessContainer,Comp,ID>
{
typedef internal::boost_::mutable_queue<IndexedType,RandomAccessContainer,Comp,ID> Base;
public:
typedef typename Base::size_type size_type;
typedef typename Base::Node Node;

mutable_queue_with_remove(size_type n, const Comp& x=Comp(), const ID& _id=ID()) : Base(n,x,_id,true)
{}

void remove(const IndexedType& x){
//first place element at the top
size_type current_pos = this->index_array[ get(this->id, x) ];
this->c[current_pos] = x;

Node node(this->c.begin(), this->c.end(), this->c.begin()+current_pos, this->id);
while (node.has_parent())
node.swap(node.parent(), this->index_array);
//then pop it
this->pop();
}

bool contains(const IndexedType& x) const {
return this->index_array[ get(this->id, x) ] !=this->index_array.size();
}
};

} } //namespace CGAL::internal
#include <boost/heap/fibonacci_heap.hpp>
#include <boost/graph/properties.hpp>
#endif //CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP

namespace CGAL {
Expand All @@ -73,33 +38,48 @@ class Modifiable_priority_queue

#ifdef CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP
typedef boost::relaxed_heap<IndexedType,Compare,ID> Heap;
#else
typedef internal::mutable_queue_with_remove<IndexedType,std::vector<IndexedType>,Compare,ID> Heap;
#endif //CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP
typedef typename Heap::value_type value_type;
typedef typename Heap::size_type size_type;

typedef bool handle ;

public:

Modifiable_priority_queue( size_type largest_ID, Compare const& c, ID const& id ) : mHeap(largest_ID,c,id) {}

typedef typename Heap::value_type value_type;
typedef typename Heap::size_type size_type;
handle push ( value_type const& v ) { mHeap.push(v) ; return handle(true) ; }

handle update ( value_type const& v, handle h ) { mHeap.update(v); return h ; }

handle erase ( value_type const& v, handle ) { mHeap.remove(v); return null_handle() ; }
handle erase ( value_type const& v ) { mHeap.remove(v); return null_handle() ; }
bool contains ( value_type const& v ) { return mHeap.contains(v) ; }
handle update ( value_type const& v, handle h ) { mHeap.update(v); return h ; }
static handle null_handle() { return handle(false); }
#else
struct Reverse_compare{
const Compare c;
Reverse_compare(){}
Reverse_compare(Compare const& c):c(c){}
template<typename T>
bool operator() (T const& a, T const& b) const
{
return !c(a,b);
}
};
typedef boost::heap::fibonacci_heap<IndexedType,boost::heap::compare<Reverse_compare> > Heap;
typedef typename Heap::handle_type handle;
//the fibonacci_heap uses the inverse of the compare used in the relaxed heap.
typedef typename Heap::value_type value_type;
typedef typename Heap::size_type size_type;
public:
Modifiable_priority_queue( size_type, Compare const& c, ID const& ):mHeap(Reverse_compare(c)) {}
handle push ( value_type const& v ) { return mHeap.push(v) ;}
handle erase ( value_type const& v, handle h) { mHeap.erase(h); return null_handle() ; }
handle update ( value_type const& v, handle h ) { mHeap.update(h); return h ; }
static handle null_handle() { return handle(); }
#endif //CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP


value_type top() const { return mHeap.top() ; }

void pop() { mHeap.pop(); }

bool empty() const { return mHeap.empty() ; }

bool contains ( value_type const& v ) { return mHeap.contains(v) ; }

boost::optional<value_type> extract_top()
{
boost::optional<value_type> r ;
Expand All @@ -112,8 +92,6 @@ class Modifiable_priority_queue
return r ;
}

static handle null_handle() { return handle(false); }

private:

Heap mHeap ;
Expand Down
Loading