|
Wildmeshing Toolkit
|
A tube around the open boundary of a triangle mesh, for operations allowed to move it. More...
#include <BoundaryEnvelope.hpp>
Public Member Functions | |
| template<typename VertexAttributes > | |
| bool | init (const TriMesh &m, VertexAttributes &vertex_attrs, double eps, bool use_exact) |
Build the tube around the boundary edges of m and flag their vertices. | |
| bool | initialized () const |
| Whether init() found a boundary to build the tube around. | |
| void | set_use_exact (bool use_exact) |
| template<typename VertexAttributes > | |
| bool | boundary_edges_inside (const TriMesh &m, const VertexAttributes &vertex_attrs, const std::vector< TriMesh::Tuple > &tris) const |
Every boundary edge of tris that touches an input_boundary vertex lies in the tube. | |
Static Public Member Functions | |
| template<typename VertexAttributes > | |
| static bool | on_input_boundary (const TriMesh &m, const VertexAttributes &vertex_attrs, const TriMesh::Tuple &v) |
v is an input_boundary vertex that is still on the boundary. | |
Private Member Functions | |
| void | build (const std::vector< Eigen::Vector3d > &V, const std::vector< Eigen::Vector2i > &E, double eps, bool use_exact) |
Private Attributes | |
| Envelope | m_envelope |
| bool | m_initialized = false |
A tube around the open boundary of a triangle mesh, for operations allowed to move it.
The alternative to freezing the boundary. Freezing keeps the outline exactly, and with it everything enclosed by boundary loops packed too tightly to leave a free vertex between them. The tube lets the outline coarsen and move instead, as long as every boundary edge that descends from the input's boundary stays within eps of the input's boundary edges. Holes and slits narrower than the tube can then close.
"Descends from" is a per-vertex lineage flag, input_boundary, kept in the mesh's own vertex attributes so that it is rolled back and consolidated with them. The operations maintain it:
A boundary edge derived from the input's outline then always touches a flagged vertex, and boundary_edges_inside() judges exactly those. Boundary that an operation opens elsewhere – a collapse with the link condition off tearing a dense closed patch, say – is not judged, as it was not judged under a frozen boundary either: such tears are transient while a patch simplifies, and refusing them leaves it stuck (Thingi10K 55928; see ShortestEdgeCollapse::create_mesh).
The vertex attributes are duck-typed: anything indexed by vertex id whose elements have an Eigen::Vector3d pos and a bool input_boundary – in practice a component's AttributeCollection<VertexAttributes>.
|
inline |
Every boundary edge of tris that touches an input_boundary vertex lies in the tube.
Meant for TriMesh::invariants(), with the triangles an operation produced: they include every edge whose position or boundary status the operation changed. Edges touching no flagged vertex are skipped before the boundary test, so a mesh far from its boundary pays one flag lookup per edge.
|
inline |
Build the tube around the boundary edges of m and flag their vertices.
Call right after TriMesh::init, before any operation.
| eps | tube radius |
| use_exact | whether queries use the exact predicate. An edge envelope builds its exact structure only when this is set here, so set it to whatever the surface envelope uses; set_use_exact() can switch to the sampled predicate later, but not back. |
|
inlinestatic |
v is an input_boundary vertex that is still on the boundary.
For placement: an operation that moves such a vertex off the boundary pulls the outline into the surface, which the tube then refuses, so the operation is better off keeping it where it is. Only flagged vertices pay for the ring walk.
The ring walk reads the connectivity of v's neighbours, so in a parallel pass ask it only where those are locked – of an endpoint of the edge an operation is about to change, say, not of the edges it hands back for re-queueing.
|
inline |