|
Wildmeshing Toolkit
|
What triwild and simwild's 2D mesh share. More...
#include <TriOptimizerMesh.h>
Classes | |
| struct | CoarsenScratch |
| Per-thread buffers for the coarsening composite, so it allocates nothing. More... | |
| struct | CoarsenStats |
| What coarsen_mesh() achieved, for the run report. Zeroed when the pass is off. More... | |
| struct | CollapseInfoCache |
| struct | FaceAttributes |
| struct | SplitInfoCache |
| struct | SwapInfoCache |
| struct | VertexAttributes |
Public Types | |
| using | EdgeAttributes = wmtk::SurfaceTagAttributes |
| using | VertAttCol = AttributeCollection< VertexAttributes > |
| using | EdgeAttCol = AttributeCollection< EdgeAttributes > |
| using | FaceAttCol = AttributeCollection< FaceAttributes > |
Public Types inherited from wmtk::TriMesh | |
| template<typename T > | |
| using | vector = std::vector< T > |
| using | VertexMutex = wmtk::threading::VertexMutex |
Public Member Functions | |
| TriOptimizerMesh (OptimizerParameters ¶ms) | |
| size_t | get_partition_id (const Tuple &loc) const |
| void | partition_mesh () |
| void | partition_mesh_morton () |
| double | get_length2 (const Tuple &l) const |
| bool | is_inverted (const std::array< size_t, 3 > &vs) const |
| Orientation check, exact for the coordinates the vertices actually carry. | |
| bool | is_inverted (const Tuple &loc) const |
| bool | is_inverted (const size_t fid) const |
| bool | is_inverted_f (const Tuple &loc) const |
| Inversion check using only the double positions. | |
| bool | is_inverted_f (const size_t fid) const |
| double | get_quality (const std::array< size_t, 3 > &vs) const |
| double | get_quality (const Tuple &loc) const |
| double | get_quality (const size_t fid) const |
| std::tuple< double, double > | get_max_avg_energy () |
| void | mesh_improvement (int max_its=80) |
| std::tuple< double, double > | local_operations (const std::array< int, 4 > &ops, bool collapse_limit_length=true) |
| bool | is_force_split_edge (const size_t v1, const size_t v2) const |
| void | split_all_edges () |
| bool | split_edge_before (const Tuple &t) override |
| User specified preparations and desideratas for an edge split. | |
| bool | split_edge_after (const Tuple &loc) override |
| User specified modifications and desideratas after an edge split. | |
| void | collapse_all_edges (bool is_limit_length=true) |
| bool | collapse_edge_before (const Tuple &t) override |
| User specified preparations and desideratas for an edge collapse including the link check as collapse prerequisite. | |
| bool | collapse_edge_after (const Tuple &t) override |
| User specified modifications and desideratas after an edge collapse. | |
| size_t | coarsen_mesh () |
| Coarsen the mesh without letting the max energy rise. | |
| bool | coarsen_collapse_edge (const Tuple &e, std::vector< Tuple > &new_tris) |
| One collapse under the coarsening rules, outside a coarsening pass. | |
| size_t | swap_all_edges () |
| Run TriWild's quality-improving interior edge-flip pass. | |
| double | swap_weight (const Tuple &t) const |
| bool | swap_edge_before (const Tuple &t) override |
| User specified preparations and desideratas for an edge swap including 1.can't swap on boundary edge. 2. when swap edge between v1, v2, there can't exist edges between the two opposite vertices v3, v4. | |
| bool | swap_edge_after (const Tuple &t) override |
| User specified modifications and desideras after an edge swap. | |
| void | smooth_all_vertices (size_t n_iters=1) |
| Run TriWild's vertex-smoothing pass. | |
| bool | smooth_before (const Tuple &t) override |
| User specified preparations and desideratas for an edge smooth. | |
| bool | smooth_after (const Tuple &t) override |
| User specified modifications and desideras after an edge smooth. | |
| Vector2d | smoothing_position (size_t vid) const |
| void | set_smoothing_position (size_t vid, const Vector2d &p) |
| virtual bool | smoothing_position_is_allowed (size_t vid, const Vector2d &p) const =0 |
| double | active_quality_threshold () const |
| virtual std::vector< size_t > | active_vertices () const |
| virtual double | quality_rel (const size_t fid) const |
| A face's quality relative to the quality it is required to reach; <= 1 means it meets it. | |
| bool | round (const Tuple &v) |
| Round a vertex position to floating point, if that inverts no incident face. | |
| bool | is_edge_on_surface (const Tuple &loc) const |
| bool | is_edge_on_surface (const std::array< size_t, 2 > &vids) const |
| bool | is_edge_on_bbox (const Tuple &loc) const |
| bool | is_edge_on_bbox (const std::array< size_t, 2 > &vids) const |
| bool | vertex_is_on_surface (const size_t vid) const override |
| Is a vertex part of the substructure. | |
| bool | edge_is_on_surface (const std::array< size_t, 2 > &vids) const override |
| Is an edge part of the substructure. | |
| virtual std::shared_ptr< SampleEnvelope > | surface_envelope_for_edge (const std::array< size_t, 2 > &vids) const |
Envelope the tracked-surface segment vids must stay inside. | |
| bool | surface_segment_is_outside (const size_t a, const size_t b) const |
| std::vector< std::array< size_t, 2 > > | get_edges_by_condition (std::function< bool(const EdgeAttributes &)> cond) const |
| void | gradation_smooth_sizing (double grade, const std::vector< size_t > &seeds) |
| Monotone (only-decreasing) gradation smoothing of the sizing field. | |
Public Member Functions inherited from wmtk::TriMesh | |
| void | init (size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris) |
| void | init (const MatrixXi &F) |
| Generate the connectivity of the mesh from an IGL-style F matrix. | |
| std::vector< Tuple > | get_vertices () const |
| std::vector< Tuple > | get_edges () const |
| std::vector< Tuple > | get_faces () const |
| Tuple | tuple_from_edge (size_t vid1, size_t vid2, size_t fid) const |
| Tuple | tuple_from_vids (size_t vid0, size_t vid1, size_t vid2) const |
| simplex::Vertex | simplex_from_vertex (const Tuple &t) const |
| simplex::Edge | simplex_from_edge (const Tuple &t) const |
| simplex::Face | simplex_from_face (const Tuple &t) const |
| simplex::Face | simplex_from_face (const size_t fid) const |
| Tuple | tuple_from_simplex (const simplex::Face &s) const |
| simplex::SimplexCollection | simplex_incident_triangles (const simplex::Vertex &v) const |
| simplex::SimplexCollection | simplex_incident_triangles (const simplex::Edge &e) const |
| simplex::SimplexCollection | simplex_link_vertices (const simplex::Vertex &v) const |
| simplex::SimplexCollection | simplex_link_vertices (const simplex::Edge &e) const |
| simplex::SimplexCollection | simplex_link_edges (const simplex::Vertex &v) const |
| 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 (retried later after a consolidate). Values < 1 are clamped to 1. | |
| double | preallocation_factor () const |
| long | request_tri_slots (size_t n) |
| long | request_vert_slots (size_t n) |
| virtual bool | invariants (const std::vector< Tuple > &) |
| User specified invariants that can't be violated. | |
| virtual bool | split_face_before (const Tuple &t) |
| User specified preparations and desideratas for a face split. | |
| virtual bool | split_face_after (const Tuple &t) |
| User specified modifications and desideratas after a face split. | |
| size_t | tri_capacity () const |
| get the current largest global fid | |
| size_t | vert_capacity () const |
| get the current largest global vid | |
| void | consolidate_mesh () |
| removing the elements that are removed | |
| void | remove_tris_by_ids (const std::vector< size_t > &fids) |
| Mark the given triangles, and any vertex left without an incident triangle, as removed. | |
| Tuple | switch_vertex (const Tuple &t) const |
| a duplicate of Tuple::switch_vertex funciton | |
| Tuple | switch_edge (const Tuple &t) const |
| a duplicate of Tuple::switch_edge funciton | |
| std::optional< Tuple > | switch_face (const Tuple &t) const |
| a duplicate of Tuple::switch_face funciton | |
| bool | check_link_condition (const Tuple &t) const |
| prerequisite for collapse | |
| void | set_use_link_condition (bool use_it) |
| Should collapse_edge_before enforce the link condition? | |
| bool | use_link_condition () const |
| bool | check_mesh_connectivity_validity () const |
| verify the connectivity validity of the mesh | |
| bool | check_edge_manifold () const |
| verify the edge manifoldness of the mesh | |
| size_t | edge_valence (const TriMesh::Tuple &t) const |
| Number of triangles incident to the edge the Tuple points at. | |
| bool | is_boundary_edge (const TriMesh::Tuple &t) const |
| Does exactly one triangle share this edge? | |
| bool | is_manifold_edge (const TriMesh::Tuple &t) const |
| Do exactly two triangles share this edge? | |
| size_t | vertex_component_count (const size_t vid) const |
| Number of edge-connected components in the fan of a vertex. | |
| size_t | vertex_component_count (const TriMesh::Tuple &t) const |
| bool | is_manifold_vertex (const size_t vid) const |
| std::optional< Tuple > | switch_component (const TriMesh::Tuple &t) const |
| Jump to the next edge-connected component of the fan of the Tuple's vertex. | |
| 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 | |
| bool | split_edge (const Tuple &t, std::vector< Tuple > &new_t) |
| virtual bool | collapse_edge (const Tuple &t, std::vector< Tuple > &new_t) |
| 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) |
| 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) |
| bool | swap_edge (const Tuple &t, std::vector< Tuple > &new_t) |
| bool | smooth_vertex (const Tuple &t) |
| bool | split_face (const Tuple &t, std::vector< Tuple > &new_t) |
| Split a face in 3 faces. | |
| size_t | get_valence_for_vertex (const Tuple &t) const |
| Count the number of the one ring tris for a vertex. | |
| size_t | vertex_valence (const size_t vid) const |
| Number of triangles incident to a vertex, by id. | |
| std::vector< Tuple > | get_one_ring_tris_for_vertex (const Tuple &t) const |
| Get the one ring tris for a vertex. | |
| const std::vector< size_t > & | get_one_ring_fids_for_vertex (const Tuple &t) const |
| const std::vector< size_t > & | get_one_ring_fids_for_vertex (const size_t vid) const |
| 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. | |
| void | get_one_ring_vids_for_vertex_duplicate (const size_t &t, std::vector< size_t > &one_ring) const |
| std::vector< size_t > | get_incident_fids_for_edge (const Tuple &t) const |
| std::vector< size_t > | get_incident_fids_for_edge (const size_t vid0, const size_t vid1) const |
| 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. | |
| std::vector< Tuple > | get_one_ring_edges_for_vertex (const size_t vid) const |
| std::array< Tuple, 3 > | oriented_tri_vertices (const Tuple &t) const |
| Get the incident vertices for a triangle. | |
| std::array< size_t, 3 > | oriented_tri_vids (const Tuple &t) const |
| Get the incident vertices for a triangle. | |
| std::array< size_t, 3 > | oriented_tri_vids (const size_t i) const |
| std::array< Tuple, 2 > | get_edge_vertices (const Tuple &t) const |
| std::array< size_t, 2 > | get_edge_vids (const Tuple &t) const |
| Tuple | tuple_from_tri (size_t fid) const |
| Tuple | tuple_from_vertex (size_t vid) const |
| Tuple | tuple_from_edge (size_t fid, size_t local_eid) const |
| std::tuple< Tuple, size_t > | tuple_from_edge (const std::array< size_t, 2 > &vids) const |
| std::optional< std::tuple< Tuple, size_t > > | try_tuple_from_edge (const std::array< size_t, 2 > &vids) const |
| tuple_from_edge for callers where a missing edge is an answer, not a bug. | |
| void | start_protect_attributes () |
| Start the phase where the attributes that will be modified can be recorded. | |
| void | release_protect_attributes () |
| End the modification phase. | |
| void | rollback_protected_attributes () |
| rollback the attributes that are modified if any condition failed | |
| 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_one_ring (const Tuple &f, int threadid) |
| try lock the one-ring neighboring triangles' incident vertices. | |
| void | for_each_face (const std::function< void(const Tuple &)> &) |
| perform the given function for each face | |
| void | for_each_edge (const std::function< void(const Tuple &)> &) |
| perform the given function for each edge | |
| void | for_each_vertex (const std::function< void(const Tuple &)> &) |
| perform the given function for each vertex | |
| simplex::SimplexCollection | get_surface_edges_for_vertex (const size_t vid) const |
| Get all edges on the surface that are incident to vid. | |
| size_t | get_order_of_edge (const std::array< size_t, 2 > &vids) const |
| Compute the order of an edge. | |
| size_t | get_order_of_vertex (const size_t vid) const |
| Get the order of a vertex. | |
| bool | substructure_link_condition (const Tuple &e_tuple) const |
| Link condition that also considers substructures. | |
| 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_edge_mutex_two_ring (const Tuple &e, int threadid) |
| Lock the edge's one-ring and, partially, its two-ring. See the note above. | |
| bool | try_set_vertex_mutex_one_ring (const Tuple &v, int threadid) |
| Lock v and its one-ring. Complete, unlike the two-ring pair. | |
| size_t | cell_capacity () const |
| Tuple | tuple_from_cell (size_t cid) const |
Public Member Functions inherited from wmtk::RationalPositions | |
| size_t | round_all_vertices () |
| Try to round every un-rounded vertex; returns the number reclaimed. | |
| bool | round_and_check_all_rounded () |
| Run the sweep, then report whether the mesh is now fully rounded. | |
Public Attributes | |
| VertAttCol | m_vertex_attribute |
| EdgeAttCol | m_edge_attribute |
| FaceAttCol | m_face_attribute |
| AttributeContainerGroup | m_vertex_attr_group |
| What p_vertex_attrs points at, so a derived class can register more. | |
| AttributeContainerGroup | m_edge_attr_group |
| What p_edge_attrs points at, so a derived class can register more. | |
| AttributeContainerGroup | m_face_attr_group |
| What p_face_attrs points at, so a derived class can register more. | |
| OptimizerParameters & | m_params |
| std::shared_ptr< SampleEnvelope > | m_envelope |
| double | m_envelope_eps = -1 |
| double | m_s_amips = -1 |
| double | m_s_envelope = -1 |
| wmtk::threading::enumerable_thread_specific< std::unique_ptr< polysolve::nonlinear::Solver > > | m_solver |
| optimization::SmoothRejectCounters | m_smooth_rejects |
| Why smoothing attempts were refused, reported once per pass. | |
| bool | m_collapse_limit_length = true |
| int | m_debug_print_counter = 0 |
| size_t | m_tags_count = 0 |
| std::map< int64_t, std::string > | m_tag_id_to_name |
| std::map< std::string, int64_t > | m_tag_name_to_id |
| int | m_iterations_used = 0 |
| Shared TriWild/SimWild outer optimization schedule. | |
| std::set< simplex::Edge > | m_force_split_edges |
| size_t | m_force_split_count = 0 |
| std::unique_ptr< std::atomic< int >[]> | m_high_valence_claim |
| size_t | m_high_valence_claim_size = 0 |
| std::atomic< size_t > | m_high_valence_rejects = 0 |
| CoarsenStats | m_coarsen_stats |
Public Attributes inherited from wmtk::TriMesh | |
| AbstractAttributeContainer * | p_vertex_attrs = nullptr |
| AbstractAttributeContainer * | p_edge_attrs = nullptr |
| AbstractAttributeContainer * | p_face_attrs = nullptr |
| wmtk::threading::enumerable_thread_specific< std::vector< size_t > > | mutex_release_stack |
| int | NUM_THREADS = 0 |
Static Public Attributes | |
| static constexpr double | MAX_ENERGY = 1e50 |
| The sentinel get_quality returns for a face AMIPS2D cannot score. | |
Static Public Attributes inherited from wmtk::TriMesh | |
| static constexpr int | EDGES_PER_CELL = 3 |
Protected Member Functions | |
| virtual std::tuple< double, double > | optimization_quality_stats () |
| virtual double | optimization_stop_metric () const |
| virtual size_t | refine_sizing_around_worst (double max_metric)=0 |
| virtual bool | optimization_stop_at_float () const |
| virtual void | collapse_pass_begin () |
| virtual void | collapse_pass_end (size_t) |
| virtual bool | collapse_before_vertex (size_t, size_t) |
| virtual bool | collapse_quality_allowed (size_t v1, size_t, double q, double ring_max) const |
| virtual void | collapse_after_vertex (size_t, size_t) |
| virtual bool | split_adjust_position (size_t, const std::vector< Tuple > &) |
| virtual void | split_after_vertex (size_t) |
| virtual void | write_smoothing_debug_output (const std::string &path) const =0 |
| std::vector< size_t > | all_vertex_ids () const override |
| Every live vertex, in the mesh's own iteration order. | |
| bool | vertex_is_rounded (const size_t vid) const override |
| Whether this vertex's double position is currently trusted. | |
| bool | round_vertex (const size_t vid) override |
Protected Member Functions inherited from wmtk::TriMesh | |
| void | vertex_fan_components (size_t vid, std::vector< size_t > &component_of, std::vector< size_t > &representatives) const |
| void | resize_mutex (size_t v) |
Protected Attributes | |
| wmtk::threading::enumerable_thread_specific< SplitInfoCache > | split_cache |
| wmtk::threading::enumerable_thread_specific< CollapseInfoCache > | collapse_cache |
| bool | m_coarsen_mode = false |
| Set for the duration of coarsen_mesh(); read-only while a pass is running. | |
Protected Attributes inherited from wmtk::RationalPositions | |
| std::atomic< bool > | m_all_rounded = false |
| True when every vertex is known to be rounded. | |
Private Member Functions | |
| const std::vector< size_t > & | collect_vertex_ball (const size_t *seeds, size_t n_seeds, int n, CoarsenScratch &scr) const |
Vertices within n edges of seeds, in BFS order. Uses coarsen_scratch. | |
| double | region_max_quality_rel (const std::vector< size_t > &vids) const |
| bool | smooth_vertex_reversible (size_t vid, CoarsenScratch &scr) |
One smoothing attempt on vid, restoring everything it wrote if it is rejected. | |
| size_t | collapse_all_edges_impl (bool is_limit_length, int lock_ring, size_t max_passes=0) |
Private Attributes | |
| wmtk::threading::enumerable_thread_specific< SwapInfoCache > | swap_cache |
| wmtk::threading::enumerable_thread_specific< CoarsenScratch > | coarsen_scratch |
What triwild and simwild's 2D mesh share.
Seeded by MOVING triwild's implementation here, not by designing an abstraction: triwild is the more heavily measured of the two, so the move leaves it byte-identical and confines any output change to the commit where simwild adopts the base.
The 3D counterpart is wmtk::TetOptimizerMesh. The two are deliberately NOT unified with each other: the same algorithms at two dimensions, but written against different primitives, and one shared copy would need the quality convention (2D stores AMIPS2D, 3D stores AMIPS^3) and the stop condition (absolute energy vs per-cell relative quality) abstracted first. Two readable copies beat one over-parameterized one.
|
inlineexplicit |
eps makes it such that the energy is relative to the envelope thickness. As it's a squared energy, we need eps^2.
|
overrideprotectedvirtual |
Every live vertex, in the mesh's own iteration order.
Implements wmtk::RationalPositions.
| bool wmtk::TriOptimizerMesh::coarsen_collapse_edge | ( | const Tuple & | e, |
| std::vector< Tuple > & | new_tris | ||
| ) |
One collapse under the coarsening rules, outside a coarsening pass.
The pass sets the mode once and leaves it set for its whole duration, because every worker reads it; this is the single-operation form, for callers that want one and are not sharing the mesh with other threads.
| size_t wmtk::TriOptimizerMesh::coarsen_mesh | ( | ) |
Coarsen the mesh without letting the max energy rise.
Alternates coarsening-collapse passes with ordinary smoothing passes, as the main optimization does, for at most m_params.coarsen_max_rounds rounds or until a round accepts nothing. See OptimizerParameters::coarsen_pass for what makes the collapse in this pass different, and collapse_edge_after for how it is undone when it does not pay off. A no-op when m_params.coarsen_pass is false.
|
overridevirtual |
User specified modifications and desideratas after an edge collapse.
| the | edge Tuple to be collapsed |
Reimplemented from wmtk::TriMesh.
|
overridevirtual |
User specified preparations and desideratas for an edge collapse including the link check as collapse prerequisite.
| the | edge Tuple to be split |
check if on bbox/surface/boundary
In general, we don't want to collapse away from feature vertices. It is always fine to collapse into a feature vertex, though. However, we allow to feature vertices to be collapsed.
Reimplemented from wmtk::TriMesh.
|
inlineoverridevirtual |
Is an edge part of the substructure.
| vids | The vertex IDs of the edge |
Reimplemented from wmtk::TriMesh.
| void wmtk::TriOptimizerMesh::gradation_smooth_sizing | ( | double | grade, |
| const std::vector< size_t > & | seeds | ||
| ) |
Monotone (only-decreasing) gradation smoothing of the sizing field.
Enforces m_sizing_scalar[v] <= grade * m_sizing_scalar[u] for every edge (u,v), propagating outward from seeds with a min-relaxation. It never raises a sizing value, so it only ever spreads more refinement into the halo around already-refined vertices, avoiding sharp resolution jumps.
| bool wmtk::TriOptimizerMesh::is_inverted | ( | const std::array< size_t, 3 > & | vs | ) | const |
Orientation check, exact for the coordinates the vertices actually carry.
Takes the floating path when all three vertices are rounded – wmtk::utils::predicates::orient2d is exact for the doubles it is handed – and the Rational cross product otherwise. The rational branch exists because for an un-rounded vertex the double is the wrong number, not because orient2d is imprecise.
|
protectedvirtual |
Quality metric used by the driver. TriWild uses absolute AMIPS; SimWild overrides this with quality normalized by each face's tag-dependent target.
Reimplemented in wmtk::components::simwild::tri::SimWildMeshTri.
|
inlinevirtual |
A face's quality relative to the quality it is required to reach; <= 1 means it meets it.
The only quality that is comparable ACROSS faces. Raw m_quality is not, once an application gives different regions different targets: the loose region's raw ceiling then hides degradation in the strict one, because a strict face may get much worse and still sit below a number set somewhere it has nothing to do with. Shared code that compares one face's quality against another's must go through here.
TriWild's target is uniform, so this is the raw quality over a constant – which cancels out of any before/after comparison and leaves its behaviour unchanged.
Reimplemented in wmtk::components::simwild::tri::SimWildMeshTri.
|
protectedpure virtual |
|
private |
Worst relative quality (quality_rel) over the faces incident to any vertex of vids.
| bool wmtk::TriOptimizerMesh::round | ( | const Tuple & | v | ) |
Round a vertex position to floating point, if that inverts no incident face.
|
inlineoverrideprotectedvirtual |
Try to replace this vertex's exact position with its rounded one; false if that would invert an incident cell, in which case nothing is changed.
Implements wmtk::RationalPositions.
|
overridevirtual |
User specified modifications and desideras after an edge smooth.
| the | edge Tuple to be smoothed |
Reimplemented from wmtk::TriMesh.
| void wmtk::TriOptimizerMesh::smooth_all_vertices | ( | size_t | n_iters = 1 | ) |
Run TriWild's vertex-smoothing pass.
TriWild is the behavioral source of truth. SimWild shares the pass verbatim, including the single m_envelope used for both smoothing energy and containment, the surface quality veto, and skip_good_regions selection.
|
overridevirtual |
User specified preparations and desideratas for an edge smooth.
| the | edge Tuple to be smoothed |
Reimplemented from wmtk::TriMesh.
|
pure virtual |
|
inlineprotectedvirtual |
Reimplemented in wmtk::components::topological_offset::TopoOffsetTriMesh.
|
overridevirtual |
User specified modifications and desideratas after an edge split.
| the | edge Tuple to be split |
check inversion & rounding
update quality
update vertex attribute
update edge attribute
Reimplemented from wmtk::TriMesh.
|
overridevirtual |
User specified preparations and desideratas for an edge split.
| the | edge Tuple to be split |
Reimplemented from wmtk::TriMesh.
|
inlinevirtual |
Envelope the tracked-surface segment vids must stay inside.
The 2D counterpart of wmtk::TetOptimizerMesh::surface_envelope_for_face. Null means this segment carries no containment requirement, and every containment check on it is skipped. Both applications that track a single surface keep one envelope for it, so the default answers with that; an application tracking more than one (see SurfaceTagAttributes::m_surface_class) overrides this to answer per class.
Keyed on the vertex ids rather than the eid because every caller is a topological operation asking about segments it is ABOUT to create or has just created.
Reimplemented in wmtk::components::topological_offset::TopoOffsetTriMesh.
|
inline |
Whether the tracked-surface segment (a,b) is outside its containment envelope. False when it has none. Every surface containment check in the operations goes through here.
| size_t wmtk::TriOptimizerMesh::swap_all_edges | ( | ) |
Run TriWild's quality-improving interior edge-flip pass.
This operation is shared verbatim by TriWild and SimWild. Face tags are copied from the old pair to the new pair, so a tag-homogeneous SimWild mesh follows exactly the same path as TriWild.
|
overridevirtual |
User specified modifications and desideras after an edge swap.
| the | edge Tuple to be swaped |
Reimplemented from wmtk::TriMesh.
|
overridevirtual |
User specified preparations and desideratas for an edge swap including 1.can't swap on boundary edge. 2. when swap edge between v1, v2, there can't exist edges between the two opposite vertices v3, v4.
| the | edge Tuple to be swaped |
Reimplemented from wmtk::TriMesh.
|
inlineoverridevirtual |
|
inlineoverrideprotectedvirtual |
Whether this vertex's double position is currently trusted.
Implements wmtk::RationalPositions.
| AttributeContainerGroup wmtk::TriOptimizerMesh::m_edge_attr_group |
What p_edge_attrs points at, so a derived class can register more.
The 2D counterpart of wmtk::TetOptimizerMesh::m_face_attr_group. An application whose edges carry data the shared operations know nothing about – topological_offset labels each edge by which part of the construction produced it – registers a second collection here, and it is resized, protected and rolled back with the shared one.
Note what this does NOT do: the shared operations propagate edge data by copying SurfaceTagAttributes values around (the split and collapse caches, the swap cache), and they only ever see their own collection. Anything registered here survives the mesh changing shape, but its values are the registering application's to maintain.
| AttributeContainerGroup wmtk::TriOptimizerMesh::m_face_attr_group |
What p_face_attrs points at, so a derived class can register more.
Unlike the 3D mesh, whose cell attributes are per-application, the 2D base owns a concrete FaceAttributes – so a derived class that needs an extra per-face field cannot add it there and registers a second collection here instead. Same caveat as the edge group: the shared operations propagate face data by copying FaceAttributes values around and never see this, so its values are the registering application's to maintain.
| OptimizerParameters& wmtk::TriOptimizerMesh::m_params |
Only the fields shared by all three applications; each derived class keeps a typed reference to its own Parameters for the rest.
| double wmtk::TriOptimizerMesh::m_s_amips = -1 |
Scale factors putting AMIPS (dimensionless) and the envelope energy (a squared distance) on a comparable footing.
| AttributeContainerGroup wmtk::TriOptimizerMesh::m_vertex_attr_group |
What p_vertex_attrs points at, so a derived class can register more.
VertexAttributes holds only what both 2D applications need. triwild adds a per-vertex feature id through here; simwild-2D has no 0-dimensional features and registers nothing, so it does not carry the field.
|
staticconstexpr |
The sentinel get_quality returns for a face AMIPS2D cannot score.
Not an energy: a positively oriented triangle whose area is too small for AMIPS, or one that produces inf/nan, gets this instead. Unlike the 3D mesh this stores AMIPS2D directly, so it surfaces in the logs verbatim as 1e+50. 1e50 rather than double::max because every downstream ratio must stay finite.