|
Wildmeshing Toolkit
|
Classes | |
| struct | RingLockScratch |
| Per-thread buffers for the n-ring lock, so a lock acquisition allocates nothing. More... | |
| class | SmartTuple |
| class | TetrahedronConnectivity |
| class | Tuple |
| a Tuple refers to a global vid and a global tet id, and a local edge id and local face id More... | |
| class | VertexConnectivity |
Public Types | |
| template<typename T > | |
| using | vector = std::vector< T > |
| using | VertexMutex = wmtk::threading::VertexMutex |
Public Member Functions | |
| size_t | vert_capacity () const |
| get the current largest global vid | |
| size_t | tet_capacity () const |
| get the current largest global tid | |
| size_t | vertex_size () const |
| get the number of unremoved verticies | |
| size_t | tet_size () const |
| get the number of unremoved tets | |
| void | init (size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets) |
| void | init_with_isolated_vertices (size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets) |
| void | init (const MatrixXi &T) |
| Generate the connectivity of the mesh from an IGL-style T matrix. | |
| bool | split_edge (const Tuple &t, std::vector< Tuple > &new_tets) |
| virtual bool | collapse_edge (const Tuple &t, std::vector< Tuple > &new_tets) |
| bool | link_condition (const Tuple &t) |
| 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) |
| 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. | |
| 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) |
| bool | swap_edge_56 (const Tuple &t, std::vector< Tuple > &new_tets) |
| bool | swap_edge_44 (const Tuple &t, std::vector< Tuple > &new_tets) |
| bool | swap_edge (const Tuple &t, std::vector< Tuple > &new_tets) |
| 3-2 edge swap | |
| bool | swap_face (const Tuple &t, std::vector< Tuple > &new_tets) |
| 2-3 face swap | |
| bool | smooth_vertex (const Tuple &t) |
| bool | split_tet (const Tuple &t, std::vector< Tuple > &new_tets) |
| Split a tet in 4 tets. | |
| bool | split_face (const Tuple &t, std::vector< Tuple > &new_tets) |
| Split a face in 3 faces. | |
| 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 > > ¢er_split_tets) |
| Insert a triangle into a tetmesh, with known intersection information. | |
| 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. In face position, split two tets. In edge position, In point position, do nothing. | |
| virtual bool | insert_point_before (const Tuple &t) |
| virtual bool | insert_point_after (std::vector< Tuple > &new_tets) |
| void | consolidate_mesh () |
| cleans up the deleted vertices or tetrahedra, fixes the corresponding indices, and reset the version number. WARNING: it invalidates all tuples! | |
| std::vector< Tuple > | get_edges () const |
| std::vector< Tuple > | get_faces () const |
| std::vector< Tuple > | get_vertices () const |
| std::vector< Tuple > | get_tets () const |
| virtual void | for_each_face (const std::function< void(const TetMesh::Tuple &)> &) |
| looping through all the unique edges and perform the given function | |
| void | set_preallocation_factor (double factor) |
| Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so operations can grab fresh slots without resizing the storage. When a pass exhausts the reserved capacity the affected operations fail (and are retried later after a consolidate). Tune per application (e.g. from JSON); values < 1 are clamped to 1. | |
| double | preallocation_factor () const |
| long | request_tet_slots (size_t n) |
| long | request_vert_slots (size_t n) |
| void | ensure_free_tet_capacity (size_t extra) |
| void | ensure_free_vert_capacity (size_t extra) |
| virtual bool | invariants (const std::vector< Tuple > &) |
| 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). | |
| Tuple | tuple_from_edge (const std::array< size_t, 2 > &vids) const |
| get a Tuple from global vids of the 2 end of an edge | |
| 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). | |
| std::tuple< Tuple, size_t > | tuple_from_face (const std::array< size_t, 3 > &vids) const |
| get a Tuple and the global face index from global vertex index of the face. | |
| 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. | |
| 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. | |
| size_t | vertex_valence (const size_t vid) const |
| Number of tets incident to a vertex, in O(1). | |
| std::tuple< Tuple, size_t > | tuple_from_face (const simplex::Face &f) const |
| Tuple | tuple_from_vertex (size_t vid) const |
| get a Tuple from global vertex index | |
| Tuple | tuple_from_tet (size_t tid) const |
| get a Tuple from global tetra index | |
| Tuple | tuple_from_vids (size_t vid0, size_t vid1, size_t vid2, size_t vid3) const |
| Get a Tuple from global vertex IDs. | |
| simplex::Tet | simplex_from_tet (const Tuple &t) const |
| simplex::Tet | simplex_from_tet (const size_t tid) const |
| simplex::Face | simplex_from_face (const Tuple &t) const |
| simplex::Edge | simplex_from_edge (const Tuple &t) const |
| Tuple | switch_vertex (const Tuple &t) const |
| wrapper function from Tuple::switch_vertex | |
| Tuple | switch_edge (const Tuple &t) const |
| wrapper function from Tuple::switch_edge | |
| Tuple | switch_face (const Tuple &t) const |
| wrapper function from Tuple::switch_face | |
| std::optional< Tuple > | switch_tetrahedron (const Tuple &t) const |
| wrapper function from Tuple::switch_tetrahedron | |
| std::vector< Tuple > | get_one_ring_tets_for_vertex (const Tuple &t) const |
| Get the one ring tets for a vertex. | |
| const std::vector< size_t > & | get_one_ring_tids_for_vertex (const Tuple &t) const |
| Get the one ring tids for vertex. | |
| const std::vector< size_t > & | get_one_ring_tids_for_vertex (const size_t vid) const |
| std::vector< Tuple > | get_one_ring_vertices_for_vertex (const Tuple &t) const |
| Get the one ring vertices for a vertex. | |
| 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. | |
| std::vector< size_t > | get_one_ring_vids_for_vertex (size_t vid) const |
| Get the one ring vids for vertex. | |
| 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. | |
| std::vector< size_t > | get_one_ring_vids_for_vertex_adj (size_t vid, std::vector< size_t > &cache) |
| Duplicate of the function TetMesh::get_one_ring_vids_for_vertex. | |
| std::vector< Tuple > | get_incident_tets_for_edge (const Tuple &t) const |
| Get the incident tets for edge. | |
| std::vector< Tuple > | get_incident_tets_for_edge (const size_t vid0, const size_t vid1) const |
| std::vector< size_t > | get_incident_tids_for_edge (const Tuple &t) const |
| std::vector< size_t > | get_incident_tids_for_edge (const size_t vid0, const size_t vid1) const |
| std::vector< Tuple > | get_one_ring_tets_for_edge (const Tuple &t) const |
| Get the one ring tets for edge. | |
| std::vector< std::array< size_t, 3 > > | vertex_adjacent_boundary_faces (const Tuple &t) const |
| std::array< Tuple, 4 > | oriented_tet_vertices (const Tuple &t) const |
| std::array< size_t, 4 > | oriented_tet_vids (const Tuple &t) const |
| std::array< size_t, 4 > | oriented_tet_vids (const size_t tid) const |
| std::array< Tuple, 3 > | get_face_vertices (const Tuple &t) const |
| Get the 3 vertices of a face represented by Tuple. | |
| std::array< size_t, 3 > | get_face_vids (const Tuple &t) const |
| std::array< Tuple, 6 > | tet_edges (const Tuple &t) const |
| get the 6 edges of a tet represented by Tuples | |
| void | check_tuple_validity (const Tuple &t) const |
| bool | check_mesh_connectivity_validity () const |
| checks the validity of the connectivity of the mesh. Including the validity of each Tuple | |
| void | remove_tets_by_ids (const std::vector< size_t > &tids) |
| remove the tetrahedrons in the mesh that have given tet ids | |
| void | start_protect_attributes () |
| void | release_protect_attributes () |
| void | rollback_protected_attributes () |
| int | release_vertex_mutex_in_stack () |
| int | release_vertex_mutex_to (size_t mark) |
Release the mutexes taken since the release stack held mark entries. | |
| 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. | |
| bool | try_set_vertex_mutex_n_ring (size_t vid, int threadid, int n) |
| 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. | |
| 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. | |
| void | for_each_edge (const std::function< void(const TetMesh::Tuple &)> &) |
| perform the given function for each edge | |
| void | for_each_vertex (const std::function< void(const TetMesh::Tuple &)> &) |
| perform the given function for each vertex | |
| void | for_each_tetra (const std::function< void(const TetMesh::Tuple &)> &) |
| perform the given function for each tet | |
| virtual bool | vertex_is_on_surface (const size_t vid) const |
| Is a vertex part of the substructure. | |
| virtual bool | face_is_on_surface (const size_t fid) const |
| Is a face part of the substructure. | |
| simplex::SimplexCollection | get_surface_faces_for_vertex (const size_t vid) const |
| Get all faces on the surface that are incident to vid. | |
| 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. | |
| 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. | |
| size_t | compute_vertex_order (const size_t vid) const |
| Compute the vertex order for a single vertex. | |
| virtual size_t | get_order_of_vertex (const size_t vid) const |
| Get the order of a vertex. | |
| size_t | get_order_of_edge (const std::array< size_t, 2 > &vids) const |
| Compute the order of an edge. | |
| bool | substructure_link_condition (const Tuple &e_tuple) const |
| Link condition that also considers substructures. | |
Ring lockers – NOT balls | |
The helpers below are the ones every pass actually uses, and none of the two-ring ones claims the ball its name suggests. Each walks the ring with if (m_vertex_mutex[w].get_owner() == threadid) continue; and that This is deliberate, and swapping in try_set_vertex_mutex_n_ring is a performance regression, not a cleanup. Measured: routing the passes through the complete ball cost +80% wall clock on the 14 challenging tetwild models at 16 threads (844s -> 1522s), against -0.4% on the 16 challenging triwild ones. 3D is where it hurts, because a tet vertex has ~30 neighbours and the honest 2-ring ball is enormous next to what these claim. It is also a coverage-vs-name mismatch rather than a known race. What the operations rely on is that the whole ONE-ring of the seed simplex is held, and that they do hold: the outer loops lock every unowned neighbour directly and only skip expanding through owned ones, so A caller that genuinely needs a complete ball asks for one explicitly, as the 2D coarsening pass does: it re-smooths a k-ring, so it writes the k-ring and reads the (k+1)-ring, well past what a plain collapse claims. | |
| 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. | |
| 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. | |
| bool | try_set_vertex_mutex_two_ring_vid (size_t v, int threadid) |
| try_set_vertex_mutex_two_ring reached through vids rather than Tuples. | |
| 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. | |
| 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. | |
| bool | try_set_face_mutex_two_ring (const Tuple &v1, const Tuple &v2, const Tuple &v3, int threadid=0) |
| Lock the face's one-ring and, partially, its two-ring. See the note above. | |
| bool | try_set_face_mutex_two_ring (size_t v1, size_t v2, size_t v3, int threadid=0) |
| Lock the face's one-ring and, partially, its two-ring. See the note above. | |
| 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. | |
Public Attributes | |
| AbstractAttributeContainer * | p_vertex_attrs = nullptr |
| AbstractAttributeContainer * | p_edge_attrs = nullptr |
| AbstractAttributeContainer * | p_face_attrs = nullptr |
| AbstractAttributeContainer * | p_tet_attrs = nullptr |
| bool | m_collapse_check_link_condition = true |
| bool | m_collapse_check_topology = false |
| bool | m_collapse_check_manifold = true |
| wmtk::threading::enumerable_thread_specific< std::vector< size_t > > | mutex_release_stack |
| wmtk::threading::enumerable_thread_specific< std::vector< size_t > > | get_one_ring_cache |
| int | NUM_THREADS = 0 |
Protected Member Functions | |
| virtual bool | triangle_insertion_before (const std::vector< Tuple > &faces) |
| virtual bool | triangle_insertion_after (const std::vector< std::vector< Tuple > > &) |
| virtual bool | split_edge_before (const Tuple &t) |
| User specified preparations and desideratas for an edge split before changing the connectivity. | |
| virtual bool | split_edge_after (const Tuple &t) |
| This function computes the attributes for the added simplices. User specified modifications and desideratas for after an edge split. | |
| virtual bool | collapse_edge_before (const Tuple &t) |
| User specified preparations and desideratas for an edge collapse before changing the connectivity. | |
| virtual bool | collapse_edge_after (const Tuple &t) |
| User specified modifications and desideratas for after an edge collapse. | |
| virtual bool | swap_edge_44_before (const Tuple &t) |
| User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity. | |
| 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. | |
| virtual bool | swap_edge_44_after (const Tuple &t) |
| User specified modifications and desideratas for after a 4-4 edge swap. | |
| 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. | |
| virtual bool | swap_edge_56_before (const Tuple &t) |
| User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity. | |
| 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. | |
| virtual bool | swap_edge_56_after (const Tuple &t) |
| User specified modifications and desideratas for after a 5-6 edge swap. | |
| 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. | |
| virtual bool | swap_edge_before (const Tuple &t) |
| User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity. | |
| virtual bool | swap_edge_after (const Tuple &t) |
| User specified modifications and desideratas for after a 3-2 edge swap. | |
| virtual bool | swap_face_before (const Tuple &t) |
| User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry. | |
| virtual bool | swap_face_after (const Tuple &t) |
| User specified modifications and desideratas for after a 2-3 face swap. | |
| virtual bool | smooth_before (const Tuple &t) |
| User specified preparations and desideratas for smoothing a vertex. | |
| virtual bool | smooth_after (const Tuple &t) |
| User specified modifications and desideratas for after smoothing a vertex. | |
| virtual bool | split_face_before (const Tuple &t) |
| User specified preparations and desideratas for a face split before changing the connectivity. | |
| virtual bool | split_face_after (const Tuple &t) |
| Compute the attributes for the added simplices. | |
| virtual bool | split_tet_before (const Tuple &t) |
| User specified preparations and desideratas for a tet split before changing the connectivity. | |
| virtual bool | split_tet_after (const Tuple &t) |
| Compute the attributes for the added simplices. | |
| void | resize_vertex_mutex (size_t v) |
Private Member Functions | |
| size_t | reserved_capacity (size_t live_count) const |
| int | get_next_empty_slot_t () |
| int | get_next_empty_slot_v () |
| 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 > > ¢er_split_tets) |
| 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 > > ¢er_split_tets) |
| 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) |
| void | operation_failure_rollback_imp (std::map< size_t, VertexConnectivity > &rollback_vert_conn, const std::vector< size_t > &affected, const std::vector< size_t > &new_tet_id, const std::vector< TetrahedronConnectivity > &old_tets) |
| std::map< size_t, VertexConnectivity > | operation_update_connectivity_impl (const std::vector< size_t > &remove_id, const std::vector< std::array< size_t, 4 > > &new_tet_conn, std::vector< size_t > &allocate_id, bool &ok) |
| bool | try_set_vertex_mutex (const Tuple &v, int threadid) |
| bool | try_set_vertex_mutex (size_t vid, int threadid) |
| void | unlock_vertex_mutex (const Tuple &v) |
| void | unlock_vertex_mutex (size_t vid) |
| 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. | |
Static Private Member Functions | |
| static std::vector< TetrahedronConnectivity > | record_old_tet_connectivity (const TetMesh::vector< TetrahedronConnectivity > &conn, const std::vector< size_t > &tets) |
Private Attributes | |
| vector< VertexConnectivity > | m_vertex_connectivity |
| vector< TetrahedronConnectivity > | m_tet_connectivity |
| std::atomic_long | current_vert_size |
| std::atomic_long | current_tet_size |
| double | m_preallocation_factor = 6.0 |
| int | m_t_empty_slot = 0 |
| int | m_v_empty_slot = 0 |
| std::vector< VertexMutex > | m_vertex_mutex |
| wmtk::threading::enumerable_thread_specific< RingLockScratch > | m_ring_lock_scratch |
Static Private Attributes | |
| static constexpr std::array< std::array< int, 2 >, 6 > | m_local_edges |
| local edges within a tet | |
| static constexpr std::array< int, 4 > | m_map_vertex2edge = {{0, 0, 1, 3}} |
| static constexpr std::array< int, 4 > | m_map_vertex2oppo_face = {{3, 1, 2, 0}} |
| static constexpr std::array< int, 6 > | m_map_edge2face = {{0, 0, 0, 1, 2, 1}} |
| static constexpr std::array< std::array< int, 3 >, 4 > | m_local_faces |
| static constexpr std::array< std::array< int, 3 >, 4 > | m_local_edges_in_a_face |
Dimension-generic cell accessors | |
A "cell" is the top-dimensional element: a tet here, a triangle in TriMesh. These three members plus EDGES_PER_CELL are the whole interface the dimension-generic helpers in wmtk/utils (ParallelCollect, SizingField) need, so the same helper works on both meshes without traits or overloads. | |
| static constexpr int | EDGES_PER_CELL = 6 |
| static constexpr int | FACES_PER_CELL = 4 |
| size_t | cell_capacity () const |
| Tuple | tuple_from_cell (size_t cid) const |
| bool wmtk::TetMesh::check_mesh_connectivity_validity | ( | ) | const |
checks the validity of the connectivity of the mesh. Including the validity of each Tuple
|
inline |
wrapper function for Tuple::check_validity
Collapse an edge
| t | Input Tuple for the edge to collapse. | |
| [out] | new_tets | a vector of Tuples for all the newly introduced tetra. |
|
inlineprotectedvirtual |
User specified modifications and desideratas for after an edge collapse.
| t | edge Tuple that's collapsed |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, wmtk::components::c1_simplification::MMTetMesh, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for an edge collapse before changing the connectivity.
| t | edge Tuple to be collapsed |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, wmtk::components::c1_simplification::MMTetMesh, wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
| bool wmtk::TetMesh::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.
| new_tet_id | new tet ids added to v2 |
| bool wmtk::TetMesh::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 | ||
| ) |
Collapse edge connectivity change part. Constains a link condition check and the connecticity update
| loc0 | Input Tuple for the edge to collapse | |
| [out] | new_tets | a vector of Tuples for all the newly introduced tetra. |
| [out] | v1_id | vertex id of the input tuple |
| [out] | new_loc | result vertex tuple |
| [out] | rollback_vert_conn | vertex connectivity got changed and will be involed in rollback |
| [out] | n1_t_ids_copy | origninal (before collape) one ring tet ids connected to the input vertex |
| [out] | new_tet_id | new tet ids added to v2 |
| [out] | old_tets | tets tv connectivities in n1_t_ids_copy |
backup of everything
| void wmtk::TetMesh::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 | ||
| ) |
rollback function for collapse edges
| [out] | v1_id | vertex id of the input tuple |
| [out] | rollback_vert_conn | vertex connectivity got changed and will be involed in rollback |
| [out] | n1_t_ids | origninal (before collape) one ring tet ids connected to the input vertex |
| [out] | new_tet_id | new tet ids added to v2 |
| [out] | old_tets | tets tv connectivities in n1_t_ids |
| size_t wmtk::TetMesh::compute_vertex_order | ( | const size_t | vid | ) | const |
Compute the vertex order for a single vertex.
This is expensive. It is recommended to store the vertex order as vertex attribute and only compute it once.
| vid | Vertex ID |
The vertex is either on a boundary or on a non-manifold edge and has two edges incident that are of the same type.
The vertex is either at the end of a non-manifold edge or the number of incident faces is different for the incident edges. In both cases, the vertex must be order 3.
Check if vertex is non-manifold: All faces must be reachable by iterating through edges, starting from one face.
|
inlinevirtual |
Is a face part of the substructure.
| fid | Face ID |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
|
virtual |
looping through all the unique edges and perform the given function
looping through all the unique faces and perform the given function
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_edges | ( | ) | const |
Get all unique undirected edges in the mesh.
| std::array< TetMesh::Tuple, 3 > wmtk::TetMesh::get_face_vertices | ( | const Tuple & | t | ) | const |
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_faces | ( | ) | const |
Get all unique faces in the mesh.
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_incident_tets_for_edge | ( | const Tuple & | t | ) | const |
Get the incident tets for edge.
| t | tuple pointing to an edge |
| size_t wmtk::TetMesh::get_num_surface_faces_for_edge | ( | const std::array< size_t, 2 > & | vids | ) | const |
Get the number of surface faces incident to the edge.
| vids | The vertex IDs of the edge |
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_one_ring_tets_for_edge | ( | const Tuple & | t | ) | const |
Get the one ring tets for edge.
| t | tuple pointing to an edge |
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_one_ring_tets_for_vertex | ( | const Tuple & | t | ) | const |
Get the one ring tets for a vertex.
| t | tuple pointing to a vertex |
| const std::vector< size_t > & wmtk::TetMesh::get_one_ring_tids_for_vertex | ( | const Tuple & | t | ) | const |
Get the one ring tids for vertex.
| t | a Tuple that refers to a vertex |
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_one_ring_vertices_for_vertex | ( | const Tuple & | t | ) | const |
Get the one ring vertices for a vertex.
| t | tuple pointing to a vertex |
| std::vector< size_t > wmtk::TetMesh::get_one_ring_vids_for_vertex | ( | size_t | vid | ) | const |
Get the one ring vids for vertex.
| vid | size_t type vertex id |
| std::vector< size_t > wmtk::TetMesh::get_one_ring_vids_for_vertex | ( | size_t | vid, |
| std::vector< size_t > & | cache | ||
| ) |
Get the one ring vids for vertex.
| vid | size_t type vertex id |
| [output] | cache stores a verctor of vids with duplicate |
| size_t wmtk::TetMesh::get_order_of_edge | ( | const std::array< size_t, 2 > & | vids | ) | const |
Compute the order of an edge.
The order of an edge in a TetMesh is as follows: 0: the edge is not on the surface 1: the edge is on the surface 2: the edge is on the surface boundary or non-manifold
| vids | The vertex IDs of the edge |
|
inlinevirtual |
Get the order of a vertex.
The order of a vertex in a TetMesh is as follows: 0: vertex is not on the surface 1: vertex is on the surface 2: vertex is on the surface boundary or a non-manifold edge 3: vertex is at the boundary of a non-manifold edge or a non-manifold vertex
Computing the vertex order is expensive. It is recommended to store the vertex order as a vertex attribute and override this method.
| vid | Vertex ID |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
| simplex::SimplexCollection wmtk::TetMesh::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.
| vids | The vertex IDs of the edge |
| simplex::SimplexCollection wmtk::TetMesh::get_surface_faces_for_vertex | ( | const size_t | vid | ) | const |
Get all faces on the surface that are incident to vid.
| vid | Vertex ID |
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_tets | ( | ) | const |
Get all unique tet in the mesh.
| std::vector< TetMesh::Tuple > wmtk::TetMesh::get_vertices | ( | ) | const |
Get all unique vertices in the mesh.
| void wmtk::TetMesh::init | ( | const MatrixXi & | T | ) |
Generate the connectivity of the mesh from an IGL-style T matrix.
| T | by 4 list of vertex indices. |
| void wmtk::TetMesh::init | ( | size_t | n_vertices, |
| const std::vector< std::array< size_t, 4 > > & | tets | ||
| ) |
Initialize TetMesh data structure
| n_vertices | number of vertices |
| tets | vector of array. Each element represents one tet, which is defined by four vertices. |
tets should not exceed n_vertices Insert a point into a tetmesh inside a tet. In general position, this split a tet into 4. In face position, split two tets. In edge position, In point position, do nothing.
|
inlinevirtual |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.
| bool wmtk::TetMesh::link_condition | ( | const Tuple & | t | ) |
Compute the link of a given simplex Return a tuple of sets for 1. vertices, 2. edges, and 3. faces.
| size_t wmtk::TetMesh::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.
Costs O(smallest incident-tet fan) rather than O(largest), which matters when the fans are skewed – see the implementation for the case that motivated it.
|
private |
| tet_conn | |
| vert_conn | |
| remove_id | this will be modified as new_tet_id, useful for rollback etc. |
| new_tet_conn |
| std::array< TetMesh::Tuple, 4 > wmtk::TetMesh::oriented_tet_vertices | ( | const Tuple & | t | ) | const |
Positively oriented 4 vertices (represented by Tuples) in a tetra.
| std::array< size_t, 4 > wmtk::TetMesh::oriented_tet_vids | ( | const Tuple & | t | ) | const |
Positively oriented 4 vertices ids in a tetra.
| int wmtk::TetMesh::release_vertex_mutex_to | ( | size_t | mark | ) |
Release the mutexes taken since the release stack held mark entries.
Unwinding to a watermark rather than clearing the whole stack is what lets one lock acquisition be composed out of several, and what lets a failed acquisition leave the caller's own locks alone. release_vertex_mutex_in_stack() is this with mark = 0.
|
inline |
remove the tetrahedrons in the mesh that have given tet ids
| tids |
|
inlineprotectedvirtual |
User specified modifications and desideratas for after smoothing a vertex.
| t | Tuple refering to a vertex |
Reimplemented in harmonic_tet::HarmonicTet, app::interior_tet_opt::InteriorTetOpt, wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for smoothing a vertex.
Reimplemented in app::interior_tet_opt::InteriorTetOpt, wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
| bool wmtk::TetMesh::smooth_vertex | ( | const Tuple & | t | ) |
Smooth a vertex
| t | Input Tuple for the vertex |
Split an edge
| t | Input Tuple for the edge to split. | |
| [out] | new_tets | a vector of Tuples for all the newly introduced tetra. |
update connectivity
|
inlineprotectedvirtual |
This function computes the attributes for the added simplices. User specified modifications and desideratas for after an edge split.
| the | edge Tuple to be split |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, wmtk::TetOptimizerMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for an edge split before changing the connectivity.
| the | edge Tuple to be split |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
Split a face in 3 faces.
The TetMesh is assumed to be face manifold, i.e., a face has at most two incident tets.
| t | Input tuple for the face to split. | |
| [out] | new_t | A vector of Tuples refering to the tets incident to the new vertex. introduced |
v2 /|\ / | \ / | \ /t1 ^ t0\
/ / \ \ // t2 \ v0 --------— v1
|
inlineprotectedvirtual |
Compute the attributes for the added simplices.
User specified modifications and desideratas for after a face split
| t | The face tuple to be split. |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for a face split before changing the connectivity.
| t | The face tuple to be split. |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.
Split a tet in 4 tets.
| t | Input tuple for the tet to split. | |
| [out] | new_t | A vector of Tuples refering to the tets incident to the new vertex. introduced |
v2
/|\
/ | \
/ | \
/t1 X t0\
/ /(t3)\ \
// t2 \ v0 --------— v1
New tet vertex connectivity: t0: (X,1,2,3) <- modified old tet t1: (0,X,2,3) t2: (0,1,X,3) t3: (0,1,2,X)
|
inlineprotectedvirtual |
Compute the attributes for the added simplices.
User specified modifications and desideratas for after a tet split
| t | The tet tuple to be split. |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for a tet split before changing the connectivity.
| t | The tet tuple to be split. |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.
|
private |
track surface
|
private |
insert new vertices
record infos
insert new tets
update conn_tets
| bool wmtk::TetMesh::substructure_link_condition | ( | const Tuple & | e_tuple | ) | const |
Link condition that also considers substructures.
Implementation based on the pseudo code from the paper: Vivodtzev et. al. - Substructure Topology Preserving Simplification of Tetrahedral Meshes
The math and the pseudo code in the paper contain errors! The theory itself is correct.
The link condition must be evaluated for the mesh and all substructures (surfaces, lines, points). If there is a substructure simplex in the star, the simplex is extended with a dummy vertex (e.g., an edge becomes a face) and this extended simplex must also be considered for the link.
3-2 edge swap
| t | Input Tuple for the edge to swap. |
| new_tets | a vector of Tuples for all the newly introduced tetra. |
Perform 4-4 swap between 2 tets
| t | Input Tuple for the edge to swap. | |
| [out] | new_tets | a vector of Tuples for all the newly introduced tetra. |
|
inlineprotectedvirtual |
Filter which of the 4-4 orientations may be chosen.
Called for every candidate 4-4 case (identified by its new edge) BEFORE the energy-based selection; a candidate whose new edge is rejected here is not considered. The default accepts everything, so interior edges keep the pure min-energy behavior. A derived mesh can override this to force a specific retetrahedralization (e.g. tetwild forces the case that realizes a surface diagonal flip).
| new_edge | The two vertices of the candidate's new edge. The ordering is implementation-defined (currently new_edge[0] is the case-selector vertex). |
Reimplemented in wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified modifications and desideratas for after a 4-4 edge swap.
| t | edge Tuple that's swaped |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity.
| t | edge Tuple to be swaped |
Reimplemented in app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified energy to decide which of the 4 possible orientations should be chosen.
Accepts the last shown orientation if not overridden.
| tets | New tets after performing a 4-4 swap. |
| op_case | The operation case, where 0 are the tets before swap. |
Reimplemented in wmtk::TetOptimizerMesh.
Perform 5-6 swap
| t | Input Tuple for the edge to swap. | |
| [out] | new_tets | a vector of Tuples for all the newly introduced tetra. |
|
inlineprotectedvirtual |
Filter which of the 5-6 orientations may be chosen.
Called for every candidate 5-6 case (identified by its new fan face) BEFORE the energy-based selection; a candidate whose new face is rejected here is not considered. The default accepts everything, so interior edges keep the pure min-energy behavior. new_face[0] is the fan apex. A derived mesh can override this to force a specific retetrahedralization (e.g. tetwild forces the fan that realizes a surface diagonal flip).
| new_face | The candidate's new fan face; new_face[0] is the fan apex. |
Reimplemented in wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified modifications and desideratas for after a 5-6 edge swap.
| t | edge Tuple that's swaped |
Reimplemented in wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity.
| t | edge Tuple to be swaped |
Reimplemented in wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified energy to decide which of the 5 possible orientations should be chosen.
Accepts the last shown orientation if not overridden.
| tets | New tets after performing a 5-6 swap. |
| op_case | The operation case, where 0 are the tets before swap. |
Reimplemented in wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified modifications and desideratas for after a 3-2 edge swap.
| t | edge Tuple that's swaped |
Reimplemented in harmonic_tet::HarmonicTet, app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity.
| t | edge Tuple to be swaped |
Reimplemented in harmonic_tet::HarmonicTet, app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
2-3 face swap
| t | Input Tuple for the edge to swap. |
| new_tets | a vector of Tuples for all the newly introduced tetra. |
|
inlineprotectedvirtual |
User specified modifications and desideratas for after a 2-3 face swap.
| t | edge Tuple that's swaped |
Reimplemented in harmonic_tet::HarmonicTet, app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
|
inlineprotectedvirtual |
User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry.
| t | edge Tuple to be swaped |
Reimplemented in harmonic_tet::HarmonicTet, app::interior_tet_opt::InteriorTetOpt, and wmtk::TetOptimizerMesh.
|
inline |
get the current largest global tid
| std::array< TetMesh::Tuple, 6 > wmtk::TetMesh::tet_edges | ( | const Tuple & | t | ) | const |
get the 6 edges of a tet represented by Tuples
| t |
| void wmtk::TetMesh::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.
| intersected_tets | the tet to split |
| intersected_edges | the edges where new points are assigned to |
| new_edge_vids | new vertices correspond to each cut-edge |
get all tets
track surface before
subdivide
track surface after
| bool wmtk::TetMesh::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.
A true breadth-first ball, expanded only through vertices this thread holds, so every connectivity read is made under a lock. On failure it releases exactly what it took and returns false; the caller must not assume anything about the mesh afterwards.
n == 0 locks the seed alone; n == 1 the seed and its one-ring, and so on. Sizing the ball is the caller's job: an operation must claim every vertex it READS as well as every vertex it writes, which for an operation that also re-smooths a k-ring means k+1 (smoothing a vertex reads its one-ring and writes the quality of its incident cells).
| std::optional< std::tuple< TetMesh::Tuple, size_t > > wmtk::TetMesh::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.
The asserting form is right for the many callers that ask for a face they know exists. collapse_edge_after is not one of them: it asks for a face across the merged vertex that the collapse may have just removed, and it already has a branch for that case.
| TetMesh::Tuple wmtk::TetMesh::tuple_from_edge | ( | const std::array< size_t, 2 > & | vids | ) | const |
get a Tuple from global vids of the 2 end of an edge
| vids | an array of the 2 vertex id of the edge |
| TetMesh::Tuple wmtk::TetMesh::tuple_from_edge | ( | size_t | tid, |
| int | local_eid | ||
| ) | const |
get a Tuple from global tetra index and local edge index (from 0-5).
| tid | Global tetra index |
| local_eid | local edge index |
| std::tuple< TetMesh::Tuple, size_t > wmtk::TetMesh::tuple_from_face | ( | const std::array< size_t, 3 > & | vids | ) | const |
get a Tuple and the global face index from global vertex index of the face.
| vids | Global vertex index of the face |
| TetMesh::Tuple wmtk::TetMesh::tuple_from_face | ( | size_t | tid, |
| int | local_fid | ||
| ) | const |
get a Tuple from global tetra index and local face index (from 0-3).
| tid | Global tetra index |
| local_fid | local face index |
| TetMesh::Tuple wmtk::TetMesh::tuple_from_tet | ( | size_t | tid | ) | const |
get a Tuple from global tetra index
| tid | Global tetra index |
| TetMesh::Tuple wmtk::TetMesh::tuple_from_vertex | ( | size_t | vid | ) | const |
get a Tuple from global vertex index
| vid | Global vertex index |
|
inline |
get the current largest global vid
| std::vector< std::array< size_t, 3 > > wmtk::TetMesh::vertex_adjacent_boundary_faces | ( | const Tuple & | t | ) | const |
| m |
|
inlinevirtual |
Is a vertex part of the substructure.
| vid | Vertex ID |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh, and wmtk::TetOptimizerMesh.
|
inline |
Number of tets incident to a vertex, in O(1).
Around 20-30 on a well-shaped mesh. Worth checking before anything that walks the one ring, since a degenerate mesh can push it into the thousands.
|
staticconstexprprivate |
local edges within a tet
|
staticconstexprprivate |
|
staticconstexprprivate |