Wildmeshing Toolkit
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
wmtk::components::isotropic_remeshing::IsotropicRemeshing Class Reference
Inheritance diagram for wmtk::components::isotropic_remeshing::IsotropicRemeshing:
wmtk::TriMesh

Classes

struct  PositionInfoCache
 

Public Types

using VertAttCol = wmtk::AttributeCollection< VertexAttributes >
 
- Public Types inherited from wmtk::TriMesh
template<typename T >
using vector = std::vector< T >
 
using VertexMutex = wmtk::threading::VertexMutex
 

Public Member Functions

void set_feature_edges (const std::vector< std::array< size_t, 2 > > &edges)
 Curves the remeshing keeps: label boundaries, say.
 
void set_feature_edges (const std::vector< std::array< size_t, 2 > > &edges, const std::vector< int64_t > &ids)
 The same, with an id for each edge (-1 for none), which the remeshing carries: the halves of a split keep it, and a collapse along a curve leaves the curve its id. A vertex on two feature edges of different ids ends one curve and starts the next, so it stays put like a junction (see stays_put). ids has one entry per edge.
 
std::vector< std::array< size_t, 2 > > feature_edges () const
 The feature edges, smaller vertex id first.
 
bool is_feature_edge (size_t a, size_t b) const
 
int64_t feature_edge_id (size_t a, size_t b) const
 The id set_feature_edges gave the feature edge (a, b): -1 for none, or for no feature edge.
 
size_t feature_degree (size_t v) const
 
void set_fixed_vertices (const std::vector< std::pair< size_t, int64_t > > &vertices)
 Vertices the remeshing keeps exactly: B-rep corners, say, which may sit inside a curve between two regions as well as where curves meet.
 
bool is_fixed (size_t v) const
 
bool stays_put (size_t v) const
 Whether v is never moved and never removed: a curve's end, a junction of curves, a vertex between feature edges of different ids, or a fixed vertex.
 
bool may_collapse_away (const Tuple &t) const
 Whether the curve rules let a collapse of t remove t.vid(): it does not stay put, and if it is on a curve, t runs along it. The rest of collapse_edge_before still applies.
 
void set_face_fields (const std::vector< std::vector< double > > &values)
 Per-face values the remeshing carries: per-face labels, say, whose boundaries are feature edges. A split gives both halves of a face its values; a collapse or swap keeps the values of the faces it changes, which is right where no swapped or collapsed edge separates faces of different values – where the boundaries are feature edges, as set_feature_edges keeps them. values has one entry per face of the mesh given to create_mesh(), in that order; call after create_mesh().
 
bool has_face_fields () const
 
void set_feature_envelope (double eps)
 Keep the curves near the feature edges as they are now – the input's, called before remeshing: every feature edge an operation leaves must lie within eps of them.
 
void consolidate_mesh ()
 TriMesh::consolidate_mesh, plus the renumbering of the feature edges.
 
size_t remove_feature_ears ()
 Removes the triangles that hold two feature edges – "ears".
 
bool is_feature_ear_tip (const Tuple &v) const
 Whether v is on a curve and one triangle holds both of its curve edges.
 
void set_check_inversions (bool check)
 Refuse a collapse, swap or smoothing that folds the surface over.
 
void set_swap_quality (bool quality)
 Swap an edge to raise the worse shape quality of its two triangles (see compute_swap_quality), instead of to bring the valences of its four vertices to 6 (4 on the boundary). Off by default.
 
void set_limit_collapse_length (bool limit)
 Refuse a collapse that leaves an edge longer than 4/3 of the target length – the split threshold – as Botsch and Kobbelt's remeshing does. Off by default: a collapse is then judged by the edge it removes alone, and those of the last iteration leave edges that no split comes after to cut. cleanup_triangles() holds its collapses to the same bound, on or off (see there).
 
void set_cleanup_angle (double degrees)
 Repair, at the end of every iteration, the triangles whose smallest angle is under degrees; 0, the default, repairs none. Call before create_mesh(), which then keeps the input's area vectors for the fold test below.
 
size_t cleanup_triangles (double degrees)
 Repairs the triangles whose smallest angle is under degrees, worst first.
 
size_t refused_inversions () const
 The operations set_check_inversions() refused, since the mesh was made.
 
bool smooth_vertex_to (size_t v, const Eigen::Vector3d &p)
 Moves v to p as a smoothing: smooth_vertex() with p in place of the smoothed position, so that the smoothing's rules, the envelopes and the fold check judge the move, and a history records it. Returns whether it moved. cleanup_triangles() moves its vertices so.
 
 IsotropicRemeshing (std::vector< Eigen::Vector3d > _m_vertex_positions, int num_threads=1, bool use_exact=true)
 
void create_mesh (size_t n_vertices, const std::vector< std::array< size_t, 3 > > &tris, const std::vector< size_t > &frozen_verts=std::vector< size_t >(), bool m_freeze=true, double eps=0, double boundary_eps=0)
 
void cache_edge_positions (const Tuple &t)
 
bool invariants (const std::vector< Tuple > &new_tris) override
 User specified invariants that can't be violated.
 
void partition_mesh ()
 
void partition_mesh_morton ()
 
size_t get_partition_id (const Tuple &loc) const
 
bool smooth_all_vertices ()
 
Eigen::Vector3d smooth (const Tuple &t)
 
Eigen::Vector3d tangential_smooth (const Tuple &t)
 
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.
 
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.
 
std::vector< TriMesh::Tuple > new_edges_after (const std::vector< TriMesh::Tuple > &tris) const
 
std::vector< TriMesh::Tuple > new_edges_after_swap (const TriMesh::Tuple &t) const
 
std::vector< TriMesh::Tuple > replace_edges_after_split (const std::vector< TriMesh::Tuple > &tris, const size_t vid_threshold) const
 
std::vector< TriMesh::Tuple > new_sub_edges_after_split (const std::vector< TriMesh::Tuple > &tris) const
 
bool split_edge_before (const Tuple &t) override
 User specified preparations and desideratas for an edge split.
 
bool split_edge_after (const Tuple &t) override
 User specified modifications and desideratas after an edge split.
 
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.
 
double compute_edge_cost_collapse (const TriMesh::Tuple &t, double L) const
 
double compute_edge_cost_split (const TriMesh::Tuple &t, double L) const
 
double compute_vertex_valence (const TriMesh::Tuple &t) const
 
double compute_swap_quality (const TriMesh::Tuple &t) const
 
std::vector< double > average_len_valen ()
 Report statistics.
 
bool split_remeshing (double L)
 
bool collapse_remeshing (double L)
 
bool swap_remeshing ()
 
bool uniform_remeshing (double L, int interations)
 
bool write_triangle_mesh (std::string path)
 
- 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
 
bool slots_exhausted () const
 
void clear_slots_exhausted ()
 
size_t request_tri_slots (size_t n)
 
size_t request_vert_slots (size_t n)
 
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
 
std::shared_ptr< history::Recorder > start_history (std::function< Eigen::Vector3d(size_t)> position)
 Record every operation this mesh commits from now on (see wmtk/history).
 
void stop_history ()
 Stop recording. The recorder keeps the edits it has.
 
std::shared_ptr< history::TrackedCurveRecorder > start_curve_history (std::function< Eigen::Vector3d(size_t)> position)
 Record every change to the tracked curves from now on (see wmtk/history/TrackedRecorder.hpp).
 
void stop_curve_history ()
 Stop recording curves. The recorder keeps what it has.
 
size_t resync_curve_history (const std::vector< std::array< size_t, 2 > > &edges)
 
std::vector< std::array< size_t, 2 > > tracked_edges () const
 Every tracked edge, each with its smaller vertex first.
 
virtual bool is_tracked_edge (const Tuple &e) const
 
virtual std::vector< size_t > tracked_feature_points () const
 
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
 
virtual bool vertex_is_on_surface (const size_t vid) const
 Is a vertex part of the substructure.
 
virtual bool edge_is_on_surface (const std::array< size_t, 2 > &vids) const
 Is an edge part of the substructure.
 
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.
 
size_t tri_storage_capacity () const
 
size_t vert_storage_capacity () const
 
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
 
size_t cell_storage_capacity () const
 
Tuple tuple_from_cell (size_t cid) const
 
size_t cell_slot_bound (const Tuple &t) const
 
void reserve_free_slots (size_t cells, size_t verts)
 
virtual bool storage_grows_on_demand () const
 

Public Attributes

wmtk::Envelope m_envelope
 
bool m_has_envelope = false
 
wmtk::BoundaryEnvelope m_boundary_envelope
 
wmtk::Envelope m_feature_envelope
 Around the feature edges set_feature_envelope() saw; initialized() is false without one.
 
VertAttCol vertex_attrs
 
wmtk::AttributeCollection< FeatureAttributes > feature_attrs
 Read and written only while the mesh has feature edges or fixed vertices.
 
wmtk::AttributeCollection< FaceFieldAttributes > face_field_attrs
 
int retry_limit = 10
 
wmtk::threading::enumerable_thread_specific< PositionInfoCache > position_cache
 
- Public Attributes inherited from wmtk::TriMesh
AbstractAttributeContainer * p_vertex_attrs = nullptr
 
AbstractAttributeContainer * p_edge_attrs = nullptr
 
AbstractAttributeContainer * p_face_attrs = nullptr
 
bool m_check_smoothing_stays_in_star = false
 While true, smooth_vertex() checks that the smooth recorded nothing outside the vertex's star – the vertex itself and the edges, faces and triangles incident to it – and throws if it did.
 
wmtk::threading::enumerable_thread_specific< std::vector< size_t > > mutex_release_stack
 
int NUM_THREADS = 0
 

Private Member Functions

void set_regions ()
 
int64_t region (const Tuple &f) const
 The region of the curves f lies in; -1 without curves.
 
std::vector< std::pair< int64_t, std::vector< Tuple > > > by_region (const std::vector< Tuple > &tris) const
 The triangles, by region (see set_feature_edges), in the order the regions first appear.
 
template<typename F >
void for_each_region (const std::vector< Tuple > &tris, F &&side) const
 
std::vector< std::array< size_t, 6 > > feature_wedges (const std::vector< Tuple > &tris) const
 
bool closes_a_crease (const std::vector< Tuple > &tris, const ReplacedSurface &before) const
 
Eigen::Vector3d area_normal (const std::vector< Tuple > &tris) const
 The area vectors of the triangles, summed (twice over).
 
size_t not_facing (const std::vector< Tuple > &tris, const Eigen::Vector3d &n) const
 How many of the triangles do not face along n.
 
size_t star_folds (const std::vector< Tuple > &tris) const
 
ReplacedSurface replaced (const std::vector< Tuple > &tris) const
 The triangles an operation is about to replace.
 
bool more_folds (const std::vector< Tuple > &tris, const ReplacedSurface &before) const
 
bool folds (const std::vector< Tuple > &tris, const ReplacedSurface &before)
 The same; counts a refusal.
 
double min_angle (const std::vector< Tuple > &tris) const
 The smallest angle of the triangles, in degrees.
 
Eigen::Vector3d input_normal (const Tuple &f) const
 The area vectors of the input triangles next to f, summed: see cleanup_triangles().
 
size_t input_folds (const std::vector< Tuple > &tris) const
 How many of the triangles do not face along input_normal().
 
bool cleanup_allows (const std::vector< Tuple > &tris, const ReplacedSurface &before, size_t input_folds_before, double floor) const
 
bool cleanup_move (size_t v, double floor)
 Moves v to where the smallest angle of its star is largest, above floor.
 

Private Attributes

wmtk::AttributeContainerGroup m_vertex_group
 
bool m_has_features = false
 
bool m_has_fixed = false
 
bool m_has_edge_ids = false
 Some feature edge has an id other than -1.
 
bool m_has_face_fields = false
 
bool m_has_feature_envelope = false
 
bool m_removing_ears = false
 Set while remove_feature_ears() runs (serially): its collapses may make an ear.
 
bool m_check_inversions = true
 
bool m_swap_quality = false
 
bool m_limit_collapse_length = false
 
double m_cleanup_angle = 0
 
double m_cleanup_floor = 0
 
bool m_cleaning = false
 
std::optional< Eigen::Vector3d > m_smooth_target
 Where cleanup_triangles() moves a vertex, in place of the smoothing's position.
 
double m_envelope_eps = 0
 With a cleanup angle: the envelope's eps, and the input's area vectors and face fields.
 
std::vector< Eigen::Vector3d > m_input_area
 
std::vector< std::vector< double > > m_input_values
 
double m_collapse_target = 0
 The target length of the last collapse_remeshing(), for the limit above.
 
std::atomic< size_t > m_refused_inversions = 0
 
bool m_has_regions = false
 The faces have their regions (see set_feature_edges).
 

Additional Inherited Members

- Static Public Member Functions inherited from wmtk::TriMesh
static bool dry_run ()
 Whether operations on this thread are dry runs (see wmtk/OperationDryRun.hpp).
 
static SlotUsage slot_usage_of_this_thread ()
 
- Static Public Attributes inherited from wmtk::TriMesh
static constexpr int EDGES_PER_CELL = 3
 
- Protected Member Functions inherited from wmtk::TriMesh
virtual void on_slot_storage_grown ()
 
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)
 

Member Function Documentation

◆ average_len_valen()

std::vector< double > wmtk::components::isotropic_remeshing::IsotropicRemeshing::average_len_valen ( )

Report statistics.

Returns a vector with: average_length max length min length average valence max valence min valence

◆ cleanup_allows()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::cleanup_allows ( const std::vector< Tuple > &  tris,
const ReplacedSurface &  before,
size_t  input_folds_before,
double  floor 
) const
private

Whether the triangles a repair left fold no more than the before they replaced and beat floor; or, where before folds already, face against the input less often than its input_folds_before. See cleanup_triangles().

◆ cleanup_triangles()

size_t wmtk::components::isotropic_remeshing::IsotropicRemeshing::cleanup_triangles ( double  degrees)

Repairs the triangles whose smallest angle is under degrees, worst first.

Each gets the first of these that is allowed: a collapse of its shortest edge, either way; a swap of one of its edges, longest first; a move of one of its vertices, or else of one of the triangles around it – one off the curves within its tangent plane, one inside a curve along it – to where the smallest angle of its star is largest. Allowed means the curve rules, the envelopes and the fixed vertices hold, as everywhere; the operation folds nothing by the rule of the fold check (see set_check_inversions; on or off, the repairs keep it); a collapse leaves no edge longer than 4/3 of the target of the last collapse_remeshing(), with set_limit_collapse_length() or without – the repairs mend angles and are not to coarsen the mesh, and those after the last iteration have no split after them; and it raises the smallest angle of the triangles it leaves over that of the triangles around the one repaired (of its star, for a move). Where what it replaces folds already, the fold check, which judges against those triangles, can count a repair of the fold as one more: there an operation that leaves fewer triangles facing against the input next to them – the input triangles within half their size plus the envelope, of the same face fields where set_face_fields() gave some – than there were is allowed too, even if no angle improves. Only there: where two sheets of the input are closer than that, a thin wall, the far one cancels the near one, and the input's orientation is noise. Rounds until one repairs nothing, 10 at most. Serial; returns the number of repairs. Throws unless set_cleanup_angle() came before create_mesh().

◆ closes_a_crease()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::closes_a_crease ( const std::vector< Tuple > &  tris,
const ReplacedSurface &  before 
) const
private

Whether at a crease of before (see set_check_inversions) the triangles an operation left open the wedge the other way, or are flat.

◆ collapse_edge_after()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::collapse_edge_after ( const Tuple &  t)
overridevirtual

User specified modifications and desideratas after an edge collapse.

Parameters
theedge Tuple to be collapsed
Returns
true if the modifications succeed

Reimplemented from wmtk::TriMesh.

◆ collapse_edge_before()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::collapse_edge_before ( const Tuple &  t)
overridevirtual

User specified preparations and desideratas for an edge collapse including the link check as collapse prerequisite.

Parameters
theedge Tuple to be split
Returns
true if the preparation succeed

Reimplemented from wmtk::TriMesh.

◆ compute_swap_quality()

double wmtk::components::isotropic_remeshing::IsotropicRemeshing::compute_swap_quality ( const TriMesh::Tuple &  t) const

1 / the worse shape quality (4 sqrt(3) area / sum of squared edge lengths) of the two triangles at t, less the same after swapping it: positive where the swap helps the worse one. -1 where t has not two faces.

◆ create_mesh()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::create_mesh ( size_t  n_vertices,
const std::vector< std::array< size_t, 3 > > &  tris,
const std::vector< size_t > &  frozen_verts = std::vector<size_t>(),
bool  m_freeze = true,
double  eps = 0,
double  boundary_eps = 0 
)
Parameters
m_freezefreeze frozen_verts and, unless boundary_eps is positive, every vertex of the open boundary
epssurface envelope thickness; 0 = no envelope
boundary_epshow the open boundary is held. 0 (default): m_freeze decides – frozen, or held only by the surface envelope, which is a containment test and does not notice an outline retracting along the surface.

‍0: no boundary vertex is frozen; instead every boundary edge an operation leaves that descends from the input's boundary (touches an input_boundary vertex) must lie within boundary_eps of the boundary edges of this input – the tube ShortestEdgeCollapse uses. It judges all four operations: a smoothed boundary vertex has to keep its boundary edges in the tube, a collapse between a boundary vertex and an interior one keeps the boundary vertex in place (the midpoint would pull the outline into the surface for the tube to refuse), and the vertex splitting a boundary edge inherits the lineage. Holes and slits narrower than the tube can close when the link condition is off. Boundary an operation opens elsewhere is not judged.

Feature edges set before it give the faces their regions here (see set_feature_edges).

◆ feature_wedges()

std::vector< std::array< size_t, 6 > > wmtk::components::isotropic_remeshing::IsotropicRemeshing::feature_wedges ( const std::vector< Tuple > &  tris) const
private

The feature edges (a, b) of the triangles with a triangle on either side, oriented the same way, as {a, b, p, q, f, g}: a to b in face f, with apex p, b to a in face g, with apex q. Once each. An operation may read the triangle across, and the stars of a and b: one that changes them holds a or b, which this operation holds.

◆ for_each_region()

template<typename F >
void wmtk::components::isotropic_remeshing::IsotropicRemeshing::for_each_region ( const std::vector< Tuple > &  tris,
F &&  side 
) const
private

Calls side(region, triangles) for each region of the triangles, in the order of by_region; without regions once, with all of them as they are, uncopied.

◆ invariants()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::invariants ( const std::vector< Tuple > &  )
overridevirtual

User specified invariants that can't be violated.

Parameters
std::vector<Tuple>a vector of Tuples that are concerned in a given operation
Returns
true if the invairnats are not violated

Reimplemented from wmtk::TriMesh.

◆ may_collapse_away()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::may_collapse_away ( const Tuple &  t) const

Whether the curve rules let a collapse of t remove t.vid(): it does not stay put, and if it is on a curve, t runs along it. The rest of collapse_edge_before still applies.

With fixed vertices or edge ids, collapse_remeshing turns a collapse around when its tuple's vertex may not go and the other end may: the queue holds an edge in one direction only, and a fixed vertex is mostly the end that has to stay.

◆ more_folds()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::more_folds ( const std::vector< Tuple > &  tris,
const ReplacedSurface &  before 
) const
private

Whether the triangles an operation left fold the surface over more than the before they replaced, or close a crease of theirs.

◆ remove_feature_ears()

size_t wmtk::components::isotropic_remeshing::IsotropicRemeshing::remove_feature_ears ( )

Removes the triangles that hold two feature edges – "ears".

Three consecutive curve vertices a, b, c that span a triangle leave b that triangle alone on one side, and smoothing b along the curve would flatten it. Swapping the edge (a, c) gives b two triangles there; where that is not possible – (a, c) is a curve or the boundary, or the swap would make a new ear or turn a triangle over – b collapses along the curve and the corner goes. Where it cannot either – the moved b would turn a triangle over – (a, c) is split at its midpoint, which gives b two triangles there and moves nothing; at a junction, which smoothing does not move, the corner stays. Where a curve zigzags, removing one ear can make the next, so call it until it removes none. No other swap or collapse makes an ear, but the input can hold them. A triangle with curves (or the boundary) all round is a region of its own, not an ear, and stays. Serial; returns the number removed.

◆ set_check_inversions()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_check_inversions ( bool  check)
inline

Refuse a collapse, swap or smoothing that folds the surface over.

The triangles an operation changes or removes have a normal, their area vectors summed; the operation may leave no more triangles that do not face along it – face against it, or are flat – than there were, nor along the normal of the triangles it leaves. Nor may it leave more folds in the stars of the vertices it touches, each star against its own normal: what it changes is in its neighbours' stars too. So it turns no triangle over against the triangles around it, and may undo a fold the input has. A triangle faces along a normal when the exact orient3d says so (see faces_along in the .cpp). A split moves no vertex and is not checked. On by default.

With feature curves, each region of the curves (see set_feature_edges) is judged on its own: its triangles against the normal of its own triangles, before and after, and in each star the triangles of each region against theirs. Across a curve the surface may turn by any angle, and where it turns by more than 90 degrees – at a sharp edge of a B-rep – the normal of triangles on both sides points between them, so that well-oriented triangles of the smaller side face away from it; at 90 degrees or less they face along it. A curve that does not close off a region has the same region on both sides, and they are judged together, as without curves.

But where the surface turns by more than 90 degrees, a side has to turn by less than 90 – by 180 less the turn – to lie flat on the other, and then to pass through it, and so still faces along its own normal. So an operation may not close a crease either: a feature edge of the triangles it leaves, between two regions whose sides – each region's triangles round the edge's ends, their area vectors summed – faced more than 90 degrees apart before it, where the two triangles at the edge opened the wedge between the regions as the sides do. They still have to after it, by the sign of the exact orient3d of the edge's ends and the two apexes. The sides, not the two triangles, tell how the surface turns there: at a curve a needle's plane need not be its side's, and two triangles can be closed through each other already – the input has such wedges, which an operation may open. The edge a collapse along the curve leaves is judged against the one it continues; a split moves nothing, and turns no wedge. Where the surface turns by 90 degrees or less, a side has to turn by 90 or more to reach the other, and then no longer faces along its region's normal (where it is flat, at least). Without curves, and at a curve with one region on both sides, the check is the first paragraph's.

◆ set_cleanup_angle()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_cleanup_angle ( double  degrees)
inline

Repair, at the end of every iteration, the triangles whose smallest angle is under degrees; 0, the default, repairs none. Call before create_mesh(), which then keeps the input's area vectors for the fold test below.

See cleanup_triangles(). The passes leave such triangles where their criteria do not see them: next to a curve, where a vertex may not leave it and no swap or collapse may make an ear, a triangle between a curve vertex and one off the curves can stay thin; and in a fold the input brings, which the splits copy into the remeshing and the fold check then holds, every operation on it can count as folding.

◆ set_feature_edges()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_feature_edges ( const std::vector< std::array< size_t, 2 > > &  edges)

Curves the remeshing keeps: label boundaries, say.

A vertex on two feature edges is on a curve; one with one, or with three or more, ends a curve or joins several, and stays where it is. A split of a feature edge leaves two feature halves. A curve vertex collapses only along its curve, onto the survivor's position – with set_feature_envelope(), onto the midpoint unless the survivor stays put; a vertex off every curve collapses as before, onto the survivor's position if that one is on a curve. A feature edge is never swapped, and a curve vertex is smoothed along its curve only. No swap or collapse makes a triangle holding two curve edges, and remove_feature_ears() removes the ones the input has.

These are the rules wmtk::history::Replay carries feature edges by, so a recorded history holds the curves at every step.

It also gives each face the region of the curves it lies in – the faces it reaches without crossing a feature edge – which every face keeps: a split gives both halves the face's region, and since no curve is swapped or merged, no swap or collapse joins two regions. The fold check judges each region on its own (see set_check_inversions). A curve that does not close off a region – one ending away from other curves and the boundary – has the same region on both sides. It may come before create_mesh(), which then gives the faces their regions.

◆ set_feature_envelope()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_feature_envelope ( double  eps)

Keep the curves near the feature edges as they are now – the input's, called before remeshing: every feature edge an operation leaves must lie within eps of them.

The surface envelope does not hold a curve. Where its two sides meet at an angle, a curve vertex smoothed across a bend of the curve, or a chord a collapse leaves across one, cuts the corner along one of the sides and stays inside the surface envelope; where they meet smoothly, a curve can wander across the surface. This tube judges the curves as BoundaryEnvelope judges the boundary, with the surface envelope's predicate (exact or sampled, as create_mesh() was given); a split, which moves nothing, is not judged. With the tube, a collapse along a curve puts the survivor at the midpoint, as any other collapse, unless it stays put (see stays_put): the tube refuses it where that leaves the curve. Off until called; eps <= 0 turns it off.

◆ set_fixed_vertices()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_fixed_vertices ( const std::vector< std::pair< size_t, int64_t > > &  vertices)

Vertices the remeshing keeps exactly: B-rep corners, say, which may sit inside a curve between two regions as well as where curves meet.

A fixed vertex stays put (see stays_put), and carries its id to the output. Call after create_mesh().

◆ set_regions()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_regions ( )
private

Gives the faces the regions of the feature edges (see set_feature_edges), if there are feature edges; on a mesh with no faces yet, create_mesh() calls it again.

◆ set_swap_quality()

void wmtk::components::isotropic_remeshing::IsotropicRemeshing::set_swap_quality ( bool  quality)
inline

Swap an edge to raise the worse shape quality of its two triangles (see compute_swap_quality), instead of to bring the valences of its four vertices to 6 (4 on the boundary). Off by default.

Valence leaves a triangle as it is when the swap would not change the valences much: a flat one between two long edges, or a needle a curve leaves, which only the quality notices. The remeshing app of the topology-first B-rep pipeline swaps by quality.

◆ smooth_after()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::smooth_after ( const Tuple &  t)
overridevirtual

User specified modifications and desideras after an edge smooth.

Parameters
theedge Tuple to be smoothed
Returns
true if the modifications succeed

Reimplemented from wmtk::TriMesh.

◆ smooth_before()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::smooth_before ( const Tuple &  t)
overridevirtual

User specified preparations and desideratas for an edge smooth.

Parameters
theedge Tuple to be smoothed
Returns
true if the preparation succeed

Reimplemented from wmtk::TriMesh.

◆ split_edge_after()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::split_edge_after ( const Tuple &  t)
overridevirtual

User specified modifications and desideratas after an edge split.

Parameters
theedge Tuple to be split
Returns
true if the modifications succeed

Reimplemented from wmtk::TriMesh.

◆ split_edge_before()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::split_edge_before ( const Tuple &  t)
overridevirtual

User specified preparations and desideratas for an edge split.

Parameters
theedge Tuple to be split
Returns
true if the preparation succeed

Reimplemented from wmtk::TriMesh.

◆ star_folds()

size_t wmtk::components::isotropic_remeshing::IsotropicRemeshing::star_folds ( const std::vector< Tuple > &  tris) const
private

Over the vertices of the triangles, the triangles of each one's star that do not face along the area_normal of their region of that star. An operation may read these stars: one that changes a star holds its centre, which is in the one-ring of what this operation changes, and so held by it.

◆ stays_put()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::stays_put ( size_t  v) const

Whether v is never moved and never removed: a curve's end, a junction of curves, a vertex between feature edges of different ids, or a fixed vertex.

A collapse removes the vertex of its tuple and keeps the other; one that would remove such a vertex is refused (see may_collapse_away).

◆ swap_edge_after()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::swap_edge_after ( const Tuple &  t)
overridevirtual

User specified modifications and desideras after an edge swap.

Parameters
theedge Tuple to be swaped
Returns
true if the modifications succeed

Reimplemented from wmtk::TriMesh.

◆ swap_edge_before()

bool wmtk::components::isotropic_remeshing::IsotropicRemeshing::swap_edge_before ( const Tuple &  t)
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.

Parameters
theedge Tuple to be swaped
Returns
true if the preparation succeed

Reimplemented from wmtk::TriMesh.

Member Data Documentation

◆ face_field_attrs

wmtk::AttributeCollection<FaceFieldAttributes> wmtk::components::isotropic_remeshing::IsotropicRemeshing::face_field_attrs

The mesh's face attributes once set_face_fields() or set_feature_edges() is called; untouched before.

◆ m_boundary_envelope

wmtk::BoundaryEnvelope wmtk::components::isotropic_remeshing::IsotropicRemeshing::m_boundary_envelope

Tube around the boundary edges of the mesh given to create_mesh(), used instead of freezing the boundary when that gets a positive boundary_eps. See there. initialized() is false otherwise, and for a closed input.

◆ m_cleanup_floor

double wmtk::components::isotropic_remeshing::IsotropicRemeshing::m_cleanup_floor = 0
private

While cleanup_triangles() runs: the smallest angle around the triangle it repairs, which a collapse or swap has to beat. 0 otherwise.


The documentation for this class was generated from the following files: