re: 98.7% coverage, and the scale-free degeneracy fix is refuted
Under the winding gate, coverage is 6212/6294 (98.7%) with 82 misses left, attributed 42 degenerate/extent, 31 winding, 9 coverage, 0 connectivity. The biggest bucket turns out NOT to be the blocker: replacing the absolute area test with a scale-free collinearity test decodes no more resources and raises inconsistency 39 -> 44, and dropping the extent floor to 0.05 adds two. Both stay as opt-in knobs (XBG7_REL_DEGEN, XBG7_MIN_EXTENT) rather than defaults. Also fixed another stale default label in edge_cap_sweep. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,6 @@ fn main() {
|
||||
}
|
||||
println!(
|
||||
"cap={} models={models} verts={verts} shared={shared} inconsistent={inconsistent}",
|
||||
std::env::var("XBG7_EDGE_CAP").unwrap_or_else(|_| "0.42 (default)".into())
|
||||
std::env::var("XBG7_EDGE_CAP").unwrap_or_else(|_| "library default".into())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -831,7 +831,10 @@ pub fn debug_best_rejection(bytes: &[u8], name: &str) -> Option<(usize, String)>
|
||||
if vb < idx_bytes + pad {
|
||||
continue;
|
||||
}
|
||||
let mc = if pad == 0 { 0.0 } else { 0.85 };
|
||||
// Mirror production exactly: the pad-0 path now carries the winding
|
||||
// floor too. Reporting at 0.0 would accept blocks the decoder
|
||||
// rejects and point at the wrong gate.
|
||||
let mc = if pad == 0 { pad0_consistency() } else { 0.85 };
|
||||
if let Err(why) = validate_block_report(
|
||||
bytes,
|
||||
vb - idx_bytes - pad,
|
||||
@@ -966,6 +969,22 @@ fn edge_cap() -> f32 {
|
||||
std::env::var("XBG7_EDGE_CAP").ok().and_then(|v| v.parse().ok()).unwrap_or(1.0)
|
||||
}
|
||||
|
||||
/// Smallest bounding-box extent a block may have (default `0.5`). An absolute
|
||||
/// floor on a format with no unit convention is a scale assumption, so it is a
|
||||
/// knob: `XBG7_MIN_EXTENT`.
|
||||
fn min_extent() -> f32 {
|
||||
std::env::var("XBG7_MIN_EXTENT").ok().and_then(|v| v.parse().ok()).unwrap_or(0.5)
|
||||
}
|
||||
|
||||
/// Use a scale-free collinearity test for degeneracy instead of the absolute
|
||||
/// triangle-area one (`XBG7_REL_DEGEN=1`). More principled in the abstract — an
|
||||
/// absolute area threshold calls a small object's every triangle degenerate —
|
||||
/// but measured on this disc it decodes **no more** resources and raises
|
||||
/// cross-container inconsistency 39 → 44, so it is **not** the default.
|
||||
fn rel_degen() -> bool {
|
||||
std::env::var("XBG7_REL_DEGEN").is_ok()
|
||||
}
|
||||
|
||||
/// Winding-consistency floor for the pad-0 single-block anchor.
|
||||
///
|
||||
/// **0.70 since 2026-08-12.** A triangle's face normal should agree with its
|
||||
@@ -1278,7 +1297,21 @@ fn validate_block_report(
|
||||
u[2] * w[0] - u[0] * w[2],
|
||||
u[0] * w[1] - u[1] * w[0],
|
||||
];
|
||||
if 0.5 * (cx[0] * cx[0] + cx[1] * cx[1] + cx[2] * cx[2]).sqrt() < 1.0e-9 {
|
||||
// Degeneracy = collinear vertices, which is a SCALE-FREE property:
|
||||
// compare the cross-product magnitude to the two edge lengths that
|
||||
// produced it (i.e. sin of the angle between them). The old absolute
|
||||
// `area < 1e-9` test called a small object's every triangle degenerate —
|
||||
// `g005` spans 0.346 units and scored 7 of 8 — so it rejected tiny props
|
||||
// for being tiny. `XBG7_ABS_DEGEN=1` restores the absolute test.
|
||||
let cross = (cx[0] * cx[0] + cx[1] * cx[1] + cx[2] * cx[2]).sqrt();
|
||||
let un = (u[0] * u[0] + u[1] * u[1] + u[2] * u[2]).sqrt();
|
||||
let wn = (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt();
|
||||
let is_degenerate = if rel_degen() {
|
||||
cross < 1.0e-6 * un * wn || un == 0.0 || wn == 0.0
|
||||
} else {
|
||||
0.5 * cross < 1.0e-9
|
||||
};
|
||||
if is_degenerate {
|
||||
degenerate += 1;
|
||||
} else if let Some(no) = decl.normal_offset {
|
||||
// Stored-normal agreement: the face normal should point the way
|
||||
@@ -1305,7 +1338,7 @@ fn validate_block_report(
|
||||
t += tstep;
|
||||
}
|
||||
let extent = (hi[0] - lo[0]).max(hi[1] - lo[1]).max(hi[2] - lo[2]);
|
||||
if extent < 0.5 || sampled == 0 || degenerate * 10 > sampled * 3 {
|
||||
if extent < min_extent() || sampled == 0 || degenerate * 10 > sampled * 3 {
|
||||
return Err(format!(
|
||||
"extent {extent:.3} (min 0.5), {degenerate}/{sampled} degenerate (max 30%)"
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user