Thread-safe version of incident_cells and incident_facets

This commit is contained in:
Clement Jamin 2014-06-23 10:45:26 +02:00
parent 48a8abb278
commit a09ed46810
4 changed files with 126 additions and 48 deletions

View File

@ -3247,7 +3247,18 @@ get_least_square_surface_plane(const Vertex_handle& v,
{
// Get incident facets
Facet_vector facets;
tr_.finite_incident_facets(v,std::back_inserter(facets));
# ifdef CGAL_LINKED_WITH_TBB
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
tr_.finite_incident_facets_threadsafe(v, std::back_inserter(facets));
}
// Sequential
else
# endif // CGAL_LINKED_WITH_TBB
{
tr_.finite_incident_facets(v,std::back_inserter(facets));
}
// Get adjacent surface points
std::vector<Point_3> surface_point_vector;
@ -3373,10 +3384,10 @@ get_incident_slivers_without_using_tds_data(const Vertex_handle& v,
Cell_vector &slivers) const
{
Is_sliver<SliverCriterion> i_s(c3t3_, criterion, sliver_bound);
tr_.incident_cells_threadsafe(v, slivers, i_s);
tr_.incident_cells_threadsafe(v, std::back_inserter(slivers), i_s);
}
// CJTODO: call tr_.try_lock_and_get_incident_cells instead?
template <typename C3T3, typename MD>
bool
C3T3_helpers<C3T3,MD>::

View File

@ -851,7 +851,7 @@ compute_move(const Vertex_handle& v)
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
tr_.incident_cells_threadsafe(v, incident_cells);
tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells));
}
else
#endif //CGAL_LINKED_WITH_TBB
@ -1066,7 +1066,7 @@ average_circumradius_length(const Vertex_handle& v) const
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
tr_.incident_cells_threadsafe(v, incident_cells);
tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells));
}
else
#endif //CGAL_LINKED_WITH_TBB

View File

@ -1844,25 +1844,26 @@ public:
}
};
template <class OutputIterator>
template <typename OutputIterator>
OutputIterator
incident_cells(Vertex_handle v, OutputIterator cells) const
{
return _tds.incident_cells(v, cells);
}
template <typename OutputIterator>
void incident_cells_threadsafe(Vertex_handle v,
std::vector<Cell_handle> &cells) const
OutputIterator cells) const
{
return _tds.incident_cells_threadsafe(v, cells);
_tds.incident_cells_threadsafe(v, cells);
}
template <typename Filter>
template <typename Filter, typename OutputIterator>
void incident_cells_threadsafe(Vertex_handle v,
std::vector<Cell_handle> &cells,
OutputIterator cells,
const Filter &filter) const
{
return _tds.incident_cells_threadsafe(v, cells, filter);
_tds.incident_cells_threadsafe(v, cells, filter);
}
bool
@ -2002,6 +2003,20 @@ public:
return _tds.incident_facets(v, facets, Finite_filter(this));
}
template <class OutputIterator>
OutputIterator
incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const
{
return _tds.incident_facets_threadsafe(v, facets);
}
template <class OutputIterator>
OutputIterator
finite_incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const
{
return _tds.incident_facets_threadsafe(v, facets, Finite_filter(this));
}
// old name (up to CGAL 3.4)
// kept for backwards compatibility but not documented
template <class OutputIterator>

View File

@ -712,6 +712,36 @@ private:
return it;
}
template <class IncidentFacetIterator>
void
incident_cells_3_threadsafe(Vertex_handle v, Cell_handle d,
std::vector<Cell_handle> &cells,
IncidentFacetIterator facet_it) const
{
boost::unordered_set<Cell_handle, Handle_hash_function> found_cells;
cells.push_back(d);
found_cells.insert(d);
int head=0;
int tail=1;
do {
Cell_handle c = cells[head];
for (int i=0; i<4; ++i) {
if (c->vertex(i) == v)
continue;
Cell_handle next = c->neighbor(i);
if (c < next)
*facet_it++ = Facet(c, i); // Incident facet
if (! found_cells.insert(next).second )
continue;
cells.push_back(next);
++tail;
}
++head;
} while(head != tail);
}
void just_incident_cells_3(Vertex_handle v,
std::vector<Cell_handle>& cells) const
{
@ -999,47 +1029,19 @@ public:
}
}
void incident_cells_threadsafe(Vertex_handle v,
std::vector<Cell_handle> &cells) const
template <class Filter, class OutputIterator>
OutputIterator
incident_cells_threadsafe(Vertex_handle v, OutputIterator cells, Filter f = Filter()) const
{
boost::unordered_set<Cell_handle, Handle_hash_function> found_cells;
Cell_handle d = v->cell();
cells.push_back(d);
found_cells.insert(d);
int head=0;
int tail=1;
do {
Cell_handle c = cells[head];
for (int i=0; i<4; ++i) {
if (c->vertex(i) == v)
continue;
Cell_handle next = c->neighbor(i);
if (! found_cells.insert(next).second )
continue;
cells.push_back(next);
++tail;
}
++head;
} while(head != tail);
return visit_incident_cells_threadsafe<Cell_extractor<OutputIterator, Filter>,
OutputIterator>(v, cells, f);
}
template <typename Filter>
void incident_cells_threadsafe(Vertex_handle v,
std::vector<Cell_handle> &cells,
const Filter &filter) const
template <class OutputIterator>
OutputIterator
incident_cells_threadsafe(Vertex_handle v, OutputIterator cells) const
{
std::vector<Cell_handle> tmp_cells;
tmp_cells.reserve(64);
incident_cells_threadsafe(v, tmp_cells);
BOOST_FOREACH(Cell_handle& ch,
std::make_pair(tmp_cells.begin(), tmp_cells.end()))
{
if (filter(ch))
cells.push_back(ch);
}
return incident_cells_threadsafe<False_filter>(v, cells);
}
template <class Filter, class OutputIterator>
@ -1060,6 +1062,24 @@ public:
return incident_facets<False_filter>(v, facets);
}
template <class Filter, class OutputIterator>
OutputIterator
incident_facets_threadsafe(Vertex_handle v, OutputIterator facets, Filter f = Filter()) const
{
CGAL_triangulation_precondition( dimension() > 1 );
if(dimension() == 3)
return visit_incident_cells_threadsafe<Facet_extractor<OutputIterator, Filter>, OutputIterator>(v, facets, f);
else
return visit_incident_cells_threadsafe<DegCell_as_Facet_extractor<OutputIterator, Filter>, OutputIterator>(v, facets, f);
}
template <class OutputIterator>
OutputIterator
incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const
{
return incident_facets<False_filter>(v, facets);
}
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_member_visited,Has_visited_for_vertex_extractor,false)
template <class Filter, class OutputIterator>
@ -1178,6 +1198,38 @@ public:
return visit.result();
}
template <class Visitor, class OutputIterator, class Filter>
OutputIterator
visit_incident_cells_threadsafe(
Vertex_handle v, OutputIterator output, Filter f) const
{
CGAL_triangulation_precondition( v != Vertex_handle() );
CGAL_triangulation_expensive_precondition( is_vertex(v) );
if ( dimension() < 2 )
return output;
Visitor visit(v, output, this, f);
std::vector<Cell_handle> tmp_cells;
tmp_cells.reserve(64);
if ( dimension() == 3 )
incident_cells_3_threadsafe(
v, v->cell(), tmp_cells, visit.facet_it());
else
incident_cells_2(v, v->cell(), std::back_inserter(tmp_cells));
typename std::vector<Cell_handle>::iterator cit;
for(cit = tmp_cells.begin();
cit != tmp_cells.end();
++cit)
{
visit(*cit);
}
return visit.result();
}
template <class Visitor, class OutputIterator, class Filter>
OutputIterator
visit_incident_cells(Vertex_handle v, OutputIterator output,