diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index cf7e8a739031..96be1186c663 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -510,11 +510,12 @@ Dynamic property tags, such as `dynamic_vertex_property_t`, are a generalization value type of the dynamic property map, and a default value. `boost::property_map::%type` is used to obtain the type of the dynamic property map for a graph of type `G`, for a -dynamic property tag `T`. This type must be default constructible and assignable. +dynamic property tag `T`. This type must be assignable, and if no +default is provided it must be default constructible. As for ordinary properties, the function `%get()` is overloaded and serves for retrieving a property map for a given graph and dynamic property tag, as well as for retrieving a value for a given key and -property map. +property map. The default value is provided as third parameter. The following example shows how to attach a `string` property to vertices and a `double` value to the halfedges of a graph. diff --git a/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h b/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h index d2a1f11653bb..a39cfd907154 100644 --- a/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h +++ b/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace CGAL { @@ -126,11 +127,20 @@ typename boost::property_map::type get(PropertyTag,CGAL_HDS_CLASS&) { return typename boost::property_map::type(); } + // generalized 3-ary get functions -template +template> && + !std::is_same_v> && + !std::is_same_v> && + !std::is_same_v> + > +> typename boost::property_traits< typename boost::property_map::type >::reference get(PropertyTag p,CGAL_HDS_CLASS& g, const Key& key) -{ return get(get(p, g), key); } +{ + return get(get(p, g), key); +} template typename boost::property_traits< typename boost::property_map::const_type >::reference @@ -139,13 +149,13 @@ get(PropertyTag p,CGAL_HDS_CLASS const& g, const Key& key) -#define DECLARE_HDS_DYNAMIC_PM(TAG, DESCRIPTOR) \ +#define DECLARE_HDS_DYNAMIC_PM(TAG, DESCRIPTOR) \ template \ typename boost::property_map::const_type \ -get(const TAG&, const CGAL_HDS_CLASS&) \ -{ \ +get(const TAG&, const CGAL_HDS_CLASS&, const T& dv = T()) \ +{ \ typedef typename boost::graph_traits< CGAL_HDS_CLASS >::DESCRIPTOR descriptor; \ - return internal::Dynamic_property_map(); \ + return internal::Dynamic_property_map(dv); \ } DECLARE_HDS_DYNAMIC_PM(dynamic_vertex_property_t, vertex_descriptor) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h index e8901ebd727b..f2a522db1e1d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h @@ -75,6 +75,7 @@ struct Non_manifold_feature_map halfedge_descriptor hd = halfedge(ed, pm); // an edge can be non-manifold only if both its vertices are non-manifold + // THIS IS NOT TRUE! if ( get(v_nm_id, source(hd, pm))==std::size_t(-1) || get(v_nm_id, target(hd, pm))==std::size_t(-1) ) continue; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/angle_and_area_smoothing.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/angle_and_area_smoothing.h index e51999b9c543..0166c85e58fe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/angle_and_area_smoothing.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/angle_and_area_smoothing.h @@ -134,7 +134,6 @@ void angle_and_area_smoothing(const FaceRange& faces, TriangleMesh& tmesh, const NamedParameters& np = parameters::default_values()) { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -209,14 +208,7 @@ void angle_and_area_smoothing(const FaceRange& faces, const bool use_Delaunay_flips = choose_parameter(get_parameter(np, internal_np::use_Delaunay_flips), true); VCMap vcmap = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained), - get(Vertex_property_tag(), tmesh)); - - // If it's the default vcmap, manually set everything to false because the dynamic pmap has no default initialization - if((std::is_same::value)) - { - for(vertex_descriptor v : vertices(tmesh)) - put(vcmap, v, false); - } + get(Vertex_property_tag(), tmesh, false)); ECMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), Static_boolean_property_map()); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/mesh_smoothing_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/mesh_smoothing_impl.h index e15ae718823d..54b15c7777a9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/mesh_smoothing_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/mesh_smoothing_impl.h @@ -154,11 +154,8 @@ class Delaunay_edge_flipper typedef typename boost::property_map::type Marked_edges_map; - Marked_edges_map marks = get(Edge_property_tag(), mesh_); + Marked_edges_map marks = get(Edge_property_tag(), mesh_, false); - // dynamic pmaps do not have default values... - for(edge_descriptor e : edges(mesh_)) - put(marks, e, false); for(edge_descriptor e : edge_range) put(marks, e, true); #ifdef CGAL_PMP_SMOOTHING_DEBUG diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h index 347db104f0c6..6dd55b9fc62c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h @@ -105,9 +105,7 @@ void simplify_range(HalfedgeRange& halfedge_range, typedef CGAL::dynamic_halfedge_property_t Halfedge_bool_tag; typedef typename boost::property_map::type Range_halfedges; - Range_halfedges range_halfedges = get(Halfedge_bool_tag(), tm); - for(halfedge_descriptor h : halfedge_range) - put(range_halfedges, h, true); + Range_halfedges range_halfedges = get(Halfedge_bool_tag(), tm, false); CGAL_postcondition_code(const std::size_t initial_n = halfedge_range.size();) @@ -1234,10 +1232,10 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, // We keep in memory pairs of source/target edges that are stitchable after vertex-vertex snapping // --> these halfedges should not be considered as targets in non-conformal snapping // Similarly, matching vertices whose incident edges have matching directions are also locked - Locked_vertices locked_vertices_A = get(Vertex_bool_tag(), tm_A); - Locked_vertices locked_vertices_B = get(Vertex_bool_tag(), tm_B); - Locked_halfedges locked_halfedges_A = get(Halfedge_bool_tag(), tm_A); - Locked_halfedges locked_halfedges_B = get(Halfedge_bool_tag(), tm_B); + Locked_vertices locked_vertices_A = get(Vertex_bool_tag(), tm_A, false); + Locked_vertices locked_vertices_B = get(Vertex_bool_tag(), tm_B, false); + Locked_halfedges locked_halfedges_A = get(Halfedge_bool_tag(), tm_A, false); + Locked_halfedges locked_halfedges_B = get(Halfedge_bool_tag(), tm_B, false); std::vector > locked_vertices; std::vector locked_halfedges_A_vector, locked_halfedges_B_vector; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/manifoldness.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/manifoldness.h index de45ca3150e1..46ac4ed6cb65 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/manifoldness.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/manifoldness.h @@ -58,9 +58,7 @@ bool is_non_manifold_vertex(typename boost::graph_traits::vertex_de typedef typename boost::property_map::const_type Visited_halfedge_map; // Dynamic pmaps do not have default initialization values (yet) - Visited_halfedge_map visited_halfedges = get(Halfedge_property_tag(), pm); - for(halfedge_descriptor h : halfedges(pm)) - put(visited_halfedges, h, false); + Visited_halfedge_map visited_halfedges = get(Halfedge_property_tag(), pm, false); std::size_t incident_null_faces_counter = 0; for(halfedge_descriptor h : halfedges_around_target(v, pm)) @@ -324,20 +322,11 @@ OutputIterator non_manifold_vertices(const PolygonMesh& pm, typedef CGAL::dynamic_halfedge_property_t Halfedge_property_tag; typedef typename boost::property_map::const_type Visited_halfedge_map; - Known_manifold_vertex_map known_nm_vertices = get(Vertex_bool_tag(), pm); - Visited_vertex_map visited_vertices = get(Vertex_halfedge_tag(), pm); - Visited_halfedge_map visited_halfedges = get(Halfedge_property_tag(), pm); - halfedge_descriptor null_h = boost::graph_traits::null_halfedge(); - // Dynamic pmaps do not have default initialization values (yet) - for(vertex_descriptor v : vertices(pm)) - { - put(known_nm_vertices, v, false); - put(visited_vertices, v, null_h); - } - for(halfedge_descriptor h : halfedges(pm)) - put(visited_halfedges, h, false); + Known_manifold_vertex_map known_nm_vertices = get(Vertex_bool_tag(), pm, false); + Visited_vertex_map visited_vertices = get(Vertex_halfedge_tag(), pm, null_h); + Visited_halfedge_map visited_halfedges = get(Halfedge_property_tag(), pm, false); for(halfedge_descriptor h : halfedges(pm)) { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index c71a5d4c8062..1dde0a5b20d3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -639,7 +639,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, // Vertex property map that combines the VCM and the fact that extremities of a constrained edge should be constrained typedef CGAL::dynamic_vertex_property_t Vertex_property_tag; typedef typename boost::property_map::type DVCM; - DVCM vcm = get(Vertex_property_tag(), tmesh); + DVCM vcm = get(Vertex_property_tag(), tmesh, false); // parameters const double cap_threshold = diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index e30f95fd2896..343007a83b2c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -190,7 +190,7 @@ struct Boundary_cycle_rep_maintainer Boundary_cycle_rep_maintainer(PolygonMesh& pmesh) : m_pmesh(pmesh) { - m_candidate_halfedges = get(Candidate_tag(), pmesh); + m_candidate_halfedges = get(Candidate_tag(), pmesh, false); } public: diff --git a/Property_map/examples/Property_map/dynamic_properties.cpp b/Property_map/examples/Property_map/dynamic_properties.cpp index e3eb014e40c7..3a3f0ee9f54c 100644 --- a/Property_map/examples/Property_map/dynamic_properties.cpp +++ b/Property_map/examples/Property_map/dynamic_properties.cpp @@ -15,16 +15,24 @@ int main() CGAL::make_triangle(Point_3(0,0,0),Point_3(1,0,0),Point_3(1,1,0), mesh); typedef boost::property_map >::type VertexNameMap; - VertexNameMap vnm = get(CGAL::dynamic_vertex_property_t(), mesh); + VertexNameMap vnm = get(CGAL::dynamic_vertex_property_t(), mesh, std::string("default")); put(vnm, *(vertices(mesh).first), "Paris"); + assert(get(vnm, *(vertices(mesh).first))=="Paris"); + assert(get(vnm, *(std::next(vertices(mesh).first)))=="default"); + std::cout << get(vnm, *(vertices(mesh).first)) << std::endl; + std::cout << get(vnm, *(std::next(vertices(mesh).first))) << std::endl; typedef boost::property_map >::type TrafficDensityMap; - TrafficDensityMap tdm = get(CGAL::dynamic_halfedge_property_t(), mesh); + TrafficDensityMap tdm = get(CGAL::dynamic_halfedge_property_t(), mesh, -1.); put(tdm, *(halfedges(mesh).first), 0.7); + assert(get(tdm, *(halfedges(mesh).first))==0.7); + assert(get(tdm, *(std::next(halfedges(mesh).first)))==-1.); + std::cout << get(tdm, *(halfedges(mesh).first)) << std::endl; + std::cout << get(tdm, *(std::next(halfedges(mesh).first))) << std::endl; return 0; } diff --git a/Property_map/include/CGAL/Dynamic_property_map.h b/Property_map/include/CGAL/Dynamic_property_map.h index bca414e19b00..949eed333827 100644 --- a/Property_map/include/CGAL/Dynamic_property_map.h +++ b/Property_map/include/CGAL/Dynamic_property_map.h @@ -135,8 +135,8 @@ struct Dynamic_with_index : m_values() {} - Dynamic_with_index(std::size_t num_features) - : m_values( new std::vector(num_features) ) + Dynamic_with_index(std::size_t num_features, Value default_value = Value()) + : m_values( new std::vector(num_features, default_value) ) {} friend reference get(const Dynamic_with_index& m, const key_type& k) @@ -228,34 +228,34 @@ namespace CGAL { template typename boost::property_map >::const_type -get(const CGAL::dynamic_vertex_property_t&, const G&) +get(const CGAL::dynamic_vertex_property_t&, const G&, const T& default_value = T()) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - return internal::Dynamic_property_map(); + return internal::Dynamic_property_map(default_value); } template typename boost::property_map >::const_type -get(const CGAL::dynamic_halfedge_property_t&, const G&) +get(const CGAL::dynamic_halfedge_property_t&, const G&, const T& default_value = T()) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - return internal::Dynamic_property_map(); + return internal::Dynamic_property_map(default_value); } template typename boost::property_map >::const_type -get(const CGAL::dynamic_edge_property_t&, const G&) +get(const CGAL::dynamic_edge_property_t&, const G&, const T& default_value = T()) { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - return internal::Dynamic_property_map(); + return internal::Dynamic_property_map(default_value); } template typename boost::property_map >::const_type -get(const CGAL::dynamic_face_property_t&, const G&) +get(const CGAL::dynamic_face_property_t&, const G&, const T& default_value = T()) { typedef typename boost::graph_traits::face_descriptor face_descriptor; - return internal::Dynamic_property_map(); + return internal::Dynamic_property_map(default_value); } template diff --git a/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h b/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h index 785cec65003d..fc6ea9d8b9f7 100644 --- a/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h +++ b/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h @@ -353,67 +353,67 @@ namespace CGAL { // get functions for dynamic properties of mutable Surface_mesh template typename boost::property_map, dynamic_vertex_property_t >::type -get(dynamic_vertex_property_t, Surface_mesh& sm) +get(dynamic_vertex_property_t, Surface_mesh& sm, const T& default_value = T()) { typedef typename boost::property_map, dynamic_vertex_property_t >::SMPM SMPM; typedef typename boost::property_map, dynamic_vertex_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Vertex_index, T>(std::string()).first)); + return DPM(sm, new SMPM(sm.template add_property_map::Vertex_index, T>(std::string(), default_value).first)); } template typename boost::property_map, dynamic_face_property_t >::type -get(dynamic_face_property_t, Surface_mesh& sm) +get(dynamic_face_property_t, Surface_mesh& sm, const T& default_value = T()) { typedef typename boost::property_map, dynamic_face_property_t >::SMPM SMPM; typedef typename boost::property_map, dynamic_face_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Face_index, T>(std::string()).first)); + return DPM(sm, new SMPM(sm.template add_property_map::Face_index, T>(std::string(), default_value).first)); } template typename boost::property_map, dynamic_edge_property_t >::type -get(dynamic_edge_property_t, Surface_mesh& sm) +get(dynamic_edge_property_t, Surface_mesh& sm, const T& default_value = T()) { typedef typename boost::property_map, dynamic_edge_property_t >::SMPM SMPM; typedef typename boost::property_map, dynamic_edge_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Edge_index, T>(std::string()).first)); + return DPM(sm, new SMPM(sm.template add_property_map::Edge_index, T>(std::string(), default_value).first)); } template typename boost::property_map, dynamic_halfedge_property_t >::type -get(dynamic_halfedge_property_t, Surface_mesh& sm) +get(dynamic_halfedge_property_t, Surface_mesh& sm, const T& default_value = T()) { typedef typename boost::property_map, dynamic_halfedge_property_t >::SMPM SMPM; typedef typename boost::property_map, dynamic_halfedge_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Halfedge_index, T>(std::string()).first)); + return DPM(sm, new SMPM(sm.template add_property_map::Halfedge_index, T>(std::string(), default_value).first)); } // get functions for dynamic properties of const Surface_mesh template typename boost::property_map, dynamic_vertex_property_t >::const_type -get(dynamic_vertex_property_t, const Surface_mesh& sm) +get(dynamic_vertex_property_t, const Surface_mesh& sm, const T& default_value = T()) { - return CGAL::internal::Dynamic_with_index::Vertex_index, T>(num_vertices(sm)); + return CGAL::internal::Dynamic_with_index::Vertex_index, T>(num_vertices(sm), default_value); } template typename boost::property_map, dynamic_face_property_t >::const_type -get(dynamic_face_property_t, const Surface_mesh& sm) +get(dynamic_face_property_t, const Surface_mesh& sm, const T& default_value = T()) { - return CGAL::internal::Dynamic_with_index::Face_index, T>(num_faces(sm)); + return CGAL::internal::Dynamic_with_index::Face_index, T>(num_faces(sm), default_value); } template typename boost::property_map, dynamic_halfedge_property_t >::const_type -get(dynamic_halfedge_property_t, const Surface_mesh& sm) +get(dynamic_halfedge_property_t, const Surface_mesh& sm, const T& default_value = T()) { - return CGAL::internal::Dynamic_with_index::Halfedge_index, T>(num_halfedges(sm)); + return CGAL::internal::Dynamic_with_index::Halfedge_index, T>(num_halfedges(sm), default_value); } template typename boost::property_map, dynamic_edge_property_t >::const_type -get(dynamic_edge_property_t, const Surface_mesh& sm) +get(dynamic_edge_property_t, const Surface_mesh& sm, const T& default_value = T()) { - return CGAL::internal::Dynamic_with_index::Edge_index, T>(num_edges(sm)); + return CGAL::internal::Dynamic_with_index::Edge_index, T>(num_edges(sm), default_value); } // implementation detail: required by Dynamic_property_map_deleter