diff --git a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h index 11d5c2b2759..17fc443567d 100644 --- a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h +++ b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h @@ -137,7 +137,7 @@ public: Triangle_property_map(&graph), Point_property_map(&graph) ) {} -#if 1 +#if 0 // for backward compatibility with Polyhedron::facets_begin() AABB_face_graph_triangle_primitive(typename boost::graph_traits::face_descriptor fd, FaceGraph& graph) : Base( Id_(fd), diff --git a/Polyhedron/include/CGAL/Polyhedron_3.h b/Polyhedron/include/CGAL/Polyhedron_3.h index c1101a222ca..3debdba74bb 100644 --- a/Polyhedron/include/CGAL/Polyhedron_3.h +++ b/Polyhedron/include/CGAL/Polyhedron_3.h @@ -37,6 +37,7 @@ #include #include +// at the end of this file: #include namespace CGAL { template @@ -1533,4 +1534,6 @@ public: } //namespace CGAL +#include + #endif // CGAL_POLYHEDRON_3_H // diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Filters.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Filters.h index ba17177e10b..1193a8359f3 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Filters.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Filters.h @@ -30,7 +30,7 @@ #include #include - +#include namespace CGAL { @@ -56,7 +56,7 @@ public: * - domain : over value distances * @param mesh `CGAL Polyhedron` on which @a values are defined * @param window_size range of effective neighbors - * @param[in, out] values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] values `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type */ template void operator()(const Polyhedron& mesh, @@ -65,8 +65,8 @@ public: boost::optional spatial_parameter = boost::optional(), boost::optional range_parameter = boost::optional() ) const { - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; double spatial_parameter_actual; if(!spatial_parameter) { @@ -78,18 +78,19 @@ public: std::vector smoothed_values; // holds smoothed values smoothed_values.reserve(mesh.size_of_facets()); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::map neighbors; - NeighborSelector()(facet_it, window_size, + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::map neighbors; + NeighborSelector()(mesh,*facet_it, window_size, neighbors); // gather neighbors in the window - double current_sdf_value = values[facet_it]; + double current_sdf_value = values[*facet_it]; double range_parameter_actual; if(!range_parameter) { // calculate deviation for range weighting. double deviation = 0.0; - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { deviation += std::pow(values[it->first] - current_sdf_value, 2); } @@ -107,7 +108,7 @@ public: // smooth double total_sdf_value = 0.0, total_weight = 0.0; - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { double spatial_weight = gaussian_function(static_cast(it->second), spatial_parameter_actual); @@ -123,10 +124,10 @@ public: } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++smoothed_value_it) { - values[facet_it] = *smoothed_value_it; + values[*facet_it] = *smoothed_value_it; } } private: @@ -147,26 +148,27 @@ public: * * @param mesh `CGAL Polyhedron` on which @a values are defined * @param window_size range of effective neighbors - * @param[in, out] values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] values `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type */ template void operator()(const Polyhedron& mesh, std::size_t window_size, ValuePropertyMap values) const { - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; std::vector smoothed_values; smoothed_values.reserve(mesh.size_of_facets()); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::map neighbors; - NeighborSelector()(facet_it, window_size, + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::map neighbors; + NeighborSelector()(*facet_it, window_size, neighbors); // gather neighbors in the window std::vector neighbor_values; neighbor_values.reserve(neighbors.size()); - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { neighbor_values.push_back(values[it->first]); } @@ -184,9 +186,8 @@ public: } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); - ++facet_it) { + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { values[facet_it] = *smoothed_value_it; } } @@ -224,20 +225,20 @@ template class Neighbor_selector_by_edge { private: - typedef typename Polyhedron::Facet::Halfedge_around_facet_const_circulator - Halfedge_around_facet_const_circulator; + typedef Halfedge_around_face_circulator Halfedge_around_face_circulator; public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; /** * Breadth-first traversal on facets by treating facets, which share a common edge, are 1-level neighbors. * @param facet root facet * @param max_level maximum allowed distance (number of levels) between root facet and visited facet * @param[out] neighbors visited facets and their distances to root facet */ - void operator()(Facet_const_handle facet, + void operator()(const Polyhedron& polyhedron, + face_descriptor facet, std::size_t max_level, - std::map& neighbors) const { - typedef std::pair Facet_level_pair; + std::map& neighbors) const { + typedef std::pair Facet_level_pair; std::queue facet_queue; facet_queue.push(Facet_level_pair(facet, 0)); @@ -250,11 +251,10 @@ public: while(!facet_queue.empty()) { const Facet_level_pair& pair = facet_queue.front(); - Halfedge_around_facet_const_circulator facet_circulator = - pair.first->facet_begin(); + Halfedge_around_face_circulator facet_circulator(halfedge(pair.first,polyhedron),polyhedron), done(facet_circulator); do { - if(!facet_circulator->opposite()->is_border()) { - Facet_level_pair new_pair(facet_circulator->opposite()->facet(), + if(!(face(opposite(*facet_circulator,polyhedron),polyhedron) == boost::graph_traits::null_face())) { + Facet_level_pair new_pair(face(opposite(*facet_circulator,polyhedron),polyhedron), pair.second + 1); if(neighbors.insert(new_pair).second && new_pair.second < max_level) { // first insert new_pair to map @@ -263,7 +263,7 @@ public: new_pair); // if its level is equal to max_level do not put it in } // queue since we do not want to traverse its neighbors } - } while(++facet_circulator != pair.first->facet_begin()); + } while(++facet_circulator != done); facet_queue.pop(); } @@ -275,22 +275,22 @@ template class Neighbor_selector_by_vertex { private: - typedef typename Polyhedron::Facet::Halfedge_around_vertex_const_circulator - Halfedge_around_vertex_const_circulator; - typedef typename Polyhedron::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Polyhedron::Vertex_const_iterator Vertex_const_iterator; + typedef Halfedge_around_target_circulator Halfedge_around_target_circulator; + typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; /** * Breadth-first traversal on facets by treating facets, which share a common vertex, are 1-level neighbors. * @param facet root facet * @param max_level maximum allowed distance (number of levels) between root facet and visited facet * @param[out] neighbors visited facets and their distances to root facet */ - void operator()(Facet_const_handle facet, + void operator()(const Polyhedron& polyhedron, + face_descriptor facet, std::size_t max_level, - std::map& neighbors) const { - typedef std::pair Facet_level_pair; + std::map& neighbors) const { + typedef std::pair Facet_level_pair; std::queue facet_queue; facet_queue.push(Facet_level_pair(facet, 0)); @@ -303,15 +303,14 @@ public: while(!facet_queue.empty()) { const Facet_level_pair& pair = facet_queue.front(); - Facet_const_handle facet_front = pair.first; - Halfedge_const_iterator edge = facet_front->halfedge(); + face_descriptor facet_front = pair.first; + halfedge_iterator edge = halfedge(facet_front,polyhedron) do { // loop on three vertices of the facet - Vertex_const_iterator vertex = edge->vertex(); - Halfedge_around_vertex_const_circulator vertex_circulator = - vertex->vertex_begin(); + Halfedge_around_target_circulator vertex_circulator(*edge,polyhedron), done(vertex_circulator); + do { // for each vertex loop on incoming edges (through those edges loop on neighbor facets which includes the vertex) - if(!vertex_circulator->is_border()) { - Facet_level_pair new_pair(vertex_circulator->opposite()->facet(), + if(!(face(*vertex_circulator,polyhedron) == graph_traitsvertex_begin()); - } while((edge = edge->next()) != facet_front->halfedge()); + } while(++vertex_circulator != done); + } while((edge = next(edge,polyhedron)) != halfedge(facet_front,polyhedron)); facet_queue.pop(); } diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h index 005d9f7acf1..59d1523751b 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h @@ -78,10 +78,8 @@ private: typedef typename GeomTraits::Segment_3 Segment; typedef typename GeomTraits::FT FT; - typedef typename Polyhedron::Facet Facet; - - typedef typename boost::graph_traits::face_iterator Facet_const_iterator; - typedef typename boost::graph_traits::face_descriptor Facet_const_handle; + typedef typename boost::graph_traits::face_iterator face_iterator; + typedef typename boost::graph_traits::face_descriptor face_handle; typedef AABB_face_graph_triangle_primitive Primitive; typedef AABB_traits_SDF @@ -184,7 +182,7 @@ public: /** * Calculates SDF values for each facet in a range, and stores them in @a sdf_values. Note that sdf values are neither smoothed nor normalized. - * @tparam FacetValueMap `WritablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @tparam FacetValueMap `WritablePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type * @tparam InputIterator Iterator over polyhedrons. Its value type is `pointer to polyhedron`. * @param facet_begin range begin * @param facet_end range past-the-end @@ -374,7 +372,7 @@ private: * @return calculated SDF value */ boost::optional calculate_sdf_value_of_facet( - Facet_const_handle facet, + face_handle facet, double cone_angle, bool accept_if_acute, const Disk_samples_list& disk_samples) const { @@ -386,9 +384,9 @@ private: normal=scale_functor(normal, FT(1.0/std::sqrt(to_double(normal.squared_length())))); - CGAL::internal::SkipPrimitiveFunctor + CGAL::internal::SkipPrimitiveFunctor skip(facet); - CGAL::internal::FirstIntersectionVisitor + CGAL::internal::FirstIntersectionVisitor visitor; return calculate_sdf_value_of_point(center, normal, skip, visitor, cone_angle, diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h index 32b0f2c8014..1002a60fa77 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h @@ -47,8 +47,8 @@ class Postprocess_sdf_values { typedef typename Polyhedron::Facet Facet; - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; typedef Bilateral_filtering Default_filter; @@ -73,48 +73,49 @@ public: * Sdf values on these facets are assigned to average sdf value of its neighbors. * If still there is any facet which has no sdf value, assigns minimum sdf value to it. * This is meaningful since (being an outlier) zero sdf values might effect normalization & log extremely. - * @param[in, out] sdf_values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] sdf_values `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type */ template void check_missing_sdf_values(const Polyhedron& mesh, SDFPropertyMap sdf_values) { - std::vector still_missing_facets; + std::vector still_missing_facets; double min_sdf = (std::numeric_limits::max)(); // If there is any facet which has no sdf value, assign average sdf value of its neighbors - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double sdf_value = sdf_values[facet_it]; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double sdf_value = sdf_values[*facet_it]; CGAL_assertion(sdf_value == -1 || sdf_value >= 0); // validity check if(sdf_value != -1.0) { min_sdf = (std::min)(sdf_value, min_sdf); continue; } - typename Facet::Halfedge_around_facet_const_circulator facet_circulator = - facet_it->facet_begin(); + typename Halfedge_around_face_circulator facet_circulator(halfedge(*facet_it,mesh),mesh), done(facet_circulator); + double total_neighbor_sdf = 0.0; std::size_t nb_valid_neighbors = 0; do { - if(!facet_circulator->opposite()->is_border()) { - double neighbor_sdf = sdf_values[facet_circulator->opposite()->facet()]; + if(!(*facet_circulator)->opposite()->is_border()) { + double neighbor_sdf = sdf_values[(*facet_circulator)->opposite()->facet()]; if(neighbor_sdf != -1) { total_neighbor_sdf += neighbor_sdf; ++nb_valid_neighbors; } } - } while( ++facet_circulator != facet_it->facet_begin()); + } while( ++facet_circulator != done); if(nb_valid_neighbors == 0) { - still_missing_facets.push_back(facet_it); + still_missing_facets.push_back(*facet_it); } else { sdf_value = total_neighbor_sdf / nb_valid_neighbors; - sdf_values[facet_it] = sdf_value; + sdf_values[*facet_it] = sdf_value; // trying to update min_sdf is pointless, since it is interpolated one of the neighbors sdf will be smaller than it } } // If still there is any facet which has no sdf value, assign minimum sdf value. // This is meaningful since (being an outlier) 0 sdf values might effect normalization & log extremely. - for(typename std::vector::iterator it = + for(typename std::vector::iterator it = still_missing_facets.begin(); it != still_missing_facets.end(); ++it) { sdf_values[*it] = min_sdf; @@ -126,9 +127,10 @@ public: SDFPropertyMap sdf_values) { double min_sdf = (std::numeric_limits::max)(); double max_sdf = -min_sdf; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double sdf_value = sdf_values[facet_it]; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double sdf_value = sdf_values[*facet_it]; max_sdf = (std::max)(sdf_value, max_sdf); min_sdf = (std::min)(sdf_value, min_sdf); } @@ -136,7 +138,7 @@ public: } /** * Normalize sdf values between [0-1]. - * @param sdf_values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param sdf_values `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type * @return minimum and maximum SDF values before normalization */ template @@ -151,9 +153,10 @@ public: } const double max_min_dif = max_sdf - min_sdf; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - sdf_values[facet_it] = (sdf_values[facet_it] - min_sdf) / max_min_dif; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + sdf_values[*facet_it] = (sdf_values[*facet_it] - min_sdf) / max_min_dif; } return std::make_pair(min_sdf, max_sdf); } @@ -207,19 +210,17 @@ class Surface_mesh_segmentation { //type definitions public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; private: //typedef typename Polyhedron::Traits Kernel; typedef typename GeomTraits::Point_3 Point; - typedef typename Polyhedron::Facet Facet; - - typedef typename Polyhedron::Edge_const_iterator Edge_const_iterator; - typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle; - typedef typename Polyhedron::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; - typedef typename Polyhedron::Vertex_const_iterator Vertex_const_iterator; + typedef typename boost::graph_traits::edge_iterator edge_iterator; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::face_iterator face_iterator; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; typedef SDF_calculation SDF_calculation_class; @@ -287,10 +288,11 @@ public: // apply graph cut GraphCut()(edges, edge_weights, probability_matrix, labels); std::vector::iterator label_it = labels.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++label_it) { - segment_pmap[facet_it] = *label_it; // fill with cluster-ids + segment_pmap[*facet_it] = *label_it; // fill with cluster-ids } if(clusters_to_segments) { // assign a segment id for each facet @@ -310,7 +312,7 @@ private: * @param edge whose dihedral angle is computed using incident facets * @return computed dihedral angle */ - double calculate_dihedral_angle_of_edge(Halfedge_const_handle edge) const { + double calculate_dihedral_angle_of_edge(halfedge_descriptor edge) const { CGAL_precondition(!edge->is_border_edge()); const Point& a = edge->vertex()->point(); const Point& b = edge->prev()->vertex()->point(); @@ -333,7 +335,7 @@ private: /** * Normalize sdf values using function: * normalized_sdf = log( alpha * ( current_sdf - min_sdf ) / ( max_sdf - min_sdf ) + 1 ) / log( alpha + 1 ) - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type * @param[out] normalized_sdf_values normalized values stored in facet iteration order * Important note: @a sdf_values parameter should contain linearly normalized values between [0-1] */ @@ -341,9 +343,10 @@ private: void log_normalize_sdf_values(SDFPropertyMap sdf_values, std::vector& normalized_sdf_values) { normalized_sdf_values.reserve(mesh.size_of_facets()); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double log_normalized = log(sdf_values[facet_it] * CGAL_NORMALIZATION_ALPHA + + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double log_normalized = log(sdf_values[*facet_it] * CGAL_NORMALIZATION_ALPHA + 1) / log(CGAL_NORMALIZATION_ALPHA + 1); normalized_sdf_values.push_back(log_normalized); } @@ -382,26 +385,31 @@ private: // important note: ids should be compatible with iteration order of facets: // [0 <- facet_begin(),...., size_of_facets() -1 <- facet_end()] // Why ? it is send to graph cut algorithm where other data associated with facets are also sorted according to iteration order. - std::map facet_index_map; + std::map facet_index_map; std::size_t facet_index = 0; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++facet_index) { - facet_index_map[facet_it] = facet_index; + facet_index_map[*facet_it] = facet_index; } const double epsilon = 5e-6; // edges and their weights. pair stores facet-id pairs (see above) (may be using boost::tuple can be more suitable) - for(Edge_const_iterator edge_it = mesh.edges_begin(); - edge_it != mesh.edges_end(); ++edge_it) { - if(edge_it->is_border_edge()) { + edge_iterator edge_it, eend; + for(boost::tie(edge_it,eend) = CGAL::edges(mesh); // AF: get rid of CGAL:: + edge_it != eend; ++edge_it) { + halfedge_descriptor hd = halfedge(*edge_it,mesh); + halfedge_descriptor ohd = opposite(hd,mesh); + if((face(hd,mesh)==boost::graph_traits::null_face()) + || (face(ohd,mesh)==boost::graph_traits::null_face())) { continue; // if edge does not contain two neighbor facets then do not include it in graph-cut } - const std::size_t index_f1 = facet_index_map[edge_it->facet()]; - const std::size_t index_f2 = facet_index_map[edge_it->opposite()->facet()]; + const std::size_t index_f1 = facet_index_map[hd->facet()]; + const std::size_t index_f2 = facet_index_map[ohd->facet()]; edges.push_back(std::make_pair(index_f1, index_f2)); - double angle = calculate_dihedral_angle_of_edge(edge_it); + double angle = calculate_dihedral_angle_of_edge(hd); angle = (std::max)(angle, epsilon); angle = -log(angle); @@ -432,8 +440,8 @@ private: * set of connected facets which are placed under same cluster. Note that returned segment-ids are ordered by average sdf value of segment ascen. * * @param number_of_clusters cluster-ids in @a segments should be between [0, number_of_clusters -1] - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type. + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type + * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `std::size_t` as value type. * @return number of segments */ template @@ -442,12 +450,12 @@ private: // assign a segment-id to each facet std::size_t segment_id = number_of_clusters; std::vector > segments_with_average_sdf_values; - - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - if(segments[facet_it] < + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + if(segments[*facet_it] < number_of_clusters) { // not visited by depth_first_traversal - double average_sdf_value = breadth_first_traversal(facet_it, segment_id, + double average_sdf_value = breadth_first_traversal(*facet_it, segment_id, sdf_values, segments); segments_with_average_sdf_values.push_back(std::make_pair(segment_id, @@ -470,10 +478,10 @@ private: } // make one-pass on facets. First make segment-id zero based by subtracting number_of_clusters // . Then place its sorted index to pmap - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::size_t segment_id = segments[facet_it] - number_of_clusters; - segments[facet_it] = segment_id_to_sorted_id_map[segment_id]; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::size_t segment_id = segments[*facet_it] - number_of_clusters; + segments[*facet_it] = segment_id_to_sorted_id_map[segment_id]; } return segment_id - number_of_clusters; } @@ -483,15 +491,15 @@ private: * Each visited facet assigned to @a segment_id. * @param facet root facet * @param segment_id segment-id of root facet - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type. + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type + * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `std::size_t` as value type. * @return average sdf value for segment */ template double - breadth_first_traversal(Facet_const_handle root, std::size_t segment_id, + breadth_first_traversal(face_descriptor root, std::size_t segment_id, SDFProperyMap sdf_values, SegmentPropertyMap segments) { - std::queue facet_queue; + std::queue facet_queue; facet_queue.push(root); std::size_t prev_segment_id = segments[root]; @@ -501,15 +509,14 @@ private: std::size_t visited_facet_count = 1; while(!facet_queue.empty()) { - Facet_const_handle facet = facet_queue.front(); + face_descriptor facet = facet_queue.front(); - typename Facet::Halfedge_around_facet_const_circulator facet_circulator = - facet->facet_begin(); + typename Halfedge_around_face_circulator facet_circulator(halfedge(facet,mesh),mesh), done(facet_circulator); do { - if(facet_circulator->opposite()->is_border()) { + if((*facet_circulator)->opposite()->is_border()) { continue; // no facet to traversal } - Facet_const_handle neighbor = facet_circulator->opposite()->facet(); + face_descriptor neighbor = (*facet_circulator)->opposite()->facet(); if(prev_segment_id == segments[neighbor]) { segments[neighbor] = segment_id; facet_queue.push(neighbor); @@ -517,7 +524,7 @@ private: total_sdf_value += sdf_values[neighbor]; ++visited_facet_count; } - } while( ++facet_circulator != facet->facet_begin()); + } while( ++facet_circulator != done); facet_queue.pop(); } diff --git a/Surface_mesh_segmentation/include/CGAL/mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/mesh_segmentation.h index 1f89c871085..5bd7fac8022 100644 --- a/Surface_mesh_segmentation/include/CGAL/mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/mesh_segmentation.h @@ -60,7 +60,7 @@ sdf_values( const Polyhedron& polyhedron, * @pre @a polyhedron.is_pure_triangle() * * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type * @tparam GeomTraits a model of SegmentationGeomTraits * * @param polyhedron surface mesh on which SDF values are computed @@ -107,7 +107,7 @@ sdf_values( const Polyhedron& polyhedron, * @pre Raw values should be greater or equal to 0. -1 indicates when no value could be computed * * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type * * @param polyhedron surface mesh on which SDF values are computed * @param[in, out] sdf_values_map the SDF value of each facet @@ -145,8 +145,8 @@ sdf_values_postprocessing(const Polyhedron& polyhedron, * @pre @a number_of_clusters > 0 * * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type + * @tparam SDFPropertyMap a `ReadablePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type + * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `std::size_t` as value type * @tparam GeomTraits a model of SegmentationGeomTraits * * @param polyhedron surface mesh corresponding to the SDF values @@ -197,7 +197,8 @@ segmentation_via_sdf_values(const Polyhedron& polyhedron, bool output_cluster_ids = false, GeomTraits traits = GeomTraits()) { - typedef std::map< typename Polyhedron::Facet_const_handle, double> + typedef boost::graph_traits::face_descriptor face_descriptor; + typedef std::map Facet_double_map; Facet_double_map internal_sdf_map; boost::associative_property_map sdf_property_map( @@ -229,7 +230,7 @@ segmentation_via_sdf_values(const Polyhedron& polyhedron, * @pre @a number_of_clusters > 0 * * @tparam Polyhedron a %CGAL polyhedron - * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type + * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `std::size_t` as value type * @tparam GeomTraits a model of SegmentationGeomTraits * * @param polyhedron surface mesh on which SDF values are computed