Loading [MathJax]/extensions/tex2jax.js
Wildmeshing Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 m_attr_transfer_strategies.emplace_back(other);
63}
64
65std::vector<simplex::Simplex> Operation::operator()(const simplex::Simplex& simplex)
66{
67 if (!mesh().is_valid(simplex)) {
68 return {};
69 }
70 if (!before(simplex)) {
71 return {};
72 }
73
74 assert(mesh().is_valid(simplex.tuple()));
75
76 auto scope = mesh().create_scope();
77 assert(simplex.primitive_type() == primitive_type());
78
79 try {
80#ifndef NDEBUG
81 assert(!simplex.tuple().is_null());
82 mesh().parent_scope([&]() { assert(mesh().is_valid(simplex.tuple())); });
83#endif
84 auto unmods = unmodified_primitives(simplex);
85#ifndef NDEBUG
86 for (const auto& s : unmods) {
87 assert(!s.tuple().is_null());
88 }
89 for (const auto& s : unmods) {
90 mesh().parent_scope([&]() { assert(mesh().is_valid(s.tuple())); });
91 }
92#endif
93 auto mods = execute(simplex);
94#ifndef NDEBUG
95 if (!mesh().is_free()) {
96 for (const auto& s : mods) {
97 assert(mesh().is_valid(s.tuple()));
98 }
99 }
100#endif
101
102 if (!mods.empty()) { // success should be marked here
104 if (after(unmods, mods)) {
105 return mods; // scope destructor is called
106 }
107 }
108 } catch (const std::exception& e) {
109 scope.mark_failed();
110 throw e;
111 }
112 scope.mark_failed();
113 return {}; // scope destructor is called
114}
115
116bool Operation::before(const simplex::Simplex& simplex) const
117{
118 // const attribute::Accessor<int64_t> accessor = hash_accessor();
119
120 // if (!mesh().is_valid(
121 // simplex.tuple(),
122 // accessor)) { // TODO: chang to is_removed and resurrect later
123 // return false;
124 // }
125
126 if (mesh().is_removed(simplex.tuple()) || !mesh().is_valid(simplex)) {
127 return false;
128 }
129
130 const auto simplex_resurrect = simplex;
131
132 // map simplex to the invariant mesh
133 const Mesh& invariant_mesh = m_invariants.mesh();
134
135 if (&invariant_mesh == &mesh()) {
136 if (!m_invariants.before(simplex_resurrect)) {
137 return false;
138 }
139 } else {
140 // TODO check if this is correct
141 const std::vector<simplex::Simplex> invariant_simplices =
142 m_mesh.map(invariant_mesh, simplex_resurrect);
143
144 for (const simplex::Simplex& s : invariant_simplices) {
145 if (!m_invariants.before(s)) {
146 return false;
147 }
148 }
149 }
150
151 return true;
152}
153
155 const std::vector<simplex::Simplex>& unmods,
156 const std::vector<simplex::Simplex>& mods) const
157{
158 return m_invariants.directly_modified_after(unmods, mods);
159}
160
161void Operation::apply_attribute_transfer(const std::vector<simplex::Simplex>& direct_mods)
162{
163 if (m_attr_transfer_strategies.size() == 0) {
164 return;
165 }
166
168 all.reserve(100);
169
170
171 for (const auto& s : direct_mods) {
172 if (!s.tuple().is_null()) {
173 assert(m_mesh.is_valid(s));
174 assert(m_mesh.get_const_flag_accessor(s.primitive_type()).is_active(s));
176 all.add(ss);
177 }
178 }
179 }
180 if (direct_mods.size() > 1) {
181 all.sort_and_clean();
182 }
183
184 for (const auto& at_ptr : m_attr_transfer_strategies) {
185 if (&m_mesh == &(at_ptr->mesh())) {
186 for (const simplex::IdSimplex& s : all.simplex_vector()) {
187 if (s.primitive_type() == at_ptr->primitive_type()) {
188 at_ptr->run(m_mesh.get_simplex(s));
189 }
190 }
191 } else {
192 auto& at_mesh = at_ptr->mesh();
193 auto at_mesh_simplices = m_mesh.map(at_mesh, direct_mods);
194
195 simplex::IdSimplexCollection at_mesh_all(at_mesh);
196 for (const simplex::Simplex& s : at_mesh_simplices) {
197 for (const simplex::IdSimplex& ss : simplex::closed_star_iterable(at_mesh, s)) {
198 at_mesh_all.add(ss);
199 }
200 }
201
202 at_mesh_all.sort_and_clean();
203
204 for (const simplex::IdSimplex& s : at_mesh_all.simplex_vector()) {
205 if (s.primitive_type() == at_ptr->primitive_type()) {
206 at_ptr->run(at_mesh.get_simplex(s));
207 }
208 }
209 }
210 }
211}
212
213
215{
216 // by default assume we'll at most create N * capacity
217 constexpr static int64_t default_preallocation_size = 3;
218
219 auto run = [&](auto&& m) {
220 if constexpr (!std::is_const_v<std::remove_reference_t<decltype(m)>>) {
221 auto cap = m.m_attribute_manager.m_capacities;
222 for (auto& v : cap) {
223 v *= default_preallocation_size;
224 }
225 m.reserve_more_attributes(cap);
226 }
227 };
228 multimesh::MultiMeshVisitor visitor(run);
229 visitor.execute_from_root(mesh());
230}
231
232} // 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
decltype(auto) parent_scope(Functor &&f, Args &&... args) const
Evaluate the passed in function inside the parent scope.
Definition Mesh.hpp:939
const attribute::FlagAccessor< Mesh > get_const_flag_accessor(PrimitiveType type) const
Definition Mesh.cpp:170
bool is_null() const
Checks if a tuple is "null". This merely implies the global index is -1.
Definition Tuple.hxx:41
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:65
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
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)