Wildmeshing Toolkit
Loading...
Searching...
No Matches
RegularSpace.cpp
Go to the documentation of this file.
1#include "RegularSpace.hpp"
2
3#include <wmtk/Scheduler.hpp>
10#include <wmtk/utils/Logger.hpp>
12
13#include <deque>
14
16
18{
19public:
22 int64_t m_val;
23
25 Mesh& m,
26 const attribute::MeshAttributeHandle& attribute,
27 PrimitiveType ptype,
28 int64_t val)
29 : m_accessor(m.create_accessor<int64_t>(attribute))
30 , m_ptype(ptype)
31 , m_val(val)
32 {}
33
35};
36
37RegularSpace::RegularSpace(
38 Mesh& mesh,
39 const std::vector<attribute::MeshAttributeHandle>& label_attributes,
40 const std::vector<int64_t>& values,
41 const std::vector<attribute::MeshAttributeHandle>& pass_through_attributes)
42 : m_mesh(mesh)
43 , m_label_attributes(label_attributes)
44 , m_values(values)
45 , m_pass_through_attributes(pass_through_attributes)
46{
47 assert(m_label_attributes.size() == m_values.size());
48}
49
50void RegularSpace::regularize_tags()
51{
52 using namespace operations;
53
54 std::vector<attribute::MeshAttributeHandle> todo_handles;
55 for (size_t i = 0; i < m_label_attributes.size(); ++i) {
57 m_mesh.register_attribute<int64_t>("todo", m_label_attributes[i].primitive_type(), 1);
58 todo_handles.emplace_back(todo_handle);
59 }
60
61 std::deque<TagAttribute> tag_attributes;
62 for (size_t i = 0; i < m_label_attributes.size(); ++i) {
63 tag_attributes.emplace_back(
64 m_mesh,
66 m_label_attributes[i].primitive_type(),
67 m_values[i]);
68 }
69
70 // make sure tag vector is complete and sorted in descending order
71 for (size_t i = 0; i < tag_attributes.size(); ++i) {
72 TagAttribute& a = tag_attributes[i];
74 log_and_throw_error("Tag array must be sorted in descending order starting with "
75 "the top simplex type up to vertex.");
76 }
77 }
78
79
80 // tag all faces of attributes
81 for (size_t attr_it = 0; attr_it < tag_attributes.size() - 1; ++attr_it) {
82 const TagAttribute& ta = tag_attributes[attr_it];
83 for (const Tuple& t : m_mesh.get_all(ta.m_ptype)) {
84 if (ta.m_accessor.const_scalar_attribute(t) != ta.m_val) {
85 continue; // t is not tagged
86 }
87
88 const PrimitiveType face_ptype =
91 m_mesh,
93 face_ptype);
94
95 TagAttribute& face_ta = tag_attributes[attr_it + 1];
96 for (const Tuple& f : faces) {
97 face_ta.m_accessor.scalar_attribute(f) = face_ta.m_val;
98 }
99 }
100 }
101
102 // split untagged simplices that have only tagged faces
103 for (size_t attr_it = 0; attr_it < tag_attributes.size() - 1; ++attr_it) {
104 const TagAttribute& ta = tag_attributes[attr_it];
105
106 attribute::MeshAttributeHandle& todo_handle = todo_handles[attr_it];
107 auto todo_acc = m_mesh.create_accessor<int64_t>(todo_handle);
108
109 for (const Tuple& t : m_mesh.get_all(ta.m_ptype)) {
110 if (ta.m_accessor.const_scalar_attribute(t) == ta.m_val) {
111 continue; // t is tagged
112 }
113
114 const PrimitiveType face_ptype =
117 m_mesh,
119 face_ptype);
120
121 const TagAttribute& face_ta = tag_attributes[attr_it + 1];
122
123 bool all_faces_are_tagged = true;
124
125 for (const Tuple& f : faces) {
126 if (face_ta.m_accessor.const_scalar_attribute(f) != face_ta.m_val) {
127 all_faces_are_tagged = false;
128 break;
129 }
130 }
131
132 if (all_faces_are_tagged) {
133 todo_acc.scalar_attribute(t) = 1;
134 }
135 }
136
138 log_and_throw_error("Regular space component not implemented for TetMeshes.");
139 }
140
141 // split simplex because all its faces are tagged
142 Scheduler scheduler;
143 switch (ta.m_ptype) {
144 case PrimitiveType::Edge: { // edge split
145 EdgeSplit op_split(m_mesh);
146 op_split.add_invariant(std::make_shared<TodoInvariant>(
147 m_mesh,
148 std::get<attribute::TypedAttributeHandle<int64_t>>(todo_handle.handle())));
149
150 // todos
151 for (const attribute::MeshAttributeHandle& h : todo_handles) {
153 h,
154 SplitBasicStrategy::None,
155 SplitRibBasicStrategy::None);
156 }
157 // labels
159 op_split.set_new_attribute_strategy(h);
160 }
161 // pass_through
162 for (const auto& attr : m_pass_through_attributes) {
163 op_split.set_new_attribute_strategy(attr);
164 }
165
166 while (true) {
167 const auto stats = scheduler.run_operation_on_all(op_split);
168 if (stats.number_of_successful_operations() == 0) {
169 break;
170 }
171 }
172
173 break;
174 }
175 case PrimitiveType::Triangle: { // face split
176 composite::TriFaceSplit op_face_split(m_mesh);
177 op_face_split.add_invariant(std::make_shared<TodoInvariant>(
178 m_mesh,
179 std::get<attribute::TypedAttributeHandle<int64_t>>(todo_handle.handle())));
180
181 // todos
182 for (const attribute::MeshAttributeHandle& h : todo_handles) {
183 op_face_split.split().set_new_attribute_strategy(
184 h,
185 SplitBasicStrategy::None,
186 SplitRibBasicStrategy::None);
187 op_face_split.collapse().set_new_attribute_strategy(h, CollapseBasicStrategy::None);
188 }
189 // labels
191 op_face_split.split().set_new_attribute_strategy(h);
192 op_face_split.collapse().set_new_attribute_strategy(h);
193 }
194 // pass_through
195 for (const auto& attr : m_pass_through_attributes) {
196 op_face_split.split().set_new_attribute_strategy(attr);
197 op_face_split.collapse().set_new_attribute_strategy(attr);
198 }
199
200 while (true) {
201 const auto stats = scheduler.run_operation_on_all(op_face_split);
202 if (stats.number_of_successful_operations() == 0) {
203 break;
204 }
205 }
206
207 break;
208 }
210 log_and_throw_error("Regular space component not implemented for TetMeshes.");
211 }
212 default: log_and_throw_error("unknown primitive type: {}", ta.m_ptype); break;
213 }
214 }
215}
216
217
218} // namespace wmtk::components::internal
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition Mesh.cpp:18
int64_t top_cell_dimension() const
Definition Mesh.hpp:978
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
SchedulerStats run_operation_on_all(operations::Operation &op)
Definition Scheduler.cpp:33
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition Accessor.hpp:28
T & scalar_attribute(const ArgType &t)
T const_scalar_attribute(const ArgType &t) const
Definition Accessor.hxx:109
Handle that represents attributes for some mesh.
std::vector< attribute::MeshAttributeHandle > m_pass_through_attributes
std::vector< attribute::MeshAttributeHandle > m_label_attributes
wmtk::attribute::Accessor< int64_t > m_accessor
TagAttribute(Mesh &m, const attribute::MeshAttributeHandle &attribute, PrimitiveType ptype, int64_t val)
void set_new_attribute_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::BaseCollapseNewAttributeStrategy > &other)
void set_new_attribute_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::BaseSplitNewAttributeStrategy > &other)
Definition EdgeSplit.cpp:85
void add_invariant(std::shared_ptr< Invariant > invariant)
Definition Operation.hpp:48
The return tuple is the new vertex, pointing to the original vertex.
std::vector< Tuple > faces_single_dimension_tuples(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)
SimplexCollection faces(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Returns all faces of a simplex.
Definition faces.cpp:10
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.