fix(xref): blocks respect their internal draw order
Xref merge now inserts entities in the source block's chain order and carries SortEntitiesTable objects across (remapped to merged handles). draw_depth_map values become [depth, half] so exploded block/xref fills and wide-polyline band wires both compose child depth as insert_depth + in-block rank x half, recursing into nested inserts with the same divisor - bands and fills from one block interleave by the block's internal order instead of stacking at the insert's single depth. Band batches split per rank via WireModel.depth_override; thin wires stay merged. The wire arena falls back to a full rebuild when a slab carries mixed depths so refreshes don't flatten band overrides. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1546c1dc30
commit
e177f92ff5
48 changed files with 337 additions and 50 deletions
|
|
@ -754,7 +754,7 @@ impl Scene {
|
|||
if self.selected.contains(&handle) {
|
||||
m.color = [0.15, 0.55, 1.00, m.color[3]];
|
||||
}
|
||||
let d = depth_map.get(&handle.value()).copied().unwrap_or(0.0);
|
||||
let d = depth_map.get(&handle.value()).map_or(0.0, |d| d[0]);
|
||||
m.draw_depth = d;
|
||||
if let Some(b) = &mut backdrop {
|
||||
b.draw_depth = d;
|
||||
|
|
@ -814,6 +814,21 @@ impl Scene {
|
|||
.unwrap_or(false)
|
||||
};
|
||||
let mut models: Vec<HatchModel> = Vec::new();
|
||||
// Draw-order composition (#408): every fill inherits its INSERT's
|
||||
// draw-depth slot, offset by the child's rank INSIDE its block
|
||||
// (draw_depth_map ranks per owning block), scaled to stay within the
|
||||
// insert's half-gap in the host ordering. Without this every block /
|
||||
// xref fill landed at depth 0 and the stack's LIFO pop reversed the
|
||||
// block's internal stacking.
|
||||
let depth_map = self.draw_depth_map();
|
||||
let block_count = |name: &str| -> usize {
|
||||
self.document
|
||||
.block_records
|
||||
.get(name)
|
||||
.map(|br| br.entity_handles.len())
|
||||
.unwrap_or(1)
|
||||
.max(1)
|
||||
};
|
||||
// Exploding an INSERT materializes (clones) every child of its block —
|
||||
// including 3D solids that each carry megabytes of SAB geometry — just
|
||||
// to scan the result for hatch fills. On xref-heavy drawings whose
|
||||
|
|
@ -874,17 +889,22 @@ impl Scene {
|
|||
&self.document,
|
||||
&ins.common.layer,
|
||||
);
|
||||
let [base_depth, half_gap] = depth_map
|
||||
.get(&ins.common.handle.value())
|
||||
.copied()
|
||||
.unwrap_or([0.0, 0.0]);
|
||||
let mut stack: Vec<(
|
||||
EntityType,
|
||||
usize,
|
||||
[f32; 4],
|
||||
crate::scene::view::render::InheritStyle,
|
||||
(f32, f32),
|
||||
)> = ins
|
||||
.explode_from_document(&self.document)
|
||||
.into_iter()
|
||||
.map(|e| (normalize(e), 0usize, ins_color, l0))
|
||||
.map(|e| (normalize(e), 0usize, ins_color, l0, (base_depth, half_gap)))
|
||||
.collect();
|
||||
while let Some((sub, depth, sub_ins_color, sub_l0)) = stack.pop() {
|
||||
while let Some((sub, depth, sub_ins_color, sub_l0, (d_base, d_half))) = stack.pop() {
|
||||
match sub {
|
||||
EntityType::Insert(nins) => {
|
||||
if depth >= 32 {
|
||||
|
|
@ -916,8 +936,22 @@ impl Scene {
|
|||
&nins.common.layer,
|
||||
)
|
||||
};
|
||||
// Nested insert: its slot = parent slot + its rank in
|
||||
// the parent block, subdivided by its own block size.
|
||||
let nd_base = d_base
|
||||
+ depth_map
|
||||
.get(&nins.common.handle.value())
|
||||
.map_or(0.0, |d| d[0])
|
||||
* d_half;
|
||||
let nd_half = d_half / (block_count(&nins.block_name) as f32 + 1.0);
|
||||
for e in nins.explode_from_document(&self.document) {
|
||||
stack.push((normalize(e), depth + 1, child_ins_color, child_l0));
|
||||
stack.push((
|
||||
normalize(e),
|
||||
depth + 1,
|
||||
child_ins_color,
|
||||
child_l0,
|
||||
(nd_base, nd_half),
|
||||
));
|
||||
}
|
||||
}
|
||||
EntityType::Hatch(dxf) => {
|
||||
|
|
@ -942,6 +976,12 @@ impl Scene {
|
|||
if let Some(mut model) =
|
||||
Self::hatch_model_from_dxf(&dxf, color)
|
||||
{
|
||||
// In-block rank → within the insert's depth slot.
|
||||
model.draw_depth = d_base
|
||||
+ depth_map
|
||||
.get(&dxf.common.handle.value())
|
||||
.map_or(0.0, |d| d[0])
|
||||
* d_half;
|
||||
if let Some(poly) = &clip_poly {
|
||||
let clipped = pick::xclip::clip_hatch_boundary(
|
||||
&model.boundary,
|
||||
|
|
|
|||
Loading…
Reference in a new issue