unrecursive version of propagating_flip and propagate_conflicts

for CDT2 and DT2 using 100 recursive calls before switching to
a local stack in a function.
This commit is contained in:
Sébastien Loriot 2012-10-30 13:16:52 +00:00
parent 9f14f937ab
commit 6da5e9e84d
3 changed files with 104 additions and 49 deletions

View File

@ -24,6 +24,7 @@ if ( CGAL_FOUND )
include_directories (BEFORE ../../../../experimental-packages/Triangulation_2-unrecursive/include)
create_single_source_cgal_program( "Triangulation_benchmark_2.cpp" )
create_single_source_cgal_program( "Triangulation_benchmark_2_with_star_hole.cpp" )
create_single_source_cgal_program( "Delaunay_remove.cpp" )
create_single_source_cgal_program( "CDT_with_intersection_2.cpp" )

View File

@ -120,7 +120,7 @@ public:
void flip(Face_handle& f, int i);
void flip_around(Vertex_handle va);
void flip_around(List_vertices & new_vertices);
#ifdef CGAL_CDT2_USE_RECURSIVE_PROPAGATING_FLIP
#ifndef CGAL_CDT2_USE_RECURSIVE_PROPAGATING_FLIP
void non_recursive_propagating_flip(Face_handle f,int i);
void propagating_flip(Face_handle f,int i, int depth=0);
#else
@ -267,24 +267,34 @@ public:
public:
// made public for the need of Mesh_2
// but not documented
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
propagate_conflicts (const Point &p,
Face_handle fh,
int i,
std::pair<OutputItFaces,OutputItBoundaryEdges> pit) const {
#ifdef CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
Face_handle fn = fh->neighbor(i);
if ( fh->is_constrained(i) || ! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
} else {
*(pit.first)++ = fn;
int j = fn->index(fh);
pit = propagate_conflicts(p,fn,ccw(j),pit);
pit = propagate_conflicts(p,fn,cw(j), pit);
}
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
propagate_conflicts (const Point &p,
Face_handle fh,
int i,
std::pair<OutputItFaces,OutputItBoundaryEdges> pit) const
{
Face_handle fn = fh->neighbor(i);
if ( fh->is_constrained(i) || ! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
} else {
*(pit.first)++ = fn;
int j = fn->index(fh);
pit = propagate_conflicts(p,fn,ccw(j),pit);
pit = propagate_conflicts(p,fn,cw(j), pit);
}
return pit;
}
#else // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
non_recursive_propagate_conflicts (const Point &p,
Face_handle fh,
int i,
std::pair<OutputItFaces,OutputItBoundaryEdges> pit) const
{
std::stack<std::pair<Face_handle, int> > stack;
stack.push(std::make_pair(fh, i));
while(!stack.empty()) {
@ -301,10 +311,33 @@ public:
stack.push(std::make_pair(fn,ccw(j)));
}
}
return pit;
}
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
propagate_conflicts (const Point &p,
Face_handle fh,
int i,
std::pair<OutputItFaces,OutputItBoundaryEdges> pit,
int depth=0) const
{
if ( depth==100) return non_recursive_propagate_conflicts(p,fh,i,pit);
Face_handle fn = fh->neighbor(i);
if ( fh->is_constrained(i) || ! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
} else {
*(pit.first)++ = fn;
int j = fn->index(fh);
pit = propagate_conflicts(p,fn,ccw(j),pit,depth+1);
pit = propagate_conflicts(p,fn,cw(j), pit,depth+1);
}
return pit;
}
#endif // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
return pit;
}
public:
@ -507,8 +540,8 @@ non_recursive_propagating_flip(Face_handle f , int i)
flip(f,i);
if ( !is_flipable(f,i) ) edges.pop();
i = n->index(vp);
if ( is_flipable(n,i) ) edges.push( Edge(n,i) );
i = ni->index(vp);
if ( is_flipable(ni,i) ) edges.push( Edge(ni,i) );
}
}

View File

@ -441,6 +441,11 @@ public:
}
private:
#ifdef CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
propagate_conflicts (const Point &p,
@ -448,7 +453,6 @@ private:
const int i,
std::pair<OutputItFaces,OutputItBoundaryEdges>
pit) const {
#ifdef CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
Face_handle fn = fh->neighbor(i);
if (! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
@ -458,44 +462,61 @@ private:
pit = propagate_conflicts(p,fn,ccw(j),pit);
pit = propagate_conflicts(p,fn,cw(j), pit);
}
#else // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
#ifdef CGAL_HAS_THREADS
static boost::thread_specific_ptr< std::vector<std::pair<Face_handle,int> > > stack_safe_ptr;
if (stack_safe_ptr.get() == NULL) {
stack_safe_ptr.reset(new std::vector<std::pair<Face_handle,int> >());
return pit;
}
std::vector<std::pair<Face_handle,int> >& stack=* stack_safe_ptr.get();
#else
static std::stack<std::pair<Face_handle, int> > stack;
#endif
stack.push_back(std::make_pair(fh, i));
#ifdef CGAL_PROFILE
std::size_t S = 0;
#endif
while(!stack.empty()) {
#ifdef CGAL_PROFILE
S = (std::max)(S, stack.size());
#endif
const Face_handle fh = stack.back().first;
const int i = stack.back().second;
stack.pop_back();
const Face_handle fn = fh->neighbor(i);
#else // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
non_recursive_propagate_conflicts ( const Point &p,
const Face_handle fh,
const int i,
std::pair<OutputItFaces,OutputItBoundaryEdges> pit) const
{
std::stack<std::pair<Face_handle, int> > stack;
stack.push( std::make_pair(fh,i) );
while ( !stack.empty() )
{
const Face_handle fh=stack.top().first;
const int i=stack.top().second;
stack.pop();
Face_handle fn = fh->neighbor(i);
if (! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
} else {
*(pit.first)++ = fn;
int j = fn->index(fh);
stack.push_back(std::make_pair(fn, cw(j)));
stack.push_back(std::make_pair(fn,ccw(j)));
stack.push( std::make_pair(fn,ccw(j)) );
stack.push( std::make_pair(fn,cw(j)) );
}
}
CGAL_HISTOGRAM_PROFILER("propagate_conflicts stack size ", S);
#endif // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
return pit;
}
template <class OutputItFaces, class OutputItBoundaryEdges>
std::pair<OutputItFaces,OutputItBoundaryEdges>
propagate_conflicts (const Point &p,
const Face_handle fh,
const int i,
std::pair<OutputItFaces,OutputItBoundaryEdges>
pit,
int depth=0) const
{
if (depth == 100)
return non_recursive_propagate_conflicts(p, fh, i, pit);
Face_handle fn = fh->neighbor(i);
if (! test_conflict(p,fn)) {
*(pit.second)++ = Edge(fn, fn->index(fh));
} else {
*(pit.first)++ = fn;
int j = fn->index(fh);
pit = propagate_conflicts(p,fn,ccw(j),pit,depth+1);
pit = propagate_conflicts(p,fn,cw(j), pit,depth+1);
}
return pit;
}
#endif // NO CGAL_TRIANGULATION_2_USE_OLD_PROPAGATE_CONFLICTS
protected:
void restore_edges(Vertex_handle v)