fix(mesh): grouped pools no longer emit sub-meshes with out-of-range indices
coverage_audit measures index coverage per decoded sub-mesh. 8586 of them reference their last vertex exactly, so the 'buffer not covered' gate is well founded -- but 18 had NEGATIVE slack: indices up to 364 vertices past the end of their own buffer, emitted because anchor_grouped_meshes reads pre-pivot sub-meshes unconditionally. Quality gates stay relaxed there (a tiny flat lead part is legitimately poor) but index range is now required. Coverage 6069/6294 unchanged, inconsistency 56 unchanged, truth table still 46/46 claimed, suite green; the vertex total drops by exactly the 1546 garbage verts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -965,6 +965,36 @@ container holds two direct copies **and** two mirrored ones
|
||||
(`0x33b7754`, `0x342e284`); our twins take the two direct copies, which is
|
||||
self-consistent but unverified — `n206` appears in no captured stage.
|
||||
|
||||
### ✅ Fixed: grouped pools emitted sub-meshes with out-of-range indices
|
||||
|
||||
Chasing whether the "buffer not covered" gate is well founded turned up a real
|
||||
defect instead. `examples/coverage_audit.rs` measures, for every decoded
|
||||
sub-mesh, how many tail vertices its indices never reference:
|
||||
|
||||
| unreferenced tail vertices | sub-meshes |
|
||||
|---|---|
|
||||
| **0** (indices reach the last vertex exactly) | **8 586** |
|
||||
| 1–3 (inside the gate's ±4 tolerance) | 48 |
|
||||
| 9, 80 (`f102_break.dat`, `f104_break.dat` in `ptc_pack.xpr`) | 2 |
|
||||
| **negative — indices point PAST the vertex buffer** | **18** |
|
||||
|
||||
The first row answers the original question: real geometry covers its pool
|
||||
**exactly**, so under-coverage is good evidence of a wrong candidate and the gate
|
||||
stands as written.
|
||||
|
||||
The last row is the defect. `anchor_grouped_meshes` reads sub-meshes *before* the
|
||||
pivot unconditionally — deliberately, since a tiny flat lead part legitimately
|
||||
fails the quality gates — but that also skipped the **index-range** check, which
|
||||
is not a quality question. Eighteen sub-meshes disc-wide were emitted with
|
||||
indices reaching up to **364 vertices past the end** of their own buffer, which
|
||||
any renderer would fault on or draw as garbage. Pre-pivot sub-meshes are now
|
||||
required to be in range (quality gates still relaxed); out-of-range ones are
|
||||
dropped and the pool's remaining parts are kept.
|
||||
|
||||
Everything else holds: 6 069/6 294 decoded, cross-container inconsistency 56, the
|
||||
capture truth table still 46/46 claimed with 0 unclaimed, suite green. The vertex
|
||||
total falls by 1 546 — exactly the garbage that is no longer emitted.
|
||||
|
||||
### Coverage has a denominator now, and the misses have a cause breakdown
|
||||
|
||||
Coverage has been quoted as "resources decoded" with no total. `examples/undecoded.rs`
|
||||
|
||||
Reference in New Issue
Block a user