|
Wildmeshing Toolkit
|
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. | |
|
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.
|
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.
| 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.
| 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.