@@ -60,8 +60,12 @@ bool exact_snapping (const typename Exact_kernel::Segment_3& s0,
6060 Vector_3 v0 = s0.to_vector ();
6161 Vector_3 v1 = s1.to_vector ();
6262 Vector_3 normal = CGAL::cross_product (v0, v1);
63+
64+ // Collinear segments
6365 if (normal == CGAL::NULL_VECTOR)
66+ {
6467 return false ;
68+ }
6569
6670 Plane_3 plane0 (s0.source (), normal);
6771 Plane_3 plane1 (s1.source (), normal);
@@ -87,8 +91,10 @@ bool exact_snapping (const typename Exact_kernel::Segment_3& s0,
8791
8892 if (const Point_3* p = boost::get<Point_3>(&*intersection0))
8993 p0 = *p;
90- else
94+ else // Coplanar segments
95+ {
9196 return false ;
97+ }
9298
9399 typename std::result_of<typename Exact_kernel::Intersect_3 (Segment_3, Segment_3)>::type
94100 intersection1 = intersection (s1, s0proj);
@@ -97,8 +103,10 @@ bool exact_snapping (const typename Exact_kernel::Segment_3& s0,
97103
98104 if (const Point_3* p = boost::get<Point_3>(&*intersection1))
99105 p1 = *p;
100- else
106+ else // Coplanar segments
107+ {
101108 return false ;
109+ }
102110
103111 result = CGAL::midpoint (p0, p1);
104112
@@ -380,6 +388,7 @@ void polyline_snapping (Graph& graph, PointMap point_map, double tolerance)
380388 using Vertex_position = std::pair<FT, vertex_descriptor>;
381389 std::map<edge_descriptor, std::vector<Vertex_position>> new_vertices;
382390
391+ // Compute intersections
383392 box_self_intersection_d
384393 (boxes.begin (), boxes.end (),
385394 [&](const Box& a, const Box& b)
@@ -427,6 +436,7 @@ void polyline_snapping (Graph& graph, PointMap point_map, double tolerance)
427436 },
428437 cutoff);
429438
439+ // Refine edges
430440 for (auto & m : new_vertices)
431441 {
432442 edge_descriptor ed = m.first ;
@@ -447,6 +457,53 @@ void polyline_snapping (Graph& graph, PointMap point_map, double tolerance)
447457 add_edge (vertices[i].second , vertices[i+1 ].second , graph);
448458 }
449459
460+ #if 0
461+ // Detect edges smaller than threshold
462+ using vedge = std::pair<vertex_descriptor, vertex_descriptor>;
463+ std::vector<vedge> vedges;
464+ for (edge_descriptor ed : make_range(edges(graph).first, edges(graph).second))
465+ {
466+ vertex_descriptor vs = source (ed, graph);
467+ vertex_descriptor vt = target (ed, graph);
468+ vedges.emplace_back (vs, vt);
469+ }
470+
471+ // Map deleted vertex -> valid vertex
472+ std::map<vertex_descriptor, vertex_descriptor> map_v2v;
473+ // Map vertex -> barycenter weight
474+ std::map<vertex_descriptor, std::size_t> map_v2b;
475+ for (vertex_descriptor vd : make_range(vertices(graph).first, vertices(graph).second))
476+ {
477+ map_v2v.insert (std::make_pair(vd, vd));
478+ map_v2b.insert (std::make_pair(vd, 1));
479+ }
480+
481+ // Collapse edges
482+ for (vedge ve : vedges)
483+ {
484+ vertex_descriptor vs = map_v2v[ve.first];
485+ vertex_descriptor vt = map_v2v[ve.second];
486+
487+ if (vs == vt)
488+ continue;
489+
490+ const Point_3& ps = get (point_map, vs);
491+ const Point_3& pt = get (point_map, vt);
492+
493+ if (squared_distance(ps, ps) > tolerance * tolerance)
494+ continue;
495+
496+ std::size_t& bs = map_v2b[vs];
497+ std::size_t& bt = map_v2b[vt];
498+ Point_3 bary = barycenter (ps, bs, pt, bt);
499+ bs += bt;
500+
501+ put (point_map, vs, bary);
502+
503+ map_v2v[vt] = vs;
504+ }
505+ #endif
506+
450507}
451508
452509
0 commit comments