1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! Six-times-the-signed-volume of a triangle list (divergence theorem), the
//! orientation + volume-magnitude primitive for [`super::mesh_bridge`].
use Tri;
/// Six times the SIGNED volume of the tetrahedron `(o, a, b, c)`:
/// `(a−o)·((b−o)×(c−o))`.
///
/// THE single tetrahedron determinant behind every divergence-theorem sum in
/// the crate — [`signed_volume6`] below and the per-segment volume in
/// [`crate::geom_hash::GeometryHasher`] both fold this one expression, so the
/// two cannot drift into subtly different arithmetic (or differing
/// associativity, which on a near-cancelling sum is a real difference). Plain
/// FMA-free `f64` for native==wasm bit-parity, same as the caller below.
///
/// Summed over a CLOSED, consistently-wound surface this telescopes to `6·V`
/// and is independent of `o`. Over an OPEN one it is not: the boundary-loop
/// flux scales with `|o|`, which is why callers must establish closedness
/// before reading the total as a volume.
pub
/// Twice-the-signed-volume sum for a triangle list (divergence theorem, ×6):
/// `Σ (v0−o)·((v1−o)×(v2−o))`, ABOUT THE OPERAND'S OWN AABB CENTER `o`. A closed
/// outward-wound mesh has this `> 0`; an inward-wound one `< 0`. Computed in
/// plain FMA-free f64 over the snapped operand coords, so only its SIGN is
/// consumed for orientation — byte-identical native==wasm. The MAGNITUDE (6×
/// the volume) is also read by `subtract_many`'s volume-safety check, where a
/// generous 1% tolerance keeps the accept/reject branch parity-stable.
///
/// WHY the local reference point: for a CLOSED mesh
/// the sign is translation-invariant, so the reference is free. But an operand
/// that re-enters a SEQUENTIAL void-cut loop can carry sliver cracks from the
/// previous subtract (flush-interface seams, the open-edge family) — and for an
/// OPEN surface the divergence sum is translation-VARIANT: the boundary-loop
/// flux grows linearly with the distance to the reference point. Referenced to
/// the WORLD origin, a 250–410 m-out tunnel wall with a 2.65 m sliver crack read
/// `vol < 0` (e.g. −59.8 from a +0.30 m³ solid), which made [`orient_outward`]
/// flip the whole host inside-out and invert the next cut (#198779's −49.3
/// cascade). About the AABB center the crack flux is bounded by the operand's
/// own extent — the sign is decided by the solid, not by where the model sits.
pub
/// Enclosed volume of a closed triangle soup, in the operands' own units.
///
/// [`signed_volume6`] returns SIX times the volume: it skips the constant
/// divide per tetrahedron, which is free for the sign tests the boolean's
/// keep/flip rules use it for. A caller that wants the VOLUME divides once,
/// here, rather than growing a second hand-rolled sum in another module, which
/// is how two producers of the same number start to disagree.
pub