-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathstraight_skeleton_2.cpp
107 lines (92 loc) · 3.48 KB
/
straight_skeleton_2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "straight_skeleton_2.h"
#include <CGAL/Polygon_2.h>
#include <CGAL/create_straight_skeleton_2.h>
#include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes;
typedef CGAL::Straight_skeleton_2<K> Ss;
typedef boost::shared_ptr<Ss> SsPtr;
typedef CGAL::Straight_skeleton_2<K>::Halfedge_const_handle Halfedge_const_handle;
typedef CGAL::Straight_skeleton_2<K>::Vertex_const_handle Vertex_const_handle;
compas::Edges pmp_create_interior_straight_skeleton(
Eigen::Ref<const compas::RowMatrixXd> &V)
{
Polygon_2 poly;
for (int i = 0; i < V.rows(); i++)
{
poly.push_back(Point(V(i, 0), V(i, 1)));
}
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly.vertices_begin(), poly.vertices_end());
compas::Edges edgelist;
for(auto hit = iss->halfedges_begin(); hit != iss->halfedges_end(); ++hit){
const Halfedge_const_handle h = hit;
if(!h->is_bisector()){
continue;
}
const Vertex_const_handle& v1 = h->vertex();
const Vertex_const_handle& v2 = h->opposite()->vertex();
if(&*v1 < &*v2){
std::vector<double> s_vec = {v1->point().x(), v1->point().y(), 0};
std::vector<double> t_vec = {v2->point().x(), v2->point().y(), 0};
compas::Edge edge = std::make_tuple(s_vec, t_vec);
edgelist.push_back(edge);
}
}
return edgelist;
};
compas::Edges pmp_create_interior_straight_skeleton_with_holes(
Eigen::Ref<const compas::RowMatrixXd> &V,
std::vector<Eigen::Ref<const compas::RowMatrixXd>> &holes)
{
Polygon_2 outer;
for (int i = 0; i < V.rows(); i++)
{
outer.push_back(Point(V(i, 0), V(i, 1)));
}
Polygon_with_holes poly(outer);
for (auto hit : holes)
{
compas::RowMatrixXd H = hit;
Polygon_2 hole;
for (int i = 0; i < H.rows(); i++)
{
hole.push_back(Point(H(i, 0), H(i, 1)));
}
poly.add_hole(hole);
}
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly);
compas::Edges edgelist;
for(auto hit = iss->halfedges_begin(); hit != iss->halfedges_end(); ++hit){
const Halfedge_const_handle h = hit;
if(!h->is_bisector()){
continue;
}
const Vertex_const_handle& v1 = h->vertex();
const Vertex_const_handle& v2 = h->opposite()->vertex();
if(&*v1 < &*v2){
std::vector<double> s_vec = {v1->point().x(), v1->point().y(), 0};
std::vector<double> t_vec = {v2->point().x(), v2->point().y(), 0};
compas::Edge edge = std::make_tuple(s_vec, t_vec);
edgelist.push_back(edge);
}
}
return edgelist;
}
// ===========================================================================
// PyBind11
// ===========================================================================
void init_straight_skeleton_2(pybind11::module &m)
{
pybind11::module submodule = m.def_submodule("straight_skeleton_2");
submodule.def(
"create_interior_straight_skeleton",
&pmp_create_interior_straight_skeleton,
pybind11::arg("V").noconvert());
submodule.def(
"create_interior_straight_skeleton_with_holes",
&pmp_create_interior_straight_skeleton_with_holes,
pybind11::arg("V").noconvert(),
pybind11::arg("holes").noconvert());
};