Split a mesh into one closed solid per zone, plus the remainder.
positions is flat XYZ (f64, caller's frame), indices flat triangle
indices. zones is flat, SEVEN numbers per zone:
[cx, cy, cz, sx, sy, sz, rotationY], where the sizes are FULL extents
(matching the viewer's Zone.size) and the rotation is radians about the
vertical axis. A trailing partial zone is ignored rather than guessed at.
A zone becomes a PRISM (#2508 item 4) when footprint_counts[i] is at
least 3: it then takes that many [x, z] pairs from footprints, in order,
and uses the 7-tuple only for its vertical extent (cy +/- sy/2). The
footprint must be CONVEX; the viewer gates that on import, because a concave
polygon fans into overlapping triangles and would cut wrong rather than
fail. A count of 1 or 2 is not a polygon: it still consumes its pairs, so
later zones stay aligned, and leaves that zone a box. Passing empty arrays
keeps every zone a box.
The caller must have established that the mesh is a closed orientable solid
first, exactly as it must before quoting a volume at all (#1891/#1993): a
clip of an open shell produces pieces whose volumes are arbitrary rather
than approximate.
A triangle with an out-of-range index or a non-finite coordinate is DROPPED
rather than reported, matching kernel::mesh_bridge::mesh_to_tris, which is
panic-free for the same reason: the alternative is a crash deep in the
predicates. It does mean a malformed caller can open the surface and get
meaningless volumes with a plausible sumErrorRel, so the closure proof
above is the caller's responsibility and not a formality.
Returns undefined when the mesh encloses no volume (no triangles survive
the filter above, or the shell is degenerate): there is nothing to split,
and a result for it would report pieceCount 1, sumErrorRel 0 and
remainderFailed false, a perfect split of nothing. A caller that gates
on those numbers must treat undefined as "no split", not as "no error".
constsplit = splitMeshByZones(positions, indices, newFloat64Array([ 0, 0, 0, 10, 10, 10, 0, ])); if (!split) return; // the mesh encloses no volume for (leti = 0; i < split.pieceCount; i++) { constpiece = split.piece(i); // piece.zoneIndex, piece.positions, piece.indices, piece.volume piece.free(); } split.free();
Split a mesh into one closed solid per zone, plus the remainder.
positionsis flat XYZ (f64, caller's frame),indicesflat triangle indices.zonesis flat, SEVEN numbers per zone:[cx, cy, cz, sx, sy, sz, rotationY], where the sizes are FULL extents (matching the viewer'sZone.size) and the rotation is radians about the vertical axis. A trailing partial zone is ignored rather than guessed at.A zone becomes a PRISM (#2508 item 4) when
footprint_counts[i]is at least 3: it then takes that many[x, z]pairs fromfootprints, in order, and uses the 7-tuple only for its vertical extent (cy +/- sy/2). The footprint must be CONVEX; the viewer gates that on import, because a concave polygon fans into overlapping triangles and would cut wrong rather than fail. A count of 1 or 2 is not a polygon: it still consumes its pairs, so later zones stay aligned, and leaves that zone a box. Passing empty arrays keeps every zone a box.The caller must have established that the mesh is a closed orientable solid first, exactly as it must before quoting a volume at all (#1891/#1993): a clip of an open shell produces pieces whose volumes are arbitrary rather than approximate.
A triangle with an out-of-range index or a non-finite coordinate is DROPPED rather than reported, matching
kernel::mesh_bridge::mesh_to_tris, which is panic-free for the same reason: the alternative is a crash deep in the predicates. It does mean a malformed caller can open the surface and get meaningless volumes with a plausiblesumErrorRel, so the closure proof above is the caller's responsibility and not a formality.Returns
undefinedwhen the mesh encloses no volume (no triangles survive the filter above, or the shell is degenerate): there is nothing to split, and a result for it would reportpieceCount1,sumErrorRel0 andremainderFailedfalse, a perfect split of nothing. A caller that gates on those numbers must treatundefinedas "no split", not as "no error".