Wildmeshing Toolkit
Loading...
Searching...
No Matches
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
15namespace wmtk::operations {
16
17
19 : m_mesh(mesh)
20 , m_invariants(mesh)
21{}
22
23Operation::~Operation() = default;
24
25
26std::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
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
66std::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
97bool 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
142void 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()) {
154 assert(m_mesh.is_valid(s));
155 assert(m_mesh.get_const_flag_accessor(s.primitive_type()).is_active(s));
157 all.add(ss);
158 }
159 }
160 }
161 if (direct_mods.size() > 1) {
162 all.sort_and_clean();
163 }
164
165 for (const auto& at_ptr : m_attr_transfer_strategies) {
166 if (&m_mesh == &(at_ptr->mesh())) {
167 for (const simplex::IdSimplex& s : all.simplex_vector()) {
168 if (s.primitive_type() == at_ptr->primitive_type()) {
169 at_ptr->run(m_mesh.get_simplex(s));
170 }
171 }
172 } else {
173 auto& at_mesh = at_ptr->mesh();
174 auto at_mesh_simplices = m_mesh.map(at_mesh, direct_mods);
175
176 simplex::IdSimplexCollection at_mesh_all(at_mesh);
177 for (const simplex::Simplex& s : at_mesh_simplices) {
178 for (const simplex::IdSimplex& ss : simplex::closed_star_iterable(at_mesh, s)) {
179 at_mesh_all.add(ss);
180 }
181 }
182
183 at_mesh_all.sort_and_clean();
184
185 for (const simplex::IdSimplex& s : at_mesh_all.simplex_vector()) {
186 if (s.primitive_type() == at_ptr->primitive_type()) {
187 at_ptr->run(at_mesh.get_simplex(s));
188 }
189 }
190 }
191 }
192}
193
194
196{
197 // by default assume we'll at most create N * capacity
198 constexpr static int64_t default_preallocation_size = 3;
199
200 auto run = [&](auto&& m) {
201 if constexpr (!std::is_const_v<std::remove_reference_t<decltype(m)>>) {
202 auto cap = m.m_attribute_manager.m_capacities;
203 for (auto& v : cap) {
204 v *= default_preallocation_size;
205 }
206 m.reserve_more_attributes(cap);
207 }
208 };
209 multimesh::MultiMeshVisitor visitor(run);
210 visitor.execute_from_root(mesh());
211}
212
213} // 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()
virtual bool is_valid(const Tuple &tuple) const
check validity of tuple including its hash
Definition Mesh.cpp:113
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
const attribute::FlagAccessor< Mesh > get_const_flag_accessor(PrimitiveType type) const
Definition Mesh.cpp:163
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
virtual std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex)=0
returns an empty vector in case of failure
virtual PrimitiveType primitive_type() const =0
const Mesh & mesh() const
Definition Operation.hpp:45
std::shared_ptr< const operations::AttributeTransferStrategyBase > get_transfer_strategy(const attribute::MeshAttributeHandle &attribute)
Definition Operation.cpp:26
virtual void reserve_enough_simplices()
std::vector< std::shared_ptr< const operations::AttributeTransferStrategyBase > > m_attr_transfer_strategies
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
virtual bool before(const simplex::Simplex &simplex) const
Definition Operation.cpp:97
void apply_attribute_transfer(const std::vector< simplex::Simplex > &direct_mods)
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)