fix: decide partition membership by extraction, not by shape

`skipped=false` on every frame of a real session — the skip added in the
previous commit never fired once.

The membership test used the same cheap structural filter that
`partition_wires` uses before attempting extraction: a tangent geom, no
fill, pick or text triangles. That filter is a pre-check, not a decision.
An ordinary drawn line carries a tangent geom for snapping and no
triangles, so it passed, and every drawn line was counted as feeding the
analytical uploads. Nothing was ever skippable.

It now decides the way the walk decides, by attempting the extraction.
`draw_depth` only rides along in the extracted instance, so the value
passed for the test cannot change the answer, and it runs only for the
handful of wires a patch changed.

Drawing a circle or an ellipse still forces the walk, correctly — those
are contributors, and the session that exposed this contained both. What
changes is that the lines drawn afterwards no longer do.

Tested on real tessellated geometry: a line must not force the walk, a
circle must.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
PanosandClaude Opus 5 committed 2026-09-08 16:42:39 +03:00
1 parent 03c64e3d38
commit d46c00281f
2 files changed
+54 -10

No files matched your search

+38
View File
@@ -10660,6 +10660,44 @@ mod journal_tests {
// Differential oracle: the incrementally-patched entity index must always
// equal a from-scratch rebuild after any add / move / erase.
#[test]
/// The partition skip turns on a membership test, and the test has to tell
/// a drawn line from a drawn circle. A line carries a tangent geom for
/// snapping and no triangles, so the cheap structural filter admits it —
/// deciding on that alone called every line a contributor and the skip
/// never fired once in a real session.
#[test]
fn the_partition_membership_test_separates_lines_from_curves() {
use acadrust::entities::{Circle, Line};
use acadrust::types::Vector3;
use crate::scene::pipeline::wire_arena::feeds_analytical_uploads;
let mut scene = Scene::new();
let feeds = |scene: &Scene, handle: Handle| {
let entity = scene.document.get_entity(handle).unwrap().clone();
scene
.tessellate_one(&entity)
.iter()
.any(feeds_analytical_uploads)
};
let line = scene.add_entity(EntityType::Line(Line::from_points(
Vector3::new(0.0, 0.0, 0.0),
Vector3::new(10.0, 5.0, 0.0),
)));
assert!(
!feeds(&scene, line),
"a drawn line must not force the partition walk",
);
let mut circle = Circle::new();
circle.radius = 4.0;
let circle = scene.add_entity(EntityType::Circle(circle));
assert!(
feeds(&scene, circle),
"a drawn circle feeds the analytical uploads and must force the walk",
);
}
/// The partition skip reuses uploads that bake a draw depth, and it is only
/// sound while existing depths hold still. An incremental add must leave
/// them alone and must not bump the generation; a rebuild from scratch may
+16 -10
View File
@@ -184,17 +184,23 @@ pub struct PartitionedWires<'a> {
/// Whether a change to this wire can alter what `partition_wires` produces for
/// the instanced, circle and ellipse uploads.
///
/// Deliberately conservative: a wire that looks analytical here may still fail
/// extraction and end up in `regular`, which costs an unnecessary re-partition
/// and never a stale upload. Shared with `partition_wires` so the test that
/// decides to skip cannot drift from the walk it is skipping.
/// Decided by attempting the extraction, exactly as the walk decides it. The
/// cheap structural test alone is not enough: an ordinary drawn line carries a
/// tangent geom for snapping and no triangles, so it passes that test, fails
/// extraction, and lands in `regular` — a membership test that stopped there
/// would call every line a contributor and never skip anything.
///
/// `draw_depth` only rides along in the extracted instance, so the value passed
/// here cannot change the answer.
pub fn feeds_analytical_uploads(wire: &WireModel) -> bool {
wire.display_visible
&& (wire.render_instance.is_some()
|| (!wire.tangent_geoms.is_empty()
&& wire.fill_tris.is_empty()
&& wire.pick_tris.is_empty()
&& wire.text_verts.is_empty()))
if !wire.display_visible {
return false;
}
if wire.render_instance.is_some() {
return true;
}
super::circle_gpu::extract_circle_instances(wire, 0.0).is_some()
|| super::ellipse_gpu::extract_ellipse_instances(wire, 0.0).is_some()
}
/// Single-pass classification and extraction of all viewport wire categories.