@@ -62,29 +62,46 @@ namespace internal {
6262// //// Helper structs
6363
6464// Used to compare halfedges based on their geometry
65- template <typename PolygonMesh, typename VertexPointMap>
65+ template <typename PolygonMesh, typename VertexPointMap, typename GeomTraits >
6666struct Less_for_halfedge
6767{
68+ typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor vertex_descriptor;
6869 typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
6970 typedef typename boost::property_traits<VertexPointMap>::reference Point;
7071
71- Less_for_halfedge (const PolygonMesh& pmesh_, const VertexPointMap& vpm_)
72- : pmesh(pmesh_), vpm(vpm_)
72+ Less_for_halfedge (const PolygonMesh& pmesh_, const VertexPointMap vpm_, const GeomTraits& gt_ )
73+ : pmesh(pmesh_), vpm(vpm_), gt(gt_)
7374 {}
7475
7576 bool operator ()(const halfedge_descriptor h1, const halfedge_descriptor h2) const
7677 {
77- Point s1 = get (vpm,target (opposite (h1, pmesh), pmesh));
78- Point t1 = get (vpm,target (h1, pmesh));
79- Point s2 = get (vpm,target (opposite (h2, pmesh), pmesh));
80- Point t2 = get (vpm,target (h2, pmesh));
78+ typename GeomTraits::Equal_3 equal = gt.equal_3_object ();
79+ typename GeomTraits::Less_xyz_3 less = gt.less_xyz_3_object ();
8180
82- return (s1 < t1 ? std::make_pair (s1,t1) : std::make_pair (t1, s1))
83- < (s2 < t2 ? std::make_pair (s2,t2) : std::make_pair (t2, s2));
81+ vertex_descriptor vm1 = source (h1, pmesh);
82+ vertex_descriptor vM1 = target (h1, pmesh);
83+ vertex_descriptor vm2 = source (h2, pmesh);
84+ vertex_descriptor vM2 = target (h2, pmesh);
85+
86+ if (less (get (vpm, vM1), get (vpm, vm1)))
87+ std::swap (vM1, vm1);
88+ if (less (get (vpm, vM2), get (vpm, vm2)))
89+ std::swap (vM2, vm2);
90+
91+ Point pm1 = get (vpm, vm1);
92+ Point pM1 = get (vpm, vM1);
93+ Point pm2 = get (vpm, vm2);
94+ Point pM2 = get (vpm, vM2);
95+
96+ if (equal (pm1, pm2))
97+ return less (pM1, pM2);
98+
99+ return less (pm1, pm2);
84100 }
85101
86102 const PolygonMesh& pmesh;
87- const VertexPointMap& vpm;
103+ const VertexPointMap vpm;
104+ const GeomTraits& gt;
88105};
89106
90107// The following structs determine which of the two halfedges is kept when a pair is merged
@@ -320,15 +337,19 @@ template<typename Halfedge,
320337 typename Border_halfedge_map,
321338 typename Halfedge_pair,
322339 typename Manifold_halfedge_pair,
340+ typename Mesh,
323341 typename VPM,
324- typename Mesh >
342+ typename GT >
325343void fill_pairs (const Halfedge& he,
326344 Border_halfedge_map& border_halfedge_map,
327345 Halfedge_pair& halfedge_pairs,
328346 Manifold_halfedge_pair& manifold_halfedge_pairs,
347+ const Mesh& pmesh,
329348 VPM vpm,
330- const Mesh& pmesh )
349+ const GT& gt )
331350{
351+ typename GT::Equal_3 equal = gt.equal_3_object ();
352+
332353 typename Border_halfedge_map::iterator set_it;
333354 bool insertion_ok;
334355 std::tie (set_it, insertion_ok) = border_halfedge_map.emplace (he, std::make_pair (1 ,0 ));
@@ -341,8 +362,8 @@ void fill_pairs(const Halfedge& he,
341362 const Halfedge other_he = set_it->first ;
342363 set_it->second .second = halfedge_pairs.size (); // set the id of the pair in the vector
343364 halfedge_pairs.emplace_back (other_he, he);
344- if (get (vpm, source (he,pmesh)) == get (vpm, target (other_he, pmesh)) &&
345- get (vpm, target (he,pmesh)) == get (vpm, source (other_he, pmesh)))
365+ if (equal ( get (vpm, source (he,pmesh)), get (vpm, target (other_he, pmesh) )) &&
366+ equal ( get (vpm, target (he,pmesh)), get (vpm, source (other_he, pmesh) )))
346367 {
347368 // Even if the halfedges are compatible, refuse to stitch if that would break the graph
348369 if (face (opposite (he, pmesh), pmesh) == face (opposite (other_he, pmesh), pmesh))
@@ -383,17 +404,20 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
383404 VPM vpm = choose_parameter (get_parameter (np, internal_np::vertex_point),
384405 get_const_property_map (vertex_point, pmesh));
385406
407+ typedef typename GetGeomTraits<PolygonMesh, CGAL_PMP_NP_CLASS>::type GT;
408+ GT gt = choose_parameter<GT>(get_parameter (np, internal_np::geom_traits));
409+
386410 typedef CGAL::dynamic_face_property_t <int > Face_property_tag;
387411 typedef typename boost::property_map<PolygonMesh, Face_property_tag>::type Face_cc_map;
388412
389413 Face_cc_map cc;
390414 std::size_t num_cc = 0 ;
391415 std::vector<std::vector<halfedge_descriptor> > border_edges_per_cc;
392416
393- typedef Less_for_halfedge<PolygonMesh, VPM> Less_hedge;
417+ typedef Less_for_halfedge<PolygonMesh, VPM, GT> Less_hedge;
394418 typedef std::map<halfedge_descriptor, std::pair<int , std::size_t >, Less_hedge> Border_halfedge_map;
395419
396- Less_hedge less_hedge (pmesh, vpm);
420+ Less_hedge less_hedge (pmesh, vpm, gt );
397421 Border_halfedge_map border_halfedge_map (less_hedge);
398422
399423 std::vector<std::pair<halfedge_descriptor, halfedge_descriptor> > halfedge_pairs;
@@ -424,7 +448,7 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
424448 if (per_cc)
425449 border_edges_per_cc[get (cc, face (opposite (he, pmesh), pmesh))].push_back (he);
426450 else
427- fill_pairs (he, border_halfedge_map, halfedge_pairs, manifold_halfedge_pairs, vpm, pmesh );
451+ fill_pairs (he, border_halfedge_map, halfedge_pairs, manifold_halfedge_pairs, pmesh, vpm, gt );
428452 }
429453
430454 if (per_cc)
@@ -439,7 +463,7 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
439463 {
440464 halfedge_descriptor he = border_edges_per_cc[i][j];
441465 fill_pairs (he, border_halfedge_map_in_cc, halfedge_pairs,
442- manifold_halfedge_pairs, vpm, pmesh );
466+ manifold_halfedge_pairs, pmesh, vpm, gt );
443467 }
444468
445469 // put in `out` only manifold edges from the set of edges to stitch.
@@ -865,17 +889,21 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_
865889// However, even if non-manifoldness exists within a loop, it is safe choice to stitch consecutive
866890// stitchable halfedges
867891template <typename HalfedgeRange,
892+ typename HalfedgeKeeper,
868893 typename PolygonMesh,
869894 typename VPM,
870- typename HalfedgeKeeper >
895+ typename GT >
871896std::size_t zip_boundary_cycle (typename boost::graph_traits<PolygonMesh>::halfedge_descriptor& bh,
872897 const HalfedgeRange& cycle_halfedges,
898+ const HalfedgeKeeper& hd_kpr,
873899 PolygonMesh& pmesh,
874900 const VPM vpm,
875- const HalfedgeKeeper& hd_kpr )
901+ const GT& gt )
876902{
877903 typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
878904
905+ typename GT::Equal_3 equal = gt.equal_3_object ();
906+
879907 std::size_t stitched_boundary_cycles_n = 0 ;
880908
881909 // Zipping cannot change the topology of the hole so the maintenance is trivial
@@ -911,10 +939,11 @@ std::size_t zip_boundary_cycle(typename boost::graph_traits<PolygonMesh>::halfed
911939 do
912940 {
913941 halfedge_descriptor hnn = next (hn, pmesh);
914- CGAL_assertion (get (vpm, target (hn, pmesh)) == get (vpm, source (hnn, pmesh)));
942+ CGAL_assertion (equal ( get (vpm, target (hn, pmesh)), get (vpm, source (hnn, pmesh) )));
915943
916- if (get (vpm, source (hn, pmesh)) == get (vpm, target (hnn, pmesh)) &&
917- !is_degenerate_edge (edge (hn, pmesh), pmesh, parameters::vertex_point_map (vpm)))
944+ if (equal (get (vpm, source (hn, pmesh)), get (vpm, target (hnn, pmesh))) &&
945+ !is_degenerate_edge (edge (hn, pmesh), pmesh,
946+ parameters::vertex_point_map (vpm).geom_traits (gt)))
918947 {
919948 if (unstitchable_halfedges.count (hn) == 0 )
920949 {
@@ -980,8 +1009,9 @@ std::size_t zip_boundary_cycle(typename boost::graph_traits<PolygonMesh>::halfed
9801009 curr_hn = next (curr_hn, pmesh);
9811010
9821011 // check if the next two halfedges are not geometrically compatible
983- if (get (vpm, source (curr_h, pmesh)) != get (vpm, target (curr_hn, pmesh)) ||
984- is_degenerate_edge (edge (curr_hn, pmesh), pmesh, parameters::vertex_point_map (vpm)))
1012+ if (!equal (get (vpm, source (curr_h, pmesh)), get (vpm, target (curr_hn, pmesh))) ||
1013+ is_degenerate_edge (edge (curr_hn, pmesh), pmesh,
1014+ parameters::vertex_point_map (vpm).geom_traits (gt)))
9851015 {
9861016 bh = curr_hn;
9871017 break ;
@@ -1046,6 +1076,9 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
10461076 VPM vpm = choose_parameter (get_parameter (np, internal_np::vertex_point),
10471077 get_const_property_map (vertex_point, pmesh));
10481078
1079+ typedef typename GetGeomTraits<PolygonMesh, CGAL_PMP_NP_CLASS>::type GT;
1080+ GT gt = choose_parameter<GT>(get_parameter (np, internal_np::geom_traits));
1081+
10491082 typedef typename internal_np::Lookup_named_param_def<internal_np::halfedges_keeper_t ,
10501083 CGAL_PMP_NP_CLASS,
10511084 Default_halfedges_keeper<PolygonMesh> >::type Halfedge_keeper;
@@ -1058,7 +1091,7 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
10581091 for (halfedge_descriptor h : halfedges_around_face (bh, pmesh))
10591092 cycle_halfedges.push_back (h);
10601093
1061- std::size_t res = internal::zip_boundary_cycle (bh, cycle_halfedges, pmesh, vpm, hd_kpr );
1094+ std::size_t res = internal::zip_boundary_cycle (bh, cycle_halfedges, hd_kpr, pmesh, vpm, gt );
10621095 if (bh == boost::graph_traits<PolygonMesh>::null_halfedge ()) // stitched everything
10631096 {
10641097 cycle_reps_maintainer.remove_representative (bh);
@@ -1112,6 +1145,17 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
11121145// / \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
11131146// / must be available in `PolygonMesh`.}
11141147// / \cgalParamNEnd
1148+ // /
1149+ // / \cgalParamNBegin{geom_traits}
1150+ // / \cgalParamDescription{an instance of a geometric traits class}
1151+ // / \cgalParamType{The traits class must provide the nested type `Point_3`,
1152+ // / and the nested functors:
1153+ // / - `Less_xyz_3` to compare lexicographically two points
1154+ // / - `Equal_3` to check whether two points are identical.
1155+ // / For each functor `Foo`, a function `Foo foo_object()` must be provided.}
1156+ // / \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
1157+ // / \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
1158+ // / \cgalParamNEnd
11151159// / \cgalNamedParamsEnd
11161160// /
11171161// / \returns the number of pairs of halfedges that were stitched.
@@ -1180,6 +1224,17 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep
11801224// / \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
11811225// / must be available in `PolygonMesh`.}
11821226// / \cgalParamNEnd
1227+ // /
1228+ // / \cgalParamNBegin{geom_traits}
1229+ // / \cgalParamDescription{an instance of a geometric traits class}
1230+ // / \cgalParamType{The traits class must provide the nested type `Point_3`,
1231+ // / and the nested functors:
1232+ // / - `Less_xyz_3` to compare lexicographically two points
1233+ // / - `Equal_3` to check whether two points are identical.
1234+ // / For each functor `Foo`, a function `Foo foo_object()` must be provided.}
1235+ // / \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
1236+ // / \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
1237+ // / \cgalParamNEnd
11831238// / \cgalNamedParamsEnd
11841239// /
11851240// / \returns the number of pairs of halfedges that were stitched.
@@ -1375,15 +1430,6 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat
13751430// / \param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
13761431// /
13771432// / \cgalNamedParamsBegin
1378- // / \cgalParamNBegin{vertex_point_map}
1379- // / \cgalParamDescription{a property map associating points to the vertices of `pmesh`}
1380- // / \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor`
1381- // / as key type and `%Point_3` as value type}
1382- // / \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
1383- // / \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
1384- // / must be available in `PolygonMesh`.}
1385- // / \cgalParamNEnd
1386- // /
13871433// / \cgalParamNBegin{apply_per_connected_component}
13881434// / \cgalParamDescription{specifies if the borders should only be stitched only within their own connected component.}
13891435// / \cgalParamType{Boolean}
@@ -1396,6 +1442,26 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat
13961442// / as key type and `std::size_t` as value type}
13971443// / \cgalParamDefault{an automatically indexed internal map}
13981444// / \cgalParamNEnd
1445+ // /
1446+ // / \cgalParamNBegin{vertex_point_map}
1447+ // / \cgalParamDescription{a property map associating points to the vertices of `pmesh`}
1448+ // / \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor`
1449+ // / as key type and `%Point_3` as value type}
1450+ // / \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
1451+ // / \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
1452+ // / must be available in `PolygonMesh`.}
1453+ // / \cgalParamNEnd
1454+ // /
1455+ // / \cgalParamNBegin{geom_traits}
1456+ // / \cgalParamDescription{an instance of a geometric traits class}
1457+ // / \cgalParamType{The traits class must provide the nested type `Point_3`,
1458+ // / and the nested functors:
1459+ // / - `Less_xyz_3` to compare lexicographically two points
1460+ // / - `Equal_3` to check whether two points are identical.
1461+ // / For each functor `Foo`, a function `Foo foo_object()` must be provided.}
1462+ // / \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
1463+ // / \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
1464+ // / \cgalParamNEnd
13991465// / \cgalNamedParamsEnd
14001466// /
14011467// / \return the number of pairs of halfedges that were stitched.
0 commit comments