Wildmeshing Toolkit
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>
12 #include <wmtk/simplex/Simplex.hpp>
15 
17 using namespace wmtk;
18 using namespace tests;
19 using namespace tests_3d;
20 using namespace components;
21 using namespace internal;
22 
23 TEST_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 
102 TEST_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 
185 TEST_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 
226 TEST_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 
313 TEST_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 
411 TEST_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 
469 TEST_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:92
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:996
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)
std::vector< PrimitiveType > primitive_below(PrimitiveType pt, bool lower_to_upper)
Definition: Accessor.hpp:6
TEST_CASE("multimesh_from_tag_tri_tri", "[components][multimesh][multimesh_from_tag]")
nlohmann::json json
nlohmann::json json
Definition: input.cpp:9