diff --git a/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h b/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h index bfae9e26801..828d6ec36ef 100644 --- a/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h +++ b/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h @@ -74,6 +74,7 @@ public: typedef typename CGAL::Default::Get::type Tree; typedef typename MeshDomain::Index Index; + typedef typename MeshDomain::Corner_index Corner_index; typedef typename MeshDomain::Subdomain_index Subdomain_index; typedef typename MeshDomain::Surface_patch_index Surface_patch_index; @@ -231,8 +232,8 @@ public: else if (dim == 0) { #ifdef CGAL_MESH_3_EXPERIMENTAL_USE_PATCHES_IDS - const Patches_ids& ids = - (m_domain.corners_incidences_map().find(p)->second); + const Corner_index cid = m_domain.corner_index(index); + const Patches_ids& ids = m_domain.corners_incidences_map().find(cid)->second; if (m_domain_is_a_box && ids.size() == 3) { diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 839718ce1e3..312d17274d1 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -623,6 +623,28 @@ of the base class. /// @cond DEVELOPERS /// @{ + + /// Add a 0-dimensional feature in the domain. + Corner_index add_corner(const Point_3& p); + + /// Overloads where the last parameter \c out is not `CGAL::Emptyset_iterator()`. + template + IndicesOutputIterator + add_corners(InputIterator first, InputIterator end, + IndicesOutputIterator out /*= CGAL::Emptyset_iterator()*/); + + /*! + Add 0-dimensional features in the domain. The value type of `InputIterator` must + be `Point_3`. + */ + template + void + add_corners(InputIterator first, InputIterator end) + { add_corners(first, end, CGAL::Emptyset_iterator()); } + + Corner_index register_corner(const Point_3& p, const Curve_index& index); + Corner_index add_corner_with_context(const Point_3& p, const Surface_patch_index& index); + /// Overloads where the last parameter \c out is not /// `CGAL::Emptyset_iterator()`. template @@ -808,7 +830,6 @@ of the base class. Curve_index insert_edge(InputIterator first, InputIterator end); /// @endcond private: - void register_corner(const Point_3& p, const Curve_index& index); void compute_corners_incidences(); /// Returns Index associated to p (p must be the coordinates of a corner @@ -843,17 +864,14 @@ private: public: /// @cond DEVELOPERS typedef CGAL::AABB_tree Curves_AABB_tree; - typedef std::set Set_of_patch_ids; - typedef std::map Corners_incidence_map; private: - Corners_incidence_map corners_incidence_map_; mutable Curves_AABB_tree curves_aabb_tree_; mutable bool curves_aabb_tree_is_built; public: - const Corners_incidence_map& corners_incidences_map() const - { return corners_incidence_map_; } + const Corners_incidences& corners_incidences_map() const + { return corners_incidences_; } const Curves_AABB_tree& curves_aabb_tree() const { if(!curves_aabb_tree_is_built) build_curves_aabb_tree(); @@ -1013,6 +1031,67 @@ construct_point_on_curve(const Point_3& starting_point, } +/// @cond DEVELOPERS +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +add_corner(const Point_3& p) +{ + typename Corners::iterator cit = corners_.lower_bound(p); + + // If the corner already exists, return its assigned Corner_index... + if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first))) + return cit->second; + + // ... otherwise, insert it! + const Corner_index index = current_corner_index_++; + corners_.insert(cit, std::make_pair(p, index)); + + return index; +} + + +template +template +IndicesOutputIterator +Mesh_domain_with_polyline_features_3:: +add_corners(InputIterator first, InputIterator end, + IndicesOutputIterator indices_out) +{ + while ( first != end ) + *indices_out++ = add_corner(*first++); + + return indices_out; +} + +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +register_corner(const Point_3& p, const Curve_index& curve_index) +{ + // 'add_corner' will itself seek if 'p' is already a corner, and, in that case, + // return the Corner_index that has been assigned to this position. + Corner_index index = add_corner(p); + corners_tmp_incidences_[index].insert(curve_index); + + return index; +} + + +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +add_corner_with_context(const Point_3& p, const Surface_patch_index& surface_patch_index) +{ + Corner_index index = add_corner(p); + + Surface_patch_index_set& incidences = corners_incidences_[index]; + incidences.insert(surface_patch_index); + + return index; +} +/// @endcond + template template @@ -1080,21 +1159,12 @@ add_features_and_incidences(InputIterator first, InputIterator end, polyline = get(polyline_pmap, *first); const typename boost::property_traits::reference patches_ids = get(inc_patches_ind_pmap, *first); - const typename Gt::Point_3& p1 = *polyline.begin(); - const typename Gt::Point_3& p2 = *boost::prior(polyline.end()); - Set_of_patch_ids& ids_p1 = corners_incidence_map_[p1]; - std::copy(patches_ids.begin(), - patches_ids.end(), - std::inserter(ids_p1, ids_p1.begin())); - Set_of_patch_ids& ids_p2 = corners_incidence_map_[p2]; - std::copy(patches_ids.begin(), - patches_ids.end(), - std::inserter(ids_p2, ids_p2.begin())); - Curve_index curve_id = - insert_edge(polyline.begin(), polyline.end()); + + Curve_index curve_id = insert_edge(polyline.begin(), polyline.end()); edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end()); *indices_out++ = curve_id; } + compute_corners_incidences(); return indices_out; } @@ -1172,7 +1242,8 @@ get_incidences(Curve_index id, { typename Edges_incidences::const_iterator it = edges_incidences_.find(id); - if(it == edges_incidences_.end()) return indices_out; + if(it == edges_incidences_.end()) + return indices_out; const Surface_patch_index_set& incidences = it->second; @@ -1187,6 +1258,9 @@ get_corner_incidences(Corner_index id, IndicesOutputIterator indices_out) const { typename Corners_incidences::const_iterator it = corners_incidences_.find(id); + if(it == corners_incidences_.end()) + return indices_out; + const Surface_patch_index_set& incidences = it->second; return std::copy(incidences.begin(), incidences.end(), indices_out); } @@ -1198,8 +1272,10 @@ Mesh_domain_with_polyline_features_3:: get_corner_incident_curves(Corner_index id, IndicesOutputIterator indices_out) const { - typename Corners_tmp_incidences::const_iterator it = - corners_tmp_incidences_.find(id); + typename Corners_tmp_incidences::const_iterator it = corners_tmp_incidences_.find(id); + if(it == corners_tmp_incidences_.end()) + return indices_out; + const std::set& incidences = it->second; return std::copy(incidences.begin(), incidences.end(), indices_out); } @@ -1323,7 +1399,6 @@ compute_corners_incidences() } Surface_patch_index_set& incidences = corners_incidences_[id]; - // That should be an empty set. BOOST_FOREACH(Curve_index curve_index, corner_tmp_incidences) { @@ -1347,34 +1422,11 @@ Mesh_domain_with_polyline_features_3:: get_incidences(Curve_index id) const { typename Edges_incidences::const_iterator it = edges_incidences_.find(id); + CGAL_assertion(it != edges_incidences_.end()); + return it->second; } -/// @endcond -template -void -Mesh_domain_with_polyline_features_3:: -register_corner(const Point_3& p, const Curve_index& curve_index) -{ - - typename Corners::iterator cit = corners_.lower_bound(p); - - // If the corner already exists, returns... - if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first))) { - corners_tmp_incidences_[cit->second].insert(curve_index); - return; - } - - // ...else insert it! - - const Corner_index index = current_corner_index_; - ++current_corner_index_; - - corners_.insert(cit, std::make_pair(p, index)); - corners_tmp_incidences_[index].insert(curve_index); -} - -/// @cond DEVELOPERS template template typename Mesh_domain_with_polyline_features_3::Curve_index diff --git a/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp b/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp index 29436d1973e..5123829ce97 100644 --- a/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp +++ b/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp @@ -53,18 +53,34 @@ class Domain_with_polyline_tester typedef Mesh_domain::Corner_index Ci; typedef Mesh_domain::Curve_index Csi; + typedef Mesh_domain::Surface_patch_index Spi; typedef Mesh_domain::Index Index; typedef std::vector > Corners_vector; typedef std::pair P_and_i; typedef CGAL::cpp11::tuple Curve_tuple; - typedef std::vector Curves_vector; + typedef std::vector Curves_vector; public: Domain_with_polyline_tester() : p1_(1,0,0), p2_(1,1,0), p3_(1,2,0.1), p4_(0.9, 0.9, 1) { } - + + void build_corners() + { + domain_.add_corner(p1_); + + std::vector corners; + corners.push_back(p2_); + domain_.add_corners(corners.begin(), corners.end()); + + Csi dummy_curve_index = 12; + domain_.register_corner(p3_, dummy_curve_index); + + Spi dummy_surface_patch_index = 21; + domain_.add_corner_with_context(p4_, dummy_surface_patch_index); + } + void build_curve() { Polylines polylines (1); @@ -90,7 +106,35 @@ public: domain_.add_features(polylines.begin(),polylines.end()); } - + + void test_corners() const + { + Corners_vector corners; + domain_.get_corners(std::back_inserter(corners)); + assert(corners.size() == 4); + + Corners_vector::const_iterator cit = corners.begin(), end = corners.end(); + for(; cit!=end; ++cit) + { + if(cit->second == p3_) + { + std::vector incident_curves; + domain_.get_corner_incident_curves(cit->first, std::back_inserter(incident_curves)); + assert(incident_curves.size() == 1 && incident_curves.front() == 12); + } + else if(cit->second == p4_) + { + std::vector incident_surface_patchs; + domain_.get_corner_incidences(cit->first, std::back_inserter(incident_surface_patchs)); + assert(incident_surface_patchs.size() == 1 && incident_surface_patchs.front() == 21); + } + else + { + assert(cit->second == p1_ || cit->second == p2_); + } + } + } + void test_curve_corners() const { Corners_vector corners; @@ -192,6 +236,11 @@ private: int main() { + std::cout << "Test corners" << std::endl; + Domain_with_polyline_tester domain_corner_tester; + domain_corner_tester.build_corners(); + domain_corner_tester.test_corners(); + std::cout << "Test curve segments" << std::endl; Domain_with_polyline_tester domain_tester; domain_tester.build_curve();