Wildmeshing Toolkit
Loading...
Searching...
No Matches
TriMesh.h
1#pragma once
2
3#include <wmtk/utils/VectorUtils.h>
4#include <wmtk/AttributeCollection.hpp>
5#include <wmtk/OperationDryRun.hpp>
6#include <wmtk/SlotPool.hpp>
7#include <wmtk/Types.hpp>
8#include <wmtk/simplex/Simplex.hpp>
9#include <wmtk/simplex/SimplexCollection.hpp>
10#include <wmtk/threading/enumerable_thread_specific.hpp>
11#include <wmtk/threading/vertex_mutex.hpp>
12#include <wmtk/utils/Logger.hpp>
13
14#include <algorithm>
15#include <array>
16#include <atomic>
17#include <cassert>
18#include <cmath>
19#include <cstdint>
20#include <functional>
21#include <map>
22#include <memory>
23#include <optional>
24#include <set>
25#include <vector>
26
27#include <wmtk/history/Fwd.hpp>
28
29namespace wmtk {
30
32{
33public:
34 // Cell Tuple Navigator
35 class Tuple
36 {
37 private:
38 size_t m_vid = -1;
39 size_t m_eid = -1;
40 size_t m_fid = -1;
41 size_t m_hash = 0;
42
43 void update_hash(const TriMesh& m);
44
45 public:
46 void print_info();
47
48 // v2 /
49 // / \ /
50 // e1 / \ e0 /
51 // v0 - - - v1 /
52 // e2 /
61 Tuple() {}
62 Tuple(size_t vid, size_t eid, size_t fid, const TriMesh& m)
63 : m_vid(vid)
64 , m_eid(eid)
65 , m_fid(fid)
66 {
67 update_hash(m);
68 }
69
70
76 inline size_t vid(const TriMesh&) const { return m_vid; }
77
84 inline size_t fid(const TriMesh&) const { return m_fid; }
85
86
95 size_t eid(const TriMesh& m) const;
96
104 size_t local_eid(const TriMesh& m) const { return m_eid; };
111 Tuple switch_vertex(const TriMesh& m) const;
117 Tuple switch_edge(const TriMesh& m) const;
133 std::optional<Tuple> switch_face(const TriMesh& m) const;
134
140 std::vector<Tuple> switch_faces(const TriMesh& m) const;
141
151 bool is_valid(const TriMesh& m) const;
162 bool is_valid_unlocked(const TriMesh& m) const;
163
168 std::array<Tuple, 3> oriented_tri_vertices(const TriMesh& m) const;
169 friend bool operator<(const Tuple& a, const Tuple& t)
170 {
171 return (
172 std::tie(a.m_vid, a.m_eid, a.m_fid, a.m_hash) <
173 std::tie(t.m_vid, t.m_eid, t.m_fid, t.m_hash));
174 }
175 };
176
178 {
179 const TriMesh& m_mesh;
180 Tuple m_tuple;
181
182 public:
183 SmartTuple(const TriMesh& mesh, const Tuple& t)
184 : m_mesh(mesh)
185 , m_tuple(t)
186 {}
187
188 const Tuple& tuple() const { return m_tuple; }
189 const TriMesh& mesh() const { return m_mesh; }
190
191 SmartTuple& operator=(const SmartTuple& t)
192 {
193 m_tuple = t.m_tuple;
194 return *this;
195 }
196
197 bool is_valid() const { return m_tuple.is_valid(m_mesh); }
198 size_t vid() const { return m_tuple.vid(m_mesh); }
199 size_t eid() const { return m_tuple.eid(m_mesh); }
200 size_t fid() const { return m_tuple.fid(m_mesh); }
201 SmartTuple switch_vertex() const { return {m_mesh, m_tuple.switch_vertex(m_mesh)}; }
202 SmartTuple switch_edge() const { return {m_mesh, m_tuple.switch_edge(m_mesh)}; }
203 std::optional<SmartTuple> switch_face() const
204 {
205 const std::optional<Tuple> t = m_tuple.switch_face(m_mesh);
206 if (t) {
207 return std::optional<SmartTuple>({m_mesh, t.value()});
208 }
209 return {};
210 }
211 };
212
219 {
220 public:
225 std::vector<size_t> m_conn_tris;
230 bool m_is_removed = false;
231
232 inline size_t& operator[](const size_t index)
233 {
234 assert(index < m_conn_tris.size());
235 return m_conn_tris[index];
236 }
237
238 inline size_t operator[](const size_t index) const
239 {
240 assert(index < m_conn_tris.size());
241 return m_conn_tris[index];
242 }
243 };
244
250 {
251 public:
256 std::array<size_t, 3> m_indices;
261 bool m_is_removed = false;
269 uint32_t hash = 0;
270
271 inline size_t& operator[](size_t index)
272 {
273 assert(index < 3);
274 return m_indices[index];
275 }
276
277 inline size_t operator[](size_t index) const
278 {
279 assert(index < 3);
280 return m_indices[index];
281 }
287 inline int find(size_t v_id) const
288 {
289 for (int j = 0; j < 3; j++) {
290 if (v_id == m_indices[j]) {
291 return j;
292 }
293 }
294 return -1;
295 }
296 };
297
298 TriMesh() {}
299 virtual ~TriMesh() {}
300
306 void init(size_t n_vertices, const std::vector<std::array<size_t, 3>>& tris);
307
313 void init(const MatrixXi& F);
314
325 std::vector<Tuple> get_vertices() const;
326
333 std::vector<Tuple> get_edges() const;
334
341 std::vector<Tuple> get_faces() const;
342
350 Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const;
351
352 Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2) const;
353
354 simplex::Vertex simplex_from_vertex(const Tuple& t) const;
355 simplex::Edge simplex_from_edge(const Tuple& t) const;
356 simplex::Face simplex_from_face(const Tuple& t) const;
357 simplex::Face simplex_from_face(const size_t fid) const;
358
359 Tuple tuple_from_simplex(const simplex::Face& s) const;
360 // Tuple tuple_from_simplex(const simplex::Edge& s) const;
361
362 simplex::SimplexCollection simplex_incident_triangles(const simplex::Vertex& v) const;
363 simplex::SimplexCollection simplex_incident_triangles(const simplex::Edge& e) const;
364 simplex::SimplexCollection simplex_link_vertices(const simplex::Vertex& v) const;
365 simplex::SimplexCollection simplex_link_vertices(const simplex::Edge& e) const;
366 simplex::SimplexCollection simplex_link_edges(const simplex::Vertex& v) const;
367
368 template <typename T>
369 using vector = std::vector<T>;
370
371public:
372 AbstractAttributeContainer* p_vertex_attrs = nullptr;
373 AbstractAttributeContainer* p_edge_attrs = nullptr;
374 AbstractAttributeContainer* p_face_attrs = nullptr;
375
376public:
384 void set_preallocation_factor(double factor)
385 {
386 if (factor >= 1.0) m_preallocation_factor = factor;
387 }
388 double preallocation_factor() const { return m_preallocation_factor; }
389
390 // Atomically reserve `n` contiguous fresh triangle/vertex slots. Returns the
391 // first index of the block, or INVALID_SLOT if that would exceed the preallocated
392 // capacity (the caller must then abort the operation before mutating).
393
411 size_t tri_storage_capacity() const { return m_tri_connectivity.capacity(); }
412 size_t vert_storage_capacity() const { return m_vertex_connectivity.capacity(); }
415 bool slots_exhausted() const
416 {
417 return m_vertex_connectivity.refused() || m_tri_connectivity.refused();
418 }
419 void clear_slots_exhausted()
420 {
421 m_vertex_connectivity.clear_refused();
422 m_tri_connectivity.clear_refused();
423 }
424
425 size_t request_tri_slots(size_t n);
426 size_t request_vert_slots(size_t n);
427
449 size_t cell_slot_bound(const Tuple& t) const;
452 void reserve_free_slots(size_t cells, size_t verts);
455 virtual bool storage_grows_on_demand() const { return false; }
456
460 {
461 size_t cells = 0;
462 size_t verts = 0;
463 };
464 static SlotUsage slot_usage_of_this_thread()
465 {
466 return {
469 }
472protected:
475 virtual void on_slot_storage_grown() {}
476
477private:
478 size_t reserved_capacity(size_t live_count) const
479 {
480 const size_t floor = 64;
481 // A mesh that grows on demand only needs room for the passes not to grow at once.
482 const double factor = storage_grows_on_demand() ? 1.25 : m_preallocation_factor;
483 double c = std::ceil(factor * static_cast<double>(live_count));
484 size_t capacity = static_cast<size_t>(c);
485 if (capacity < live_count) capacity = live_count;
486 return capacity < floor ? floor : capacity;
487 }
488
489 SlotPool<VertexConnectivity> m_vertex_connectivity;
490 SlotPool<TriangleConnectivity> m_tri_connectivity;
491 double m_preallocation_factor = 6.0;
492 bool m_use_link_condition = true;
493
494protected:
508 size_t vid,
509 std::vector<size_t>& component_of,
510 std::vector<size_t>& representatives) const;
511
512private:
518 size_t get_next_empty_slot_t();
524 size_t get_next_empty_slot_v();
525
526public:
532 virtual bool invariants(const std::vector<Tuple>&) { return true; }
538 virtual bool split_edge_before(const Tuple& t) { return true; }
544 virtual bool split_edge_after(const Tuple& t) { return true; }
545
553 virtual bool collapse_edge_before(const Tuple& t)
554 {
555 if (!m_use_link_condition) {
556 return true;
557 }
558 return check_link_condition(t);
559 }
565 virtual bool collapse_edge_after(const Tuple& t) { return true; }
571 virtual bool swap_edge_after(const Tuple& t) { return true; }
580 virtual bool swap_edge_before(const Tuple& t);
587 virtual bool smooth_before(const Tuple& t) { return true; }
589 static bool dry_run() { return operation_dry_run(); }
595 virtual bool smooth_after(const Tuple& t) { return true; }
596
602 virtual bool split_face_before(const Tuple& t) { return true; }
608 virtual bool split_face_after(const Tuple& t) { return true; }
609
610public:
616 size_t tri_capacity() const { return m_tri_connectivity.live(); }
622 size_t vert_capacity() const { return m_vertex_connectivity.live(); }
623
633 static constexpr int EDGES_PER_CELL = 3;
634 size_t cell_capacity() const { return tri_capacity(); }
635 size_t cell_storage_capacity() const { return m_tri_connectivity.capacity(); }
636 Tuple tuple_from_cell(size_t cid) const { return tuple_from_tri(cid); }
643 void consolidate_mesh();
644
653 std::shared_ptr<history::Recorder> start_history(
654 std::function<Eigen::Vector3d(size_t)> position);
656 void stop_history();
657
670 std::shared_ptr<history::TrackedCurveRecorder> start_curve_history(
671 std::function<Eigen::Vector3d(size_t)> position);
673 void stop_curve_history();
677 size_t resync_curve_history(const std::vector<std::array<size_t, 2>>& edges);
679 std::vector<std::array<size_t, 2>> tracked_edges() const;
683 virtual bool is_tracked_edge(const Tuple& e) const { return false; }
687 virtual std::vector<size_t> tracked_feature_points() const { return {}; }
688
696 void remove_tris_by_ids(const std::vector<size_t>& fids);
700 Tuple switch_vertex(const Tuple& t) const { return t.switch_vertex(*this); }
704 Tuple switch_edge(const Tuple& t) const { return t.switch_edge(*this); }
709 std::optional<Tuple> switch_face(const Tuple& t) const { return t.switch_face(*this); }
710
716 bool check_link_condition(const Tuple& t) const;
717
729 void set_use_link_condition(bool use_it) { m_use_link_condition = use_it; }
730 bool use_link_condition() const { return m_use_link_condition; }
731
740 bool check_edge_manifold() const;
741
747 size_t edge_valence(const TriMesh::Tuple& t) const;
748
754 bool is_boundary_edge(const TriMesh::Tuple& t) const;
755
765 bool is_manifold_edge(const TriMesh::Tuple& t) const;
766
773 size_t vertex_component_count(const size_t vid) const;
774 size_t vertex_component_count(const TriMesh::Tuple& t) const
775 {
776 return vertex_component_count(t.vid(*this));
777 }
778
779 bool is_manifold_vertex(const size_t vid) const { return vertex_component_count(vid) <= 1; }
780
789 std::optional<Tuple> switch_component(const TriMesh::Tuple& t) const;
790
791#ifdef WMTK_DEBUG_BRUTE_FORCE_OPS
807 std::string debug_canonical_form() const;
808
810 std::string debug_reference_collapse(size_t v_removed, size_t v_kept) const;
811
819 std::string debug_reference_swap(size_t v0, size_t v1, size_t fa, size_t fb) const;
820
828 std::string debug_reference_split_face(
829 size_t fid,
830 size_t v0,
831 size_t v1,
832 size_t v2,
833 size_t new_v,
834 size_t tri_cap) const;
835
843 std::string debug_reference_split(size_t v0, size_t v1, size_t new_v, size_t tri_cap) const;
844#endif
845
852 {
854 for (auto e : ve)
855 if (is_boundary_edge(e)) return true;
856 return false;
857 }
858
867 bool split_edge(const Tuple& t, std::vector<Tuple>& new_t);
868
879 virtual bool collapse_edge(const Tuple& t, std::vector<Tuple>& new_t);
880
885 const Tuple& loc0,
886 std::vector<Tuple>& new_tris,
887 Tuple& return_t,
888 size_t& new_vid,
889 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
890 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
891 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
892 std::vector<size_t>& n12_intersect_fids);
893
899 size_t& new_vid,
900 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
901 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
902 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
903 std::vector<size_t>& n12_intersect_fids);
904
905
915 bool swap_edge(const Tuple& t, std::vector<Tuple>& new_t);
916
924 bool smooth_vertex(const Tuple& t);
940
949 bool split_face(const Tuple& t, std::vector<Tuple>& new_t);
950
957 size_t get_valence_for_vertex(const Tuple& t) const
958 {
959 return m_vertex_connectivity[t.vid(*this)].m_conn_tris.size();
960 }
961
969 size_t vertex_valence(const size_t vid) const
970 {
971 return m_vertex_connectivity[vid].m_conn_tris.size();
972 }
973
980 std::vector<Tuple> get_one_ring_tris_for_vertex(const Tuple& t) const;
981 const std::vector<size_t>& get_one_ring_fids_for_vertex(const Tuple& t) const;
982 const std::vector<size_t>& get_one_ring_fids_for_vertex(const size_t vid) const;
989 std::vector<size_t> get_one_ring_vids_for_vertex_duplicate(const size_t& t) const;
990 void get_one_ring_vids_for_vertex_duplicate(const size_t& t, std::vector<size_t>& one_ring)
991 const;
992
993 std::vector<size_t> get_incident_fids_for_edge(const Tuple& t) const;
994 std::vector<size_t> get_incident_fids_for_edge(const size_t vid0, const size_t vid1) const;
995
1005 std::vector<Tuple> get_one_ring_edges_for_vertex(const Tuple& t) const;
1006 std::vector<Tuple> get_one_ring_edges_for_vertex(const size_t vid) const;
1007
1014 std::array<Tuple, 3> oriented_tri_vertices(const Tuple& t) const;
1015
1022 std::array<size_t, 3> oriented_tri_vids(const Tuple& t) const;
1023 std::array<size_t, 3> oriented_tri_vids(const size_t i) const;
1024
1025 std::array<Tuple, 2> get_edge_vertices(const Tuple& t) const;
1026 std::array<size_t, 2> get_edge_vids(const Tuple& t) const;
1027
1035 Tuple tuple_from_tri(size_t fid) const
1036 {
1037 if (fid >= m_tri_connectivity.capacity() || m_tri_connectivity[fid].m_is_removed)
1038 return Tuple();
1039 auto vid = m_tri_connectivity[fid][0];
1040 return Tuple(vid, 1, fid, *this);
1041 }
1056 Tuple tuple_from_vertex(size_t vid) const
1057 {
1058 if (vid >= m_vertex_connectivity.capacity() || m_vertex_connectivity[vid].m_is_removed ||
1059 m_vertex_connectivity[vid].m_conn_tris.empty()) {
1060 return Tuple();
1061 }
1062 auto fid = m_vertex_connectivity[vid][0];
1063 auto eid = m_tri_connectivity[fid].find((int)vid);
1064 return Tuple(vid, (eid + 1) % 3, fid, *this);
1065 }
1072 Tuple tuple_from_edge(size_t fid, size_t local_eid) const
1073 {
1074 auto vid = m_tri_connectivity[fid][(local_eid + 1) % 3];
1075 return Tuple(vid, local_eid, fid, *this);
1076 }
1077
1078 std::tuple<Tuple, size_t> tuple_from_edge(const std::array<size_t, 2>& vids) const;
1086 std::optional<std::tuple<Tuple, size_t>> try_tuple_from_edge(
1087 const std::array<size_t, 2>& vids) const;
1088
1089public:
1095 {
1096 if (p_vertex_attrs) p_vertex_attrs->begin_protect();
1097 if (p_edge_attrs) p_edge_attrs->begin_protect();
1098 if (p_face_attrs) p_face_attrs->begin_protect();
1099 }
1105 {
1106 if (p_vertex_attrs) p_vertex_attrs->end_protect();
1107 if (p_edge_attrs) p_edge_attrs->end_protect();
1108 if (p_face_attrs) p_face_attrs->end_protect();
1109 }
1115 {
1116 if (p_vertex_attrs) p_vertex_attrs->rollback();
1117 if (p_edge_attrs) p_edge_attrs->rollback();
1118 if (p_face_attrs) p_face_attrs->rollback();
1119 }
1120
1121private:
1122 std::shared_ptr<history::Recorder> m_history;
1123 std::function<Eigen::Vector3d(size_t)> m_history_position;
1126 void commit_history(history::Edit&& e);
1127
1128 std::shared_ptr<history::TrackedCurveRecorder> m_curve_history;
1134 std::vector<std::array<size_t, 2>> tracked_edges_around(const std::vector<size_t>& vs) const;
1135 void curve_history_before(const std::vector<size_t>& vs);
1140 history::EditKind kind,
1141 std::vector<size_t> v,
1142 const std::vector<size_t>& vs_after);
1143
1144 // Moved code from concurrent TriMesh
1145
1146public:
1150
1151private:
1152 std::vector<VertexMutex> m_vertex_mutex;
1153
1154 bool try_set_vertex_mutex(const Tuple& v, int threadid)
1155 {
1156 bool got = m_vertex_mutex[v.vid(*this)].trylock();
1157 if (got) m_vertex_mutex[v.vid(*this)].set_owner(threadid);
1158 return got;
1159 }
1160 bool try_set_vertex_mutex(size_t vid, int threadid)
1161 {
1162 bool got = m_vertex_mutex[vid].trylock();
1163 if (got) m_vertex_mutex[vid].set_owner(threadid);
1164 return got;
1165 }
1166
1167 void unlock_vertex_mutex(const Tuple& v) { m_vertex_mutex[v.vid(*this)].unlock(); }
1168 void unlock_vertex_mutex(size_t vid) { m_vertex_mutex[vid].unlock(); }
1169
1177 {
1178 std::vector<uint32_t> stamp;
1179 uint32_t epoch = 0;
1180 std::vector<size_t> frontier;
1181 std::vector<size_t> next;
1182 std::vector<size_t> one_ring;
1183 };
1185
1187 bool lock_vertex_ball(const size_t* seeds, size_t n_seeds, int threadid, int n, size_t mark);
1188
1190 void check_smoothing_stayed_in_star(size_t vid);
1191
1192protected:
1193 void resize_mutex(size_t v)
1194 {
1195 if (m_vertex_mutex.size() < v) m_vertex_mutex.resize(v);
1196 }
1197
1198public:
1200
1201 int release_vertex_mutex_in_stack();
1209 int release_vertex_mutex_to(size_t mark);
1210
1227 bool try_set_vertex_mutex_n_ring(const Tuple& v, int threadid, int n);
1228 bool try_set_vertex_mutex_n_ring(size_t vid, int threadid, int n);
1232 bool try_set_edge_mutex_n_ring(const Tuple& e, int threadid, int n);
1233
1273 bool try_set_vertex_mutex_two_ring(const Tuple& v, int threadid);
1275 bool try_set_edge_mutex_two_ring(const Tuple& e, int threadid);
1277 bool try_set_vertex_mutex_one_ring(const Tuple& v, int threadid);
1286 bool try_set_face_mutex_one_ring(const Tuple& f, int threadid);
1287
1292 void for_each_face(const std::function<void(const Tuple&)>&);
1297 void for_each_edge(const std::function<void(const Tuple&)>&);
1302 void for_each_vertex(const std::function<void(const Tuple&)>&);
1303 int NUM_THREADS = 0;
1304
1305public:
1306 // substructure functionality
1307
1313 virtual bool vertex_is_on_surface(const size_t vid) const { return false; }
1314
1320 virtual bool edge_is_on_surface(const std::array<size_t, 2>& vids) const { return false; }
1321
1328
1338 size_t get_order_of_edge(const std::array<size_t, 2>& vids) const;
1339
1350 size_t get_order_of_vertex(const size_t vid) const;
1351
1365 bool substructure_link_condition(const Tuple& e_tuple) const;
1366};
1367
1368} // namespace wmtk
static size_t taken_by_this_thread()
Slots this thread has been handed by pools of this type, over its lifetime.
Definition SlotPool.hpp:88
Definition TriMesh.h:178
Definition TriMesh.h:250
bool m_is_removed
is the triangle removed
Definition TriMesh.h:261
int find(size_t v_id) const
Definition TriMesh.h:287
uint32_t hash
the hash is changed every time there is an operation that influences the triangle
Definition TriMesh.h:269
std::array< size_t, 3 > m_indices
incident vertices of a given triangle
Definition TriMesh.h:256
Definition TriMesh.h:36
size_t eid(const TriMesh &m) const
Definition TriMesh.cpp:98
size_t fid(const TriMesh &) const
Definition TriMesh.h:84
bool is_valid_unlocked(const TriMesh &m) const
is_valid() without its debug-build consistency checks: the same answer as is_valid() in a release bui...
Definition TriMesh.cpp:299
Tuple switch_vertex(const TriMesh &m) const
Definition TriMesh.cpp:161
bool is_valid(const TriMesh &m) const
check if a Tuple is valid
Definition TriMesh.cpp:311
std::vector< Tuple > switch_faces(const TriMesh &m) const
Definition TriMesh.cpp:253
Tuple switch_edge(const TriMesh &m) const
Definition TriMesh.cpp:190
std::array< Tuple, 3 > oriented_tri_vertices(const TriMesh &m) const
std::optional< Tuple > switch_face(const TriMesh &m) const
Definition TriMesh.cpp:217
size_t vid(const TriMesh &) const
Definition TriMesh.h:76
size_t local_eid(const TriMesh &m) const
Definition TriMesh.h:104
Tuple()
Definition TriMesh.h:61
Definition TriMesh.h:219
std::vector< size_t > m_conn_tris
incident triangles of a given vertex
Definition TriMesh.h:225
bool m_is_removed
is the vertex removed
Definition TriMesh.h:230
Definition TriMesh.h:32
virtual bool split_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge split.
Definition TriMesh.h:544
void set_preallocation_factor(double factor)
Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so op...
Definition TriMesh.h:384
std::array< size_t, 3 > oriented_tri_vids(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:2286
std::vector< size_t > get_one_ring_vids_for_vertex_duplicate(const size_t &t) const
Get the vids of the incident one ring tris for a vertex.
Definition TriMesh.cpp:2137
void collapse_edge_rollback(size_t &new_vid, std::vector< std::pair< size_t, TriangleConnectivity > > &old_tris, std::vector< std::pair< size_t, VertexConnectivity > > &old_vertices, std::vector< std::pair< size_t, size_t > > &same_edge_vid_fid, std::vector< size_t > &n12_intersect_fids)
Definition TriMesh.cpp:1270
size_t edge_valence(const TriMesh::Tuple &t) const
Number of triangles incident to the edge the Tuple points at.
Definition TriMesh.cpp:441
void vertex_fan_components(size_t vid, std::vector< size_t > &component_of, std::vector< size_t > &representatives) const
Definition TriMesh.cpp:341
void check_smoothing_stayed_in_star(size_t vid)
See m_check_smoothing_stays_in_star; throws, after dropping the record, if the check fails.
Definition TriMesh.cpp:1688
size_t get_order_of_vertex(const size_t vid) const
Get the order of a vertex.
Definition TriMesh.cpp:3164
void commit_history(history::Edit &&e)
Definition TriMesh.cpp:2123
void release_protect_attributes()
End the modification phase.
Definition TriMesh.h:1104
void stop_history()
Stop recording. The recorder keeps the edits it has.
Definition TriMesh.cpp:2003
size_t get_valence_for_vertex(const Tuple &t) const
Count the number of the one ring tris for a vertex.
Definition TriMesh.h:957
bool lock_vertex_ball(const size_t *seeds, size_t n_seeds, int threadid, int n, size_t mark)
The n-ring BFS. mark is the release-stack watermark to unwind to on failure.
Definition TriMesh.cpp:2835
std::vector< Tuple > get_vertices() const
Definition TriMesh.cpp:2410
size_t get_next_empty_slot_t()
Get the next avaiblie global index for the triangle.
Definition TriMesh.cpp:2692
void curve_history_commit(history::EditKind kind, std::vector< size_t > v, const std::vector< size_t > &vs_after)
Definition TriMesh.cpp:2069
size_t get_next_empty_slot_v()
Get the next avaiblie global index for the vertex.
Definition TriMesh.cpp:2697
void collapse_edge_conn(const Tuple &loc0, std::vector< Tuple > &new_tris, Tuple &return_t, size_t &new_vid, std::vector< std::pair< size_t, TriangleConnectivity > > &old_tris, std::vector< std::pair< size_t, VertexConnectivity > > &old_vertices, std::vector< std::pair< size_t, size_t > > &same_edge_vid_fid, std::vector< size_t > &n12_intersect_fids)
Definition TriMesh.cpp:1307
virtual bool swap_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge swap including 1.can't swap on boundary edge....
Definition TriMesh.cpp:2702
bool try_set_face_mutex_one_ring(const Tuple &f, int threadid)
try lock the one-ring neighboring triangles' incident vertices.
Definition TriMesh.cpp:3052
void for_each_vertex(const std::function< void(const Tuple &)> &)
perform the given function for each vertex
Definition TriMesh.cpp:3102
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideras after an edge smooth.
Definition TriMesh.h:595
std::vector< std::array< size_t, 2 > > tracked_edges() const
Every tracked edge, each with its smaller vertex first.
Definition TriMesh.cpp:2055
virtual bool invariants(const std::vector< Tuple > &)
User specified invariants that can't be violated.
Definition TriMesh.h:532
virtual bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const
Is an edge part of the substructure.
Definition TriMesh.h:1320
void remove_tris_by_ids(const std::vector< size_t > &fids)
Mark the given triangles, and any vertex left without an incident triangle, as removed.
Definition TriMesh.cpp:2085
std::vector< std::array< size_t, 2 > > tracked_edges_around(const std::vector< size_t > &vs) const
Definition TriMesh.cpp:2032
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge collapse.
Definition TriMesh.h:565
std::shared_ptr< history::TrackedCurveRecorder > start_curve_history(std::function< Eigen::Vector3d(size_t)> position)
Record every change to the tracked curves from now on (see wmtk/history/TrackedRecorder....
Definition TriMesh.cpp:2009
std::optional< Tuple > switch_component(const TriMesh::Tuple &t) const
Jump to the next edge-connected component of the fan of the Tuple's vertex.
Definition TriMesh.cpp:730
Tuple tuple_from_edge(size_t fid, size_t local_eid) const
Definition TriMesh.h:1072
Tuple switch_edge(const Tuple &t) const
a duplicate of Tuple::switch_edge funciton
Definition TriMesh.h:704
std::vector< Tuple > get_one_ring_tris_for_vertex(const Tuple &t) const
Get the one ring tris for a vertex.
Definition TriMesh.cpp:2171
virtual bool split_face_after(const Tuple &t)
User specified modifications and desideratas after a face split.
Definition TriMesh.h:608
void reserve_free_slots(size_t cells, size_t verts)
Definition TriMesh.cpp:2665
bool split_face(const Tuple &t, std::vector< Tuple > &new_t)
Split a face in 3 faces.
Definition TriMesh.cpp:1730
virtual bool is_tracked_edge(const Tuple &e) const
Definition TriMesh.h:683
int release_vertex_mutex_to(size_t mark)
Release the mutexes taken since the release stack held mark entries.
Definition TriMesh.cpp:2818
void rollback_protected_attributes()
rollback the attributes that are modified if any condition failed
Definition TriMesh.h:1114
bool split_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:795
bool try_set_vertex_mutex_one_ring(const Tuple &v, int threadid)
Lock v and its one-ring. Complete, unlike the two-ring pair.
Definition TriMesh.cpp:3023
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideras after an edge swap.
Definition TriMesh.h:571
bool try_set_vertex_mutex_two_ring(const Tuple &v, int threadid)
Lock v's one-ring and, partially, its two-ring. See the note above.
Definition TriMesh.cpp:2938
bool m_check_smoothing_stays_in_star
While true, smooth_vertex() checks that the smooth recorded nothing outside the vertex's star – the v...
Definition TriMesh.h:939
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1541
Tuple tuple_from_tri(size_t fid) const
Definition TriMesh.h:1035
std::optional< std::tuple< Tuple, size_t > > try_tuple_from_edge(const std::array< size_t, 2 > &vids) const
tuple_from_edge for callers where a missing edge is an answer, not a bug.
Definition TriMesh.cpp:2324
static bool dry_run()
Whether operations on this thread are dry runs (see wmtk/OperationDryRun.hpp).
Definition TriMesh.h:589
bool is_boundary_edge(const TriMesh::Tuple &t) const
Does exactly one triangle share this edge?
Definition TriMesh.cpp:451
void init(size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris)
Definition TriMesh.cpp:2366
size_t get_order_of_edge(const std::array< size_t, 2 > &vids) const
Compute the order of an edge.
Definition TriMesh.cpp:3159
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:622
std::vector< Tuple > get_one_ring_edges_for_vertex(const Tuple &t) const
Get all edges that are incident to the vertex of Tuple t.
Definition TriMesh.cpp:2196
std::vector< Tuple > get_faces() const
Definition TriMesh.cpp:2447
bool check_mesh_connectivity_validity() const
verify the connectivity validity of the mesh
Definition TriMesh.cpp:758
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:2484
virtual bool storage_grows_on_demand() const
Definition TriMesh.h:455
void consolidate_mesh()
removing the elements that are removed
Definition TriMesh.cpp:1889
bool try_set_edge_mutex_n_ring(const Tuple &e, int threadid, int n)
try_set_vertex_mutex_n_ring seeded from both ends of an edge.
Definition TriMesh.cpp:2916
bool is_manifold_edge(const TriMesh::Tuple &t) const
Do exactly two triangles share this edge?
Definition TriMesh.cpp:466
bool try_set_vertex_mutex_n_ring(const Tuple &v, int threadid, int n)
Lock every vertex within graph distance n of v, the seed included.
Definition TriMesh.cpp:2911
bool try_set_edge_mutex_two_ring(const Tuple &e, int threadid)
Lock the edge's one-ring and, partially, its two-ring. See the note above.
Definition TriMesh.cpp:2963
virtual bool vertex_is_on_surface(const size_t vid) const
Is a vertex part of the substructure.
Definition TriMesh.h:1313
std::array< Tuple, 3 > oriented_tri_vertices(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:2273
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for an edge smooth.
Definition TriMesh.h:587
std::shared_ptr< history::Recorder > start_history(std::function< Eigen::Vector3d(size_t)> position)
Record every operation this mesh commits from now on (see wmtk/history).
Definition TriMesh.cpp:1976
size_t tri_capacity() const
get the current largest global fid
Definition TriMesh.h:616
size_t vertex_component_count(const size_t vid) const
Number of edge-connected components in the fan of a vertex.
Definition TriMesh.cpp:723
void start_protect_attributes()
Start the phase where the attributes that will be modified can be recorded.
Definition TriMesh.h:1094
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split.
Definition TriMesh.h:602
bool substructure_link_condition(const Tuple &e_tuple) const
Link condition that also considers substructures.
Definition TriMesh.cpp:3185
size_t resync_curve_history(const std::vector< std::array< size_t, 2 > > &edges)
Definition TriMesh.cpp:2027
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split.
Definition TriMesh.h:538
virtual std::vector< size_t > tracked_feature_points() const
Definition TriMesh.h:687
std::optional< Tuple > switch_face(const Tuple &t) const
a duplicate of Tuple::switch_face funciton
Definition TriMesh.h:709
simplex::SimplexCollection get_surface_edges_for_vertex(const size_t vid) const
Get all edges on the surface that are incident to vid.
Definition TriMesh.cpp:3135
size_t vertex_valence(const size_t vid) const
Number of triangles incident to a vertex, by id.
Definition TriMesh.h:969
virtual void on_slot_storage_grown()
Definition TriMesh.h:475
void stop_curve_history()
Stop recording curves. The recorder keeps what it has.
Definition TriMesh.cpp:2022
size_t cell_slot_bound(const Tuple &t) const
Definition TriMesh.cpp:2655
wmtk::threading::enumerable_thread_specific< std::vector< std::array< size_t, 2 > > > m_curve_history_before
The tracked edges around the running operation, before it changed anything.
Definition TriMesh.h:1131
void for_each_edge(const std::function< void(const Tuple &)> &)
perform the given function for each edge
Definition TriMesh.cpp:3082
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:1056
bool check_link_condition(const Tuple &t) const
prerequisite for collapse
Definition TriMesh.cpp:2721
void set_use_link_condition(bool use_it)
Should collapse_edge_before enforce the link condition?
Definition TriMesh.h:729
bool smooth_vertex(const Tuple &t)
Definition TriMesh.cpp:1649
std::vector< Tuple > get_edges() const
Definition TriMesh.cpp:2463
virtual bool collapse_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge collapse including the link check as collapse...
Definition TriMesh.h:553
Tuple switch_vertex(const Tuple &t) const
a duplicate of Tuple::switch_vertex funciton
Definition TriMesh.h:700
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1155
bool is_boundary_vertex(const TriMesh::Tuple &t) const
check if the vertex that's represented by a Tuple is at the boundary of the mesh
Definition TriMesh.h:851
bool check_edge_manifold() const
verify the edge manifoldness of the mesh
Definition TriMesh.cpp:787
void for_each_face(const std::function< void(const Tuple &)> &)
perform the given function for each face
Definition TriMesh.cpp:3118
Definition SimplexCollection.hpp:9
A per-vertex lock plus the id of the thread currently holding it.
Definition vertex_mutex.hpp:29
Definition enumerable_thread_specific.hpp:37
EditKind
The kinds of edit a complex goes through.
Definition History.hpp:27
Per-thread buffers for the n-ring lock, so a lock acquisition allocates nothing.
Definition TriMesh.h:1177
Definition TriMesh.h:460
One committed operation.
Definition History.hpp:79