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>
18 using namespace tests;
19 using namespace tests_3d;
20 using namespace components;
23 TEST_CASE(
"multimesh_from_tag_tri_tri",
"[components][multimesh][multimesh_from_tag]")
25 auto mesh_in = tests::disk(6);
26 DEBUG_TriMesh& m =
static_cast<DEBUG_TriMesh&
>(*mesh_in);
29 int64_t tag_value = 1;
33 int64_t n_vertices = -1;
36 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
38 SECTION(
"one_component")
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;
48 SECTION(
"two_components")
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;
59 SECTION(
"three_components")
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;
74 REQUIRE(m.get_child_meshes().size() == 2);
75 REQUIRE(m.is_multi_mesh_root());
78 CHECK(m.get_child_meshes().size() == 1);
79 REQUIRE(m.is_multi_mesh_root());
82 Mesh& sub_mesh = *substructure_mesh_ptr;
91 for (
const Tuple& t : m.get_all(pt)) {
93 if (non_manifold_root_simplices.
contains(s)) {
102 TEST_CASE(
"multimesh_from_tag_tri_edge",
"[components][multimesh][multimesh_from_tag]")
104 auto mesh_in = tests::disk(6);
105 DEBUG_TriMesh& m =
static_cast<DEBUG_TriMesh&
>(*mesh_in);
108 int64_t tag_value = 1;
110 int64_t n_edges = -1;
111 int64_t n_vertices = -1;
114 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
116 SECTION(
"one_component")
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;
124 SECTION(
"two_components")
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;
132 SECTION(
"three_components")
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;
141 SECTION(
"two_closed_loops")
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;
158 REQUIRE(m.get_child_meshes().size() == 2);
159 REQUIRE(m.is_multi_mesh_root());
162 CHECK(m.get_child_meshes().size() == 1);
163 REQUIRE(m.is_multi_mesh_root());
166 Mesh& sub_mesh = *substructure_mesh_ptr;
174 for (
const Tuple& t : m.get_all(pt)) {
176 if (non_manifold_root_simplices.
contains(s)) {
185 TEST_CASE(
"multimesh_from_tag_tri_point",
"[components][multimesh][multimesh_from_tag]")
187 auto mesh_in = tests::disk(6);
188 DEBUG_TriMesh& m =
static_cast<DEBUG_TriMesh&
>(*mesh_in);
191 int64_t tag_value = 1;
194 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
197 for (
size_t i = 0; i < 4; ++i) {
198 tag_acc.scalar_attribute(
vertices[i]) = tag_value;
205 REQUIRE(m.get_child_meshes().size() == 2);
206 REQUIRE(m.is_multi_mesh_root());
209 CHECK(m.get_child_meshes().size() == 1);
210 REQUIRE(m.is_multi_mesh_root());
213 Mesh& sub_mesh = *substructure_mesh_ptr;
219 for (
const Tuple& t : m.get_all(pt)) {
226 TEST_CASE(
"multimesh_from_tag_tet_tet",
"[components][multimesh][multimesh_from_tag]")
228 DEBUG_TetMesh m = six_cycle_tets();
231 int64_t tag_value = 1;
234 int64_t n_faces = -1;
235 int64_t n_edges = -1;
236 int64_t n_vertices = -1;
239 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
241 SECTION(
"one_component")
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;
251 SECTION(
"two_components")
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;
265 SECTION(
"three_components")
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;
284 REQUIRE(m.get_child_meshes().size() == 2);
285 REQUIRE(m.is_multi_mesh_root());
288 CHECK(m.get_child_meshes().size() == 1);
289 REQUIRE(m.is_multi_mesh_root());
292 Mesh& sub_mesh = *substructure_mesh_ptr;
302 for (
const Tuple& t : m.get_all(pt)) {
304 if (non_manifold_root_simplices.
contains(s)) {
313 TEST_CASE(
"multimesh_from_tag_tet_tri",
"[components][multimesh][multimesh_from_tag]")
315 DEBUG_TetMesh m = six_cycle_tets();
318 int64_t tag_value = 1;
320 int64_t n_faces = -1;
321 int64_t n_edges = -1;
322 int64_t n_vertices = -1;
325 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
327 SECTION(
"one_component")
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;
336 SECTION(
"non_manifold_vertex")
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;
348 SECTION(
"non_manifold_vertex_2")
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;
360 SECTION(
"non_manifold_edge")
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;
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;
383 REQUIRE(m.get_child_meshes().size() == 2);
384 REQUIRE(m.is_multi_mesh_root());
387 CHECK(m.get_child_meshes().size() == 1);
388 REQUIRE(m.is_multi_mesh_root());
391 Mesh& sub_mesh = *substructure_mesh_ptr;
400 for (
const Tuple& t : m.get_all(pt)) {
402 if (non_manifold_root_simplices.
contains(s)) {
411 TEST_CASE(
"multimesh_from_tag_tri_visualization",
"[components][multimesh][multimesh_from_tag][.]")
413 DEBUG_TriMesh m = tests::edge_region_with_position();
416 int64_t tag_value = 1;
418 int64_t n_faces = -1;
419 int64_t n_edges = -1;
420 int64_t n_vertices = -1;
422 auto tag_acc = m.create_accessor<int64_t>(tag_handle);
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;
436 CHECK(m.get_child_meshes().size() == 2);
437 CHECK(m.is_multi_mesh_root());
440 Mesh& sub_mesh = *substructure_mesh_ptr;
449 auto subs_pos_handle =
452 auto propagate_to_child_position = [](
const Eigen::MatrixXd& P) -> Eigen::VectorXd {
457 std::make_shared<wmtk::operations::SingleAttributeTransferStrategy<double, double>>(
460 propagate_to_child_position);
461 pos_transfer->run_on_all();
463 ParaviewWriter writer(
"child_mesh",
"vertices", sub_mesh,
false,
false,
true,
false);
465 ParaviewWriter writer2(
"root_mesh",
"vertices", m,
false,
false,
true,
false);
466 m.serialize(writer2);
469 TEST_CASE(
"multimesh_from_tag",
"[components][multimesh][multimesh_from_tag]")
473 auto mesh_in = tests::disk(6);
474 DEBUG_TriMesh& m =
static_cast<DEBUG_TriMesh&
>(*mesh_in);
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;
488 "input": "input_mesh",
489 "output": "output_mesh",
490 "substructure_label": "tag",
491 "substructure_value": 1,
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
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
PrimitiveType top_simplex_type() const
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.
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)
TEST_CASE("multimesh_from_tag_tri_tri", "[components][multimesh][multimesh_from_tag]")