Skip to content

Commit a54b342

Browse files
committed
More on polyline snapping
1 parent b07dc33 commit a54b342

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polyline_snapping.h

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Polygon_mesh_processing/test/Polygon_mesh_processing/test_polyline_snapping.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
55
#include <CGAL/Polygon_mesh_processing/polyline_snapping.h>
6+
#include <CGAL/boost/graph/split_graph_into_polylines.h>
67

78
#include <boost/graph/adjacency_list.hpp>
89

@@ -15,6 +16,34 @@ using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS
1516
using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor;
1617
using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor;
1718

19+
class Visitor
20+
{
21+
const Graph& graph;
22+
std::ofstream& ofile;
23+
std::vector<vertex_descriptor> vertices;
24+
25+
public:
26+
27+
Visitor (const Graph& graph, std::ofstream& ofile) : graph (graph), ofile(ofile) { }
28+
29+
void start_new_polyline()
30+
{
31+
vertices.clear();
32+
}
33+
34+
void add_node (vertex_descriptor v)
35+
{
36+
vertices.push_back(v);
37+
}
38+
39+
void end_polyline()
40+
{
41+
ofile << vertices.size();
42+
for (vertex_descriptor vd : vertices)
43+
ofile << " " << graph[vd].point;
44+
ofile << std::endl;
45+
}
46+
};
1847

1948
int main (int argc, char** argv)
2049
{
@@ -81,10 +110,14 @@ int main (int argc, char** argv)
81110

82111
std::cerr << "Snapping..." << std::endl;
83112

84-
CGAL::Polygon_mesh_processing::polyline_snapping (graph, get(&Vertex_property::point, graph), 0.001);
113+
CGAL::Polygon_mesh_processing::polyline_snapping (graph, get(&Vertex_property::point, graph), 0.1);
85114

86115
std::cerr << " -> resulting graph has " << num_vertices(graph)
87116
<< " vertices and " << num_edges(graph) << " edges" << std::endl;
88117

118+
std::ofstream ofile ("snapped.polylines.txt");
119+
Visitor visitor(graph, ofile);
120+
CGAL::split_graph_into_polylines (graph, visitor);
121+
89122
return EXIT_SUCCESS;
90123
}

0 commit comments

Comments
 (0)