diff --git a/src/wmtk/multimesh/utils/find_local_switch_sequence.cpp b/src/wmtk/multimesh/utils/find_local_switch_sequence.cpp index 131b15efdf..0cc8e85bc1 100644 --- a/src/wmtk/multimesh/utils/find_local_switch_sequence.cpp +++ b/src/wmtk/multimesh/utils/find_local_switch_sequence.cpp @@ -1,48 +1,132 @@ #include "find_local_switch_sequence.hpp" +#include #include "local_switch_tuple.hpp" namespace wmtk::multimesh::utils { namespace { - -std::vector find_local_switch_sequence_trimesh( +std::pair> find_local_switch_sequence_on_edge( const Tuple& source, - const Tuple& target) + const Tuple& target, + const PrimitiveType mesh_pt) { - // TODO: assert that base_source and base_target use the same global CID + assert(mesh_pt >= PrimitiveType::Edge); if (source == target) { - return std::vector{}; + return {true, std::vector{}}; + } else if (local_switch_tuple(mesh_pt, source, PrimitiveType::Vertex) == target) { + return {true, std::vector{PrimitiveType::Vertex}}; } + return {false, std::vector{}}; +} + +std::pair> find_local_switch_sequence_on_triangle( + const Tuple& source, + const Tuple& target, + const PrimitiveType mesh_pt) +{ + assert(mesh_pt >= PrimitiveType::Face); - // circulate Tuple cur_tuple = source; std::vector switches; - auto try_and_record = [&](PrimitiveType pt) -> bool { - cur_tuple = local_switch_tuple(PrimitiveType::Face, cur_tuple, pt); - switches.emplace_back(pt); - return cur_tuple == target; - }; - for (long j = 0; j < 3; ++j) { - for (PrimitiveType pt : {PrimitiveType::Vertex, PrimitiveType::Edge}) { - if (try_and_record(pt)) { - return switches; - } - } - } - throw "switch sequence was unable to find a sequence of switches to match tuples"; - return switches; + { + auto [success, edge_local_operations] = + find_local_switch_sequence_on_edge(cur_tuple, target, mesh_pt); + if (success) { + return {true, edge_local_operations}; + } + } + switches.emplace_back(PrimitiveType::Edge); + cur_tuple = local_switch_tuples(mesh_pt, source, switches); + { + auto [success, edge_local_operations] = + find_local_switch_sequence_on_edge(cur_tuple, target, mesh_pt); + if (success) { + switches.insert( + switches.end(), + edge_local_operations.begin(), + edge_local_operations.end()); + return {true, switches}; + } + } + + switches.insert(switches.begin(), PrimitiveType::Vertex); + cur_tuple = local_switch_tuples(mesh_pt, source, switches); + { + auto [success, edge_local_operations] = + find_local_switch_sequence_on_edge(cur_tuple, target, mesh_pt); + if (success) { + switches.insert( + switches.end(), + edge_local_operations.begin(), + edge_local_operations.end()); + return {true, switches}; + } + } + return {false, std::vector{}}; } -std::vector find_local_switch_sequence_edgemesh( + +std::pair> find_local_switch_sequence_on_tet( const Tuple& source, - const Tuple& target) + const Tuple& target, + const PrimitiveType mesh_pt) { - if (source != target) { - return std::vector{PrimitiveType::Vertex}; - } else { - return std::vector{}; + // TODO: test it in the future + throw "not tested yet"; + assert(mesh_pt == PrimitiveType::Tetrahedron); + Tuple cur_tuple = source; + std::vector switches; + + { + auto [success, triangle_local_operations] = + find_local_switch_sequence_on_triangle(cur_tuple, target, mesh_pt); + if (success) { + return {true, triangle_local_operations}; + } + } + switches.emplace_back(PrimitiveType::Face); + cur_tuple = local_switch_tuples(mesh_pt, source, switches); + { + auto [success, triangle_local_operations] = + find_local_switch_sequence_on_triangle(cur_tuple, target, mesh_pt); + if (success) { + switches.insert( + switches.end(), + triangle_local_operations.begin(), + triangle_local_operations.end()); + return {true, switches}; + } + } + + switches.insert(switches.begin(), PrimitiveType::Edge); + cur_tuple = local_switch_tuples(mesh_pt, source, switches); + { + auto [success, triangle_local_operations] = + find_local_switch_sequence_on_triangle(cur_tuple, target, mesh_pt); + if (success) { + switches.insert( + switches.end(), + triangle_local_operations.begin(), + triangle_local_operations.end()); + return {true, switches}; + } + } + + switches.insert(switches.begin(), PrimitiveType::Vertex); + cur_tuple = local_switch_tuples(mesh_pt, source, switches); + { + auto [success, triangle_local_operations] = + find_local_switch_sequence_on_triangle(cur_tuple, target, mesh_pt); + if (success) { + switches.insert( + switches.end(), + triangle_local_operations.begin(), + triangle_local_operations.end()); + return {true, switches}; + } } - throw "switch sequence was unable to find a sequence of switches to match tuples"; + return {false, std::vector{}}; } + } // namespace // Maps the tuple source according to the operation sequence @@ -52,10 +136,31 @@ std::vector find_local_switch_sequence(const Tuple& source, const Tuple& target, PrimitiveType primitive_type) { switch (primitive_type) { - case PrimitiveType::Face: return find_local_switch_sequence_trimesh(source, target); - case PrimitiveType::Edge: return find_local_switch_sequence_edgemesh(source, target); + case PrimitiveType::Edge: { + auto [success, operations] = + find_local_switch_sequence_on_edge(source, target, PrimitiveType::Edge); + if (!success) { + throw "switch sequence was unable to find a sequence of switches to match tuples"; + } + return operations; + } + case PrimitiveType::Face: { + auto [success, operations] = + find_local_switch_sequence_on_triangle(source, target, PrimitiveType::Face); + if (!success) { + throw "switch sequence was unable to find a sequence of switches to match tuples"; + } + return operations; + } + case PrimitiveType::Tetrahedron: { + auto [success, operations] = + find_local_switch_sequence_on_tet(source, target, PrimitiveType::Tetrahedron); + if (!success) { + throw "switch sequence was unable to find a sequence of switches to match tuples"; + } + return operations; + } case PrimitiveType::Vertex: return {}; - case PrimitiveType::Tetrahedron: default: return {}; } }