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/SlotPool.hpp>
6#include <wmtk/Types.hpp>
7#include <wmtk/simplex/Simplex.hpp>
8#include <wmtk/simplex/SimplexCollection.hpp>
9#include <wmtk/threading/enumerable_thread_specific.hpp>
10#include <wmtk/threading/vertex_mutex.hpp>
11#include <wmtk/utils/Logger.hpp>
12
13#include <algorithm>
14#include <array>
15#include <atomic>
16#include <cassert>
17#include <cmath>
18#include <cstdint>
19#include <map>
20#include <memory>
21#include <optional>
22#include <set>
23#include <vector>
24
25namespace wmtk {
26
28{
29public:
30 // Cell Tuple Navigator
31 class Tuple
32 {
33 private:
34 size_t m_vid = -1;
35 size_t m_eid = -1;
36 size_t m_fid = -1;
37 size_t m_hash = 0;
38
39 void update_hash(const TriMesh& m);
40
41 public:
42 void print_info();
43
44 // v2 /
45 // / \ /
46 // e1 / \ e0 /
47 // v0 - - - v1 /
48 // e2 /
57 Tuple() {}
58 Tuple(size_t vid, size_t eid, size_t fid, const TriMesh& m)
59 : m_vid(vid)
60 , m_eid(eid)
61 , m_fid(fid)
62 {
63 update_hash(m);
64 }
65
66
72 inline size_t vid(const TriMesh&) const { return m_vid; }
73
80 inline size_t fid(const TriMesh&) const { return m_fid; }
81
82
91 size_t eid(const TriMesh& m) const;
92
100 size_t local_eid(const TriMesh& m) const { return m_eid; };
107 Tuple switch_vertex(const TriMesh& m) const;
113 Tuple switch_edge(const TriMesh& m) const;
129 std::optional<Tuple> switch_face(const TriMesh& m) const;
130
136 std::vector<Tuple> switch_faces(const TriMesh& m) const;
137
147 bool is_valid(const TriMesh& m) const;
148
153 std::array<Tuple, 3> oriented_tri_vertices(const TriMesh& m) const;
154 friend bool operator<(const Tuple& a, const Tuple& t)
155 {
156 return (
157 std::tie(a.m_vid, a.m_eid, a.m_fid, a.m_hash) <
158 std::tie(t.m_vid, t.m_eid, t.m_fid, t.m_hash));
159 }
160 };
161
163 {
164 const TriMesh& m_mesh;
165 Tuple m_tuple;
166
167 public:
168 SmartTuple(const TriMesh& mesh, const Tuple& t)
169 : m_mesh(mesh)
170 , m_tuple(t)
171 {}
172
173 const Tuple& tuple() const { return m_tuple; }
174 const TriMesh& mesh() const { return m_mesh; }
175
176 SmartTuple& operator=(const SmartTuple& t)
177 {
178 m_tuple = t.m_tuple;
179 return *this;
180 }
181
182 bool is_valid() const { return m_tuple.is_valid(m_mesh); }
183 size_t vid() const { return m_tuple.vid(m_mesh); }
184 size_t eid() const { return m_tuple.eid(m_mesh); }
185 size_t fid() const { return m_tuple.fid(m_mesh); }
186 SmartTuple switch_vertex() const { return {m_mesh, m_tuple.switch_vertex(m_mesh)}; }
187 SmartTuple switch_edge() const { return {m_mesh, m_tuple.switch_edge(m_mesh)}; }
188 std::optional<SmartTuple> switch_face() const
189 {
190 const std::optional<Tuple> t = m_tuple.switch_face(m_mesh);
191 if (t) {
192 return std::optional<SmartTuple>({m_mesh, t.value()});
193 }
194 return {};
195 }
196 };
197
204 {
205 public:
210 std::vector<size_t> m_conn_tris;
215 bool m_is_removed = false;
216
217 inline size_t& operator[](const size_t index)
218 {
219 assert(index < m_conn_tris.size());
220 return m_conn_tris[index];
221 }
222
223 inline size_t operator[](const size_t index) const
224 {
225 assert(index < m_conn_tris.size());
226 return m_conn_tris[index];
227 }
228 };
229
235 {
236 public:
241 std::array<size_t, 3> m_indices;
246 bool m_is_removed = false;
252 size_t hash = 0;
253
254 inline size_t& operator[](size_t index)
255 {
256 assert(index < 3);
257 return m_indices[index];
258 }
259
260 inline size_t operator[](size_t index) const
261 {
262 assert(index < 3);
263 return m_indices[index];
264 }
270 inline int find(size_t v_id) const
271 {
272 for (int j = 0; j < 3; j++) {
273 if (v_id == m_indices[j]) {
274 return j;
275 }
276 }
277 return -1;
278 }
279 };
280
281 TriMesh() {}
282 virtual ~TriMesh() {}
283
289 void init(size_t n_vertices, const std::vector<std::array<size_t, 3>>& tris);
290
296 void init(const MatrixXi& F);
297
308 std::vector<Tuple> get_vertices() const;
309
316 std::vector<Tuple> get_edges() const;
317
324 std::vector<Tuple> get_faces() const;
325
333 Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const;
334
335 Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2) const;
336
337 simplex::Vertex simplex_from_vertex(const Tuple& t) const;
338 simplex::Edge simplex_from_edge(const Tuple& t) const;
339 simplex::Face simplex_from_face(const Tuple& t) const;
340 simplex::Face simplex_from_face(const size_t fid) const;
341
342 Tuple tuple_from_simplex(const simplex::Face& s) const;
343 // Tuple tuple_from_simplex(const simplex::Edge& s) const;
344
345 simplex::SimplexCollection simplex_incident_triangles(const simplex::Vertex& v) const;
346 simplex::SimplexCollection simplex_incident_triangles(const simplex::Edge& e) const;
347 simplex::SimplexCollection simplex_link_vertices(const simplex::Vertex& v) const;
348 simplex::SimplexCollection simplex_link_vertices(const simplex::Edge& e) const;
349 simplex::SimplexCollection simplex_link_edges(const simplex::Vertex& v) const;
350
351 template <typename T>
352 using vector = std::vector<T>;
353
354public:
355 AbstractAttributeContainer* p_vertex_attrs = nullptr;
356 AbstractAttributeContainer* p_edge_attrs = nullptr;
357 AbstractAttributeContainer* p_face_attrs = nullptr;
358
359public:
367 void set_preallocation_factor(double factor)
368 {
369 if (factor >= 1.0) m_preallocation_factor = factor;
370 }
371 double preallocation_factor() const { return m_preallocation_factor; }
372
373 // Atomically reserve `n` contiguous fresh triangle/vertex slots. Returns the
374 // first index of the block, or INVALID_SLOT if that would exceed the preallocated
375 // capacity (the caller must then abort the operation before mutating).
376
394 size_t tri_storage_capacity() const { return m_tri_connectivity.capacity(); }
395 size_t vert_storage_capacity() const { return m_vertex_connectivity.capacity(); }
398 bool slots_exhausted() const
399 {
400 return m_vertex_connectivity.refused() || m_tri_connectivity.refused();
401 }
402 void clear_slots_exhausted()
403 {
404 m_vertex_connectivity.clear_refused();
405 m_tri_connectivity.clear_refused();
406 }
407
408 size_t request_tri_slots(size_t n);
409 size_t request_vert_slots(size_t n);
410
411private:
412 size_t reserved_capacity(size_t live_count) const
413 {
414 const size_t floor = 64;
415 double c = std::ceil(m_preallocation_factor * static_cast<double>(live_count));
416 size_t capacity = static_cast<size_t>(c);
417 if (capacity < live_count) capacity = live_count;
418 return capacity < floor ? floor : capacity;
419 }
420
421 SlotPool<VertexConnectivity> m_vertex_connectivity;
422 SlotPool<TriangleConnectivity> m_tri_connectivity;
423 double m_preallocation_factor = 6.0;
424 bool m_use_link_condition = true;
425
426protected:
440 size_t vid,
441 std::vector<size_t>& component_of,
442 std::vector<size_t>& representatives) const;
443
444private:
450 size_t get_next_empty_slot_t();
456 size_t get_next_empty_slot_v();
457
458public:
464 virtual bool invariants(const std::vector<Tuple>&) { return true; }
470 virtual bool split_edge_before(const Tuple& t) { return true; }
476 virtual bool split_edge_after(const Tuple& t) { return true; }
477
485 virtual bool collapse_edge_before(const Tuple& t)
486 {
487 if (!m_use_link_condition) {
488 return true;
489 }
490 return check_link_condition(t);
491 }
497 virtual bool collapse_edge_after(const Tuple& t) { return true; }
503 virtual bool swap_edge_after(const Tuple& t) { return true; }
512 virtual bool swap_edge_before(const Tuple& t);
519 virtual bool smooth_before(const Tuple& t) { return true; }
525 virtual bool smooth_after(const Tuple& t) { return true; }
526
532 virtual bool split_face_before(const Tuple& t) { return true; }
538 virtual bool split_face_after(const Tuple& t) { return true; }
539
540public:
546 size_t tri_capacity() const { return m_tri_connectivity.live(); }
552 size_t vert_capacity() const { return m_vertex_connectivity.live(); }
553
563 static constexpr int EDGES_PER_CELL = 3;
564 size_t cell_capacity() const { return tri_capacity(); }
565 Tuple tuple_from_cell(size_t cid) const { return tuple_from_tri(cid); }
572 void consolidate_mesh();
573
581 void remove_tris_by_ids(const std::vector<size_t>& fids)
582 {
583 for (const size_t fid : fids) {
584 m_tri_connectivity[fid].m_is_removed = true;
585 for (int j = 0; j < 3; j++) {
586 vector_erase(m_vertex_connectivity[m_tri_connectivity[fid][j]].m_conn_tris, fid);
587 }
588 }
589 for (auto& v : m_vertex_connectivity) {
590 if (v.m_is_removed) continue;
591 if (v.m_conn_tris.empty()) v.m_is_removed = true;
592 }
593 }
597 Tuple switch_vertex(const Tuple& t) const { return t.switch_vertex(*this); }
601 Tuple switch_edge(const Tuple& t) const { return t.switch_edge(*this); }
606 std::optional<Tuple> switch_face(const Tuple& t) const { return t.switch_face(*this); }
607
613 bool check_link_condition(const Tuple& t) const;
614
626 void set_use_link_condition(bool use_it) { m_use_link_condition = use_it; }
627 bool use_link_condition() const { return m_use_link_condition; }
628
637 bool check_edge_manifold() const;
638
644 size_t edge_valence(const TriMesh::Tuple& t) const;
645
651 bool is_boundary_edge(const TriMesh::Tuple& t) const;
652
662 bool is_manifold_edge(const TriMesh::Tuple& t) const;
663
670 size_t vertex_component_count(const size_t vid) const;
671 size_t vertex_component_count(const TriMesh::Tuple& t) const
672 {
673 return vertex_component_count(t.vid(*this));
674 }
675
676 bool is_manifold_vertex(const size_t vid) const { return vertex_component_count(vid) <= 1; }
677
686 std::optional<Tuple> switch_component(const TriMesh::Tuple& t) const;
687
688#ifdef WMTK_DEBUG_BRUTE_FORCE_OPS
704 std::string debug_canonical_form() const;
705
707 std::string debug_reference_collapse(size_t v_removed, size_t v_kept) const;
708
716 std::string debug_reference_swap(size_t v0, size_t v1, size_t fa, size_t fb) const;
717
725 std::string debug_reference_split_face(
726 size_t fid,
727 size_t v0,
728 size_t v1,
729 size_t v2,
730 size_t new_v,
731 size_t tri_cap) const;
732
740 std::string debug_reference_split(size_t v0, size_t v1, size_t new_v, size_t tri_cap) const;
741#endif
742
749 {
751 for (auto e : ve)
752 if (is_boundary_edge(e)) return true;
753 return false;
754 }
755
764 bool split_edge(const Tuple& t, std::vector<Tuple>& new_t);
765
775 virtual bool collapse_edge(const Tuple& t, std::vector<Tuple>& new_t);
776
781 const Tuple& loc0,
782 std::vector<Tuple>& new_tris,
783 Tuple& return_t,
784 size_t& new_vid,
785 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
786 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
787 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
788 std::vector<size_t>& n12_intersect_fids);
789
795 size_t& new_vid,
796 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
797 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
798 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
799 std::vector<size_t>& n12_intersect_fids);
800
801
811 bool swap_edge(const Tuple& t, std::vector<Tuple>& new_t);
812
820 bool smooth_vertex(const Tuple& t);
821
830 bool split_face(const Tuple& t, std::vector<Tuple>& new_t);
831
838 size_t get_valence_for_vertex(const Tuple& t) const
839 {
840 return m_vertex_connectivity[t.vid(*this)].m_conn_tris.size();
841 }
842
850 size_t vertex_valence(const size_t vid) const
851 {
852 return m_vertex_connectivity[vid].m_conn_tris.size();
853 }
854
861 std::vector<Tuple> get_one_ring_tris_for_vertex(const Tuple& t) const;
862 const std::vector<size_t>& get_one_ring_fids_for_vertex(const Tuple& t) const;
863 const std::vector<size_t>& get_one_ring_fids_for_vertex(const size_t vid) const;
870 std::vector<size_t> get_one_ring_vids_for_vertex_duplicate(const size_t& t) const;
871 void get_one_ring_vids_for_vertex_duplicate(const size_t& t, std::vector<size_t>& one_ring)
872 const;
873
874 std::vector<size_t> get_incident_fids_for_edge(const Tuple& t) const;
875 std::vector<size_t> get_incident_fids_for_edge(const size_t vid0, const size_t vid1) const;
876
886 std::vector<Tuple> get_one_ring_edges_for_vertex(const Tuple& t) const;
887 std::vector<Tuple> get_one_ring_edges_for_vertex(const size_t vid) const;
888
895 std::array<Tuple, 3> oriented_tri_vertices(const Tuple& t) const;
896
903 std::array<size_t, 3> oriented_tri_vids(const Tuple& t) const;
904 std::array<size_t, 3> oriented_tri_vids(const size_t i) const;
905
906 std::array<Tuple, 2> get_edge_vertices(const Tuple& t) const;
907 std::array<size_t, 2> get_edge_vids(const Tuple& t) const;
908
916 Tuple tuple_from_tri(size_t fid) const
917 {
918 if (fid >= m_tri_connectivity.capacity() || m_tri_connectivity[fid].m_is_removed)
919 return Tuple();
920 auto vid = m_tri_connectivity[fid][0];
921 return Tuple(vid, 1, fid, *this);
922 }
937 Tuple tuple_from_vertex(size_t vid) const
938 {
939 if (vid >= m_vertex_connectivity.capacity() || m_vertex_connectivity[vid].m_is_removed ||
940 m_vertex_connectivity[vid].m_conn_tris.empty()) {
941 return Tuple();
942 }
943 auto fid = m_vertex_connectivity[vid][0];
944 auto eid = m_tri_connectivity[fid].find((int)vid);
945 return Tuple(vid, (eid + 1) % 3, fid, *this);
946 }
953 Tuple tuple_from_edge(size_t fid, size_t local_eid) const
954 {
955 auto vid = m_tri_connectivity[fid][(local_eid + 1) % 3];
956 return Tuple(vid, local_eid, fid, *this);
957 }
958
959 std::tuple<Tuple, size_t> tuple_from_edge(const std::array<size_t, 2>& vids) const;
967 std::optional<std::tuple<Tuple, size_t>> try_tuple_from_edge(
968 const std::array<size_t, 2>& vids) const;
969
970public:
976 {
977 if (p_vertex_attrs) p_vertex_attrs->begin_protect();
978 if (p_edge_attrs) p_edge_attrs->begin_protect();
979 if (p_face_attrs) p_face_attrs->begin_protect();
980 }
986 {
987 if (p_vertex_attrs) p_vertex_attrs->end_protect();
988 if (p_edge_attrs) p_edge_attrs->end_protect();
989 if (p_face_attrs) p_face_attrs->end_protect();
990 }
996 {
997 if (p_vertex_attrs) p_vertex_attrs->rollback();
998 if (p_edge_attrs) p_edge_attrs->rollback();
999 if (p_face_attrs) p_face_attrs->rollback();
1000 }
1001
1002 // Moved code from concurrent TriMesh
1003
1004public:
1008
1009private:
1010 std::vector<VertexMutex> m_vertex_mutex;
1011
1012 bool try_set_vertex_mutex(const Tuple& v, int threadid)
1013 {
1014 bool got = m_vertex_mutex[v.vid(*this)].trylock();
1015 if (got) m_vertex_mutex[v.vid(*this)].set_owner(threadid);
1016 return got;
1017 }
1018 bool try_set_vertex_mutex(size_t vid, int threadid)
1019 {
1020 bool got = m_vertex_mutex[vid].trylock();
1021 if (got) m_vertex_mutex[vid].set_owner(threadid);
1022 return got;
1023 }
1024
1025 void unlock_vertex_mutex(const Tuple& v) { m_vertex_mutex[v.vid(*this)].unlock(); }
1026 void unlock_vertex_mutex(size_t vid) { m_vertex_mutex[vid].unlock(); }
1027
1035 {
1036 std::vector<uint32_t> stamp;
1037 uint32_t epoch = 0;
1038 std::vector<size_t> frontier;
1039 std::vector<size_t> next;
1040 std::vector<size_t> one_ring;
1041 };
1043
1045 bool lock_vertex_ball(const size_t* seeds, size_t n_seeds, int threadid, int n, size_t mark);
1046
1047protected:
1048 void resize_mutex(size_t v)
1049 {
1050 if (m_vertex_mutex.size() < v) m_vertex_mutex.resize(v);
1051 }
1052
1053public:
1055
1056 int release_vertex_mutex_in_stack();
1064 int release_vertex_mutex_to(size_t mark);
1065
1082 bool try_set_vertex_mutex_n_ring(const Tuple& v, int threadid, int n);
1083 bool try_set_vertex_mutex_n_ring(size_t vid, int threadid, int n);
1087 bool try_set_edge_mutex_n_ring(const Tuple& e, int threadid, int n);
1088
1128 bool try_set_vertex_mutex_two_ring(const Tuple& v, int threadid);
1130 bool try_set_edge_mutex_two_ring(const Tuple& e, int threadid);
1132 bool try_set_vertex_mutex_one_ring(const Tuple& v, int threadid);
1141 bool try_set_face_mutex_one_ring(const Tuple& f, int threadid);
1142
1147 void for_each_face(const std::function<void(const Tuple&)>&);
1152 void for_each_edge(const std::function<void(const Tuple&)>&);
1157 void for_each_vertex(const std::function<void(const Tuple&)>&);
1158 int NUM_THREADS = 0;
1159
1160public:
1161 // substructure functionality
1162
1168 virtual bool vertex_is_on_surface(const size_t vid) const { return false; }
1169
1175 virtual bool edge_is_on_surface(const std::array<size_t, 2>& vids) const { return false; }
1176
1183
1193 size_t get_order_of_edge(const std::array<size_t, 2>& vids) const;
1194
1205 size_t get_order_of_vertex(const size_t vid) const;
1206
1220 bool substructure_link_condition(const Tuple& e_tuple) const;
1221};
1222
1223} // namespace wmtk
Definition TriMesh.h:163
Definition TriMesh.h:235
bool m_is_removed
is the triangle removed
Definition TriMesh.h:246
int find(size_t v_id) const
Definition TriMesh.h:270
size_t hash
the hash is changed every time there is an operation that influences the triangle
Definition TriMesh.h:252
std::array< size_t, 3 > m_indices
incident vertices of a given triangle
Definition TriMesh.h:241
Definition TriMesh.h:32
size_t eid(const TriMesh &m) const
Definition TriMesh.cpp:95
size_t fid(const TriMesh &) const
Definition TriMesh.h:80
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:72
size_t local_eid(const TriMesh &m) const
Definition TriMesh.h:100
Tuple()
Definition TriMesh.h:57
Definition TriMesh.h:204
std::vector< size_t > m_conn_tris
incident triangles of a given vertex
Definition TriMesh.h:210
bool m_is_removed
is the vertex removed
Definition TriMesh.h:215
Definition TriMesh.h:28
virtual bool split_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge split.
Definition TriMesh.h:476
void set_preallocation_factor(double factor)
Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so op...
Definition TriMesh.h:367
std::array< size_t, 3 > oriented_tri_vids(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:2004
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:1855
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:1236
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:2848
void release_protect_attributes()
End the modification phase.
Definition TriMesh.h:985
size_t get_valence_for_vertex(const Tuple &t) const
Count the number of the one ring tris for a vertex.
Definition TriMesh.h:838
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:2521
std::vector< Tuple > get_vertices() const
Definition TriMesh.cpp:2128
size_t get_next_empty_slot_t()
Get the next avaiblie global index for the triangle.
Definition TriMesh.cpp:2378
size_t get_next_empty_slot_v()
Get the next avaiblie global index for the vertex.
Definition TriMesh.cpp:2383
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:1273
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:2388
bool try_set_face_mutex_one_ring(const Tuple &f, int threadid)
try lock the one-ring neighboring triangles' incident vertices.
Definition TriMesh.cpp:2736
void for_each_vertex(const std::function< void(const Tuple &)> &)
perform the given function for each vertex
Definition TriMesh.cpp:2786
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideras after an edge smooth.
Definition TriMesh.h:525
virtual bool invariants(const std::vector< Tuple > &)
User specified invariants that can't be violated.
Definition TriMesh.h:464
virtual bool edge_is_on_surface(const std::array< size_t, 2 > &vids) const
Is an edge part of the substructure.
Definition TriMesh.h:1175
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge collapse.
Definition TriMesh.h:497
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:953
Tuple switch_edge(const Tuple &t) const
a duplicate of Tuple::switch_edge funciton
Definition TriMesh.h:601
std::vector< Tuple > get_one_ring_tris_for_vertex(const Tuple &t) const
Get the one ring tris for a vertex.
Definition TriMesh.cpp:1889
virtual bool split_face_after(const Tuple &t)
User specified modifications and desideratas after a face split.
Definition TriMesh.h:538
bool split_face(const Tuple &t, std::vector< Tuple > &new_t)
Split a face in 3 faces.
Definition TriMesh.cpp:1640
int release_vertex_mutex_to(size_t mark)
Release the mutexes taken since the release stack held mark entries.
Definition TriMesh.cpp:2504
void rollback_protected_attributes()
rollback the attributes that are modified if any condition failed
Definition TriMesh.h:995
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:2707
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideras after an edge swap.
Definition TriMesh.h:503
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:2624
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1507
Tuple tuple_from_tri(size_t fid) const
Definition TriMesh.h:916
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:2042
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:2084
size_t get_order_of_edge(const std::array< size_t, 2 > &vids) const
Compute the order of an edge.
Definition TriMesh.cpp:2843
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:552
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:581
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:1914
std::vector< Tuple > get_faces() const
Definition TriMesh.cpp:2165
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:2202
void consolidate_mesh()
removing the elements that are removed
Definition TriMesh.cpp:1786
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:2602
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:2597
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:2649
virtual bool vertex_is_on_surface(const size_t vid) const
Is a vertex part of the substructure.
Definition TriMesh.h:1168
std::array< Tuple, 3 > oriented_tri_vertices(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1991
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for an edge smooth.
Definition TriMesh.h:519
size_t tri_capacity() const
get the current largest global fid
Definition TriMesh.h:546
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:975
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split.
Definition TriMesh.h:532
bool substructure_link_condition(const Tuple &e_tuple) const
Link condition that also considers substructures.
Definition TriMesh.cpp:2869
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split.
Definition TriMesh.h:470
std::optional< Tuple > switch_face(const Tuple &t) const
a duplicate of Tuple::switch_face funciton
Definition TriMesh.h:606
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:2819
size_t vertex_valence(const size_t vid) const
Number of triangles incident to a vertex, by id.
Definition TriMesh.h:850
void for_each_edge(const std::function< void(const Tuple &)> &)
perform the given function for each edge
Definition TriMesh.cpp:2766
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:937
bool check_link_condition(const Tuple &t) const
prerequisite for collapse
Definition TriMesh.cpp:2407
void set_use_link_condition(bool use_it)
Should collapse_edge_before enforce the link condition?
Definition TriMesh.h:626
bool smooth_vertex(const Tuple &t)
Definition TriMesh.cpp:1606
std::vector< Tuple > get_edges() const
Definition TriMesh.cpp:2181
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:485
Tuple switch_vertex(const Tuple &t) const
a duplicate of Tuple::switch_vertex funciton
Definition TriMesh.h:597
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:1133
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:748
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:2802
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:1035