Wildmeshing Toolkit
Operation.cpp
Go to the documentation of this file.
1 #include "Operation.hpp"
2 
3 #include <wmtk/Mesh.hpp>
7 
8 
9 // it's ugly but for teh visitor we need these included
10 #include <wmtk/EdgeMesh.hpp>
11 #include <wmtk/PointMesh.hpp>
12 #include <wmtk/TetMesh.hpp>
13 #include <wmtk/TriMesh.hpp>
14 
15 namespace wmtk::operations {
16 
17 
19  : m_mesh(mesh)
20  , m_invariants(mesh)
21 {}
22 
23 Operation::~Operation() = default;
24 
25 
26 std::shared_ptr<const operations::AttributeTransferStrategyBase> Operation::get_transfer_strategy(
27  const attribute::MeshAttributeHandle& attribute)
28 {
29  assert(attribute.is_same_mesh(mesh()));
30 
31  for (auto& s : m_attr_transfer_strategies) {
32  if (s->matches_attribute(attribute)) return s;
33  }
34 
35  throw std::runtime_error("unable to find attribute");
36 }
37 
39 {
41 }
42 
44  const attribute::MeshAttributeHandle& attribute,
45  const std::shared_ptr<const operations::AttributeTransferStrategyBase>& other)
46 {
47  assert(attribute.is_same_mesh(mesh()));
48 
49  for (auto& s : m_attr_transfer_strategies) {
50  if (s->matches_attribute(attribute)) {
51  s = other;
52  return;
53  }
54  }
55 
56  throw std::runtime_error("unable to find attribute");
57 }
58 
60  const std::shared_ptr<const operations::AttributeTransferStrategyBase>& other)
61 {
62  spdlog::debug("Adding a transfer");
63  m_attr_transfer_strategies.emplace_back(other);
64 }
65 
66 std::vector<simplex::Simplex> Operation::operator()(const simplex::Simplex& simplex)
67 {
68  if (!mesh().is_valid(simplex)) {
69  return {};
70  }
71  if (!before(simplex)) {
72  return {};
73  }
74 
75  const auto simplex_resurrect = simplex;
76 
77  auto scope = mesh().create_scope();
78  assert(simplex.primitive_type() == primitive_type());
79 
80  try {
81  auto unmods = unmodified_primitives(simplex_resurrect);
82  auto mods = execute(simplex_resurrect);
83  if (!mods.empty()) { // success should be marked here
85  if (after(unmods, mods)) {
86  return mods; // scope destructor is called
87  }
88  }
89  } catch (const std::exception& e) {
90  scope.mark_failed();
91  throw e;
92  }
93  scope.mark_failed();
94  return {}; // scope destructor is called
95 }
96 
97 bool Operation::before(const simplex::Simplex& simplex) const
98 {
99  // const attribute::Accessor<int64_t> accessor = hash_accessor();
100 
101  // if (!mesh().is_valid(
102  // simplex.tuple(),
103  // accessor)) { // TODO: chang to is_removed and resurrect later
104  // return false;
105  // }
106 
107  if (mesh().is_removed(simplex.tuple()) || !mesh().is_valid(simplex)) {
108  return false;
109  }
110 
111  const auto simplex_resurrect = simplex;
112 
113  // map simplex to the invariant mesh
114  const Mesh& invariant_mesh = m_invariants.mesh();
115 
116  if (&invariant_mesh == &mesh()) {
117  if (!m_invariants.before(simplex_resurrect)) {
118  return false;
119  }
120  } else {
121  // TODO check if this is correct
122  const std::vector<simplex::Simplex> invariant_simplices =
123  m_mesh.map(invariant_mesh, simplex_resurrect);
124 
125  for (const simplex::Simplex& s : invariant_simplices) {
126  if (!m_invariants.before(s)) {
127  return false;
128  }
129  }
130  }
131 
132  return true;
133 }
134 
136  const std::vector<simplex::Simplex>& unmods,
137  const std::vector<simplex::Simplex>& mods) const
138 {
139  return m_invariants.directly_modified_after(unmods, mods);
140 }
141 
142 void Operation::apply_attribute_transfer(const std::vector<simplex::Simplex>& direct_mods)
143 {
144  if (m_attr_transfer_strategies.size() == 0) {
145  return;
146  }
147 
149  all.reserve(100);
150 
151 
152  for (const auto& s : direct_mods) {
153  if (!s.tuple().is_null()) {
155  all.add(ss);
156  }
157  }
158  }
159  if (direct_mods.size() > 1) {
160  all.sort_and_clean();
161  }
162 
163  for (const auto& at_ptr : m_attr_transfer_strategies) {
164  if (&m_mesh == &(at_ptr->mesh())) {
165  for (const simplex::IdSimplex& s : all.simplex_vector()) {
166  if (s.primitive_type() == at_ptr->primitive_type()) {
167  at_ptr->run(m_mesh.get_simplex(s));
168  }
169  }
170  } else {
171  auto& at_mesh = at_ptr->mesh();
172  auto at_mesh_simplices = m_mesh.map(at_mesh, direct_mods);
173 
174  simplex::IdSimplexCollection at_mesh_all(at_mesh);
175  for (const simplex::Simplex& s : at_mesh_simplices) {
176  for (const simplex::IdSimplex& ss : simplex::closed_star_iterable(at_mesh, s)) {
177  at_mesh_all.add(ss);
178  }
179  }
180 
181  at_mesh_all.sort_and_clean();
182 
183  for (const simplex::IdSimplex& s : at_mesh_all.simplex_vector()) {
184  if (s.primitive_type() == at_ptr->primitive_type()) {
185  at_ptr->run(at_mesh.get_simplex(s));
186  }
187  }
188  }
189  }
190 }
191 
192 
194 {
195  // by default assume we'll at most create N * capacity
196  constexpr static int64_t default_preallocation_size = 3;
197 
198  auto run = [&](auto&& m) {
199  if constexpr (!std::is_const_v<std::remove_reference_t<decltype(m)>>) {
200  auto cap = m.m_attribute_manager.m_capacities;
201  for (auto& v : cap) {
202  v *= default_preallocation_size;
203  }
204  m.reserve_more_attributes(cap);
205  }
206  };
207  multimesh::MultiMeshVisitor visitor(run);
208  visitor.execute_from_root(mesh());
209 }
210 
211 } // namespace wmtk::operations
simplex::Simplex get_simplex(const simplex::IdSimplex &s) const
Convert an IdSimplex into a Simplex.
Definition: Mesh.cpp:38
multimesh::attribute::AttributeScopeHandle create_scope()
std::vector< simplex::Simplex > map(const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
bool directly_modified_after(const std::vector< simplex::Simplex > &simplices_before, const std::vector< simplex::Simplex > &simplices_after) const override
bool before(const simplex::Simplex &t) const override
const Mesh & mesh() const
Definition: Invariant.cpp:35
void set_transfer_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::AttributeTransferStrategyBase > &other)
Definition: Operation.cpp:43
virtual bool after(const std::vector< simplex::Simplex > &unmods, const std::vector< simplex::Simplex > &mods) const
Definition: Operation.cpp:135
const Mesh & mesh() const
Definition: Operation.hpp:45
virtual PrimitiveType primitive_type() const =0
void clear_attribute_transfer_strategies()
Definition: Operation.cpp:38
virtual std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex)=0
returns an empty vector in case of failure
std::shared_ptr< const operations::AttributeTransferStrategyBase > get_transfer_strategy(const attribute::MeshAttributeHandle &attribute)
Definition: Operation.cpp:26
virtual void reserve_enough_simplices()
Definition: Operation.cpp:193
std::vector< std::shared_ptr< const operations::AttributeTransferStrategyBase > > m_attr_transfer_strategies
Definition: Operation.hpp:104
virtual std::vector< simplex::Simplex > operator()(const simplex::Simplex &simplex)
Definition: Operation.cpp:66
void add_transfer_strategy(const std::shared_ptr< const operations::AttributeTransferStrategyBase > &other)
Definition: Operation.cpp:59
virtual std::vector< simplex::Simplex > unmodified_primitives(const simplex::Simplex &simplex) const =0
Returns all simplices that will be potentially affected by the operation.
invariants::InvariantCollection m_invariants
Definition: Operation.hpp:101
virtual bool before(const simplex::Simplex &simplex) const
Definition: Operation.cpp:97
void apply_attribute_transfer(const std::vector< simplex::Simplex > &direct_mods)
Definition: Operation.cpp:142
void sort_and_clean()
Sort simplex vector and remove duplicates.
void add(const IdSimplex &simplex)
Add simplex to the collection.
const std::vector< IdSimplex > & simplex_vector() const
Return const reference to the simplex vector.
const Tuple & tuple() const
Definition: Simplex.hpp:53
PrimitiveType primitive_type() const
Definition: Simplex.hpp:51
ClosedStarIterable closed_star_iterable(const Mesh &mesh, const Simplex &simplex)