Wildmeshing Toolkit
Loading...
Searching...
No Matches
TetMesh.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 <array>
14#include <atomic>
15#include <cassert>
16#include <cmath>
17#include <cstdint>
18#include <limits>
19#include <map>
20#include <optional>
21#include <vector>
22
23namespace wmtk {
25{
26private:
31 static constexpr std::array<std::array<int, 2>, 6> m_local_edges = {
32 {{{0, 1}}, {{1, 2}}, {{0, 2}}, {{0, 3}}, {{1, 3}}, {{2, 3}}}};
33
34 static constexpr std::array<int, 4> m_map_vertex2edge = {{0, 0, 1, 3}};
35 static constexpr std::array<int, 4> m_map_vertex2oppo_face = {{3, 1, 2, 0}};
36 static constexpr std::array<int, 6> m_map_edge2face = {{0, 0, 0, 1, 2, 1}};
37 static constexpr std::array<std::array<int, 3>, 4> m_local_faces = {
38 {{{0, 1, 2}}, {{0, 2, 3}}, {{0, 1, 3}}, {{1, 2, 3}}}}; // sorted local vids
39 static constexpr std::array<std::array<int, 3>, 4> m_local_edges_in_a_face = {
40 {{{0, 1, 2}}, {{2, 5, 3}}, {{3, 4, 0}}, {{5, 1, 4}}}};
41
42public:
43 // Cell Tuple Navigator
49 class Tuple
50 {
51 size_t m_global_vid = std::numeric_limits<size_t>::max();
52 size_t m_local_eid = std::numeric_limits<size_t>::max();
53 size_t m_local_fid = std::numeric_limits<size_t>::max();
54 size_t m_global_tid = std::numeric_limits<size_t>::max();
55
56 size_t m_hash = 0;
57
58 private:
68 Tuple(const TetMesh& m, size_t vid, size_t local_eid, size_t local_fid, size_t tid);
69
70 public:
71 Tuple() {}
72
73 friend TetMesh;
74
82 bool is_valid(const TetMesh& m) const;
89 bool is_boundary_edge(const TetMesh& m) const;
96 bool is_boundary_face(const TetMesh& m) const;
97
102 void print_info() const;
103
109 void print_info(const TetMesh& m) const;
110
116 size_t vid(const TetMesh& m) const;
117
126 size_t eid(const TetMesh& m) const;
127
135 size_t fid(const TetMesh& m) const;
136
143 size_t tid(const TetMesh& m) const;
144
151 Tuple switch_vertex(const TetMesh& m) const;
158 Tuple switch_edge(const TetMesh& m) const;
165 Tuple switch_face(const TetMesh& m) const;
166
174 std::optional<Tuple> switch_tetrahedron(const TetMesh& m) const;
175 std::optional<Tuple> switch_tetrahedron_slow(const TetMesh& m) const;
176
177
179
182 void check_validity(const TetMesh& m) const;
183 friend bool operator==(const Tuple& a, const Tuple& t)
184 {
185 return (
186 std::tie(a.m_global_vid, a.m_local_eid, a.m_local_fid, a.m_global_tid, a.m_hash) ==
187 std::tie(t.m_global_vid, t.m_local_eid, t.m_local_fid, t.m_global_tid, t.m_hash));
188 }
189 friend bool operator<(const Tuple& a, const Tuple& t)
190 {
191 return (
192 std::tie(a.m_global_vid, a.m_local_eid, a.m_local_fid, a.m_global_tid, a.m_hash) <
193 std::tie(t.m_global_vid, t.m_local_eid, t.m_local_fid, t.m_global_tid, t.m_hash));
194 }
195 };
196
202 {
203 const TetMesh& m_mesh;
204 Tuple m_tuple;
205
206 public:
207 SmartTuple(const TetMesh& mesh, const Tuple& t)
208 : m_mesh(mesh)
209 , m_tuple(t)
210 {}
211
212 const Tuple& tuple() { return m_tuple; }
213 const TetMesh& mesh() { return m_mesh; }
214
215 SmartTuple& operator=(const SmartTuple& t)
216 {
217 m_tuple = t.m_tuple;
218 return *this;
219 }
220
221 bool is_valid() const { return m_tuple.is_valid(m_mesh); }
222 bool is_boundary_edge() const { return m_tuple.is_boundary_edge(m_mesh); }
223 bool is_boundary_face() const { return m_tuple.is_boundary_face(m_mesh); }
224 size_t vid() const { return m_tuple.vid(m_mesh); }
225 size_t eid() const { return m_tuple.eid(m_mesh); }
226 size_t fid() const { return m_tuple.fid(m_mesh); }
227 size_t tid() const { return m_tuple.tid(m_mesh); }
228 SmartTuple switch_vertex() const { return {m_mesh, m_tuple.switch_vertex(m_mesh)}; }
229 SmartTuple switch_edge() const { return {m_mesh, m_tuple.switch_edge(m_mesh)}; }
230 SmartTuple switch_face() const { return {m_mesh, m_tuple.switch_face(m_mesh)}; }
231 std::optional<SmartTuple> switch_tetrahedron() const
232 {
233 const std::optional<Tuple> t = m_tuple.switch_tetrahedron(m_mesh);
234 if (t) {
235 return std::optional<SmartTuple>({m_mesh, t.value()});
236 }
237 return {};
238 }
239 void check_validity() const { return m_tuple.check_validity(m_mesh); }
240 };
241
248 {
249 public:
250 std::vector<size_t> m_conn_tets; // todo: always keep it sorted
251 bool m_is_removed = false;
252
253 size_t& operator[](const size_t index)
254 {
255 assert(index < m_conn_tets.size());
256 return m_conn_tets[index];
257 }
258
259 size_t operator[](const size_t index) const
260 {
261 assert(index < m_conn_tets.size());
262 return m_conn_tets[index];
263 }
264
265 friend bool operator==(const VertexConnectivity& l, const VertexConnectivity& r)
266 {
267 return std::tie(l.m_conn_tets, l.m_is_removed) ==
268 std::tie(r.m_conn_tets, r.m_is_removed); // keep the same order
269 }
270
271 void print_info() {}
272 };
273
279 {
280 public:
281 std::array<size_t, 4> m_indices;
282 bool m_is_removed = false;
283
290 size_t hash = 0;
291
292 size_t& operator[](size_t index)
293 {
294 assert(index < 4);
295 return m_indices[index];
296 }
297
298 size_t operator[](size_t index) const
299 {
300 assert(index < 4);
301 return m_indices[index];
302 }
303
304 int find(size_t v_id) const
305 {
306 for (int j = 0; j < 4; j++) {
307 if (v_id == m_indices[j]) return j;
308 }
309 return -1;
310 }
311
312 int find_local_edge(size_t v1_id, size_t v2_id) const
313 {
314 std::array<int, 2> e;
315 for (int j = 0; j < 4; j++) {
316 if (v1_id == m_indices[j])
317 e[0] = j;
318 else if (v2_id == m_indices[j])
319 e[1] = j;
320 }
321 if (e[0] > e[1]) std::swap(e[0], e[1]);
322 int i =
323 std::find(m_local_edges.begin(), m_local_edges.end(), e) - m_local_edges.begin();
324 if (i >= m_local_edges.size()) return -1;
325 return i;
326 }
327
328 int find_local_face(size_t v1_id, size_t v2_id, size_t v3_id) const
329 {
330 std::array<int, 3> f;
331 for (int j = 0; j < 4; j++) {
332 if (v1_id == m_indices[j])
333 f[0] = j;
334 else if (v2_id == m_indices[j])
335 f[1] = j;
336 else if (v3_id == m_indices[j])
337 f[2] = j;
338 }
339 std::sort(f.begin(), f.end());
340 int i =
341 std::find(m_local_faces.begin(), m_local_faces.end(), f) - m_local_faces.begin();
342 if (i >= m_local_edges.size()) return -1;
343 return i;
344 }
345
346 friend bool operator==(const TetrahedronConnectivity& l, const TetrahedronConnectivity& r)
347 {
348 return std::tie(l.m_indices, l.m_is_removed, l.hash) ==
349 std::tie(r.m_indices, r.m_is_removed, r.hash); // keep the same order
350 }
351
352 void print_info() {}
353 };
354
355 TetMesh();
356 virtual ~TetMesh() = default;
362 size_t vert_capacity() const { return m_vertex_connectivity.live(); }
368 size_t tet_capacity() const { return m_tet_connectivity.live(); }
369
379 static constexpr int EDGES_PER_CELL = 6;
380 static constexpr int FACES_PER_CELL = 4;
381 size_t cell_capacity() const { return tet_capacity(); }
382 Tuple tuple_from_cell(size_t cid) const { return tuple_from_tet(cid); }
389 size_t vertex_size() const
390 {
391 int cnt = 0;
392 for (auto i = 0; i < vert_capacity(); i++) {
393 if (!m_vertex_connectivity[i].m_is_removed) cnt++;
394 }
395 return cnt;
396 }
401 size_t tet_size() const
402 {
403 int cnt = 0;
404 for (auto i = 0; i < tet_capacity(); i++) {
405 if (!m_tet_connectivity[i].m_is_removed) cnt++;
406 }
407 return cnt;
408 }
418 void init(size_t n_vertices, const std::vector<std::array<size_t, 4>>& tets);
419 void init_with_isolated_vertices(
420 size_t n_vertices,
421 const std::vector<std::array<size_t, 4>>& tets);
422
428 void init(const MatrixXi& T);
429
437 bool split_edge(const Tuple& t, std::vector<Tuple>& new_tets);
445 virtual bool collapse_edge(const Tuple& t, std::vector<Tuple>& new_tets);
446
447 bool link_condition(const Tuple& t);
448
467 const Tuple& loc0,
468 size_t& v1_id,
469 Tuple& new_loc,
470 std::map<size_t, wmtk::TetMesh::VertexConnectivity>& rollback_vert_conn,
471 std::vector<size_t>& n1_t_ids_copy,
472 std::vector<size_t>& new_tet_id,
473 std::vector<TetrahedronConnectivity>& old_tets);
474
483 bool collapse_edge_check_topology(const std::vector<size_t>& new_tet_id);
484
498 size_t& v1_id,
499 std::map<size_t, wmtk::TetMesh::VertexConnectivity>& rollback_vert_conn,
500 std::vector<size_t>& n1_t_ids,
501 std::vector<size_t>& new_tet_id,
502 std::vector<TetrahedronConnectivity>& old_tets);
503
512 bool swap_edge_56(const Tuple& t, std::vector<Tuple>& new_tets);
521 bool swap_edge_44(const Tuple& t, std::vector<Tuple>& new_tets);
530 bool swap_edge(const Tuple& t, std::vector<Tuple>& new_tets);
537 bool swap_face(const Tuple& t, std::vector<Tuple>& new_tets);
545 bool smooth_vertex(const Tuple& t);
546
555 bool split_tet(const Tuple& t, std::vector<Tuple>& new_tets);
556
567 bool split_face(const Tuple& t, std::vector<Tuple>& new_tets);
568
577 const std::vector<Tuple>& intersected_tets,
578 const std::vector<Tuple>& intersected_edges,
579 std::vector<size_t>& new_edge_vids,
580 std::vector<size_t>& new_center_vids,
581 std::vector<std::array<size_t, 4>>& center_split_tets);
582
592 bool insert_point(const Tuple& t, std::vector<Tuple>& new_tets);
593 virtual bool insert_point_before(const Tuple& t) { return true; };
594 virtual bool insert_point_after(std::vector<Tuple>& new_tets) { return true; };
600 void consolidate_mesh();
601
607 std::vector<Tuple> get_edges() const;
613 std::vector<Tuple> get_faces() const;
619 std::vector<Tuple> get_vertices() const;
625 std::vector<Tuple> get_tets() const;
630 // virtual void for_each_edge(const std::function<void(const TetMesh::Tuple&)>&);
631
632 // TODO: make this concurrent
637 virtual void for_each_face(const std::function<void(const TetMesh::Tuple&)>&);
638 // /**
639 // * @brief looping through all the unique vertices and perform the given function
640 // *
641 // */
642 // virtual void for_each_vertex(const std::function<void(const TetMesh::Tuple&)>&);
643 // /**
644 // * @brief looping through all the unique tet and perform the given function
645 // *
646 // */
647 // virtual void for_each_tetra(const std::function<void(const TetMesh::Tuple&)>&);
648
649public:
650 template <typename T>
651 using vector = std::vector<T>;
652
653public:
654 AbstractAttributeContainer* p_vertex_attrs = nullptr;
655 AbstractAttributeContainer* p_edge_attrs = nullptr;
656 AbstractAttributeContainer* p_face_attrs = nullptr;
657 AbstractAttributeContainer* p_tet_attrs = nullptr;
658 // AbstractAttributeContainer vertex_attrs, edge_attrs, face_attrs, tet_attrs;
659
660
661public:
669 void set_preallocation_factor(double factor)
670 {
671 if (factor >= 1.0) m_preallocation_factor = factor;
672 }
673 double preallocation_factor() const { return m_preallocation_factor; }
674
675 // Atomically reserve `n` contiguous fresh tet/vertex slots. Returns the first
676 // index of the block, or -1 if that would exceed the preallocated capacity (the
677 // caller must then abort the operation before mutating any connectivity).
678
696 size_t tet_storage_capacity() const { return m_tet_connectivity.capacity(); }
697 size_t vert_storage_capacity() const { return m_vertex_connectivity.capacity(); }
700 bool slots_exhausted() const
701 {
702 return m_vertex_connectivity.refused() || m_tet_connectivity.refused();
703 }
704 void clear_slots_exhausted()
705 {
706 m_vertex_connectivity.clear_refused();
707 m_tet_connectivity.clear_refused();
708 }
709
710 size_t request_tet_slots(size_t n);
711 size_t request_vert_slots(size_t n);
712
713 // Construction/insertion helpers (single-threaded ONLY): guarantee at least
714 // `extra` free tet/vertex slots beyond the current used count, growing the
715 // storage geometrically if necessary. Unlike request_*_slots these never fail;
716 // they are used by the (legacy, non-concurrent) triangle-insertion path where
717 // the mesh is being built rather than edited by concurrent operations.
718 void ensure_free_tet_capacity(size_t extra)
719 {
720 const size_t need = m_tet_connectivity.live() + extra;
721 if (m_tet_connectivity.capacity() >= need) return;
722 const size_t newcap = std::max(need, m_tet_connectivity.capacity() * 2 + 1);
723 m_tet_connectivity.resize(newcap);
724 if (p_tet_attrs) p_tet_attrs->resize(newcap);
725 if (p_face_attrs) p_face_attrs->resize(4 * newcap);
726 if (p_edge_attrs) p_edge_attrs->resize(6 * newcap);
727 }
728 void ensure_free_vert_capacity(size_t extra)
729 {
730 const size_t need = m_vertex_connectivity.live() + extra;
731 if (m_vertex_connectivity.capacity() >= need) return;
732 const size_t newcap = std::max(need, m_vertex_connectivity.capacity() * 2 + 1);
733 m_vertex_connectivity.resize(newcap);
734 resize_vertex_mutex(newcap);
735 if (p_vertex_attrs) p_vertex_attrs->resize(newcap);
736 }
737
738private:
739 // capacity to reserve for a live element count
740 size_t reserved_capacity(size_t live_count) const
741 {
742 const size_t floor = 64;
743 double c = std::ceil(m_preallocation_factor * static_cast<double>(live_count));
744 size_t capacity = static_cast<size_t>(c);
745 if (capacity < live_count) capacity = live_count;
746 return capacity < floor ? floor : capacity;
747 }
748
749 // Stores the connectivity of the mesh
750 SlotPool<VertexConnectivity> m_vertex_connectivity;
751 SlotPool<TetrahedronConnectivity> m_tet_connectivity;
752
753 double m_preallocation_factor = 6.0;
754
755 int m_t_empty_slot = 0;
756 int m_v_empty_slot = 0;
757 size_t get_next_empty_slot_t();
758 size_t get_next_empty_slot_v();
759
760 // TODO: subdivide_tets function should not be in the TetMesh API.
761 void subdivide_tets(
762 const std::vector<size_t> t_ids,
763 const std::vector<bool>& mark_surface,
764 const std::map<std::array<size_t, 2>, size_t>& map_edge2vid,
765 std::map<std::array<size_t, 3>, std::vector<std::array<size_t, 5>>>& new_face_vids,
766 const std::vector<size_t>& new_vids,
767 std::vector<size_t>& new_tids,
768 std::vector<size_t>& new_center_vids,
769 std::vector<std::array<size_t, 4>>& center_split_tets);
770 void subdivide_a_tet(
771 size_t t_id,
772 const std::array<int, 6>& new_v_ids,
773 bool mark_surface,
774 std::map<std::array<size_t, 3>, std::vector<std::array<size_t, 5>>>& new_face_vids,
775 std::vector<size_t>& new_tids,
776 std::vector<size_t>& new_center_vids,
777 std::vector<std::array<size_t, 4>>& center_split_tets);
778
779public:
780 virtual bool invariants(const std::vector<Tuple>&) { return true; }
781
782 // ---- OPERATION ACCOUNTING (counting only) ----
783 // Every call into split_edge, collapse_edge, swap_edge, swap_edge_44, swap_edge_56 and
784 // swap_face reports `attempt` on entry and exactly ONE other event on the way out: `committed`,
785 // or the place that refused it. The application's hooks are two of those places (before_hook,
786 // after_hook); why a hook said no is the hook's own to count. So for each kind, attempt equals
787 // the sum of the other events, and a subclass that counts can check both that identity and a
788 // hook's refusals against the reasons the hook counted. Added because the refusals made here,
789 // below every hook, were visible only as a difference: on the deliverable cube at
790 // target_distance_rel 1e-2 / front_conv_rel 1e-4, 521142 of the 542123 edge swaps that
791 // passed every before-hook in turn 5 were refused inside this class with no reason recorded.
792 //
793 // The default does nothing and no site reads a count: the mesh behaves identically with or
794 // without an override.
795 enum class OpKind : int { split, collapse, swap_32, swap_44, swap_56, swap_face, COUNT };
796 enum class OpEvent : int {
797 attempt,
798 before_hook, // the application's *_before said no
799 link_condition, // collapse: the classical link condition (m_collapse_check_link_condition)
800 no_return_tet, // collapse: both probes for the return tuple hit a boundary face
801 duplicate_tet, // a new tet repeats an existing one (collapse manifold check, 4-4, 5-6)
802 topology, // collapse: m_collapse_check_topology found a face missing
803 valence, // edge swap: the edge does not have this swap's number of tets around it
804 boundary, // edge swap: the edge's ring of tets is open; face swap: a boundary face
805 exists, // 3-2: the new face already exists; face swap: the new edge already exists
806 no_case_allowed, // 4-4 / 5-6: every candidate was vetoed by *_accept_case
807 no_better_case, // 4-4 / 5-6: no allowed candidate scored below the current cells
808 out_of_slots, // the preallocated vertex or tet slots ran out
809 after_hook, // the application's *_after said no, so the operation was rolled back
810 invariants, // invariants() said no after the after-hook passed; rolled back
811 committed,
812 COUNT
813 };
814 virtual void op_event(OpKind, OpEvent) const {}
816 bool op_refused(const OpKind k, const OpEvent e) const
817 {
818 op_event(k, e);
819 return false;
820 }
821
822protected:
823 virtual bool triangle_insertion_before(const std::vector<Tuple>& faces) { return true; }
824 virtual bool triangle_insertion_after(const std::vector<std::vector<Tuple>>&) { return true; }
825
827 // Checks if the split should be performed or not (user controlled)
834 virtual bool split_edge_before(const Tuple& t) { return true; } // check edge condition
835 // This function computes the attributes for the added simplices
836 // if it returns false then the operation is undone
843 virtual bool split_edge_after(const Tuple& t) { return true; } // check tet condition
844
846 // Checks if the collapse should be performed or not (user controlled)
854 virtual bool collapse_edge_before(const Tuple& t) { return true; }
855 // If it returns false then the operation is undone (the tuple indexes a vertex and tet that
856 // survived)
863 virtual bool collapse_edge_after(const Tuple& t) { return true; }
871 virtual bool swap_edge_44_before(const Tuple& t) { return true; }
882 virtual double swap_edge_44_energy(
883 const std::vector<std::array<size_t, 4>>& tets,
884 const int op_case)
885 {
886 return -op_case;
887 }
894 virtual bool swap_edge_44_after(const Tuple& t) { return true; }
907 virtual bool swap_edge_44_accept_case(const std::array<size_t, 2>& new_edge) { return true; }
915 virtual bool swap_edge_56_before(const Tuple& t) { return true; }
926 virtual double swap_edge_56_energy(
927 const std::vector<std::array<size_t, 4>>& tets,
928 const int op_case)
929 {
930 return -op_case;
931 }
938 virtual bool swap_edge_56_after(const Tuple& t) { return true; }
951 virtual bool swap_edge_56_accept_case(const std::array<size_t, 3>& new_face) { return true; }
959 virtual bool swap_edge_before(const Tuple& t) { return true; }
966 virtual bool swap_edge_after(const Tuple& t) { return true; }
974 virtual bool swap_face_before(const Tuple& t) { return true; }
981 virtual bool swap_face_after(const Tuple& t) { return true; }
988 virtual bool smooth_before(const Tuple& t) { return true; }
995 virtual bool smooth_after(const Tuple& t) { return true; }
996
1003 virtual bool split_face_before(const Tuple& t) { return true; }
1004
1012 virtual bool split_face_after(const Tuple& t) { return true; }
1013
1020 virtual bool split_tet_before(const Tuple& t) { return true; }
1021
1029 virtual bool split_tet_after(const Tuple& t) { return true; }
1030
1031 // virtual void resize_vertex_mutex(size_t v) {}
1032
1033public:
1040 Tuple tuple_from_edge(size_t tid, int local_eid) const;
1046 Tuple tuple_from_edge(const std::array<size_t, 2>& vids) const;
1047
1054 Tuple tuple_from_face(size_t tid, int local_fid) const;
1055
1061 std::tuple<Tuple, size_t> tuple_from_face(const std::array<size_t, 3>& vids) const;
1069 std::optional<std::tuple<Tuple, size_t>> try_tuple_from_face(
1070 const std::array<size_t, 3>& vids) const;
1071
1078 size_t lowest_common_tet(size_t v0_id, size_t v1_id, size_t v2_id) const;
1079
1086 size_t vertex_valence(const size_t vid) const
1087 {
1088 return m_vertex_connectivity[vid].m_conn_tets.size();
1089 }
1090 std::tuple<Tuple, size_t> tuple_from_face(const simplex::Face& f) const;
1091
1097 Tuple tuple_from_vertex(size_t vid) const;
1098
1104 Tuple tuple_from_tet(size_t tid) const;
1105
1110 Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2, size_t vid3) const;
1111
1112 simplex::Tet simplex_from_tet(const Tuple& t) const;
1113 simplex::Tet simplex_from_tet(const size_t tid) const;
1114 simplex::Face simplex_from_face(const Tuple& t) const;
1115 simplex::Edge simplex_from_edge(const Tuple& t) const;
1116
1117
1121 Tuple switch_vertex(const Tuple& t) const
1122 {
1123 auto loc = t.switch_vertex(*this);
1125 return loc;
1126 }
1130 Tuple switch_edge(const Tuple& t) const
1131 {
1132 auto loc = t.switch_edge(*this);
1134 return loc;
1135 }
1139 Tuple switch_face(const Tuple& t) const
1140 {
1141 auto loc = t.switch_face(*this);
1143 return loc;
1144 }
1148 std::optional<Tuple> switch_tetrahedron(const Tuple& t) const
1149 {
1150 auto loc = t.switch_tetrahedron(*this);
1151 if (loc.has_value()) check_tuple_validity(loc.value());
1152 return loc;
1153 }
1154
1161 std::vector<Tuple> get_one_ring_tets_for_vertex(const Tuple& t) const;
1168 const std::vector<size_t>& get_one_ring_tids_for_vertex(const Tuple& t) const;
1169 const std::vector<size_t>& get_one_ring_tids_for_vertex(const size_t vid) const;
1170
1177 std::vector<Tuple> get_one_ring_vertices_for_vertex(const Tuple& t) const;
1185 std::vector<size_t> get_one_ring_vids_for_vertex(size_t vid, std::vector<size_t>& cache);
1192 std::vector<size_t> get_one_ring_vids_for_vertex(size_t vid) const;
1197 std::vector<size_t> get_one_ring_vids_for_vertex_adj(size_t vid) const;
1202 std::vector<size_t> get_one_ring_vids_for_vertex_adj(size_t vid, std::vector<size_t>& cache);
1203
1210 std::vector<Tuple> get_incident_tets_for_edge(const Tuple& t) const;
1211 std::vector<Tuple> get_incident_tets_for_edge(const size_t vid0, const size_t vid1) const;
1212
1213 std::vector<size_t> get_incident_tids_for_edge(const Tuple& t) const;
1214 std::vector<size_t> get_incident_tids_for_edge(const size_t vid0, const size_t vid1) const;
1215
1222 std::vector<Tuple> get_one_ring_tets_for_edge(const Tuple& t) const;
1223
1230 std::vector<std::array<size_t, 3>> vertex_adjacent_boundary_faces(const Tuple& t) const;
1235 std::array<Tuple, 4> oriented_tet_vertices(const Tuple& t) const;
1240 std::array<size_t, 4> oriented_tet_vids(const Tuple& t) const;
1241 std::array<size_t, 4> oriented_tet_vids(const size_t tid) const;
1248 std::array<Tuple, 3> get_face_vertices(const Tuple& t) const;
1249 std::array<size_t, 3> get_face_vids(const Tuple& t) const;
1250
1258 std::array<Tuple, 6> tet_edges(const Tuple& t) const;
1262 void check_tuple_validity(const Tuple& t) const { t.check_validity(*this); }
1275 void remove_tets_by_ids(const std::vector<size_t>& tids)
1276 {
1277 for (size_t tid : tids) {
1278 m_tet_connectivity[tid].m_is_removed = true;
1279 for (int j = 0; j < 4; j++)
1280 vector_erase(m_vertex_connectivity[m_tet_connectivity[tid][j]].m_conn_tets, tid);
1281 }
1282 for (auto& v : m_vertex_connectivity) {
1283 if (v.m_is_removed) continue;
1284 if (v.m_conn_tets.empty()) v.m_is_removed = true;
1285 }
1286 }
1287 bool m_collapse_check_link_condition = true; // classical link condition
1288 bool m_collapse_check_topology = false; // sanity check
1289 bool m_collapse_check_manifold = true; // manifoldness check after collapse
1290
1291private:
1292 // `ok` is set to false if the operation ran out of preallocated tet slots; in
1293 // that case no connectivity is mutated and the caller must abort the operation.
1294 std::map<size_t, VertexConnectivity> operation_update_connectivity_impl(
1295 std::vector<size_t>& affected_tid,
1296 const std::vector<std::array<size_t, 4>>& new_tet_conn,
1297 bool& ok);
1298 void operation_failure_rollback_imp(
1299 std::map<size_t, VertexConnectivity>& rollback_vert_conn,
1300 const std::vector<size_t>& affected,
1301 const std::vector<size_t>& new_tet_id,
1302 const std::vector<TetrahedronConnectivity>& old_tets);
1303 std::map<size_t, VertexConnectivity> operation_update_connectivity_impl(
1304 const std::vector<size_t>& remove_id,
1305 const std::vector<std::array<size_t, 4>>& new_tet_conn,
1306 std::vector<size_t>& allocate_id,
1307 bool& ok);
1308 static std::vector<TetrahedronConnectivity> record_old_tet_connectivity(
1310 const std::vector<size_t>& tets)
1311 {
1312 std::vector<TetrahedronConnectivity> tet_conn;
1313 for (size_t i : tets) {
1314 tet_conn.push_back(conn[i]);
1315 }
1316 return tet_conn;
1317 }
1318
1319public:
1320 void start_protect_attributes()
1321 {
1322 if (p_vertex_attrs) {
1323 p_vertex_attrs->begin_protect();
1324 }
1325 if (p_edge_attrs) {
1326 p_edge_attrs->begin_protect();
1327 }
1328 if (p_face_attrs) {
1329 p_face_attrs->begin_protect();
1330 }
1331 if (p_tet_attrs) {
1332 p_tet_attrs->begin_protect();
1333 }
1334 }
1335
1336 void release_protect_attributes()
1337 {
1338 if (p_vertex_attrs) {
1339 p_vertex_attrs->end_protect();
1340 }
1341 if (p_edge_attrs) {
1342 p_edge_attrs->end_protect();
1343 }
1344 if (p_face_attrs) {
1345 p_face_attrs->end_protect();
1346 }
1347 if (p_tet_attrs) {
1348 p_tet_attrs->end_protect();
1349 }
1350 }
1351
1352 void rollback_protected_attributes()
1353 {
1354 if (p_vertex_attrs) {
1355 p_vertex_attrs->rollback();
1356 }
1357 if (p_edge_attrs) {
1358 p_edge_attrs->rollback();
1359 }
1360 if (p_face_attrs) {
1361 p_face_attrs->rollback();
1362 }
1363 if (p_tet_attrs) {
1364 p_tet_attrs->rollback();
1365 }
1366 }
1367
1368public:
1372
1373private:
1374 std::vector<VertexMutex> m_vertex_mutex;
1375
1376 bool try_set_vertex_mutex(const Tuple& v, int threadid)
1377 {
1378 bool got = m_vertex_mutex[v.vid(*this)].trylock();
1379 if (got) m_vertex_mutex[v.vid(*this)].set_owner(threadid);
1380 return got;
1381 }
1382 bool try_set_vertex_mutex(size_t vid, int threadid)
1383 {
1384 bool got = m_vertex_mutex[vid].trylock();
1385 if (got) m_vertex_mutex[vid].set_owner(threadid);
1386 return got;
1387 }
1388
1389 void unlock_vertex_mutex(const Tuple& v) { m_vertex_mutex[v.vid(*this)].unlock(); }
1390 void unlock_vertex_mutex(size_t vid) { m_vertex_mutex[vid].unlock(); }
1391
1399 {
1400 std::vector<uint32_t> stamp;
1401 uint32_t epoch = 0;
1402 std::vector<size_t> frontier;
1403 std::vector<size_t> next;
1404 std::vector<size_t> one_ring;
1405 };
1407
1409 bool lock_vertex_ball(const size_t* seeds, size_t n_seeds, int threadid, int n, size_t mark);
1410
1411protected:
1412 void resize_vertex_mutex(size_t v)
1413 {
1414 if (m_vertex_mutex.size() < v) m_vertex_mutex.resize(v);
1415 }
1416
1417public:
1420
1421 // void init(size_t n_vertices, const std::vector<std::array<size_t, 4>>& tets);
1422 int release_vertex_mutex_in_stack();
1430 int release_vertex_mutex_to(size_t mark);
1431
1448 bool try_set_vertex_mutex_n_ring(const Tuple& v, int threadid, int n);
1449 bool try_set_vertex_mutex_n_ring(size_t vid, int threadid, int n);
1453 bool try_set_edge_mutex_n_ring(const Tuple& e, int threadid, int n);
1457 bool try_set_face_mutex_n_ring(size_t v1, size_t v2, size_t v3, int threadid, int n);
1458
1499 bool try_set_vertex_mutex_two_ring(const Tuple& v, int threadid);
1501 bool try_set_vertex_mutex_two_ring_vid(const Tuple& v, int threadid);
1503 bool try_set_vertex_mutex_two_ring_vid(size_t v, int threadid);
1505 bool try_set_edge_mutex_two_ring(const Tuple& e, int threadid = 0);
1507 bool try_set_face_mutex_two_ring(const Tuple& f, int threadid = 0);
1510 const Tuple& v1,
1511 const Tuple& v2,
1512 const Tuple& v3,
1513 int threadid = 0);
1515 bool try_set_face_mutex_two_ring(size_t v1, size_t v2, size_t v3, int threadid = 0);
1517 bool try_set_vertex_mutex_one_ring(const Tuple& v, int threadid = 0);
1520public:
1525 void for_each_edge(const std::function<void(const TetMesh::Tuple&)>&);
1530 void for_each_vertex(const std::function<void(const TetMesh::Tuple&)>&);
1535 void for_each_tetra(const std::function<void(const TetMesh::Tuple&)>&);
1536 int NUM_THREADS = 0;
1537
1538public:
1539 // substructure functionality
1540
1546 virtual bool vertex_is_on_surface(const size_t vid) const { return false; }
1547
1553 virtual bool face_is_on_surface(const size_t fid) const { return false; }
1554
1561
1567 simplex::SimplexCollection get_surface_faces_for_edge(const std::array<size_t, 2>& vids) const;
1573 size_t get_num_surface_faces_for_edge(const std::array<size_t, 2>& vids) const;
1574
1575
1584 size_t compute_vertex_order(const size_t vid) const;
1585
1600 virtual size_t get_order_of_vertex(const size_t vid) const { return compute_vertex_order(vid); }
1601
1612 size_t get_order_of_edge(const std::array<size_t, 2>& vids) const;
1613
1627 bool substructure_link_condition(const Tuple& e_tuple) const;
1628};
1629
1630
1631} // namespace wmtk
Preallocated storage plus the atomic counter that hands slots out of it.
Definition SlotPool.hpp:38
Definition TetMesh.h:202
size_t hash
Definition TetMesh.h:290
a Tuple refers to a global vid and a global tet id, and a local edge id and local face id
Definition TetMesh.h:50
Tuple switch_face(const TetMesh &m) const
Definition TetMeshTuple.cpp:284
bool is_valid(const TetMesh &m) const
Definition TetMeshTuple.cpp:57
bool is_boundary_face(const TetMesh &m) const
Definition TetMeshTuple.cpp:17
void print_info() const
prints the tuple
Definition TetMeshTuple.cpp:68
std::optional< Tuple > switch_tetrahedron(const TetMesh &m) const
Definition TetMeshTuple.cpp:304
size_t eid(const TetMesh &m) const
Definition TetMeshTuple.cpp:111
Tuple switch_edge(const TetMesh &m) const
Definition TetMeshTuple.cpp:269
Tuple switch_vertex(const TetMesh &m) const
Definition TetMeshTuple.cpp:255
size_t tid(const TetMesh &m) const
Definition TetMeshTuple.cpp:250
size_t vid(const TetMesh &m) const
Definition TetMeshTuple.cpp:106
size_t fid(const TetMesh &m) const
Definition TetMeshTuple.cpp:184
bool is_boundary_edge(const TetMesh &m) const
Definition TetMeshTuple.cpp:34
void check_validity(const TetMesh &m) const
check Tuple validity and connectivity validity
Definition TetMeshTuple.cpp:389
Definition TetMesh.h:248
Definition TetMesh.h:25
size_t compute_vertex_order(const size_t vid) const
Compute the vertex order for a single vertex.
Definition TetMeshSubstructure.cpp:117
virtual bool swap_edge_44_after(const Tuple &t)
User specified modifications and desideratas for after a 4-4 edge swap.
Definition TetMesh.h:894
std::vector< Tuple > get_one_ring_vertices_for_vertex(const Tuple &t) const
Get the one ring vertices for a vertex.
Definition TetMesh.cpp:752
size_t vertex_valence(const size_t vid) const
Number of tets incident to a vertex, in O(1).
Definition TetMesh.h:1086
virtual bool swap_edge_44_before(const Tuple &t)
User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity.
Definition TetMesh.h:871
virtual bool split_tet_before(const Tuple &t)
User specified preparations and desideratas for a tet split before changing the connectivity.
Definition TetMesh.h:1020
size_t lowest_common_tet(size_t v0_id, size_t v1_id, size_t v2_id) const
Lowest tet id incident to all three vertices, or size_t(-1) if there is none.
Definition TetMesh.cpp:372
bool try_set_face_mutex_n_ring(size_t v1, size_t v2, size_t v3, int threadid, int n)
try_set_vertex_mutex_n_ring seeded from the three vertices of a face.
Definition TetMesh.cpp:1113
size_t tet_size() const
get the number of unremoved tets
Definition TetMesh.h:401
virtual size_t get_order_of_vertex(const size_t vid) const
Get the order of a vertex.
Definition TetMesh.h:1600
std::vector< Tuple > get_faces() const
Definition TetMesh.cpp:200
std::array< Tuple, 6 > tet_edges(const Tuple &t) const
get the 6 edges of a tet represented by Tuples
Definition TetMesh.cpp:715
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideratas for after smoothing a vertex.
Definition TetMesh.h:995
void consolidate_mesh()
cleans up the deleted vertices or tetrahedra, fixes the corresponding indices, and reset the version ...
Definition TetMesh.cpp:880
size_t vert_capacity() const
get the current largest global vid
Definition TetMesh.h:362
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas for after an edge collapse.
Definition TetMesh.h:863
void set_preallocation_factor(double factor)
Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so op...
Definition TetMesh.h:669
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideratas for after a 3-2 edge swap.
Definition TetMesh.h:966
size_t get_num_surface_faces_for_edge(const std::array< size_t, 2 > &vids) const
Get the number of surface faces incident to the edge.
Definition TetMeshSubstructure.cpp:82
bool smooth_vertex(const Tuple &t)
Definition TetMesh.cpp:328
virtual bool face_is_on_surface(const size_t fid) const
Is a face part of the substructure.
Definition TetMesh.h:1553
bool insert_point(const Tuple &t, std::vector< Tuple > &new_tets)
Insert a point into a tetmesh inside a tet. In general position, this split a tet into 4....
Definition TetMeshTriangleInsertionConn.cpp:415
bool split_edge(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshEdgeSplittingConn.cpp:6
Tuple switch_face(const Tuple &t) const
wrapper function from Tuple::switch_face
Definition TetMesh.h:1139
std::array< Tuple, 4 > oriented_tet_vertices(const Tuple &t) const
Definition TetMesh.cpp:675
void for_each_vertex(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each vertex
Definition TetMesh.cpp:1530
bool try_set_vertex_mutex_one_ring(const Tuple &v, int threadid=0)
Lock v and its one-ring. Complete, unlike the two-ring family.
Definition TetMesh.cpp:1442
std::array< size_t, 4 > oriented_tet_vids(const Tuple &t) const
Definition TetMesh.cpp:687
bool collapse_edge_check_topology(const std::vector< size_t > &new_tet_id)
Check topology after collapse connectivity change. This is a sanity check and should not be necessary...
Definition TetMeshEdgeCollapsingConn.cpp:427
bool try_set_vertex_mutex_two_ring_vid(const Tuple &v, int threadid)
try_set_vertex_mutex_two_ring reached through vids rather than Tuples.
Definition TetMesh.cpp:1147
Tuple tuple_from_tet(size_t tid) const
get a Tuple from global tetra index
Definition TetMesh.cpp:605
void subdivide_tets(const std::vector< size_t > t_ids, const std::vector< bool > &mark_surface, const std::map< std::array< size_t, 2 >, size_t > &map_edge2vid, std::map< std::array< size_t, 3 >, std::vector< std::array< size_t, 5 > > > &new_face_vids, const std::vector< size_t > &new_vids, std::vector< size_t > &new_tids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Definition TetMeshTriangleInsertionConn.cpp:142
void init(size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets)
Definition TetMesh.cpp:44
std::optional< std::tuple< Tuple, size_t > > try_tuple_from_face(const std::array< size_t, 3 > &vids) const
tuple_from_face for callers where a missing face is an answer, not a bug.
Definition TetMesh.cpp:430
void subdivide_a_tet(size_t t_id, const std::array< int, 6 > &new_v_ids, bool mark_surface, std::map< std::array< size_t, 3 >, std::vector< std::array< size_t, 5 > > > &new_face_vids, std::vector< size_t > &new_tids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Definition TetMeshTriangleInsertionConn.cpp:235
virtual bool swap_edge_56_before(const Tuple &t)
User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity.
Definition TetMesh.h:915
std::vector< Tuple > get_incident_tets_for_edge(const Tuple &t) const
Get the incident tets for edge.
Definition TetMesh.cpp:824
virtual bool split_face_after(const Tuple &t)
Compute the attributes for the added simplices.
Definition TetMesh.h:1012
bool swap_edge_56(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshSwapMeshConnectivity.cpp:749
bool split_face(const Tuple &t, std::vector< Tuple > &new_tets)
Split a face in 3 faces.
Definition TetMeshFaceSplittingConn.cpp:6
bool link_condition(const Tuple &t)
Definition TetMeshEdgeCollapsingConn.cpp:318
std::vector< Tuple > get_one_ring_tets_for_edge(const Tuple &t) const
Get the one ring tets for edge.
Definition TetMesh.cpp:860
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split before changing the connectivity.
Definition TetMesh.h:1003
virtual double swap_edge_44_energy(const std::vector< std::array< size_t, 4 > > &tets, const int op_case)
User specified energy to decide which of the 4 possible orientations should be chosen.
Definition TetMesh.h:882
Tuple tuple_from_vertex(size_t vid) const
get a Tuple from global vertex index
Definition TetMesh.cpp:592
simplex::SimplexCollection get_surface_faces_for_vertex(const size_t vid) const
Get all faces on the surface that are incident to vid.
Definition TetMeshSubstructure.cpp:7
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 TetMesh.cpp:1097
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 TetMesh.cpp:1007
virtual void for_each_face(const std::function< void(const TetMesh::Tuple &)> &)
looping through all the unique edges and perform the given function
Definition TetMesh.cpp:186
std::vector< size_t > get_one_ring_vids_for_vertex(size_t vid, std::vector< size_t > &cache)
Get the one ring vids for vertex.
Definition TetMesh.cpp:800
std::optional< Tuple > switch_tetrahedron(const Tuple &t) const
wrapper function from Tuple::switch_tetrahedron
Definition TetMesh.h:1148
bool op_refused(const OpKind k, const OpEvent e) const
op_event() for a refusal, returning false so a site reads return op_refused(...).
Definition TetMesh.h:816
size_t get_order_of_edge(const std::array< size_t, 2 > &vids) const
Compute the order of an edge.
Definition TetMeshSubstructure.cpp:203
const std::vector< size_t > & get_one_ring_tids_for_vertex(const Tuple &t) const
Get the one ring tids for vertex.
Definition TetMesh.cpp:728
std::vector< Tuple > get_tets() const
Definition TetMesh.cpp:295
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for smoothing a vertex.
Definition TetMesh.h:988
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split before changing the connectivity.
Definition TetMesh.h:834
std::vector< size_t > get_one_ring_vids_for_vertex_adj(size_t vid) const
Duplicate of the function TetMesh::get_one_ring_vids_for_vertex.
Definition TetMesh.cpp:786
virtual bool swap_edge_before(const Tuple &t)
User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity.
Definition TetMesh.h:959
void triangle_insertion(const std::vector< Tuple > &intersected_tets, const std::vector< Tuple > &intersected_edges, std::vector< size_t > &new_edge_vids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Insert a triangle into a tetmesh, with known intersection information.
Definition TetMeshTriangleInsertionConn.cpp:11
std::map< size_t, VertexConnectivity > operation_update_connectivity_impl(std::vector< size_t > &affected_tid, const std::vector< std::array< size_t, 4 > > &new_tet_conn, bool &ok)
Definition TetMeshSwapMeshConnectivity.cpp:43
bool check_mesh_connectivity_validity() const
checks the validity of the connectivity of the mesh. Including the validity of each Tuple
Definition TetMesh.cpp:221
bool split_tet(const Tuple &t, std::vector< Tuple > &new_tets)
Split a tet in 4 tets.
Definition TetMeshTetSplittingConn.cpp:6
Tuple tuple_from_edge(size_t tid, int local_eid) const
get a Tuple from global tetra index and local edge index (from 0-5).
Definition TetMesh.cpp:342
size_t vertex_size() const
get the number of unremoved verticies
Definition TetMesh.h:389
Tuple switch_vertex(const Tuple &t) const
wrapper function from Tuple::switch_vertex
Definition TetMesh.h:1121
simplex::SimplexCollection get_surface_faces_for_edge(const std::array< size_t, 2 > &vids) const
Get all faces on the surface that are incident to the edge.
Definition TetMeshSubstructure.cpp:42
bool substructure_link_condition(const Tuple &e_tuple) const
Link condition that also considers substructures.
Definition TetMeshSubstructure.cpp:218
virtual bool swap_face_before(const Tuple &t)
User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry.
Definition TetMesh.h:974
bool try_set_edge_mutex_two_ring(const Tuple &e, int threadid=0)
Lock the edge's one-ring and, partially, its two-ring. See the note above.
Definition TetMesh.cpp:1196
virtual bool vertex_is_on_surface(const size_t vid) const
Is a vertex part of the substructure.
Definition TetMesh.h:1546
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_tets)
3-2 edge swap
Definition TetMeshSwapMeshConnectivity.cpp:135
Tuple switch_edge(const Tuple &t) const
wrapper function from Tuple::switch_edge
Definition TetMesh.h:1130
std::vector< Tuple > get_edges() const
Definition TetMesh.cpp:146
virtual bool split_tet_after(const Tuple &t)
Compute the attributes for the added simplices.
Definition TetMesh.h:1029
void for_each_edge(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each edge
Definition TetMesh.cpp:1471
int release_vertex_mutex_to(size_t mark)
Release the mutexes taken since the release stack held mark entries.
Definition TetMesh.cpp:990
void check_tuple_validity(const Tuple &t) const
Definition TetMesh.h:1262
void collapse_edge_rollback(size_t &v1_id, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
Definition TetMeshEdgeCollapsingConn.cpp:446
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 TetMesh.cpp:1125
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 TetMesh.cpp:1092
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshEdgeCollapsingConn.cpp:263
bool try_set_face_mutex_two_ring(const Tuple &f, int threadid=0)
Lock the face's one-ring and, partially, its two-ring. See the note above.
Definition TetMesh.cpp:1242
Tuple tuple_from_face(size_t tid, int local_fid) const
get a Tuple from global tetra index and local face index (from 0-3).
Definition TetMesh.cpp:352
virtual bool split_edge_after(const Tuple &t)
This function computes the attributes for the added simplices. User specified modifications and desid...
Definition TetMesh.h:843
static constexpr std::array< std::array< int, 2 >, 6 > m_local_edges
local edges within a tet
Definition TetMesh.h:31
std::array< Tuple, 3 > get_face_vertices(const Tuple &t) const
Get the 3 vertices of a face represented by Tuple.
Definition TetMesh.cpp:697
virtual bool swap_edge_56_after(const Tuple &t)
User specified modifications and desideratas for after a 5-6 edge swap.
Definition TetMesh.h:938
virtual bool collapse_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge collapse before changing the connectivity.
Definition TetMesh.h:854
std::vector< Tuple > get_vertices() const
Definition TetMesh.cpp:311
bool collapse_edge_conn(const Tuple &loc0, size_t &v1_id, Tuple &new_loc, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids_copy, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
Definition TetMeshEdgeCollapsingConn.cpp:457
size_t tet_capacity() const
get the current largest global tid
Definition TetMesh.h:368
std::vector< Tuple > get_one_ring_tets_for_vertex(const Tuple &t) const
Get the one ring tets for a vertex.
Definition TetMesh.cpp:741
void for_each_tetra(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each tet
Definition TetMesh.cpp:1504
bool swap_edge_44(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshSwapMeshConnectivity.cpp:508
virtual bool swap_edge_56_accept_case(const std::array< size_t, 3 > &new_face)
Filter which of the 5-6 orientations may be chosen.
Definition TetMesh.h:951
virtual bool swap_edge_44_accept_case(const std::array< size_t, 2 > &new_edge)
Filter which of the 4-4 orientations may be chosen.
Definition TetMesh.h:907
virtual double swap_edge_56_energy(const std::vector< std::array< size_t, 4 > > &tets, const int op_case)
User specified energy to decide which of the 5 possible orientations should be chosen.
Definition TetMesh.h:926
bool swap_face(const Tuple &t, std::vector< Tuple > &new_tets)
2-3 face swap
Definition TetMeshSwapMeshConnectivity.cpp:257
void remove_tets_by_ids(const std::vector< size_t > &tids)
remove the tetrahedrons in the mesh that have given tet ids
Definition TetMesh.h:1275
Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2, size_t vid3) const
Get a Tuple from global vertex IDs.
Definition TetMesh.cpp:616
std::vector< std::array< size_t, 3 > > vertex_adjacent_boundary_faces(const Tuple &t) const
Definition TetMesh.cpp:965
virtual bool swap_face_after(const Tuple &t)
User specified modifications and desideratas for after a 2-3 face swap.
Definition TetMesh.h:981
Definition Simplex.hpp:46
Definition Simplex.hpp:57
Definition SimplexCollection.hpp:9
Definition Simplex.hpp:71
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 TetMesh.h:1399