diff --git a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h index c3827763867..09bd6a4a02d 100644 --- a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h @@ -803,6 +803,13 @@ detect_features(FT angle_in_degree, BOOST_FOREACH(Polyhedron_type& p, poly) { initialize_ts(p); + typedef typename boost::graph_traits::face_descriptor face_descriptor; + std::map face_ids; + std::size_t id = 0; + BOOST_FOREACH(face_descriptor& f, faces(p)) + { + face_ids[f] = id++; + } #if CGAL_MESH_3_VERBOSE std::size_t poly_id = &p-&poly[0]; @@ -816,7 +823,8 @@ detect_features(FT angle_in_degree, typedef typename boost::property_map >::type VIPMap; PIDMap pid_map = get(face_patch_id_t(), p); VIPMap vip_map = get(vertex_incident_patches_t(), p); - nb_of_patch_plus_one +=PMP::detect_features(p, angle_in_degree,pid_map, vip_map, PMP::parameters::first_index(nb_of_patch_plus_one)); + nb_of_patch_plus_one +=PMP::detect_features(p, angle_in_degree,pid_map, vip_map, PMP::parameters::first_index(nb_of_patch_plus_one) + .face_index_map(boost::make_assoc_property_map(face_ids))); internal::Mesh_3::Is_featured_edge is_featured_edge(p); diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index cd615e2da54..161fb60388e 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -453,12 +453,21 @@ detect_features(FT angle_in_degree, std::vector& poly) BOOST_FOREACH(Polyhedron& p, poly) { initialize_ts(p); + typedef typename boost::graph_traits::face_descriptor face_descriptor; + std::map face_ids; + std::size_t id = 0; + BOOST_FOREACH(face_descriptor& f, faces(p)) + { + face_ids[f] = id++; + } + typedef typename boost::property_map >::type PIDMap; typedef typename boost::property_map >::type VIPMap; PIDMap pid_map = get(face_patch_id_t(), p); VIPMap vip_map = get(vertex_incident_patches_t(), p); // Get sharp features - nb_of_patch_plus_one += PMP::detect_features(p, angle_in_degree,pid_map, vip_map, PMP::parameters::first_index(nb_of_patch_plus_one)); + nb_of_patch_plus_one += PMP::detect_features(p, angle_in_degree,pid_map, vip_map, PMP::parameters::first_index(nb_of_patch_plus_one) + .face_index_map(boost::make_assoc_property_map(face_ids))); internal::Mesh_3::Is_featured_edge is_featured_edge(p); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h index aeb94ea90c1..c03ea194422 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h @@ -28,8 +28,10 @@ #include #include #include +#include #include + namespace CGAL { namespace Polygon_mesh_processing { @@ -72,63 +74,31 @@ is_sharp(PolygonMesh& polygonMesh, } -template -void -flood(PolygonMesh& polygonMesh, - typename boost::graph_traits::face_descriptor f, - PatchIdMap& pid_map, - const typename boost::property_traits::value_type& patch_id, - std::set::face_descriptor>& unsorted_faces, - EIF_map& eif) +//wrapper for patchid map. +template +struct PatchIdMapWrapper { - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::property_traits::category category; + typedef typename boost::property_traits::value_type value_type; + typedef typename boost::property_traits::reference reference; + typedef typename boost::property_traits::key_type key_type; - typedef std::set face_descriptor_set; - typedef std::set He_handle_set; - // Initialize he_to_explore with halfedges of the starting facet - He_handle_set he_to_explore; - BOOST_FOREACH(halfedge_descriptor hd, - CGAL::halfedges_around_face(halfedge(f,polygonMesh), polygonMesh)) - { - he_to_explore.insert(opposite(hd,polygonMesh)); - } + PatchIdMap map; + value_type offset; + PatchIdMapWrapper(PatchIdMap& map, value_type offset) + :map(map), offset(offset){} +}; +template +typename PatchIdMapWrapper::value_type get(PatchIdMapWrapper& map, Handle_type h) +{ + return get(map.map, h) - map.offset; +} - // While there is something to explore - while ( ! he_to_explore.empty() ) - { - // Get next halfedge to explore - halfedge_descriptor he = *(he_to_explore.begin()); - he_to_explore.erase(he_to_explore.begin()); - - // If we don't go through a border of the patch - if ( ! get(eif, edge(he, polygonMesh)) && ! is_border(he,polygonMesh)) - { - face_descriptor explored_facet = face(he,polygonMesh); - - // Mark facet and delete it from unsorted - put(pid_map, explored_facet, patch_id); - unsorted_faces.erase(explored_facet); - - // Add/Remove facet's halfedge to/from explore list - BOOST_FOREACH(halfedge_descriptor hd, - CGAL::halfedges_around_face(halfedge(explored_facet,polygonMesh), - polygonMesh)) - { - halfedge_descriptor current_he = hd; - - // do not explore heh again - if ( current_he == he ) { continue; } - - // if current_he is not in to_explore set, add it, otherwise remove it - // (because we just explore the facet he_begin is pointing to) - if ( he_to_explore.erase(current_he) == 0 ) - { - he_to_explore.insert(opposite(current_he,polygonMesh)); - } - } - } - } +template +void put(PatchIdMapWrapper& map, Handle_type h, + typename PatchIdMapWrapper::value_type pid) +{ + put(map.map, h, pid + map.offset); } } //end internal @@ -138,7 +108,7 @@ flood(PolygonMesh& polygonMesh, * * Detects the sharp edges of `p` according to `angle_in_deg` and computes the number of sharp edges incident to each vertex. * - * Property maps for CGAL::edge_is_feature_t and CGAL::vertex_feature_degree_t should be either + * Property maps for `CGAL::edge_is_feature_t` and `CGAL::vertex_feature_degree_t` should be either * available as internal property maps to `p` or provided as Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` @@ -224,9 +194,8 @@ void detect_sharp_edges(PolygonMesh& p, * * Computes for each face the index of the corresponding surface patch, * based on the feature edges which are considered as barriers between surface patches. - * - * A filled property map for CGAL::edge_is_feature_t should be either - * available as an internal property map to `p` or provided as one of the Named Parameters. + * Filled property maps for `CGAL::edge_is_feature_t` and `CGAL::face_index_t`should be either + * available as a internal property maps to `p` or provided as Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` * \tparam PatchIdMap a model of `ReadWritePropertyMap` with @@ -242,6 +211,7 @@ void detect_sharp_edges(PolygonMesh& p, * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalParamBegin{edge_is_feature_map} a property map containing the sharp edges of `p` \cgalParamEnd * \cgalParamBegin{first_index} an std::size_t containing the index of the first surface patch of `p` \cgalParamEnd + * \cgalParamBegin{face_index_map} a property map containing the index of each face of `p` \cgalParamEnd * \cgalNamedParamsEnd * \returns the number of surface patches. * @@ -262,33 +232,20 @@ detect_surface_patches(PolygonMesh& p, EIF_map eif = choose_param(get_param(np, internal_np::edge_is_feature), get(CGAL::edge_is_feature, p)); - std::size_t current_surface_index_ = boost::choose_param(get_param(np, internal_np::first_index), + typename GetFaceIndexMap::const_type + fimap = choose_param(get_param(np, internal_np::face_index), + get_const_property_map(boost::face_index, p)); + + std::size_t offset = boost::choose_param(get_param(np, internal_np::first_index), 1); typedef typename GetGeomTraits::type GT; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename boost::property_traits::value_type PatchId; - // Initialize unsorted_faces - typedef std::set face_descriptor_set; - face_descriptor_set unsorted_faces; - BOOST_FOREACH(typename boost::graph_traits::face_descriptor fd, faces(p)) - { - unsorted_faces.insert(fd); - } + internal::PatchIdMapWrapper wrapmap(patch_id_map, offset); + return connected_components(p, wrapmap, parameters::edge_is_constrained_map(eif) + .face_index_map(fimap)); - // Flood - while ( ! unsorted_faces.empty() ) - { - face_descriptor f = *(unsorted_faces.begin()); - unsorted_faces.erase(unsorted_faces.begin()); - - const PatchId patch_id = internal::generate_patch_id(PatchId(), - current_surface_index_); - put(patch_id_map, f, patch_id); - internal::flood(p, f, patch_id_map, patch_id,unsorted_faces, eif); - ++current_surface_index_; - } - return current_surface_index_ - 1; } @@ -297,7 +254,7 @@ detect_surface_patches(PolygonMesh& p, * * Collects the surface patches of the faces incident to each vertex * - * * A filled property map for CGAL::edge_is_feature_t should be either + * * A filled property map for `CGAL::edge_is_feature_t` should be either * available as an internal property map to `p` or provided as one of the Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` @@ -378,8 +335,8 @@ void detect_incident_patches(PolygonMesh& p, * `CGAL::Polygon_mesh_processing::detect_surface_patches()` and * `CGAL::Polygon_mesh_processing::detect_incident_patches()` * - * Property maps for CGAL::edge_is_feature_t and CGAL::vertex_feature_degree_t should be either - * available as internal property maps to `p` or provided as Named Parameters. + * Property maps for `CGAL::edge_is_feature_t`, `CGAL::vertex_feature_degree_t` and `CGAL::face_index_t` + * should be either available as internal property maps to `p` or provided as Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` * \tparam FT a number type. It is @@ -406,6 +363,7 @@ void detect_incident_patches(PolygonMesh& p, * \cgalParamBegin{edge_is_feature_map} a property map that will contain the constrained-or-not status of each edge of `p` \cgalParamEnd * \cgalParamBegin{vertex_feature_degree_map} a property map that will contain the number of adjacent feature edges for each vertex of `p` \cgalParamEnd * \cgalParamBegin{first_index} an std::size_t containing the index of the first surface patch of `p` \cgalParamEnd + * \cgalParamBegin{face_index_map} a property map containing the index of each face of `p` \cgalParamEnd * \cgalNamedParamsEnd * \returns the number of surface patches. * diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp index 0a42dd4d585..f46dcd9c2d5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp @@ -85,6 +85,7 @@ void Polyhedron_demo_detect_sharp_edges_plugin::detectSharpEdgesWithInputDialog( detectSharpEdges(true); } +namespace PMP = CGAL::Polygon_mesh_processing; void Polyhedron_demo_detect_sharp_edges_plugin::detectSharpEdges(bool input_dialog, double angle) { @@ -123,6 +124,7 @@ void Polyhedron_demo_detect_sharp_edges_plugin::detectSharpEdges(bool input_dial // Detect edges QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::processEvents(); + std::size_t first_patch = 1; Q_FOREACH(Poly_tuple tuple, polyhedrons) { Scene_facegraph_item* item = @@ -133,9 +135,13 @@ void Polyhedron_demo_detect_sharp_edges_plugin::detectSharpEdges(bool input_dial PatchID pid = get(CGAL::face_patch_id_t(), *pMesh); typedef typename boost::property_map >::type VIP; VIP vip = get(CGAL::vertex_incident_patches_t(), *pMesh); - CGAL::Polygon_mesh_processing::detect_features(*pMesh, angle, pid, vip); + first_patch+=PMP::detect_features(*pMesh, angle, pid, vip, + PMP::parameters::first_index(first_patch)); //update item item->setItemIsMulticolor(true); +#ifndef USE_SURFACE_MESH + item->set_color_vector_read_only(false); +#endif item->invalidateOpenGLBuffers(); // update scene