Log which body/step fails inside tessellate_sat() instead of a silent None
Every early-out here (a bad-body abort, or zero triangles produced) used to vanish with no trace anywhere, including upstream's own UI - the exact reason the open '3D solids don't survive save/reopen' bug has resisted diagnosis so far. Now logs the body index, which step failed, and (for the zero-bodies case) how many surfaces/curves/pointers lift() couldn't resolve, so the next real occurrence is diagnosable from the browser console instead of another silent None. No behavior change - purely diagnostic.
This commit is contained in:
parent
0d654a8a79
commit
6bfdd6c31d
1 changed files with 44 additions and 5 deletions
|
|
@ -27,13 +27,43 @@ pub fn tessellate_sat(
|
|||
isolines: usize,
|
||||
) -> Option<MeshLodSet> {
|
||||
let (bodies, loss) = lift(document);
|
||||
let body_count = bodies.len();
|
||||
if bodies.is_empty() {
|
||||
log::warn!(
|
||||
"tessellate_sat({name}): lift() returned zero bodies - {} unsupported surface(s), {} unsupported curve(s), {} broken/malformed pointer(s) - nothing to draw",
|
||||
loss.surfaces.len(),
|
||||
loss.curves.len(),
|
||||
loss.broken.len()
|
||||
);
|
||||
return None;
|
||||
}
|
||||
let mut placed_bodies = Vec::with_capacity(bodies.len());
|
||||
for body in bodies {
|
||||
let source = body.provenance.source()?;
|
||||
let transform = body_transform(document, source.index() as usize).ok()?;
|
||||
// Each of the three early-outs below used to be a bare `?`, which - since
|
||||
// this is a plain `for` loop, not a closure - aborted the *entire*
|
||||
// document (discarding every other body's perfectly good geometry, not
|
||||
// just the one that failed) with zero trace anywhere, including
|
||||
// upstream's own UI. That's the exact "reopen shows nothing, Zoom
|
||||
// Extents finds nothing" symptom this function has been blamed for.
|
||||
// Logging *which* body and *which* step failed turns the next real
|
||||
// occurrence into something diagnosable from a browser console instead
|
||||
// of another silent None (CMMS incident, 2026-08-27).
|
||||
let mut placed_bodies = Vec::with_capacity(body_count);
|
||||
for (index, body) in bodies.into_iter().enumerate() {
|
||||
let Some(source) = body.provenance.source() else {
|
||||
log::warn!(
|
||||
"tessellate_sat({name}): body {index}/{body_count} has no provenance source - aborting the whole document instead of just this body"
|
||||
);
|
||||
return None;
|
||||
};
|
||||
let transform = match body_transform(document, source.index() as usize) {
|
||||
Ok(t) => t,
|
||||
Err(err) => {
|
||||
log::warn!(
|
||||
"tessellate_sat({name}): body {index}/{body_count} (source record {}) has no resolvable transform: {err:?} - aborting the whole document",
|
||||
source.index()
|
||||
);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let placement_scale = transform.map_or(1.0, |(_, _, scale)| scale.abs());
|
||||
let placed = if let Some((matrix, translation, scale)) = transform {
|
||||
let placement = brep::Placement {
|
||||
|
|
@ -42,7 +72,13 @@ pub fn tessellate_sat(
|
|||
z_axis: [scale * matrix[6], scale * matrix[7], scale * matrix[8]],
|
||||
origin: translation,
|
||||
};
|
||||
brep::transform(&body, &placement)?
|
||||
let Some(placed) = brep::transform(&body, &placement) else {
|
||||
log::warn!(
|
||||
"tessellate_sat({name}): body {index}/{body_count} failed brep::transform() - aborting the whole document"
|
||||
);
|
||||
return None;
|
||||
};
|
||||
placed
|
||||
} else {
|
||||
body
|
||||
};
|
||||
|
|
@ -160,6 +196,9 @@ pub fn tessellate_sat(
|
|||
}
|
||||
}
|
||||
if indices.is_empty() {
|
||||
log::warn!(
|
||||
"tessellate_sat({name}): {body_count} placed bodies produced zero triangles ({undrawn} face(s) undrawn) - every face was either missing or unrepresentable in its surface's own parameters"
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue