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/Types.hpp>
6#include <wmtk/simplex/Simplex.hpp>
7#include <wmtk/simplex/SimplexCollection.hpp>
8#include <wmtk/threading/enumerable_thread_specific.hpp>
9#include <wmtk/threading/vertex_mutex.hpp>
10#include <wmtk/utils/Logger.hpp>
11
12#include <algorithm>
13#include <array>
14#include <atomic>
15#include <cassert>
16#include <cmath>
17#include <cstdint>
18#include <map>
19#include <memory>
20#include <optional>
21#include <set>
22#include <vector>
23
24namespace wmtk {
25
27{
28public:
29 // Cell Tuple Navigator
30 class Tuple
31 {
32 private:
33 size_t m_vid = -1;
34 size_t m_eid = -1;
35 size_t m_fid = -1;
36 size_t m_hash = -1;
37
38 void update_hash(const TriMesh& m);
39
40 public:
41 void print_info();
42
43 // v2 /
44 // / \ /
45 // e1 / \ e0 /
46 // v0 - - - v1 /
47 // e2 /
56 Tuple() {}
57 Tuple(size_t vid, size_t eid, size_t fid, const TriMesh& m)
58 : m_vid(vid)
59 , m_eid(eid)
60 , m_fid(fid)
61 {
62 update_hash(m);
63 }
64
65
71 inline size_t vid(const TriMesh&) const { return m_vid; }
72
79 inline size_t fid(const TriMesh&) const { return m_fid; }
80
81
90 size_t eid(const TriMesh& m) const;
91
99 size_t local_eid(const TriMesh& m) const { return m_eid; };
106 Tuple switch_vertex(const TriMesh& m) const;
112 Tuple switch_edge(const TriMesh& m) const;
128 std::optional<Tuple> switch_face(const TriMesh& m) const;
129
135 std::vector<Tuple> switch_faces(const TriMesh& m) const;
136
146 bool is_valid(const TriMesh& m) const;
147
152 std::array<Tuple, 3> oriented_tri_vertices(const TriMesh& m) const;
153 friend bool operator<(const Tuple& a, const Tuple& t)
154 {
155 return (
156 std::tie(a.m_vid, a.m_eid, a.m_fid, a.m_hash) <
157 std::tie(t.m_vid, t.m_eid, t.m_fid, t.m_hash));
158 }
159 };
160
162 {
163 const TriMesh& m_mesh;
164 Tuple m_tuple;
165
166 public:
167 SmartTuple(const TriMesh& mesh, const Tuple& t)
168 : m_mesh(mesh)
169 , m_tuple(t)
170 {}
171
172 const Tuple& tuple() const { return m_tuple; }
173 const TriMesh& mesh() const { return m_mesh; }
174
175 SmartTuple& operator=(const SmartTuple& t)
176 {
177 m_tuple = t.m_tuple;
178 return *this;
179 }
180
181 bool is_valid() const { return m_tuple.is_valid(m_mesh); }
182 size_t vid() const { return m_tuple.vid(m_mesh); }
183 size_t eid() const { return m_tuple.eid(m_mesh); }
184 size_t fid() const { return m_tuple.fid(m_mesh); }
185 SmartTuple switch_vertex() const { return {m_mesh, m_tuple.switch_vertex(m_mesh)}; }
186 SmartTuple switch_edge() const { return {m_mesh, m_tuple.switch_edge(m_mesh)}; }
187 std::optional<SmartTuple> switch_face() const
188 {
189 const std::optional<Tuple> t = m_tuple.switch_face(m_mesh);
190 if (t) {
191 return std::optional<SmartTuple>({m_mesh, t.value()});
192 }
193 return {};
194 }
195 };
196
203 {
204 public:
209 std::vector<size_t> m_conn_tris;
214 bool m_is_removed = false;
215
216 inline size_t& operator[](const size_t index)
217 {
218 assert(index < m_conn_tris.size());
219 return m_conn_tris[index];
220 }
221
222 inline size_t operator[](const size_t index) const
223 {
224 assert(index < m_conn_tris.size());
225 return m_conn_tris[index];
226 }
227 };
228
234 {
235 public:
240 std::array<size_t, 3> m_indices;
245 bool m_is_removed = false;
251 size_t hash = 0;
252
253 inline size_t& operator[](size_t index)
254 {
255 assert(index < 3);
256 return m_indices[index];
257 }
258
259 inline size_t operator[](size_t index) const
260 {
261 assert(index < 3);
262 return m_indices[index];
263 }
269 inline int find(size_t v_id) const
270 {
271 for (int j = 0; j < 3; j++) {
272 if (v_id == m_indices[j]) {
273 return j;
274 }
275 }
276 return -1;
277 }
278 };
279
280 TriMesh() {}
281 virtual ~TriMesh() {}
282
288 void init(size_t n_vertices, const std::vector<std::array<size_t, 3>>& tris);
289
295 void init(const MatrixXi& F);
296
307 std::vector<Tuple> get_vertices() const;
308
315 std::vector<Tuple> get_edges() const;
316
323 std::vector<Tuple> get_faces() const;
324
332 Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const;
333
334 Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2) const;
335
336 simplex::Vertex simplex_from_vertex(const Tuple& t) const;
337 simplex::Edge simplex_from_edge(const Tuple& t) const;
338 simplex::Face simplex_from_face(const Tuple& t) const;
339 simplex::Face simplex_from_face(const size_t fid) const;
340
341 Tuple tuple_from_simplex(const simplex::Face& s) const;
342 // Tuple tuple_from_simplex(const simplex::Edge& s) const;
343
344 simplex::SimplexCollection simplex_incident_triangles(const simplex::Vertex& v) const;
345 simplex::SimplexCollection simplex_incident_triangles(const simplex::Edge& e) const;
346 simplex::SimplexCollection simplex_link_vertices(const simplex::Vertex& v) const;
347 simplex::SimplexCollection simplex_link_vertices(const simplex::Edge& e) const;
348 simplex::SimplexCollection simplex_link_edges(const simplex::Vertex& v) const;
349
350 template <typename T>
351 using vector = std::vector<T>;
352
353public:
354 AbstractAttributeContainer* p_vertex_attrs = nullptr;
355 AbstractAttributeContainer* p_edge_attrs = nullptr;
356 AbstractAttributeContainer* p_face_attrs = nullptr;
357
358public:
366 void set_preallocation_factor(double factor)
367 {
368 if (factor >= 1.0) m_preallocation_factor = factor;
369 }
370 double preallocation_factor() const { return m_preallocation_factor; }
371
372 // Atomically reserve `n` contiguous fresh triangle/vertex slots. Returns the
373 // first index of the block, or -1 if that would exceed the preallocated
374 // capacity (the caller must then abort the operation before mutating).
375 long request_tri_slots(size_t n);
376 long request_vert_slots(size_t n);
377
378private:
379 size_t reserved_capacity(size_t live_count) const
380 {
381 const size_t floor = 64;
382 double c = std::ceil(m_preallocation_factor * static_cast<double>(live_count));
383 size_t capacity = static_cast<size_t>(c);
384 if (capacity < live_count) capacity = live_count;
385 return capacity < floor ? floor : capacity;
386 }
387
388 vector<VertexConnectivity> m_vertex_connectivity;
389 vector<TriangleConnectivity> m_tri_connectivity;
390 std::atomic_long current_vert_size;
391 std::atomic_long current_tri_size;
392 double m_preallocation_factor = 6.0;
393 bool m_use_link_condition = true;
394
395protected:
409 size_t vid,
410 std::vector<size_t>& component_of,
411 std::vector<size_t>& representatives) const;
412
413private:
419 size_t get_next_empty_slot_t();
425 size_t get_next_empty_slot_v();
426
427public:
433 virtual bool invariants(const std::vector<Tuple>&) { return true; }
439 virtual bool split_edge_before(const Tuple& t) { return true; }
445 virtual bool split_edge_after(const Tuple& t) { return true; }
446
454 virtual bool collapse_edge_before(const Tuple& t)
455 {
456 if (!m_use_link_condition) {
457 return true;
458 }
459 return check_link_condition(t);
460 }
466 virtual bool collapse_edge_after(const Tuple& t) { return true; }
472 virtual bool swap_edge_after(const Tuple& t) { return true; }
481 virtual bool swap_edge_before(const Tuple& t);
488 virtual bool smooth_before(const Tuple& t) { return true; }
494 virtual bool smooth_after(const Tuple& t) { return true; }
495
501 virtual bool split_face_before(const Tuple& t) { return true; }
507 virtual bool split_face_after(const Tuple& t) { return true; }
508
509public:
515 size_t tri_capacity() const { return current_tri_size; }
521 size_t vert_capacity() const { return current_vert_size; }
522
532 static constexpr int EDGES_PER_CELL = 3;
533 size_t cell_capacity() const { return tri_capacity(); }
534 Tuple tuple_from_cell(size_t cid) const { return tuple_from_tri(cid); }
541 void consolidate_mesh();
542
550 void remove_tris_by_ids(const std::vector<size_t>& fids)
551 {
552 for (const size_t fid : fids) {
553 m_tri_connectivity[fid].m_is_removed = true;
554 for (int j = 0; j < 3; j++) {
555 vector_erase(m_vertex_connectivity[m_tri_connectivity[fid][j]].m_conn_tris, fid);
556 }
557 }
558 for (auto& v : m_vertex_connectivity) {
559 if (v.m_is_removed) continue;
560 if (v.m_conn_tris.empty()) v.m_is_removed = true;
561 }
562 }
566 Tuple switch_vertex(const Tuple& t) const { return t.switch_vertex(*this); }
570 Tuple switch_edge(const Tuple& t) const { return t.switch_edge(*this); }
575 std::optional<Tuple> switch_face(const Tuple& t) const { return t.switch_face(*this); }
576
582 bool check_link_condition(const Tuple& t) const;
583
595 void set_use_link_condition(bool use_it) { m_use_link_condition = use_it; }
596 bool use_link_condition() const { return m_use_link_condition; }
597
606 bool check_edge_manifold() const;
607
613 size_t edge_valence(const TriMesh::Tuple& t) const;
614
620 bool is_boundary_edge(const TriMesh::Tuple& t) const;
621
631 bool is_manifold_edge(const TriMesh::Tuple& t) const;
632
639 size_t vertex_component_count(const size_t vid) const;
640 size_t vertex_component_count(const TriMesh::Tuple& t) const
641 {
642 return vertex_component_count(t.vid(*this));
643 }
644
645 bool is_manifold_vertex(const size_t vid) const { return vertex_component_count(vid) <= 1; }
646
655 std::optional<Tuple> switch_component(const TriMesh::Tuple& t) const;
656
657#ifdef WMTK_DEBUG_BRUTE_FORCE_OPS
673 std::string debug_canonical_form() const;
674
676 std::string debug_reference_collapse(size_t v_removed, size_t v_kept) const;
677
685 std::string debug_reference_swap(size_t v0, size_t v1, size_t fa, size_t fb) const;
686
694 std::string debug_reference_split_face(
695 size_t fid,
696 size_t v0,
697 size_t v1,
698 size_t v2,
699 size_t new_v,
700 size_t tri_cap) const;
701
709 std::string debug_reference_split(size_t v0, size_t v1, size_t new_v, size_t tri_cap) const;
710#endif
711
718 {
720 for (auto e : ve)
721 if (is_boundary_edge(e)) return true;
722 return false;
723 }
724
733 bool split_edge(const Tuple& t, std::vector<Tuple>& new_t);
734
744 virtual bool collapse_edge(const Tuple& t, std::vector<Tuple>& new_t);
745
750 const Tuple& loc0,
751 std::vector<Tuple>& new_tris,
752 Tuple& return_t,
753 size_t& new_vid,
754 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
755 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
756 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
757 std::vector<size_t>& n12_intersect_fids);
758
764 size_t& new_vid,
765 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
766 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
767 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
768 std::vector<size_t>& n12_intersect_fids);
769
770
780 bool swap_edge(const Tuple& t, std::vector<Tuple>& new_t);
781
789 bool smooth_vertex(const Tuple& t);
790
799 bool split_face(const Tuple& t, std::vector<Tuple>& new_t);
800
807 size_t get_valence_for_vertex(const Tuple& t) const
808 {
809 return m_vertex_connectivity[t.vid(*this)].m_conn_tris.size();
810 }
811
819 size_t vertex_valence(const size_t vid) const
820 {
821 return m_vertex_connectivity[vid].m_conn_tris.size();
822 }
823
830 std::vector<Tuple> get_one_ring_tris_for_vertex(const Tuple& t) const;
831 const std::vector<size_t>& get_one_ring_fids_for_vertex(const Tuple& t) const;
832 const std::vector<size_t>& get_one_ring_fids_for_vertex(const size_t vid) const;
839 std::vector<size_t> get_one_ring_vids_for_vertex_duplicate(const size_t& t) const;
840 void get_one_ring_vids_for_vertex_duplicate(const size_t& t, std::vector<size_t>& one_ring)
841 const;
842
843 std::vector<size_t> get_incident_fids_for_edge(const Tuple& t) const;
844 std::vector<size_t> get_incident_fids_for_edge(const size_t vid0, const size_t vid1) const;
845
855 std::vector<Tuple> get_one_ring_edges_for_vertex(const Tuple& t) const;
856 std::vector<Tuple> get_one_ring_edges_for_vertex(const size_t vid) const;
857
864 std::array<Tuple, 3> oriented_tri_vertices(const Tuple& t) const;
865
872 std::array<size_t, 3> oriented_tri_vids(const Tuple& t) const;
873 std::array<size_t, 3> oriented_tri_vids(const size_t i) const;
874
875 std::array<Tuple, 2> get_edge_vertices(const Tuple& t) const;
876 std::array<size_t, 2> get_edge_vids(const Tuple& t) const;
877
885 Tuple tuple_from_tri(size_t fid) const
886 {
887 if (fid >= m_tri_connectivity.size() || m_tri_connectivity[fid].m_is_removed)
888 return Tuple();
889 auto vid = m_tri_connectivity[fid][0];
890 return Tuple(vid, 1, fid, *this);
891 }
906 Tuple tuple_from_vertex(size_t vid) const
907 {
908 if (vid >= m_vertex_connectivity.size() || m_vertex_connectivity[vid].m_is_removed ||
909 m_vertex_connectivity[vid].m_conn_tris.empty()) {
910 return Tuple();
911 }
912 auto fid = m_vertex_connectivity[vid][0];
913 auto eid = m_tri_connectivity[fid].find((int)vid);
914 return Tuple(vid, (eid + 1) % 3, fid, *this);
915 }
922 Tuple tuple_from_edge(size_t fid, size_t local_eid) const
923 {
924 auto vid = m_tri_connectivity[fid][(local_eid + 1) % 3];
925 return Tuple(vid, local_eid, fid, *this);
926 }
927
928 std::tuple<Tuple, size_t> tuple_from_edge(const std::array<size_t, 2>& vids) const;
936 std::optional<std::tuple<Tuple, size_t>> try_tuple_from_edge(
937 const std::array<size_t, 2>& vids) const;
938
939public:
945 {
946 if (p_vertex_attrs) p_vertex_attrs->begin_protect();
947 if (p_edge_attrs) p_edge_attrs->begin_protect();
948 if (p_face_attrs) p_face_attrs->begin_protect();
949 }
955 {
956 if (p_vertex_attrs) p_vertex_attrs->end_protect();
957 if (p_edge_attrs) p_edge_attrs->end_protect();
958 if (p_face_attrs) p_face_attrs->end_protect();
959 }
965 {
966 if (p_vertex_attrs) p_vertex_attrs->rollback();
967 if (p_edge_attrs) p_edge_attrs->rollback();
968 if (p_face_attrs) p_face_attrs->rollback();
969 }
970
971 // Moved code from concurrent TriMesh
972
973public:
977
978private:
979 std::vector<VertexMutex> m_vertex_mutex;
980
981 bool try_set_vertex_mutex(const Tuple& v, int threadid)
982 {
983 bool got = m_vertex_mutex[v.vid(*this)].trylock();
984 if (got) m_vertex_mutex[v.vid(*this)].set_owner(threadid);
985 return got;
986 }
987 bool try_set_vertex_mutex(size_t vid, int threadid)
988 {
989 bool got = m_vertex_mutex[vid].trylock();
990 if (got) m_vertex_mutex[vid].set_owner(threadid);
991 return got;
992 }
993
994 void unlock_vertex_mutex(const Tuple& v) { m_vertex_mutex[v.vid(*this)].unlock(); }
995 void unlock_vertex_mutex(size_t vid) { m_vertex_mutex[vid].unlock(); }
996
1004 {
1005 std::vector<uint32_t> stamp;
1006 uint32_t epoch = 0;
1007 std::vector<size_t> frontier;
1008 std::vector<size_t> next;
1009 std::vector<size_t> one_ring;
1010 };
1012
1014 bool lock_vertex_ball(const size_t* seeds, size_t n_seeds, int threadid, int n, size_t mark);
1015
1016protected:
1017 void resize_mutex(size_t v)
1018 {
1019 if (m_vertex_mutex.size() < v) m_vertex_mutex.resize(v);
1020 }
1021
1022public:
1024
1025 int release_vertex_mutex_in_stack();
1033 int release_vertex_mutex_to(size_t mark);
1034
1051 bool try_set_vertex_mutex_n_ring(const Tuple& v, int threadid, int n);
1052 bool try_set_vertex_mutex_n_ring(size_t vid, int threadid, int n);
1056 bool try_set_edge_mutex_n_ring(const Tuple& e, int threadid, int n);
1057
1097 bool try_set_vertex_mutex_two_ring(const Tuple& v, int threadid);
1099 bool try_set_edge_mutex_two_ring(const Tuple& e, int threadid);
1101 bool try_set_vertex_mutex_one_ring(const Tuple& v, int threadid);
1110 bool try_set_face_mutex_one_ring(const Tuple& f, int threadid);
1111
1116 void for_each_face(const std::function<void(const Tuple&)>&);
1121 void for_each_edge(const std::function<void(const Tuple&)>&);
1126 void for_each_vertex(const std::function<void(const Tuple&)>&);
1127 int NUM_THREADS = 0;
1128
1129public:
1130 // substructure functionality
1131
1137 virtual bool vertex_is_on_surface(const size_t vid) const { return false; }
1138
1144 virtual bool edge_is_on_surface(const std::array<size_t, 2>& vids) const { return false; }
1145
1152
1162 size_t get_order_of_edge(const std::array<size_t, 2>& vids) const;
1163
1174 size_t get_order_of_vertex(const size_t vid) const;
1175
1189 bool substructure_link_condition(const Tuple& e_tuple) const;
1190};
1191
1192} // namespace wmtk
Definition TriMesh.h:162
Definition TriMesh.h:234
bool m_is_removed
is the triangle removed
Definition TriMesh.h:245
int find(size_t v_id) const
Definition TriMesh.h:269
size_t hash
the hash is changed every time there is an operation that influences the triangle
Definition TriMesh.h:251
std::array< size_t, 3 > m_indices
incident vertices of a given triangle
Definition TriMesh.h:240
Definition TriMesh.h:31
size_t eid(const TriMesh &m) const
Definition TriMesh.cpp:95
size_t fid(const TriMesh &) const
Definition TriMesh.h:79
Tuple switch_vertex(const TriMesh &m) const
Definition TriMesh.cpp:158
bool is_valid(const TriMesh &m) const
check if a Tuple is valid
Definition TriMesh.cpp:296
std::vector< Tuple > switch_faces(const TriMesh &m) const
Definition TriMesh.cpp:250
Tuple switch_edge(const TriMesh &m) const
Definition TriMesh.cpp:187
std::array< Tuple, 3 > oriented_tri_vertices(const TriMesh &m) const
std::optional< Tuple > switch_face(const TriMesh &m) const
Definition TriMesh.cpp:214
size_t vid(const TriMesh &) const
Definition TriMesh.h:71
size_t local_eid(const TriMesh &m) const
Definition TriMesh.h:99
Tuple()
Definition TriMesh.h:56
Definition TriMesh.h:203
std::vector< size_t > m_conn_tris
incident triangles of a given vertex
Definition TriMesh.h:209
bool m_is_removed
is the vertex removed
Definition TriMesh.h:214
Definition TriMesh.h:27
virtual bool split_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge split.
Definition TriMesh.h:445
void set_preallocation_factor(double factor)
Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so op...
Definition TriMesh.h:366
std::array< size_t, 3 > oriented_tri_vids(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:2006
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:1857
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:1237
size_t edge_valence(const TriMesh::Tuple &t) const
Number of triangles incident to the edge the Tuple points at.
Definition TriMesh.cpp:435
void vertex_fan_components(size_t vid, std::vector< size_t > &component_of, std::vector< size_t > &representatives) const
Definition TriMesh.cpp:335
size_t get_order_of_vertex(const size_t vid) const
Get the order of a vertex.
Definition TriMesh.cpp:2883
void release_protect_attributes()
End the modification phase.
Definition TriMesh.h:954
size_t get_valence_for_vertex(const Tuple &t) const
Count the number of the one ring tris for a vertex.
Definition TriMesh.h:807
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:2556
std::vector< Tuple > get_vertices() const
Definition TriMesh.cpp:2130
size_t get_next_empty_slot_t()
Get the next avaiblie global index for the triangle.
Definition TriMesh.cpp:2411
size_t get_next_empty_slot_v()
Get the next avaiblie global index for the vertex.
Definition TriMesh.cpp:2417
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:1274
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:2423
bool try_set_face_mutex_one_ring(const Tuple &f, int threadid)
try lock the one-ring neighboring triangles' incident vertices.
Definition TriMesh.cpp:2771
void for_each_vertex(const std::function< void(const Tuple &)> &)
perform the given function for each vertex
Definition TriMesh.cpp:2821
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideras after an edge smooth.
Definition TriMesh.h:494
virtual bool invariants(const std::vector< Tuple > &)
User specified invariants that can't be violated.
Definition TriMesh.h:433
virtual bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const
Is an edge part of the substructure.
Definition TriMesh.h:1144
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge collapse.
Definition TriMesh.h:466
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:724
Tuple tuple_from_edge(size_t fid, size_t local_eid) const
Definition TriMesh.h:922
Tuple switch_edge(const Tuple &t) const
a duplicate of Tuple::switch_edge funciton
Definition TriMesh.h:570
std::vector< Tuple > get_one_ring_tris_for_vertex(const Tuple &t) const
Get the one ring tris for a vertex.
Definition TriMesh.cpp:1891
virtual bool split_face_after(const Tuple &t)
User specified modifications and desideratas after a face split.
Definition TriMesh.h:507
bool split_face(const Tuple &t, std::vector< Tuple > &new_t)
Split a face in 3 faces.
Definition TriMesh.cpp:1641
int release_vertex_mutex_to(size_t mark)
Release the mutexes taken since the release stack held mark entries.
Definition TriMesh.cpp:2539
void rollback_protected_attributes()
rollback the attributes that are modified if any condition failed
Definition TriMesh.h:964
bool split_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:789
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:2742
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideras after an edge swap.
Definition TriMesh.h:472
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:2659
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1508
Tuple tuple_from_tri(size_t fid) const
Definition TriMesh.h:885
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:2044
bool is_boundary_edge(const TriMesh::Tuple &t) const
Does exactly one triangle share this edge?
Definition TriMesh.cpp:445
void init(size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris)
Definition TriMesh.cpp:2086
size_t get_order_of_edge(const std::array< size_t, 2 > &vids) const
Compute the order of an edge.
Definition TriMesh.cpp:2878
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:521
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.h:550
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:1916
std::vector< Tuple > get_faces() const
Definition TriMesh.cpp:2167
bool check_mesh_connectivity_validity() const
verify the connectivity validity of the mesh
Definition TriMesh.cpp:752
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:2204
void consolidate_mesh()
removing the elements that are removed
Definition TriMesh.cpp:1788
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:2637
bool is_manifold_edge(const TriMesh::Tuple &t) const
Do exactly two triangles share this edge?
Definition TriMesh.cpp:460
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:2632
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:2684
virtual bool vertex_is_on_surface(const size_t vid) const
Is a vertex part of the substructure.
Definition TriMesh.h:1137
std::array< Tuple, 3 > oriented_tri_vertices(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1993
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for an edge smooth.
Definition TriMesh.h:488
size_t tri_capacity() const
get the current largest global fid
Definition TriMesh.h:515
size_t vertex_component_count(const size_t vid) const
Number of edge-connected components in the fan of a vertex.
Definition TriMesh.cpp:717
void start_protect_attributes()
Start the phase where the attributes that will be modified can be recorded.
Definition TriMesh.h:944
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split.
Definition TriMesh.h:501
bool substructure_link_condition(const Tuple &e_tuple) const
Link condition that also considers substructures.
Definition TriMesh.cpp:2904
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split.
Definition TriMesh.h:439
std::optional< Tuple > switch_face(const Tuple &t) const
a duplicate of Tuple::switch_face funciton
Definition TriMesh.h:575
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:2854
size_t vertex_valence(const size_t vid) const
Number of triangles incident to a vertex, by id.
Definition TriMesh.h:819
void for_each_edge(const std::function< void(const Tuple &)> &)
perform the given function for each edge
Definition TriMesh.cpp:2801
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:906
bool check_link_condition(const Tuple &t) const
prerequisite for collapse
Definition TriMesh.cpp:2442
void set_use_link_condition(bool use_it)
Should collapse_edge_before enforce the link condition?
Definition TriMesh.h:595
bool smooth_vertex(const Tuple &t)
Definition TriMesh.cpp:1607
std::vector< Tuple > get_edges() const
Definition TriMesh.cpp:2183
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:454
Tuple switch_vertex(const Tuple &t) const
a duplicate of Tuple::switch_vertex funciton
Definition TriMesh.h:566
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1134
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:717
bool check_edge_manifold() const
verify the edge manifoldness of the mesh
Definition TriMesh.cpp:781
void for_each_face(const std::function< void(const Tuple &)> &)
perform the given function for each face
Definition TriMesh.cpp:2837
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:26
Per-thread buffers for the n-ring lock, so a lock acquisition allocates nothing.
Definition TriMesh.h:1004