diff --git a/src/wmtk/operations/EdgeSplit.hpp b/src/wmtk/operations/EdgeSplit.hpp index 3d1a7aadd9..cf96b357d5 100644 --- a/src/wmtk/operations/EdgeSplit.hpp +++ b/src/wmtk/operations/EdgeSplit.hpp @@ -5,7 +5,6 @@ #include "attribute_new/SplitNewAttributeStrategy.hpp" namespace wmtk::operations { - class EdgeSplit : public Operation { public: @@ -30,6 +29,9 @@ class EdgeSplit : public Operation const wmtk::operations::SplitRibBasicStrategy& rib = wmtk::operations::SplitRibBasicStrategy::Default); + /** + * @return the new simplex, toward to the next simplex along the splited line + */ std::vector execute(const simplex::Simplex& simplex) override; std::vector unmodified_primitives( const simplex::Simplex& simplex) const override; diff --git a/src/wmtk/operations/composite/TetCellSplit.cpp b/src/wmtk/operations/composite/TetCellSplit.cpp index 0d3b930915..9c4cf4c595 100644 --- a/src/wmtk/operations/composite/TetCellSplit.cpp +++ b/src/wmtk/operations/composite/TetCellSplit.cpp @@ -18,20 +18,29 @@ std::vector TetCellSplit::execute(const simplex::Simplex& simp assert(first_split_simplicies.size() == 1); const Tuple first_split_ret = first_split_simplicies.front().tuple(); - const Tuple second_split_input = mesh().switch_tuples(first_split_ret, {PrimitiveType::Vertex, PrimitiveType::Edge}); + const Tuple second_split_input = mesh().switch_tuples(first_split_ret, {PrimitiveType::Edge}); const auto second_split_simplicies = m_split(simplex::Simplex::edge(second_split_input)); if (second_split_simplicies.empty()) return {}; assert(second_split_simplicies.size() == 1); const Tuple second_split_ret = second_split_simplicies.front().tuple(); - const Tuple third_split_input = mesh().switch_tuples(second_split_ret, {PrimitiveType::Triangle, PrimitiveType::Vertex, PrimitiveType::Edge}); + const Tuple third_split_input = mesh().switch_tuples( + second_split_ret, + {PrimitiveType::Triangle, PrimitiveType::Edge, PrimitiveType::Vertex}); const auto third_split_simplicies = m_split(simplex::Simplex::edge(third_split_input)); if (third_split_simplicies.empty()) return {}; assert(third_split_simplicies.size() == 1); const Tuple third_split_ret = third_split_simplicies.front().tuple(); - - const Tuple first_collapse_input = mesh().switch_tuples(third_split_ret, {PrimitiveType::Edge, PrimitiveType::Triangle}); + const Tuple first_collapse_input = mesh().switch_tuples( + third_split_ret, + {PrimitiveType::Triangle, + PrimitiveType::Tetrahedron, + PrimitiveType::Triangle, + PrimitiveType::Tetrahedron, + PrimitiveType::Vertex, + PrimitiveType::Edge, + PrimitiveType::Triangle}); const auto first_collapse_simplicies = m_collapse(simplex::Simplex::edge(first_collapse_input)); if (first_collapse_simplicies.empty()) return {}; assert(first_collapse_simplicies.size() == 1); @@ -44,7 +53,9 @@ std::vector TetCellSplit::execute(const simplex::Simplex& simp assert(second_collapse_simplicies.size() == 1); const Tuple second_collapse_ret = second_collapse_simplicies.front().tuple(); - const Tuple output_tuple = mesh().switch_tuples(second_collapse_ret, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle}); + const Tuple output_tuple = mesh().switch_tuples( + second_collapse_ret, + {PrimitiveType::Tetrahedron, PrimitiveType::Triangle}); return {simplex::Simplex::vertex(output_tuple)}; } diff --git a/tests/test_3d_operations.cpp b/tests/test_3d_operations.cpp index e13d2973d9..262683ae5d 100644 --- a/tests/test_3d_operations.cpp +++ b/tests/test_3d_operations.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include #include #include @@ -516,7 +516,7 @@ TEST_CASE("tet_edge_collapse", "[operations][collapse][3d]") } -TEST_CASE("tet_tet_split", "[operations][split][collapse][3d][.]") +TEST_CASE("tet_tet_split", "[operations][split][collapse][3d]") { using namespace operations::composite; SECTION("single_tet") @@ -534,7 +534,9 @@ TEST_CASE("tet_tet_split", "[operations][split][collapse][3d][.]") m.id( m.switch_vertex(m.switch_edge(m.edge_tuple_between_v1_v2(1, 2, 0))), PrimitiveType::Vertex) == 3); - auto res = op(Simplex::tetrahedron(m.edge_tuple_between_v1_v2(1, 2, 0))); + auto s = Simplex::tetrahedron(m.edge_tuple_between_v1_v2(1, 2, 0)); + + auto res = op(s); CHECK(!res.empty()); auto res_tuple = res.front().tuple(); CHECK(m.get_all(PrimitiveType::Tetrahedron).size() == 4); @@ -633,7 +635,7 @@ TEST_CASE("tet_tet_split", "[operations][split][collapse][3d][.]") } } -TEST_CASE("tet_split_with_tags", "[operations][split][3d][.]") +TEST_CASE("tet_split_with_tags", "[operations][split][3d]") { using namespace operations; @@ -671,14 +673,27 @@ TEST_CASE("tet_split_with_tags", "[operations][split][3d][.]") embedding_tag_value); wmtk::attribute::MeshAttributeHandle todo_tag_handle = m.register_attribute("todo_tag", wmtk::PrimitiveType::Tetrahedron, 1); - wmtk::attribute::Accessor acc_edge_tag = m.create_accessor(edge_tag_handle); + wmtk::attribute::Accessor acc_edge_tag = + m.create_accessor(edge_tag_handle); acc_edge_tag.scalar_attribute(m.edge_tuple_between_v1_v2(1, 2, 0)) = 5; - wmtk::attribute::Accessor acc_todo_tag = m.create_accessor(todo_tag_handle); + wmtk::attribute::Accessor acc_todo_tag = + m.create_accessor(todo_tag_handle); acc_todo_tag.scalar_attribute(m.edge_tuple_between_v1_v2(1, 2, 0)) = 1; composite::TetCellSplit op(m); op.add_invariant(std::make_shared(m, todo_tag_handle.as())); op.collapse().add_invariant(std::make_shared(m)); + + auto pos_handle = m.get_attribute_handle("vertices", PrimitiveType::Vertex); + op.collapse().set_new_attribute_strategy(todo_tag_handle); + op.collapse().set_new_attribute_strategy(edge_tag_handle); + op.collapse().set_new_attribute_strategy(vertex_tag_handle); + op.collapse().set_new_attribute_strategy(pos_handle); + op.split().set_new_attribute_strategy(todo_tag_handle); + op.split().set_new_attribute_strategy(edge_tag_handle); + op.split().set_new_attribute_strategy(vertex_tag_handle); + op.split().set_new_attribute_strategy(pos_handle); + auto res = op(Simplex::tetrahedron(m.edge_tuple_between_v1_v2(1, 2, 0))); CHECK(!res.empty()); @@ -728,7 +743,8 @@ TEST_CASE("tet_split_with_tags", "[operations][split][3d][.]") embedding_tag_value); wmtk::attribute::MeshAttributeHandle todo_tag_handle = m.register_attribute("todo_tag", wmtk::PrimitiveType::Tetrahedron, 1); - wmtk::attribute::Accessor acc_todo_tag = m.create_accessor(todo_tag_handle); + wmtk::attribute::Accessor acc_todo_tag = + m.create_accessor(todo_tag_handle); acc_todo_tag.scalar_attribute(m.get_all(PrimitiveType::Tetrahedron)[0]) = 1; acc_todo_tag.scalar_attribute(m.get_all(PrimitiveType::Tetrahedron)[3]) = 1; @@ -740,6 +756,20 @@ TEST_CASE("tet_split_with_tags", "[operations][split][3d][.]") composite::TetCellSplit op(m); op.add_invariant(std::make_shared(m, todo_tag_handle.as())); op.collapse().add_invariant(std::make_shared(m)); + + // used the default strategy, so the tag is not updated. + auto pos_handle = m.get_attribute_handle("vertices", PrimitiveType::Vertex); + op.collapse().set_new_attribute_strategy(todo_tag_handle); + op.collapse().set_new_attribute_strategy(edge_tag_handle); + op.collapse().set_new_attribute_strategy(vertex_tag_handle); + op.collapse().set_new_attribute_strategy(pos_handle); + op.split().set_new_attribute_strategy(todo_tag_handle); + op.split().set_new_attribute_strategy(edge_tag_handle); + op.split().set_new_attribute_strategy(vertex_tag_handle); + op.split().set_new_attribute_strategy(pos_handle); + + CHECK(op(Simplex::tetrahedron(m.edge_tuple_between_v1_v2(7, 2, 5))).empty()); + auto res = op(Simplex::tetrahedron(m.edge_tuple_between_v1_v2(1, 2, 0))); CHECK(!res.empty()); @@ -755,7 +785,6 @@ TEST_CASE("tet_split_with_tags", "[operations][split][3d][.]") CHECK( acc_todo_tag.scalar_attribute(m.switch_tetrahedron( m.switch_face(m.switch_tetrahedron(m.switch_edge(return_tuple))))) == 1); - CHECK(op(Simplex::tetrahedron(return_tuple)).empty()); } }