Wildmeshing Toolkit
Loading...
Searching...
No Matches
test_component_multimesh_from_tag.cpp
Go to the documentation of this file.
1#include <catch2/catch_test_macros.hpp>
2#include <nlohmann/json.hpp>
3#include <tools/DEBUG_TetMesh.hpp>
4#include <tools/DEBUG_TriMesh.hpp>
5#include <tools/TetMesh_examples.hpp>
6#include <tools/TriMesh_examples.hpp>
8#include <wmtk/components/multimesh_from_tag/internal/MultiMeshFromTagOptions.hpp>
15
16using json = nlohmann::json;
17using namespace wmtk;
18using namespace tests;
19using namespace tests_3d;
20using namespace components;
21using namespace internal;
22
23TEST_CASE("multimesh_from_tag_tri_tri", "[components][multimesh][multimesh_from_tag]")
24{
25 auto mesh_in = tests::disk(6);
26 DEBUG_TriMesh& m = static_cast<DEBUG_TriMesh&>(*mesh_in);
27
28 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Triangle, 1);
29 int64_t tag_value = 1;
30
31 int64_t n_faces = -1;
32 int64_t n_edges = -1;
33 int64_t n_vertices = -1;
34 simplex::SimplexCollection non_manifold_root_simplices(m);
35
36 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
37
38 SECTION("one_component")
39 {
40 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
41 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 3)) = tag_value;
42 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 3, 4)) = tag_value;
43 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 4, 5)) = tag_value;
44 n_faces = 4;
45 n_edges = 9;
46 n_vertices = 6;
47 }
48 SECTION("two_components")
49 {
50 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
51 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 3)) = tag_value;
52 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 3, 4)) = tag_value;
53 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 5, 6)) = tag_value;
54 n_faces = 4;
55 n_edges = 10;
56 n_vertices = 8;
57 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(0));
58 }
59 SECTION("three_components")
60 {
61 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
62 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 3, 4)) = tag_value;
63 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 5, 6)) = tag_value;
64 n_faces = 3;
65 n_edges = 9;
66 n_vertices = 9;
67 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(0));
68 }
69
70 MultiMeshFromTag mmft(m, tag_handle, tag_value);
71
73
74 REQUIRE(m.get_child_meshes().size() == 2);
75 REQUIRE(m.is_multi_mesh_root());
76
77 mmft.remove_soup();
78 CHECK(m.get_child_meshes().size() == 1);
79 REQUIRE(m.is_multi_mesh_root());
80
81 auto substructure_mesh_ptr = mmft.substructure();
82 Mesh& sub_mesh = *substructure_mesh_ptr;
83
84 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Triangle);
85 CHECK(sub_mesh.get_all(PrimitiveType::Triangle).size() == n_faces);
86 CHECK(sub_mesh.get_all(PrimitiveType::Edge).size() == n_edges);
87 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == n_vertices);
88
89 non_manifold_root_simplices.sort_and_clean();
90 for (const PrimitiveType pt : utils::primitive_below(m.top_simplex_type())) {
91 for (const Tuple& t : m.get_all(pt)) {
92 const simplex::Simplex s(m, pt, t);
93 if (non_manifold_root_simplices.contains(s)) {
94 CHECK_FALSE(mmft.is_root_simplex_manifold(s));
95 } else {
96 CHECK(mmft.is_root_simplex_manifold(s));
97 }
98 }
99 }
100}
101
102TEST_CASE("multimesh_from_tag_tri_edge", "[components][multimesh][multimesh_from_tag]")
103{
104 auto mesh_in = tests::disk(6);
105 DEBUG_TriMesh& m = static_cast<DEBUG_TriMesh&>(*mesh_in);
106
107 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Edge, 1);
108 int64_t tag_value = 1;
109
110 int64_t n_edges = -1;
111 int64_t n_vertices = -1;
112 simplex::SimplexCollection non_manifold_root_simplices(m);
113
114 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
115
116 SECTION("one_component")
117 {
118 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 1)) = tag_value;
119 tag_acc.scalar_attribute(m.edge_tuple_from_vids(1, 2)) = tag_value;
120 tag_acc.scalar_attribute(m.edge_tuple_from_vids(2, 3)) = tag_value;
121 n_edges = 3;
122 n_vertices = 4;
123 }
124 SECTION("two_components")
125 {
126 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 1)) = tag_value;
127 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 4)) = tag_value;
128 tag_acc.scalar_attribute(m.edge_tuple_from_vids(5, 6)) = tag_value;
129 n_edges = 3;
130 n_vertices = 5;
131 }
132 SECTION("three_components")
133 {
134 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 1)) = tag_value;
135 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 4)) = tag_value;
136 tag_acc.scalar_attribute(m.edge_tuple_from_vids(5, 0)) = tag_value;
137 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(0));
138 n_edges = 3;
139 n_vertices = 6;
140 }
141 SECTION("two_closed_loops")
142 {
143 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 1)) = tag_value;
144 tag_acc.scalar_attribute(m.edge_tuple_from_vids(1, 2)) = tag_value;
145 tag_acc.scalar_attribute(m.edge_tuple_from_vids(2, 0)) = tag_value;
146 tag_acc.scalar_attribute(m.edge_tuple_from_vids(0, 4)) = tag_value;
147 tag_acc.scalar_attribute(m.edge_tuple_from_vids(4, 5)) = tag_value;
148 tag_acc.scalar_attribute(m.edge_tuple_from_vids(5, 0)) = tag_value;
149 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(0));
150 n_edges = 6;
151 n_vertices = 8;
152 }
153
154 MultiMeshFromTag mmft(m, tag_handle, tag_value);
155
157
158 REQUIRE(m.get_child_meshes().size() == 2);
159 REQUIRE(m.is_multi_mesh_root());
160
161 mmft.remove_soup();
162 CHECK(m.get_child_meshes().size() == 1);
163 REQUIRE(m.is_multi_mesh_root());
164
165 auto substructure_mesh_ptr = mmft.substructure();
166 Mesh& sub_mesh = *substructure_mesh_ptr;
167
168 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Edge);
169 CHECK(sub_mesh.get_all(PrimitiveType::Edge).size() == n_edges);
170 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == n_vertices);
171
172 non_manifold_root_simplices.sort_and_clean();
173 for (const PrimitiveType pt : utils::primitive_below(m.top_simplex_type())) {
174 for (const Tuple& t : m.get_all(pt)) {
175 const simplex::Simplex s(m, pt, t);
176 if (non_manifold_root_simplices.contains(s)) {
177 CHECK_FALSE(mmft.is_root_simplex_manifold(s));
178 } else {
179 CHECK(mmft.is_root_simplex_manifold(s));
180 }
181 }
182 }
183}
184
185TEST_CASE("multimesh_from_tag_tri_point", "[components][multimesh][multimesh_from_tag]")
186{
187 auto mesh_in = tests::disk(6);
188 DEBUG_TriMesh& m = static_cast<DEBUG_TriMesh&>(*mesh_in);
189
190 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Vertex, 1);
191 int64_t tag_value = 1;
192
193
194 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
195
196 auto vertices = m.get_all(PrimitiveType::Vertex);
197 for (size_t i = 0; i < 4; ++i) {
198 tag_acc.scalar_attribute(vertices[i]) = tag_value;
199 }
200
201 MultiMeshFromTag mmft(m, tag_handle, tag_value);
202
204
205 REQUIRE(m.get_child_meshes().size() == 2);
206 REQUIRE(m.is_multi_mesh_root());
207
208 mmft.remove_soup();
209 CHECK(m.get_child_meshes().size() == 1);
210 REQUIRE(m.is_multi_mesh_root());
211
212 auto substructure_mesh_ptr = mmft.substructure();
213 Mesh& sub_mesh = *substructure_mesh_ptr;
214
215 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Vertex);
216 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == 4);
217
218 for (const PrimitiveType pt : utils::primitive_below(m.top_simplex_type())) {
219 for (const Tuple& t : m.get_all(pt)) {
220 const simplex::Simplex s(m, pt, t);
221 CHECK(mmft.is_root_simplex_manifold(s));
222 }
223 }
224}
225
226TEST_CASE("multimesh_from_tag_tet_tet", "[components][multimesh][multimesh_from_tag]")
227{
228 DEBUG_TetMesh m = six_cycle_tets();
229
230 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Tetrahedron, 1);
231 int64_t tag_value = 1;
232
233 int64_t n_tets = -1;
234 int64_t n_faces = -1;
235 int64_t n_edges = -1;
236 int64_t n_vertices = -1;
237 simplex::SimplexCollection non_manifold_root_simplices(m);
238
239 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
240
241 SECTION("one_component")
242 {
243 tag_acc.scalar_attribute(m.tet_tuple_from_vids(0, 1, 2, 3)) = tag_value;
244 tag_acc.scalar_attribute(m.tet_tuple_from_vids(0, 2, 3, 4)) = tag_value;
245 tag_acc.scalar_attribute(m.tet_tuple_from_vids(2, 3, 4, 5)) = tag_value;
246 n_tets = 3;
247 n_faces = 10;
248 n_edges = 12;
249 n_vertices = 6;
250 }
251 SECTION("two_components")
252 {
253 tag_acc.scalar_attribute(m.tet_tuple_from_vids(0, 1, 2, 3)) = tag_value;
254 tag_acc.scalar_attribute(m.tet_tuple_from_vids(0, 2, 3, 4)) = tag_value;
255 tag_acc.scalar_attribute(m.tet_tuple_from_vids(2, 3, 4, 5)) = tag_value;
256 tag_acc.scalar_attribute(m.tet_tuple_from_vids(2, 3, 6, 7)) = tag_value;
257 n_tets = 4;
258 n_faces = 14;
259 n_edges = 18;
260 n_vertices = 10;
261 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(2));
262 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(3));
263 non_manifold_root_simplices.add(PrimitiveType::Edge, m.edge_tuple_from_vids(2, 3));
264 }
265 SECTION("three_components")
266 {
267 tag_acc.scalar_attribute(m.tet_tuple_from_vids(0, 1, 2, 3)) = tag_value;
268 tag_acc.scalar_attribute(m.tet_tuple_from_vids(2, 3, 4, 5)) = tag_value;
269 tag_acc.scalar_attribute(m.tet_tuple_from_vids(2, 3, 6, 7)) = tag_value;
270 n_tets = 3;
271 n_faces = 12;
272 n_edges = 18;
273 n_vertices = 12;
274
275 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(2));
276 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(3));
277 non_manifold_root_simplices.add(PrimitiveType::Edge, m.edge_tuple_from_vids(2, 3));
278 }
279
280 MultiMeshFromTag mmft(m, tag_handle, tag_value);
281
283
284 REQUIRE(m.get_child_meshes().size() == 2);
285 REQUIRE(m.is_multi_mesh_root());
286
287 mmft.remove_soup();
288 CHECK(m.get_child_meshes().size() == 1);
289 REQUIRE(m.is_multi_mesh_root());
290
291 auto substructure_mesh_ptr = mmft.substructure();
292 Mesh& sub_mesh = *substructure_mesh_ptr;
293
294 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Tetrahedron);
295 CHECK(sub_mesh.get_all(PrimitiveType::Tetrahedron).size() == n_tets);
296 CHECK(sub_mesh.get_all(PrimitiveType::Triangle).size() == n_faces);
297 CHECK(sub_mesh.get_all(PrimitiveType::Edge).size() == n_edges);
298 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == n_vertices);
299
300 non_manifold_root_simplices.sort_and_clean();
301 for (const PrimitiveType pt : utils::primitive_below(m.top_simplex_type())) {
302 for (const Tuple& t : m.get_all(pt)) {
303 const simplex::Simplex s(m, pt, t);
304 if (non_manifold_root_simplices.contains(s)) {
305 CHECK_FALSE(mmft.is_root_simplex_manifold(s));
306 } else {
307 CHECK(mmft.is_root_simplex_manifold(s));
308 }
309 }
310 }
311}
312
313TEST_CASE("multimesh_from_tag_tet_tri", "[components][multimesh][multimesh_from_tag]")
314{
315 DEBUG_TetMesh m = six_cycle_tets();
316
317 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Triangle, 1);
318 int64_t tag_value = 1;
319
320 int64_t n_faces = -1;
321 int64_t n_edges = -1;
322 int64_t n_vertices = -1;
323 simplex::SimplexCollection non_manifold_root_simplices(m);
324
325 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
326
327 SECTION("one_component")
328 {
329 tag_acc.scalar_attribute(m.face_tuple_from_vids(1, 2, 3)) = tag_value;
330 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
331 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 3, 5)) = tag_value;
332 n_faces = 3;
333 n_edges = 7;
334 n_vertices = 5;
335 }
336 SECTION("non_manifold_vertex")
337 {
338 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
339 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 4)) = tag_value;
340 tag_acc.scalar_attribute(m.face_tuple_from_vids(1, 2, 6)) = tag_value;
341 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 5, 7)) = tag_value;
342 tag_acc.scalar_attribute(m.face_tuple_from_vids(3, 5, 7)) = tag_value;
343 n_faces = 5;
344 n_edges = 12;
345 n_vertices = 9;
346 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(2));
347 }
348 SECTION("non_manifold_vertex_2")
349 {
350 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
351 tag_acc.scalar_attribute(m.face_tuple_from_vids(1, 2, 3)) = tag_value;
352 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 3)) = tag_value;
353 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 3)) = tag_value;
354 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 5, 7)) = tag_value;
355 n_faces = 5;
356 n_edges = 9;
357 n_vertices = 7;
358 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(2));
359 }
360 SECTION("non_manifold_edge")
361 {
362 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = tag_value;
363 tag_acc.scalar_attribute(m.face_tuple_from_vids(1, 2, 3)) = tag_value;
364 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 3)) = tag_value;
365 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 3)) = tag_value;
366
367 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 3, 5)) = tag_value;
368 tag_acc.scalar_attribute(m.face_tuple_from_vids(3, 5, 7)) = tag_value;
369 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 5, 7)) = tag_value;
370 tag_acc.scalar_attribute(m.face_tuple_from_vids(2, 3, 7)) = tag_value;
371 n_faces = 8;
372 n_edges = 14;
373 n_vertices = 8;
374 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(2));
375 non_manifold_root_simplices.add(PrimitiveType::Vertex, m.vertex_tuple_from_id(3));
376 non_manifold_root_simplices.add(PrimitiveType::Edge, m.edge_tuple_from_vids(2, 3));
377 }
378
379 MultiMeshFromTag mmft(m, tag_handle, tag_value);
380
382
383 REQUIRE(m.get_child_meshes().size() == 2);
384 REQUIRE(m.is_multi_mesh_root());
385
386 mmft.remove_soup();
387 CHECK(m.get_child_meshes().size() == 1);
388 REQUIRE(m.is_multi_mesh_root());
389
390 auto substructure_mesh_ptr = mmft.substructure();
391 Mesh& sub_mesh = *substructure_mesh_ptr;
392
393 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Triangle);
394 CHECK(sub_mesh.get_all(PrimitiveType::Triangle).size() == n_faces);
395 CHECK(sub_mesh.get_all(PrimitiveType::Edge).size() == n_edges);
396 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == n_vertices);
397
398 non_manifold_root_simplices.sort_and_clean();
399 for (const PrimitiveType pt : utils::primitive_below(m.top_simplex_type())) {
400 for (const Tuple& t : m.get_all(pt)) {
401 const simplex::Simplex s(m, pt, t);
402 if (non_manifold_root_simplices.contains(s)) {
403 CHECK_FALSE(mmft.is_root_simplex_manifold(s));
404 } else {
405 CHECK(mmft.is_root_simplex_manifold(s));
406 }
407 }
408 }
409}
410
411TEST_CASE("multimesh_from_tag_tri_visualization", "[components][multimesh][multimesh_from_tag][.]")
412{
413 DEBUG_TriMesh m = tests::edge_region_with_position();
414
415 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Triangle, 1);
416 int64_t tag_value = 1;
417
418 int64_t n_faces = -1;
419 int64_t n_edges = -1;
420 int64_t n_vertices = -1;
421
422 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
423
424 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 3, 4)) = tag_value;
425 tag_acc.scalar_attribute(m.face_tuple_from_vids(3, 7, 4)) = tag_value;
426 tag_acc.scalar_attribute(m.face_tuple_from_vids(4, 5, 1)) = tag_value;
427 tag_acc.scalar_attribute(m.face_tuple_from_vids(5, 6, 2)) = tag_value;
428 n_faces = 4;
429 n_edges = 11;
430 n_vertices = 10;
431
432 MultiMeshFromTag mmft(m, tag_handle, tag_value);
433
435
436 CHECK(m.get_child_meshes().size() == 2);
437 CHECK(m.is_multi_mesh_root());
438
439 auto substructure_mesh_ptr = mmft.substructure();
440 Mesh& sub_mesh = *substructure_mesh_ptr;
441
442 CHECK(sub_mesh.top_simplex_type() == PrimitiveType::Triangle);
443 CHECK(sub_mesh.get_all(PrimitiveType::Triangle).size() == n_faces);
444 CHECK(sub_mesh.get_all(PrimitiveType::Edge).size() == n_edges);
445 CHECK(sub_mesh.get_all(PrimitiveType::Vertex).size() == n_vertices);
446
447
448 auto root_pos_handle = m.get_attribute_handle<double>("vertices", PrimitiveType::Vertex);
449 auto subs_pos_handle =
450 sub_mesh.register_attribute<double>("vertices", PrimitiveType::Vertex, 3);
451
452 auto propagate_to_child_position = [](const Eigen::MatrixXd& P) -> Eigen::VectorXd {
453 return P;
454 };
455
456 auto pos_transfer =
457 std::make_shared<wmtk::operations::SingleAttributeTransferStrategy<double, double>>(
458 subs_pos_handle,
459 root_pos_handle,
460 propagate_to_child_position);
461 pos_transfer->run_on_all();
462
463 ParaviewWriter writer("child_mesh", "vertices", sub_mesh, false, false, true, false);
464 sub_mesh.serialize(writer);
465 ParaviewWriter writer2("root_mesh", "vertices", m, false, false, true, false);
466 m.serialize(writer2);
467}
468
469TEST_CASE("multimesh_from_tag", "[components][multimesh][multimesh_from_tag]")
470{
471 io::Cache cache("wmtk_cache", ".");
472 {
473 auto mesh_in = tests::disk(6);
474 DEBUG_TriMesh& m = static_cast<DEBUG_TriMesh&>(*mesh_in);
475
476 auto tag_handle = m.register_attribute<int64_t>("tag", PrimitiveType::Triangle, 1);
477 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
478 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 1, 2)) = 1;
479 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 2, 3)) = 1;
480 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 3, 4)) = 1;
481 tag_acc.scalar_attribute(m.face_tuple_from_vids(0, 5, 6)) = 1;
482
483 cache.write_mesh(*mesh_in, "input_mesh");
484 }
485
486 json o = R"(
487 {
488 "input": "input_mesh",
489 "output": "output_mesh",
490 "substructure_label": "tag",
491 "substructure_value": 1,
492 "pass_through": []
493 }
494 )"_json;
495
496 CHECK_NOTHROW(multimesh_from_tag(utils::Paths(), o, cache));
497}
498
499// TODO add tests for tet_edge and tet_point
500// TODO add hour glass test (non-manifold vertex) in tet_tri
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
void serialize(MeshWriter &writer, const Mesh *local_root=nullptr) const
Definition Mesh.cpp:93
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition Mesh.cpp:18
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
This class generates a multi-mesh from a mesh where the substructure is represented by a tag.
void remove_soup()
Remove the substructure soup from the multimesh.
std::shared_ptr< Mesh > substructure() const
Returns a pointer to the manifold substructure mesh.
bool is_root_simplex_manifold(const simplex::Simplex &s) const
void compute_substructure_mesh()
Create a manifold mesh from the substructure.
void write_mesh(const Mesh &m, const std::string &name, const std::map< std::string, std::vector< int64_t > > &multimesh_names={})
Write a mesh to cache.
Definition Cache.cpp:194
void add(const Simplex &simplex)
Add simplex to the collection.
bool contains(const Simplex &simplex) const
Check if simplex is contained in collection.
void sort_and_clean()
Sort simplex vector and remove duplicates.
void multimesh_from_tag(std::shared_ptr< Mesh > &mesh_in, attribute::MeshAttributeHandle &substructure_label, int64_t substructure_value)
Generate a multi-mesh from a mesh with a tag that represents the substructure, the mesh is changed.
std::vector< Tuple > vertices(const Mesh &m, const Simplex &simplex)
TEST_CASE("multimesh_from_tag_tri_tri", "[components][multimesh][multimesh_from_tag]")
nlohmann::json json
Definition input.cpp:9