Wildmeshing Toolkit
TetEdgeSwap.cpp
Go to the documentation of this file.
1 #include "TetEdgeSwap.hpp"
5 
6 
7 #include <wmtk/Mesh.hpp>
8 
10 TetEdgeSwap::TetEdgeSwap(Mesh& m, int64_t collapse_index)
11  : Operation(m)
12  , m_split(m)
13  , m_collapse(m)
14  , m_collapse_index(collapse_index)
15 {}
16 
17 std::vector<simplex::Simplex> TetEdgeSwap::execute(const simplex::Simplex& simplex)
18 {
19  const auto split_simplicies = m_split(simplex);
20  if (split_simplicies.empty()) return {};
21  assert(split_simplicies.size() == 1);
22 
23  // after split
24  const Tuple& split_ret = split_simplicies.front().tuple();
25  assert(!mesh().is_boundary(split_simplicies.front()));
26  auto iter_tuple = split_ret;
27  std::vector<Tuple> candidate_edge_tuples;
28  while (true) {
29  candidate_edge_tuples.push_back(mesh().switch_tuple(iter_tuple, PrimitiveType::Edge));
30  iter_tuple =
32  if (iter_tuple == split_ret) {
33  break;
34  }
35  }
36 
37  // collapse index failed, return empty
38  if (m_collapse_index >= candidate_edge_tuples.size()) return {};
39 
40  const Tuple& collapse_tuple = candidate_edge_tuples[m_collapse_index];
41 
42 
43  // before collapse, compute the edges generated by split - edges deleted by collapse
44 
45  // auto edges_generated_by_split = m_split.new_edge_tuples();
46  const auto split_tuple_open_star =
48  std::array<std::vector<simplex::Simplex>, 4> simplices_generated_by_split;
49  for (const simplex::Simplex& s : split_tuple_open_star.simplex_vector()) {
50  simplices_generated_by_split[get_primitive_type_id(s.primitive_type())].emplace_back(s);
51  }
52 
53  const auto v_open_star =
55  const auto e_closed_star =
57  const auto sc = simplex::SimplexCollection::get_intersection(v_open_star, e_closed_star);
58 
59  std::array<std::vector<simplex::Simplex>, 4> simplices_deleted_by_collapse;
60 
61  for (const simplex::Simplex& s : sc.simplex_vector()) {
62  simplices_deleted_by_collapse[get_primitive_type_id(s.primitive_type())].emplace_back(s);
63  }
64 
65  // check if #edge_generated_by_split > #edges_deleted_by_collapse, if not, return face instead
66  assert(simplices_generated_by_split[1].size() >= simplices_deleted_by_collapse[1].size());
67 
68  bool able_to_return_edges = true;
69  if (simplices_generated_by_split[1].size() == simplices_deleted_by_collapse[1].size())
70  able_to_return_edges = false;
71 
72 
73  std::vector<simplex::Simplex> edges_generated_by_swap;
74  std::vector<simplex::Simplex> faces_generated_by_swap;
75 
76  // add compare lambda here
77  auto comp_simplex = [&](const simplex::Simplex& s1, const simplex::Simplex& s2) {
79  };
80 
81  if (able_to_return_edges) {
82  std::sort(
83  simplices_generated_by_split[1].begin(),
84  simplices_generated_by_split[1].end(),
85  comp_simplex);
86  std::sort(
87  simplices_deleted_by_collapse[1].begin(),
88  simplices_deleted_by_collapse[1].end(),
89  comp_simplex);
90 
91  std::set_difference(
92  simplices_generated_by_split[1].begin(),
93  simplices_generated_by_split[1].end(),
94  simplices_deleted_by_collapse[1].begin(),
95  simplices_deleted_by_collapse[1].end(),
96  std::back_inserter(edges_generated_by_swap),
97  comp_simplex);
98 
99  assert(
100  edges_generated_by_swap.size() ==
101  (simplices_generated_by_split[1].size() - simplices_deleted_by_collapse[1].size()));
102  } else {
103  // return face
104  // std::cout << "swap returns face" << std::endl;
105  assert(simplices_generated_by_split[2].size() >= simplices_deleted_by_collapse[2].size());
106 
107  std::sort(
108  simplices_generated_by_split[2].begin(),
109  simplices_generated_by_split[2].end(),
110  comp_simplex);
111  std::sort(
112  simplices_deleted_by_collapse[2].begin(),
113  simplices_deleted_by_collapse[2].end(),
114  comp_simplex);
115 
116  std::set_difference(
117  simplices_generated_by_split[2].begin(),
118  simplices_generated_by_split[2].end(),
119  simplices_deleted_by_collapse[2].begin(),
120  simplices_deleted_by_collapse[2].end(),
121  std::back_inserter(faces_generated_by_swap),
122  comp_simplex);
123 
124  assert(
125  faces_generated_by_swap.size() ==
126  (simplices_generated_by_split[2].size() - simplices_deleted_by_collapse[2].size()));
127  assert(faces_generated_by_swap.size() == 1);
128 
129  if (faces_generated_by_swap.size() != 1) {
130  std::cout << "swap return more than one face!!" << std::endl;
131  throw std::runtime_error("faces_generated_by_swap.size() != 1");
132  }
133  }
134 
135 
136  // do collapse
137  const auto collapse_simplicies =
139  if (collapse_simplicies.empty()) return {};
140  assert(collapse_simplicies.size() == 1);
141 
142  if (able_to_return_edges) {
143  for (int64_t i = 0; i < edges_generated_by_swap.size(); ++i) {
144  edges_generated_by_swap[i] =
145  simplex::Simplex::edge(mesh(), edges_generated_by_swap[i].tuple());
146  }
147 
148  return edges_generated_by_swap;
149  } else {
150  for (int64_t i = 0; i < faces_generated_by_swap.size(); ++i) {
151  faces_generated_by_swap[i] =
152  simplex::Simplex::face(mesh(), faces_generated_by_swap[i].tuple());
153  }
154 
155  return faces_generated_by_swap;
156  }
157 }
158 
159 std::vector<simplex::Simplex> TetEdgeSwap::unmodified_primitives(
160  const simplex::Simplex& simplex) const
161 {
162  return {simplex};
163 }
164 
165 } // namespace wmtk::operations::composite
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Definition: Mesh.hpp:968
PrimitiveType primitive_type() const override
const Mesh & mesh() const
Definition: Operation.hpp:45
std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex) override
returns an empty vector in case of failure
Definition: TetEdgeSwap.cpp:17
std::vector< simplex::Simplex > unmodified_primitives(const simplex::Simplex &simplex) const override
Returns all simplices that will be potentially affected by the operation.
TetEdgeSwap(Mesh &m, int64_t collapse_index=0)
Definition: TetEdgeSwap.cpp:10
static SimplexCollection get_intersection(const SimplexCollection &collection_a, const SimplexCollection &collection_b)
Get intersection of two simplex collections.
static Simplex face(const Mesh &m, const Tuple &t)
Definition: Simplex.hpp:63
static Simplex edge(const Mesh &m, const Tuple &t)
Definition: Simplex.hpp:61
static Simplex vertex(const Mesh &m, const Tuple &t)
Definition: Simplex.hpp:56
static bool less(const Mesh &m, const Simplex &s0, const Simplex &s1)
SimplexCollection open_star(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Definition: open_star.cpp:12
SimplexCollection closed_star(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
The closed star contains the input simplex, all its top dimension cofaces, and their faces.
Definition: closed_star.cpp:13
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.