diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index ec4dfe43ba5..4c9dab18b43 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -303,35 +303,6 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits::fa > ::type type; }; - namespace Polygon_mesh_processing - { - template - class GetSplitVisitor - { - public: - struct DummySplitVisitor - { - template - void start(const T&) const - {} - - template - void visit(const T&) const - {} - - void end() const - {} - }; - - typedef typename internal_np::Lookup_named_param_def< - internal_np::split_visitor_t, - NamedParameters, - DummySplitVisitor//default - >::type type; - }; - - } // namespace Polygon_mesh_processing - namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false) } diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 3918b5df2d6..391ded449e5 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -47,7 +47,7 @@ CGAL_add_named_parameter(geom_traits_t, geom_traits, geom_traits) CGAL_add_named_parameter(vertex_incident_patches_t, vertex_incident_patches, vertex_incident_patches_map) CGAL_add_named_parameter(density_control_factor_t, density_control_factor, density_control_factor) CGAL_add_named_parameter(use_delaunay_triangulation_t, use_delaunay_triangulation, use_delaunay_triangulation) -CGAL_add_named_parameter(split_visitor_t, split_visitor, split_visitor) +CGAL_add_named_parameter(triangulate_visitor_t, triangulate_visitor, triangulate_visitor) CGAL_add_named_parameter(fairing_continuity_t, fairing_continuity, fairing_continuity) CGAL_add_named_parameter(sparse_linear_solver_t, sparse_linear_solver, sparse_linear_solver) CGAL_add_named_parameter(number_of_relaxation_steps_t, number_of_relaxation_steps, number_of_relaxation_steps) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPTriangulateFaceVisitor.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPTriangulateFaceVisitor.h new file mode 100644 index 00000000000..a9445369792 --- /dev/null +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPTriangulateFaceVisitor.h @@ -0,0 +1,34 @@ +/// \ingroup PkgPolygonMeshProcessingConcepts +/// \cgalConcept +/// +/// The concept `PMPTriangulateFaceVisitor` defines the requirements for the visitor +/// used in \link PMP_meshing_grp triangulation-related functions \endlink to track +/// the creation of new faces. +/// +/// \cgalRefines `CopyConstructible` +/// \cgalHasModel `CGAL::Polygon_mesh_processing::Corefinement::Default_visitor`. + + +class PMPTriangulateFaceVisitor { +public: +/// Face decriptor type +typedef unspecified_type face_descriptor; + +/// @name Functions used by `triangulate_face()` and `triangulate_faces()` +/// @{ + /// called before the triangulation of `f_split`. Note that `f_split` + /// will be one of the faces of the triangulation. Each subsequent call to + /// `after_subface_created()` will correspond to + /// the creation of a new face of the triangulation of `f_split`. + void before_subface_creations(face_descriptor f_split); + + /// called when the triangulation of a face in `tm` is finished + void after_subface_creations(); + + /// called after creating a new triangle face `f_new` to triangulate the face passed to `before_subface_creations()`. + /// Note that the call is placed just after a call to `add_face()` so the halfedge pointer is not set yet. + void after_subface_created(face_descriptor f_new); + + /// @} + +}; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp index 931a0a0e0c7..1e5ed579627 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp @@ -53,7 +53,7 @@ struct Visitor : container(container) {} - void start(face_descriptor fd) + void before_subface_creations(face_descriptor fd) { std::cout << "split : " << fd << " into:" << std::endl; Container::iterator it = container.find(fd); @@ -61,13 +61,13 @@ struct Visitor container.erase(it); } - void visit(face_descriptor fd) + void after_subface_created(face_descriptor fd) { std::cout << " " << fd; container[fd]=qfd; } - void end() + void after_subface_creations() { std::cout << std::endl; } @@ -94,7 +94,7 @@ int main(int argc, char* argv[]) Visitor v(t2q); CGAL::Polygon_mesh_processing::triangulate_faces(copy, - CGAL::Polygon_mesh_processing::parameters::split_visitor(v)); + CGAL::Polygon_mesh_processing::parameters::triangulate_visitor(v)); for(boost::unordered_map::iterator it = t2q.begin(); it != t2q.end(); ++it){ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h index ca546a6ba81..0cba62ebd28 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h @@ -45,6 +45,26 @@ namespace CGAL { namespace Polygon_mesh_processing { +namespace Triangulate_faces +{ +/** \ingroup PMP_meshing_grp +* Default new face visitor model of `PMPTriangulateFaceVisitor`. +* All its functions have an empty body. This class can be used as a +* base class if only some of the functions of the concept require to be +* overriden. +*/ +template +struct Default_visitor { + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + + void before_subface_creations(face_descriptor /*f_old*/) {} + void after_subface_creations() {} + void after_subface_created(face_descriptor /*f_new*/) {} +}; + +} //end namespace Triangulate_faces + namespace internal { template p1p3) ? CGAL::Euler::split_face(v0, v2, pmesh) : CGAL::Euler::split_face(v1, v3, pmesh); - visitor.visit(face(res,pmesh)); - visitor.visit(face(opposite(res,pmesh),pmesh)); - visitor.end(); + visitor.after_subface_created(face(res,pmesh)); + visitor.after_subface_created(face(opposite(res,pmesh),pmesh)); } else { @@ -213,7 +232,7 @@ public: // then modify the polyhedron - visitor.start(f); + visitor.before_subface_creations(f); // make_hole. (see comment in function body) this->make_hole(halfedge(f, pmesh), pmesh); @@ -270,10 +289,10 @@ public: set_next(h2, h0, pmesh); Euler::fill_hole(h0, pmesh); - visitor.visit(face(h0, pmesh)); + visitor.after_subface_created(face(h0, pmesh)); } } - visitor.end(); + visitor.after_subface_creations(); return true; } @@ -311,7 +330,7 @@ public: ++i; } - visitor.start(f); + visitor.before_subface_creations(f); bool first = true; std::vector hedges; hedges.reserve(4); @@ -321,7 +340,7 @@ public: first=false; else f=add_face(pmesh); - visitor.visit(f); + visitor.after_subface_created(f); std::array indices = make_array( triangle.first, @@ -352,7 +371,7 @@ public: set_halfedge(f, hedges[0], pmesh); hedges.clear(); } - visitor.end(); + visitor.after_subface_creations(); return true; } @@ -430,10 +449,10 @@ public: * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} * \cgalParamNEnd * -* \cgalParamNBegin{split_visitor} -* \cgalParamDescription{a visitor that allows track how faces are split} -* \cgalParamType{a class model of `SplitVisitor`} -* \cgalParamDefault{No visitor.} +* \cgalParamNBegin{triangulate_visitor} +* \cgalParamDescription{a visitor that allows to track how faces are triangulated into subfaces} +* \cgalParamType{a class model of `PMPTriangulateFaceVisitor`} +* \cgalParamDefault{`Triangulate_faces::Default_visitor`} * \cgalParamExtra{Note that the visitor will be copied, so * it should not have any data member that does have a reference-like type.} * `\cgalParamNEnd @@ -461,12 +480,16 @@ bool triangulate_face(typename boost::graph_traits::face_descriptor //Option bool use_cdt = choose_parameter(get_parameter(np, internal_np::use_delaunay_triangulation), true); - typedef typename GetSplitVisitor::type SplitVisitor; - typedef typename GetSplitVisitor::DummySplitVisitor DummySplitVisitor; - SplitVisitor visitor = choose_param(get_param(np, internal_np::split_visitor), - DummySplitVisitor()); + typedef typename internal_np::Lookup_named_param_def< + internal_np::triangulate_visitor_t, + NamedParameters, + Triangulate_faces::Default_visitor//default + >::type Visitor; + Visitor visitor = choose_parameter( + get_parameter(np, internal_np::triangulate_visitor), + Triangulate_faces::Default_visitor()); - internal::Triangulate_modifier modifier(vpmap); + internal::Triangulate_modifier modifier(vpmap); return modifier.triangulate_face(f, pmesh, use_cdt, visitor); } @@ -507,6 +530,14 @@ bool triangulate_face(typename boost::graph_traits::face_descriptor * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} * \cgalParamNEnd +* +* \cgalParamNBegin{triangulate_visitor} +* \cgalParamDescription{a visitor that allows to track how faces are triangulated into subfaces} +* \cgalParamType{a class model of `PMPTriangulateFaceVisitor`} +* \cgalParamDefault{`Triangulate_faces::Default_visitor`} +* \cgalParamExtra{Note that the visitor will be copied, so +* it should not have any data member that does have a reference-like type.} +* `\cgalParamNEnd * \cgalNamedParamsEnd * * @return `true` if all the faces have been triangulated. @@ -533,12 +564,16 @@ bool triangulate_faces(FaceRange face_range, //Option bool use_cdt = choose_parameter(get_parameter(np, internal_np::use_delaunay_triangulation), true); - typedef typename GetSplitVisitor::type SplitVisitor; - typedef typename GetSplitVisitor::DummySplitVisitor DummySplitVisitor; - SplitVisitor visitor = choose_parameter(get_parameter(np, internal_np::split_visitor), - DummySplitVisitor()); + typedef typename internal_np::Lookup_named_param_def< + internal_np::triangulate_visitor_t, + NamedParameters, + Triangulate_faces::Default_visitor//default + >::type Visitor; + Visitor visitor = choose_parameter( + get_parameter(np, internal_np::triangulate_visitor), + Triangulate_faces::Default_visitor()); - internal::Triangulate_modifier modifier(vpmap); + internal::Triangulate_modifier modifier(vpmap); return modifier(face_range, pmesh, use_cdt, visitor); }