Wildmeshing Toolkit
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | List of all members
wmtk::SurfaceTagAttributes Class Reference

Public Member Functions

InputSet input_set () const
 The INPUT SET: which inputs this simplex covers, bit i for input i. At most max_inputs, the width of InputSet.
 
void set_input_set (InputSet s)
 
void set_orientation (int o)
 Store an orientation already measured against the ascending vertex order, clamped.
 
template<size_t N>
int orientation_along (const std::array< size_t, N > &v) const
 The orientation measured against the simplex ordered as v (which must be its vertices).
 
template<size_t N>
void set_orientation_along (const std::array< size_t, N > &v, int o)
 Store orientation o, measured against the simplex ordered as v.
 
void reset ()
 
void merge (const SurfaceTagAttributes &attr)
 

Static Public Member Functions

template<size_t N>
static int ascending_parity (const std::array< size_t, N > &v)
 +1 if v is an even permutation of its ascending sort, -1 if odd. N is 2 or 3.
 

Public Attributes

bool m_is_surface_fs = false
 Is this simplex part of the tracked surface.
 
int8_t m_is_bbox_fs = -1
 Which bbox side this simplex is on; -1 for none.
 
int8_t m_surface_class: 3
 Which tracked surface this simplex belongs to, for applications that track more than one. 0 to 3.
 
int8_t m_orientation: 5
 The input's orientation on this simplex: a signed count of input sheets lying on it, measured against its vertices in ASCENDING id order. -15 to 15.
 
uint8_t m_input_set [sizeof(InputSet)] = {}
 

Static Public Attributes

static constexpr int max_orientation = 15
 
static constexpr int max_inputs = int(8 * sizeof(InputSet))
 One input per bit of InputSet: the width is set there, and only there.
 

Member Function Documentation

◆ input_set()

InputSet wmtk::SurfaceTagAttributes::input_set ( ) const
inline

The INPUT SET: which inputs this simplex covers, bit i for input i. At most max_inputs, the width of InputSet.

The invariant it carries: a tracked simplex stays within eps of EVERY input in its set – not merely of the union of all inputs, which is what one envelope around everything enforces. With one envelope the solid's tracked boundary may ride on a sheet that crosses it: measured on Thingi10K 104509 cut by a wavy sheet (eps 0.1956), 12 of the 9532 tracked faces separating the solid's inside from its outside ended up farther than eps from the solid (at most 3.61 eps), 7 of them within eps of the sheet, and kept tets reached a sheet vertex 2.50 eps outside the solid. One bit per simplex usually; several where inputs coincide, and then the simplex is held by all of them.

Set at insertion from the arrangement's provenance (tetwild, triwild); 0 on a mesh whose application never set it, which then answers containment without it. The operations carry it like every other field here: a split's halves copy it, merge() – the faces a collapse makes one – takes the union, and a surface flip gives both new simplices the union of the two it replaces. Bytes rather than one uint64_t so the struct keeps alignment 1: eleven bytes, not sixteen.

◆ merge()

void wmtk::SurfaceTagAttributes::merge ( const SurfaceTagAttributes &  attr)
inline

Does NOT combine m_orientation – see there; the caller converts and sums it. The input sets unite: the one simplex left covers what both covered.

Member Data Documentation

◆ m_orientation

int8_t wmtk::SurfaceTagAttributes::m_orientation

The input's orientation on this simplex: a signed count of input sheets lying on it, measured against its vertices in ASCENDING id order. -15 to 15.

For a face (a < b < c), +k means a net k sheets cover it with normal along (b-a) x (c-a); for an edge (a < b), +k means a net k run a -> b. A count rather than a sign so coincident sheets combine the way they do in a winding number: two opposite ones cancel to 0 (a solid resting on another, a fold), two equal ones give 2. A tracked simplex can therefore have orientation 0 and still be constrained; m_is_surface_fs keeps that meaning, and the orientation only feeds winding numbers.

At insertion a SHEET is a set of coincident input triangles (segments) of one orientation: duplicates of one triangle count once, as do the triangles of one coplanar group overlapping the same way, so the count is +-1 or 0 per coplanar group (per input curve in 2D). A collapse merging two separate sheets can make it larger. See embed_triangles_in_tets and embed_segments.

Ascending ids because the value then depends on nothing but the simplex's vertex set: attribute copies keyed by the sorted vertex tuple (the swap trackers), a different slot becoming the simplex's canonical one, and consolidate_mesh (which renumbers monotonically) all leave it valid. Anything that moves a value onto a simplex with a DIFFERENT vertex set – the halves of a split, the faces a collapse merges or renames in place, the faces a surface flip creates – must convert it, through orientation_along / set_orientation_along. merge() does not touch it for that reason: it cannot know the two vertex orders.

Meaningful only on a mesh whose application set it at insertion (TetOptimizerMesh / TriOptimizerMesh::m_tracks_orientation); 0 elsewhere. Writes clamp to the range rather than wrap: a face would need 16 net coincident sheets to reach it.

◆ m_surface_class

int8_t wmtk::SurfaceTagAttributes::m_surface_class

Which tracked surface this simplex belongs to, for applications that track more than one. 0 to 3.

0 is the application's primary surface, and is all tetwild and simwild ever use. topological_offset tracks two – the input complex it must stay in the envelope of, and the offset boundary it is free to move – and uses 1 for the latter. Meaningless, and left at 0, when m_is_surface_fs is false.

The class lives here, on the attribute struct, rather than in a container of its own because the shared operations copy face attributes WHOLESALE – assignment in the split and collapse caches, merge() in collapse_edge_before, reset() in the swap tracker. A field here is carried by all of that for free; a parallel container would be silently dropped by every one of those operations.


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