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;
330 Tuple tuple_from_simplex(
const simplex::Face& s)
const;
333 simplex::RawSimplexCollection simplex_incident_triangles(
const simplex::Vertex& v)
const;
334 simplex::RawSimplexCollection simplex_incident_triangles(
const simplex::Edge& e)
const;
335 simplex::RawSimplexCollection simplex_link_vertices(
const simplex::Vertex& v)
const;
336 simplex::RawSimplexCollection simplex_link_vertices(
const simplex::Edge& e)
const;
337 simplex::RawSimplexCollection simplex_link_edges(
const simplex::Vertex& v)
const;
339 template <
typename T>
340 using vector = tbb::concurrent_vector<T>;
343 AbstractAttributeContainer* p_vertex_attrs =
nullptr;
344 AbstractAttributeContainer* p_edge_attrs =
nullptr;
345 AbstractAttributeContainer* p_face_attrs =
nullptr;
348 vector<VertexConnectivity> m_vertex_connectivity;
349 vector<TriangleConnectivity> m_tri_connectivity;
350 std::atomic_long current_vert_size;
351 std::atomic_long current_tri_size;
352 tbb::spin_mutex vertex_connectivity_lock;
353 tbb::spin_mutex tri_connectivity_lock;
354 bool vertex_connectivity_synchronizing_flag =
false;
355 bool tri_connectivity_synchronizing_flag =
false;
356 int MAX_THREADS = 128;
376 virtual bool invariants(
const std::vector<Tuple>&) {
return true; }
527 bool split_edge(
const Tuple& t, std::vector<Tuple>& new_t);
538 virtual bool collapse_edge(
const Tuple& t, std::vector<Tuple>& new_t);
545 std::vector<Tuple>& new_tris,
548 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
549 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
550 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
551 std::vector<size_t>& n12_intersect_fids);
559 std::vector<std::pair<size_t, TriangleConnectivity>>& old_tris,
560 std::vector<std::pair<size_t, VertexConnectivity>>& old_vertices,
561 std::vector<std::pair<size_t, size_t>>& same_edge_vid_fid,
562 std::vector<size_t>& n12_intersect_fids);
574 bool swap_edge(
const Tuple& t, std::vector<Tuple>& new_t);
593 bool split_face(
const Tuple& t, std::vector<Tuple>& new_t);
603 return m_vertex_connectivity[t.vid(*
this)].m_conn_tris.size();
658 if (fid >= m_tri_connectivity.size() || m_tri_connectivity[fid].m_is_removed)
660 auto vid = m_tri_connectivity[fid][0];
661 return Tuple(vid, 1, fid, *
this);
670 auto fid = m_vertex_connectivity[vid][0];
671 auto eid = m_tri_connectivity[fid].find((
int)vid);
672 return Tuple(vid, (eid + 1) % 3, fid, *
this);
682 auto vid = m_tri_connectivity[fid][(local_eid + 1) % 3];
683 return Tuple(vid, local_eid, fid, *
this);
693 if (p_vertex_attrs) p_vertex_attrs->begin_protect();
694 if (p_edge_attrs) p_edge_attrs->begin_protect();
695 if (p_face_attrs) p_face_attrs->begin_protect();
703 if (p_vertex_attrs) p_vertex_attrs->end_protect();
704 if (p_edge_attrs) p_edge_attrs->end_protect();
705 if (p_face_attrs) p_face_attrs->end_protect();
713 if (p_vertex_attrs) p_vertex_attrs->rollback();
714 if (p_edge_attrs) p_edge_attrs->rollback();
715 if (p_face_attrs) p_face_attrs->rollback();
723 tbb::spin_mutex mutex;
724 int owner = std::numeric_limits<int>::max();
727 bool trylock() {
return mutex.try_lock(); }
735 int get_owner() {
return owner; }
737 void set_owner(
int n) { owner = n; }
739 void reset_owner() { owner = std::numeric_limits<int>::max(); }
743 tbb::concurrent_vector<VertexMutex> m_vertex_mutex;
745 bool try_set_vertex_mutex(
const Tuple& v,
int threadid)
747 bool got = m_vertex_mutex[v.vid(*
this)].trylock();
748 if (got) m_vertex_mutex[v.vid(*
this)].set_owner(threadid);
751 bool try_set_vertex_mutex(
size_t vid,
int threadid)
753 bool got = m_vertex_mutex[vid].trylock();
754 if (got) m_vertex_mutex[vid].set_owner(threadid);
758 void unlock_vertex_mutex(
const Tuple& v) { m_vertex_mutex[v.vid(*
this)].unlock(); }
759 void unlock_vertex_mutex(
size_t vid) { m_vertex_mutex[vid].unlock(); }
762 void resize_mutex(
size_t v) { m_vertex_mutex.grow_to_at_least(v); }
765 tbb::enumerable_thread_specific<std::vector<size_t>> mutex_release_stack;
767 int release_vertex_mutex_in_stack();
806 void for_each_face(
const std::function<
void(
const Tuple&)>&);
811 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:388
std::array< size_t, 3 > oriented_tri_vids(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1268
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:701
size_t get_valence_for_vertex(const Tuple &t) const
Count the number of the one ring tris for a vertex.
Definition TriMesh.h:601
std::vector< Tuple > get_vertices() const
Definition TriMesh.cpp:1326
size_t get_next_empty_slot_t()
Get the next avaiblie global index for the triangle.
Definition TriMesh.cpp:1530
size_t get_next_empty_slot_v()
Get the next avaiblie global index for the vertex.
Definition TriMesh.cpp:1553
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:1576
bool try_set_face_mutex_one_ring(const Tuple &f, int threadid)
try lock the one-ring neighboring triangles' incident vertices.
Definition TriMesh.cpp:1811
void for_each_vertex(const std::function< void(const Tuple &)> &)
perform the given function for each vertex
Definition TriMesh.cpp:1861
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideras after an edge smooth.
Definition TriMesh.h:435
virtual bool invariants(const std::vector< Tuple > &)
User specified invariants that can't be violated.
Definition TriMesh.h:376
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas after an edge collapse.
Definition TriMesh.h:407
Tuple tuple_from_edge(size_t fid, size_t local_eid) const
Definition TriMesh.h:680
Tuple switch_edge(const Tuple &t) const
a duplicate of Tuple::switch_edge funciton
Definition TriMesh.h:476
virtual bool split_face_after(const Tuple &t)
User specified modifications and desideratas after a face split.
Definition TriMesh.h:448
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:711
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:1786
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideras after an edge swap.
Definition TriMesh.h:413
bool try_set_vertex_mutex_two_ring(const Tuple &v, int threadid)
try lock the two-ring neighboring triangles' incident vertices
Definition TriMesh.cpp:1703
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:656
void init(size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris)
Definition TriMesh.cpp:1286
size_t vert_capacity() const
get the current largest global vid
Definition TriMesh.h:462
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:1190
std::vector< Tuple > get_faces() const
Definition TriMesh.cpp:1358
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:1390
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:1728
std::array< Tuple, 3 > oriented_tri_vertices(const Tuple &t) const
Get the incident vertices for a triangle.
Definition TriMesh.cpp:1255
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for an edge smooth.
Definition TriMesh.h:429
size_t tri_capacity() const
get the current largest global fid
Definition TriMesh.h:456
void start_protect_attributes()
Start the phase where the attributes that will be modified can be recorded.
Definition TriMesh.h:691
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split.
Definition TriMesh.h:442
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split.
Definition TriMesh.h:382
std::optional< Tuple > switch_face(const Tuple &t) const
a duplicate of Tuple::switch_face funciton
Definition TriMesh.h:481
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:504
void for_each_edge(const std::function< void(const Tuple &)> &)
perform the given function for each edge
Definition TriMesh.cpp:1841
Tuple tuple_from_vertex(size_t vid) const
Definition TriMesh.h:668
bool check_link_condition(const Tuple &t) const
prerequisite for collapse
Definition TriMesh.cpp:1597
bool smooth_vertex(const Tuple &t)
Definition TriMesh.cpp:971
std::vector< Tuple > get_edges() const
Definition TriMesh.cpp:1374
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:397
Tuple switch_vertex(const Tuple &t) const
a duplicate of Tuple::switch_vertex funciton
Definition TriMesh.h:472
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:511
std::vector< Tuple > get_one_ring_tris_for_vertex(const Tuple &t) const
Get the one ring tris for a vertex.
Definition TriMesh.cpp:1174
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:1877