Wildmeshing Toolkit
Loading...
Searching...
No Matches
cdt_lib.cpp
Go to the documentation of this file.
1#include "cdt_lib.hpp"
2
3#include <CDT/PLC.h>
4#include <CDT/delaunay.h>
5#include <CDT/inputPLC.h>
6#include <map>
7
8namespace cdt_lib {
9
11 const std::vector<double>& V,
12 const uint32_t npts,
13 const std::vector<uint32_t>& F,
14 const uint32_t ntri,
15 cdt::inputPLC& plc)
16{
17 plc.initFromVectors(
18 const_cast<double*>(V.data()),
19 npts,
20 const_cast<uint32_t*>(F.data()),
21 ntri,
22 true);
23}
24
25cdt::TetMesh* createSteinerCDT(cdt::inputPLC& plc, bool bbox, bool snap)
26{
27 if (bbox) {
28 plc.addBoundingBoxVertices();
29 }
30
31 cdt::TetMesh* tin = new cdt::TetMesh;
32 tin->init_vertices(plc.coordinates.data(), plc.numVertices());
33 tin->tetrahedrize();
34
35 // copied from cdt/main.cpp
36 // Build a structured PLC linked to the Delaunay tetrahedrization
37 cdt::PLCx Steiner_plc(*tin, plc.triangle_vertices.data(), plc.numTriangles());
38
39 // Recover segments by inserting Steiner points in both the PLC and the
40 // tetrahedrization
41 Steiner_plc.segmentRecovery_HSi(true);
42
43 // Recover PLC faces by locally remeshing the tetrahedrization
44 bool sisMethodWorks = Steiner_plc.faceRecovery(true);
45
46 // Mark the tets which are bounded by the PLC.
47 // If the PLC is not a valid polyhedron (i.e. it has odd-valency edges)
48 // all the tets but the ghosts are marked as "internal".
49 uint32_t num_inner_tets = (uint32_t)Steiner_plc.markInnerTets();
50
51 return tin;
52}
53
55 cdt::TetMesh& tin,
56 std::vector<std::array<bool, 4>>& local_f_on_input,
57 std::vector<std::array<int64_t, 4>>& T_final,
58 std::vector<std::array<std::string, 3>>& V_final,
59 bool inner_only)
60{
61 std::vector<std::array<int64_t, 4>> T;
62 std::vector<std::array<std::string, 3>> V;
63
64 uint32_t ngnt = 0;
65 for (uint32_t i = 0; i < tin.numTets(); ++i) {
66 if (tin.mark_tetrahedra[i] == 2) {
67 ngnt++;
68 }
69 }
70
71 for (uint32_t i = 0; i < tin.numVertices(); ++i) {
72 cdt::bigrational c[3];
73 tin.vertices[i]->getExactXYZCoordinates(c[0], c[1], c[2]);
74
75 std::array<std::string, 3> v;
76
77#ifdef USE_GNU_GMP_CLASSES // TODO
78 v[0].init(c[0].get_mpq_t());
79 v[1].init(c[1].get_mpq_t());
80 v[2].init(c[2].get_mpq_t());
81#else
82 v[0] = c[0].get_str();
83 v[1] = c[1].get_str();
84 v[2] = c[2].get_str();
85#endif
86 V.push_back(v);
87 }
88
89 int64_t row = 0;
90 for (uint32_t i = 0; i < tin.numTets(); ++i) {
91 if (tin.mark_tetrahedra[i] == 2) {
92 T.push_back(
93 {{tin.tet_node[i * 4],
94 tin.tet_node[i * 4 + 1],
95 tin.tet_node[i * 4 + 2],
96 tin.tet_node[i * 4 + 3]}});
97
98 // mark surfaces
99 // assuming opposite face to node
100 std::array<bool, 4> on_input = {{false, false, false, false}};
101 for (uint64_t j = i; j < i + 4; ++j) {
102 if (tin.mark_tetrahedra[tin.tet_neigh[j] >> 2] != tin.mark_tetrahedra[j >> 2]) {
103 on_input[j - i] = true;
104 }
105 }
106
107 local_f_on_input.push_back(on_input);
108
109 row++;
110 }
111 }
112
113 if (!inner_only) {
114 for (uint32_t i = 0; i < tin.numTets(); ++i) {
115 if (!tin.isGhost(i) && tin.mark_tetrahedra[i] != 2) {
116 T.push_back(
117 {{tin.tet_node[i * 4],
118 tin.tet_node[i * 4 + 1],
119 tin.tet_node[i * 4 + 2],
120 tin.tet_node[i * 4 + 3]}});
121
122 // mark surfaces
123 // assuming opposite face to node
124 std::array<bool, 4> on_input = {{false, false, false, false}};
125 for (uint64_t j = i; j < i + 4; ++j) {
126 if (tin.mark_tetrahedra[tin.tet_neigh[j] >> 2] != tin.mark_tetrahedra[j >> 2]) {
127 on_input[j] = true;
128 }
129 }
130
131 local_f_on_input.push_back(on_input);
132
133 row++;
134 }
135 }
136 }
137
138 // remove unused vertices
139 std::vector<int> v_is_used_in_tet(V.size(), 0);
140 for (int64_t i = 0; i < T.size(); ++i) {
141 for (int64_t j = 0; j < 4; ++j) {
142 v_is_used_in_tet[T[i][j]] = 1;
143 }
144 }
145
146 int64_t v_used_cnt = std::count(v_is_used_in_tet.begin(), v_is_used_in_tet.end(), 1);
147
148 std::map<int64_t, int64_t> v_map;
149
150 for (int64_t i = 0; i < V.size(); ++i) {
151 if (v_is_used_in_tet[i]) {
152 v_map[i] = V_final.size();
153 V_final.push_back(V[i]);
154 }
155 }
156
157 T_final = T;
158
159 for (int64_t i = 0; i < T.size(); ++i) {
160 for (int64_t j = 0; j < 4; ++j) {
161 T_final[i][j] = v_map[T[i][j]];
162 }
163 }
164}
165
167 const std::vector<double>& V,
168 const uint32_t npts,
169 const std::vector<uint32_t>& F,
170 const uint32_t ntri,
171 std::vector<std::array<bool, 4>>& local_f_on_input,
172 std::vector<std::array<int64_t, 4>>& T_final,
173 std::vector<std::array<std::string, 3>>& V_final,
174 bool inner_only)
175{
176 cdt::inputPLC plc;
177
178 convert_trimesh_to_input_plc(V, npts, F, ntri, plc);
179
180 cdt::TetMesh* tin = createSteinerCDT(plc, true, false);
181 convert_cdt_to_stl(*tin, local_f_on_input, T_final, V_final, inner_only);
182}
183} // namespace cdt_lib
void convert_trimesh_to_input_plc(const std::vector< double > &V, const uint32_t npts, const std::vector< uint32_t > &F, const uint32_t ntri, cdt::inputPLC &plc)
Definition cdt_lib.cpp:10
void convert_cdt_to_stl(cdt::TetMesh &tin, std::vector< std::array< bool, 4 > > &local_f_on_input, std::vector< std::array< int64_t, 4 > > &T_final, std::vector< std::array< std::string, 3 > > &V_final, bool inner_only)
Definition cdt_lib.cpp:54
void cdt_to_string(const std::vector< double > &V, const uint32_t npts, const std::vector< uint32_t > &F, const uint32_t ntri, std::vector< std::array< bool, 4 > > &local_f_on_input, std::vector< std::array< int64_t, 4 > > &T_final, std::vector< std::array< std::string, 3 > > &V_final, bool inner_only)
Definition cdt_lib.cpp:166
cdt::TetMesh * createSteinerCDT(cdt::inputPLC &plc, bool bbox, bool snap)
Definition cdt_lib.cpp:25