diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp index 6416f6fd3341..96abe70b90db 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp @@ -39,6 +39,8 @@ using Vertex_pair = std::pair; using Constraints_set = std::unordered_set>; using Constraints_pmap = CGAL::Boolean_property_map; +using Corners_set = std::unordered_set>; +using Corners_pmap = CGAL::Boolean_property_map; // To avoid verbose function and named parameters call using namespace CGAL::parameters; @@ -72,8 +74,12 @@ int main(int argc, char* argv[]) Constraints_set constraints; Constraints_pmap constraints_pmap(constraints); + Corners_set corners; + Corners_pmap corners_pmap(corners); + Triangulation_3 tr = CGAL::convert_to_triangulation_3(std::move(c3t3), - CGAL::parameters::edge_is_constrained_map(constraints_pmap)); + CGAL::parameters::edge_is_constrained_map(constraints_pmap). + vertex_is_constrained_map(corners_pmap)); //note we use the move semantic, with std::move(c3t3), // to avoid a copy of the triangulation by the function diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index 8118105559a9..5912bb67575b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -77,6 +77,7 @@ struct All_cells_selected template 2 //corner + || get(vcmap, vit) // constrained vertex || (incident_edges.size() == 2 && edges_form_a_sharp_angle(incident_edges, 60, m_c3t3))) { diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index 3eac9a222bdd..451cab5ee57b 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -107,6 +107,15 @@ namespace CGAL * by `Remeshing_edge_is_constrained_map` and `Remeshing_facet_is_constrained_map`.} * \cgalParamNEnd * +* \cgalParamNBegin{facet_is_constrained_map} +* \cgalParamDescription{a property map containing the constrained-or-not status of each facet of `tr`.} +* \cgalParamType{a class model of `ReadablePropertyMap` with `Triangulation_3::Facet` +* as key type and `bool` as value type. It must be default constructible.} +* \cgalParamDefault{a default property map where no facet is constrained} +* \cgalParamExtra{A constrained facet can be split or collapsed, but not flipped.} +* \cgalParamExtra{This map, contrary to the others, is not updated throughout the remeshing process.} +* \cgalParamNEnd +* * \cgalParamNBegin{edge_is_constrained_map} * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tr`.} * \cgalParamType{a class model of `ReadWritePropertyMap` with `std::pair` @@ -118,13 +127,12 @@ namespace CGAL * with edge splits and collapses, so the property map must be writable.} * \cgalParamNEnd * -* \cgalParamNBegin{facet_is_constrained_map} -* \cgalParamDescription{a property map containing the constrained-or-not status of each facet of `tr`.} -* \cgalParamType{a class model of `ReadablePropertyMap` with `Triangulation_3::Facet` +* \cgalParamNBegin{vertex_is_constrained_map} +* \cgalParamDescription{a property map containing the constrained-or-not status of each vertex of `tr`.} +* \cgalParamType{a class model of `ReadWritePropertyMap` with `Triangulation_3::Vertex_handle` * as key type and `bool` as value type. It must be default constructible.} -* \cgalParamDefault{a default property map where no facet is constrained} -* \cgalParamExtra{A constrained facet can be split or collapsed, but not flipped.} -* \cgalParamExtra{This map, contrary to the others, is not updated throughout the remeshing process.} +* \cgalParamDefault{a default property map where no vertex is constrained} +* \cgalParamExtra{A constrained vertex cannot be removed by collapse, nor moved by smoothing.} * \cgalParamNEnd * * \cgalParamNBegin{cell_is_selected_map} @@ -147,7 +155,8 @@ namespace CGAL * \cgalParamExtra{The endvertices of constraints listed * by `edge_is_constrained_map`, and edges incident to at least three subdomains * are made eligible to one dimensional smoothing, along the constrained polylines they belong to. -* Corners (i.e. vertices incident to more than 2 constrained edges) are not allowed +* Corners (i.e. vertices listed by `vertex_is_constrained_map` or +* incident to more than 2 constrained edges) are not allowed * to move at all.\n * Note that activating the smoothing step on polyline constraints tends to reduce * the quality of the minimal dihedral angle in the mesh.\n @@ -225,6 +234,15 @@ void tetrahedral_isotropic_remeshing( = choose_parameter(get_parameter(np, internal_np::cell_selector), Tetrahedral_remeshing::internal::All_cells_selected()); + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename internal_np::Lookup_named_param_def < + internal_np::vertex_is_constrained_t, + NamedParameters, + Constant_property_map//default + > ::type VCMap; + VCMap vcmap = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained), + Constant_property_map(false)); + typedef std::pair Edge_vv; typedef typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, @@ -263,9 +281,9 @@ void tetrahedral_isotropic_remeshing( #endif typedef Tetrahedral_remeshing::internal::Adaptive_remesher< - Tr, SizingFunction, ECMap, FCMap, SelectionFunctor, Visitor> Remesher; + Tr, SizingFunction, VCMap, ECMap, FCMap, SelectionFunctor, Visitor> Remesher; Remesher remesher(tr, sizing, protect - , ecmap, fcmap + , vcmap, ecmap, fcmap , smooth_constrained_edges , cell_select , visitor); @@ -331,7 +349,16 @@ void tetrahedral_isotropic_remeshing( * as key type and `bool` as value type. It must be default constructible.} * \cgalParamDefault{a default property map where no edge is constrained} * \cgalParamNEnd -* +* \cgalParamNBegin{vertex_is_constrained_map} +* \cgalParamDescription{a property map containing the constrained-or-not status of each vertex of +* `c3t3.triangulation()`. +* For each vertex `v` for which `c3t3.is_in_complex(v)` returns `true`, +* the constrained status of `v` is set to `true`.} +* \cgalParamType{a class model of `ReadWritePropertyMap` +* with `Triangulation_3::Vertex_handle` +* as key type and `bool` as value type. It must be default constructible.} +* \cgalParamDefault{a default property map where no vertex is constrained} +* \cgalParamNEnd * \cgalNamedParamsEnd */ @@ -353,16 +380,25 @@ convert_to_triangulation_3( using Vertex_handle = typename Tr::Vertex_handle; using Edge_vv = std::pair; - using Default_pmap = Constant_property_map; + using Default_edge_pmap = Constant_property_map; using ECMap = typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, NamedParameters, - Default_pmap + Default_edge_pmap + >::type; + using Default_vertex_pmap = Constant_property_map; + using VCMap = typename internal_np::Lookup_named_param_def < + internal_np::vertex_is_constrained_t, + NamedParameters, + Default_vertex_pmap >::type; + ECMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), - Default_pmap(false)); + Default_edge_pmap(false)); + VCMap vcmap = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained), + Default_vertex_pmap(false)); - if (!std::is_same_v) + if (!std::is_same_v) { for (auto e : c3t3.edges_in_complex()) { @@ -371,6 +407,13 @@ convert_to_triangulation_3( put(ecmap, evv, true); } } + if (!std::is_same_v) + { + for (auto v : c3t3.vertices_in_complex()) + { + put(vcmap, v, true); + } + } CGAL::Triangulation_3 tr; tr.swap(c3t3.triangulation()); @@ -448,6 +491,15 @@ void tetrahedral_isotropic_remeshing( = choose_parameter(get_parameter(np, internal_np::cell_selector), Tetrahedral_remeshing::internal::All_cells_selected()); + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename internal_np::Lookup_named_param_def < + internal_np::vertex_is_constrained_t, + NamedParameters, + Constant_property_map//default + > ::type VCMap; + VCMap vcmap = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained), + Constant_property_map(false)); + typedef std::pair Edge_vv; typedef typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, @@ -486,12 +538,9 @@ void tetrahedral_isotropic_remeshing( #endif typedef Tetrahedral_remeshing::internal::Adaptive_remesher< - Tr, SizingFunction, ECMap, FCMap, SelectionFunctor, - Visitor, - CornerIndex, CurveIndex - > Remesher; + Tr, SizingFunction, VCMap, ECMap, FCMap, SelectionFunctor, Visitor> Remesher; Remesher remesher(c3t3, sizing, protect - , ecmap, fcmap + , vcmap, ecmap, fcmap , smooth_constrained_edges , cell_select , visitor);