3#include <wmtk/utils/VectorUtils.h>
4#include <wmtk/AttributeCollection.hpp>
5#include <wmtk/Types.hpp>
6#include <wmtk/simplex/RawSimplex.hpp>
7#include <wmtk/simplex/RawSimplexCollection.hpp>
8#include <wmtk/utils/Logger.hpp>
11#include <wmtk/utils/DisableWarnings.hpp>
12#include <tbb/concurrent_vector.h>
13#include <tbb/spin_mutex.h>
14#include <wmtk/utils/EnableWarnings.hpp>
39 void update_hash(
const TriMesh& m);
72 inline size_t vid(
const TriMesh&)
const {
return m_vid; }
80 inline size_t fid(
const TriMesh&)
const {
return m_fid; }
125 std::vector<Tuple> switch_faces(
const TriMesh& m)
const;
143 friend bool operator<(
const Tuple& a,
const Tuple& t)
146 std::tie(a.m_vid, a.m_eid, a.m_fid, a.m_hash) <
147 std::tie(t.m_vid, t.m_eid, t.m_fid, t.m_hash));
162 const Tuple& tuple()
const {
return m_tuple; }
163 const TriMesh& mesh()
const {
return m_mesh; }
171 bool is_valid()
const {
return m_tuple.
is_valid(m_mesh); }
172 size_t vid()
const {
return m_tuple.
vid(m_mesh); }
173 size_t eid()
const {
return m_tuple.
eid(m_mesh); }
174 size_t fid()
const {
return m_tuple.
fid(m_mesh); }
177 std::optional<SmartTuple> switch_face()
const
179 const std::optional<Tuple> t = m_tuple.
switch_face(m_mesh);
181 return std::optional<SmartTuple>({m_mesh, t.value()});
206 inline size_t& operator[](
const size_t index)
212 inline size_t operator[](
const size_t index)
const
243 inline size_t& operator[](
size_t index)
249 inline size_t operator[](
size_t index)
const
259 inline int find(
size_t v_id)
const
261 for (
int j = 0; j < 3; j++) {
271 virtual ~TriMesh() {}
278 void init(
size_t n_vertices,
const std::vector<std::array<size_t, 3>>& tris);
285 void init(
const MatrixXi& F);
324 Tuple tuple_from_vids(
size_t vid0,
size_t vid1,
size_t vid2)
const;
326 simplex::Vertex simplex_from_vertex(
const Tuple& t)
const;
327 simplex::Edge simplex_from_edge(
const Tuple& t)
const;
328 simplex::Face simplex_from_face(
const Tuple& t)
const;
329 simplex::Face simplex_from_face(
const size_t fid)
const;
331 Tuple tuple_from_simplex(
const simplex::Face& s)
const;
334 simplex::RawSimplexCollection simplex_incident_triangles(
const simplex::Vertex& v)
const;
335 simplex::RawSimplexCollection simplex_incident_triangles(
const simplex::Edge& e)
const;
336 simplex::RawSimplexCollection simplex_link_vertices(
const simplex::Vertex& v)
const;
337 simplex::RawSimplexCollection simplex_link_vertices(
const simplex::Edge& e)
const;
338 simplex::RawSimplexCollection simplex_link_edges(
const simplex::Vertex& v)
const;
340 template <
typename T>
341 using vector = tbb::concurrent_vector<T>;
344 AbstractAttributeContainer* p_vertex_attrs =
nullptr;
345 AbstractAttributeContainer* p_edge_attrs =
nullptr;
346 AbstractAttributeContainer* p_face_attrs =
nullptr;
349 vector<VertexConnectivity> m_vertex_connectivity;
350 vector<TriangleConnectivity> m_tri_connectivity;
351 std::atomic_long current_vert_size;
352 std::atomic_long current_tri_size;
353 tbb::spin_mutex vertex_connectivity_lock;
354 tbb::spin_mutex tri_connectivity_lock;
355 bool vertex_connectivity_synchronizing_flag =
false;
356 bool tri_connectivity_synchronizing_flag =
false;
357 int MAX_THREADS = 128;
377 virtual bool invariants(
const std::vector<Tuple>&) {
return true; }
528 bool split_edge(
const Tuple& t, std::vector<Tuple>& new_t);
539 virtual bool collapse_edge(
const Tuple& t, std::vector<Tuple>& new_t);
546 std::vector<Tuple>& new_tris,
549 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
550 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
551 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
552 std::vector<size_t>& n12_intersect_fids);
560 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
561 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
562 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
563 std::vector<size_t>& n12_intersect_fids);
575 bool swap_edge(
const Tuple& t, std::vector<Tuple>& new_t);
594 bool split_face(
const Tuple& t, std::vector<Tuple>& new_t);
604 return m_vertex_connectivity[t.vid(*
this)].m_conn_tris.size();
614 const std::vector<size_t>& get_one_ring_fids_for_vertex(
const Tuple& t)
const;
615 const std::vector<size_t>& get_one_ring_fids_for_vertex(
const size_t vid)
const;
624 std::vector<size_t> get_incident_fids_for_edge(
const Tuple& t)
const;
625 std::vector<size_t> get_incident_fids_for_edge(
const size_t vid0,
const size_t vid1)
const;
656 std::array<Tuple, 2> get_edge_vertices(
const Tuple& t)
const;
657 std::array<size_t, 2> get_edge_vids(
const Tuple& t)
const;
668 if (fid >= m_tri_connectivity.size() || m_tri_connectivity[fid].m_is_removed)
670 auto vid = m_tri_connectivity[fid][0];
671 return Tuple(vid, 1, fid, *
this);
680 auto fid = m_vertex_connectivity[vid][0];
681 auto eid = m_tri_connectivity[fid].find((
int)vid);
682 return Tuple(vid, (eid + 1) % 3, fid, *
this);
692 auto vid = m_tri_connectivity[fid][(local_eid + 1) % 3];
693 return Tuple(vid, local_eid, fid, *
this);
696 std::tuple<Tuple, size_t>
tuple_from_edge(
const std::array<size_t, 2>& vids)
const;
705 if (p_vertex_attrs) p_vertex_attrs->begin_protect();
706 if (p_edge_attrs) p_edge_attrs->begin_protect();
707 if (p_face_attrs) p_face_attrs->begin_protect();
715 if (p_vertex_attrs) p_vertex_attrs->end_protect();
716 if (p_edge_attrs) p_edge_attrs->end_protect();
717 if (p_face_attrs) p_face_attrs->end_protect();
725 if (p_vertex_attrs) p_vertex_attrs->rollback();
726 if (p_edge_attrs) p_edge_attrs->rollback();
727 if (p_face_attrs) p_face_attrs->rollback();
735 tbb::spin_mutex mutex;
736 int owner = std::numeric_limits<int>::max();
739 bool trylock() {
return mutex.try_lock(); }
747 int get_owner() {
return owner; }
749 void set_owner(
int n) { owner = n; }
751 void reset_owner() { owner = std::numeric_limits<int>::max(); }
755 tbb::concurrent_vector<VertexMutex> m_vertex_mutex;
757 bool try_set_vertex_mutex(
const Tuple& v,
int threadid)
759 bool got = m_vertex_mutex[v.vid(*
this)].trylock();
760 if (got) m_vertex_mutex[v.vid(*
this)].set_owner(threadid);
763 bool try_set_vertex_mutex(
size_t vid,
int threadid)
765 bool got = m_vertex_mutex[vid].trylock();
766 if (got) m_vertex_mutex[vid].set_owner(threadid);
770 void unlock_vertex_mutex(
const Tuple& v) { m_vertex_mutex[v.vid(*
this)].unlock(); }
771 void unlock_vertex_mutex(
size_t vid) { m_vertex_mutex[vid].unlock(); }
774 void resize_mutex(
size_t v) { m_vertex_mutex.grow_to_at_least(v); }
777 tbb::enumerable_thread_specific<std::vector<size_t>> mutex_release_stack;
779 int release_vertex_mutex_in_stack();
818 void for_each_face(
const std::function<
void(
const Tuple&)>&);
823 void for_each_edge(
const std::function<
void(
const Tuple&)>&);
bool m_is_removed
is the triangle removed
Definition TriMesh.h:235
int find(size_t v_id) const
Definition TriMesh.h:259
size_t hash
the hash is changed every time there is an operation that influences the triangle
Definition TriMesh.h:241
std::array< size_t, 3 > m_indices
incident vertices of a given triangle
Definition TriMesh.h:230
size_t eid(const TriMesh &m) const
Definition TriMesh.cpp:27
size_t fid(const TriMesh &) const
Definition TriMesh.h:80
Tuple switch_vertex(const TriMesh &m) const
Definition TriMesh.cpp:78
bool is_valid(const TriMesh &m) const
check if a Tuple is valid
Definition TriMesh.cpp:233
Tuple switch_edge(const TriMesh &m) const
Definition TriMesh.cpp:107
std::array< Tuple, 3 > oriented_tri_vertices(const TriMesh &m) const
std::optional< Tuple > switch_face(const TriMesh &m) const
Definition TriMesh.cpp:134
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
std::vector< size_t > m_conn_tris
incident triangles of a given vertex
Definition TriMesh.h:199
bool m_is_removed
is the vertex removed
Definition TriMesh.h:204
virtual bool split_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge split.
Definition TriMesh.h:389
std::array< size_t, 3 > oriented_tri_vids(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1296
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:1159
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:684
void release_protect_attributes()
End the modification phase.
Definition TriMesh.h:713
size_t get_valence_for_vertex(const Tuple &t) const
Count the number of the one ring tris for a vertex.
Definition TriMesh.h:602
std::vector< Tuple > get_vertices() const
Definition TriMesh.cpp:1399
size_t get_next_empty_slot_t()
Get the next avaiblie global index for the triangle.
Definition TriMesh.cpp:1608
size_t get_next_empty_slot_v()
Get the next avaiblie global index for the vertex.
Definition TriMesh.cpp:1635
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:721
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:1658
bool try_set_face_mutex_one_ring(const Tuple &f, int threadid)
try lock the one-ring neighboring triangles' incident vertices.
Definition TriMesh.cpp:1893
void for_each_vertex(const std::function< void(const Tuple &)> &)
perform the given function for each vertex
Definition TriMesh.cpp:1943
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideras after an edge smooth.
Definition TriMesh.h:436
virtual bool invariants(const std::vector< Tuple > &)
User specified invariants that can't be violated.
Definition TriMesh.h:377
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge collapse.
Definition TriMesh.h:408
Tuple tuple_from_edge(size_t fid, size_t local_eid) const
Definition TriMesh.h:690
Tuple switch_edge(const Tuple &t) const
a duplicate of Tuple::switch_edge funciton
Definition TriMesh.h:477
std::vector< Tuple > get_one_ring_tris_for_vertex(const Tuple &t) const
Get the one ring tris for a vertex.
Definition TriMesh.cpp:1186
virtual bool split_face_after(const Tuple &t)
User specified modifications and desideratas after a face split.
Definition TriMesh.h:449
bool split_face(const Tuple &t, std::vector< Tuple > &new_t)
Split a face in 3 faces.
Definition TriMesh.cpp:983
void rollback_protected_attributes()
rollback the attributes that are modified if any condition failed
Definition TriMesh.h:723
bool split_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:312
bool try_set_vertex_mutex_one_ring(const Tuple &v, int threadid)
get the lock for one ring neighboring triangles' incident vertices
Definition TriMesh.cpp:1868
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideras after an edge swap.
Definition TriMesh.h:414
bool try_set_vertex_mutex_two_ring(const Tuple &v, int threadid)
try lock the two-ring neighboring triangles' incident vertices
Definition TriMesh.cpp:1785
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:891
Tuple tuple_from_tri(size_t fid) const
Definition TriMesh.h:666
void init(size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris)
Definition TriMesh.cpp:1359
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:463
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:1211
std::vector< Tuple > get_faces() const
Definition TriMesh.cpp:1431
bool check_mesh_connectivity_validity() const
verify the connectivity validity of the mesh
Definition TriMesh.cpp:271
Tuple tuple_from_edge(size_t vid1, size_t vid2, size_t fid) const
Definition TriMesh.cpp:1463
void consolidate_mesh()
removing the elements that are removed
Definition TriMesh.cpp:1094
bool try_set_edge_mutex_two_ring(const Tuple &e, int threadid)
try lock the two-ring neighboring triangles' incident vertices for the two ends of an edge
Definition TriMesh.cpp:1810
std::array< Tuple, 3 > oriented_tri_vertices(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1283
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for an edge smooth.
Definition TriMesh.h:430
size_t tri_capacity() const
get the current largest global fid
Definition TriMesh.h:457
void start_protect_attributes()
Start the phase where the attributes that will be modified can be recorded.
Definition TriMesh.h:703
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split.
Definition TriMesh.h:443
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split.
Definition TriMesh.h:383
std::optional< Tuple > switch_face(const Tuple &t) const
a duplicate of Tuple::switch_face funciton
Definition TriMesh.h:482
bool is_boundary_edge(const TriMesh::Tuple &t) const
check if edge that's represented by a Tuple is at the boundary of the mesh
Definition TriMesh.h:505
void for_each_edge(const std::function< void(const Tuple &)> &)
perform the given function for each edge
Definition TriMesh.cpp:1923
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:678
bool check_link_condition(const Tuple &t) const
prerequisite for collapse
Definition TriMesh.cpp:1679
bool smooth_vertex(const Tuple &t)
Definition TriMesh.cpp:971
std::vector< Tuple > get_edges() const
Definition TriMesh.cpp:1447
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:398
Tuple switch_vertex(const Tuple &t) const
a duplicate of Tuple::switch_vertex funciton
Definition TriMesh.h:473
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_t)
Definition TriMesh.cpp:618
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:512
bool check_edge_manifold() const
verify the edge manifoldness of the mesh
Definition TriMesh.cpp:293
void for_each_face(const std::function< void(const Tuple &)> &)
perform the given function for each face
Definition TriMesh.cpp:1959