forked from 1b-agent/opencadstudio-upstream
fix(scene): render INSERT attribute values
Inserting a block with attributes (ATTRIB entities attached to the INSERT) drew only the block's primary geometry — the attribute values the user filled in were silently dropped. block_cache::expand_insert walks the block's BlockRecord which lists the ATTDEF templates, not the per-INSERT ATTRIB instances, so they were never tessellated. Add append_insert_attribute_wires: after expanding the block sub-wires, iterate ins.attributes, skip the entries flagged invisible, and emit a text wire for each at its stored WCS position. The wire's name reuses the parent INSERT handle so selection / picking still treats the block and its attribute text as one entity. Runs on both the block-cache fast path and the legacy explode fallback. Closes #20 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0e2b6282a
commit
e0ec7f1999
1 file changed
+103
@@ -4778,6 +4778,27 @@ fn tessellate_entity(
|
||||
is_xref,
|
||||
bg_color,
|
||||
) {
|
||||
// Per-INSERT attribute values. The block defn carries the
|
||||
// AttributeDefinitions (templates) which expand_insert skips;
|
||||
// the AttributeEntity instances live on the Insert itself in
|
||||
// WCS and need their own tessellation so the user sees the
|
||||
// values they actually filled in. See #20.
|
||||
append_insert_attribute_wires(
|
||||
&mut wires,
|
||||
document,
|
||||
ins,
|
||||
h,
|
||||
sel,
|
||||
ins_color,
|
||||
ins_pat_len,
|
||||
ins_pat,
|
||||
ins_lw_px,
|
||||
bg_color,
|
||||
is_xref,
|
||||
pslt_factor,
|
||||
anno_scale,
|
||||
world_offset,
|
||||
);
|
||||
wires.push(marker);
|
||||
return wires;
|
||||
}
|
||||
@@ -4832,6 +4853,22 @@ fn tessellate_entity(
|
||||
vec![wire]
|
||||
})
|
||||
.collect();
|
||||
append_insert_attribute_wires(
|
||||
&mut wires,
|
||||
document,
|
||||
ins,
|
||||
h,
|
||||
sel,
|
||||
ins_color,
|
||||
ins_pat_len,
|
||||
ins_pat,
|
||||
ins_lw_px,
|
||||
bg_color,
|
||||
is_xref,
|
||||
pslt_factor,
|
||||
anno_scale,
|
||||
world_offset,
|
||||
);
|
||||
wires.push(marker);
|
||||
return wires;
|
||||
}
|
||||
@@ -5089,6 +5126,72 @@ pub(crate) fn text_obb_corners_native(
|
||||
])
|
||||
}
|
||||
|
||||
/// Tessellate each visible AttributeEntity attached to an Insert and append
|
||||
/// the resulting wires. AttributeEntity positions are already in WCS — the
|
||||
/// INSERT only stamps the geometry once, attribute text sits at the world
|
||||
/// position recorded on each ATTRIB. See #20.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn append_insert_attribute_wires(
|
||||
wires: &mut Vec<WireModel>,
|
||||
document: &acadrust::CadDocument,
|
||||
ins: &acadrust::entities::Insert,
|
||||
insert_handle: Handle,
|
||||
sel: bool,
|
||||
ins_color: [f32; 4],
|
||||
ins_pat_len: f32,
|
||||
ins_pat: [f32; 8],
|
||||
ins_lw_px: f32,
|
||||
bg_color: [f32; 4],
|
||||
is_xref: bool,
|
||||
pslt_factor: f32,
|
||||
anno_scale: f32,
|
||||
world_offset: [f64; 3],
|
||||
) {
|
||||
if ins.attributes.is_empty() {
|
||||
return;
|
||||
}
|
||||
for attr in &ins.attributes {
|
||||
if attr.common.invisible || attr.flags.invisible {
|
||||
continue;
|
||||
}
|
||||
let attr_entity = EntityType::AttributeEntity(attr.clone());
|
||||
let (sub_color, sub_plen, sub_pat, sub_lw_px, sub_aci) =
|
||||
render::render_style_for_block_sub(
|
||||
document,
|
||||
&attr_entity,
|
||||
ins_color,
|
||||
ins_pat_len,
|
||||
ins_pat,
|
||||
ins_lw_px,
|
||||
);
|
||||
let sub_color = render::adapt_to_bg(sub_color, bg_color);
|
||||
let sub_color = if is_xref && !sel {
|
||||
block_cache::fade_toward_bg(sub_color, bg_color)
|
||||
} else {
|
||||
sub_color
|
||||
};
|
||||
let sub_aabb = entity_aabb(&attr_entity, world_offset);
|
||||
let mut wire = tessellate::tessellate(
|
||||
document,
|
||||
insert_handle,
|
||||
&attr_entity,
|
||||
sel,
|
||||
sub_color,
|
||||
sub_plen * pslt_factor,
|
||||
sub_pat.map(|v| v * pslt_factor),
|
||||
sub_lw_px,
|
||||
world_offset,
|
||||
anno_scale,
|
||||
);
|
||||
// Use the INSERT's handle so selection / picking groups attribute
|
||||
// text with the parent insert instead of treating it as a stray text.
|
||||
wire.name = insert_handle.value().to_string();
|
||||
wire.aci = sub_aci;
|
||||
wire.aabb = sub_aabb;
|
||||
wires.push(wire);
|
||||
}
|
||||
}
|
||||
|
||||
/// NaN-separated baseline segments — one per visible wrap line — for a
|
||||
/// sub-pixel Text / MText, in world-offset-subtracted f32 space. `n_lines`
|
||||
/// must be the actual rendered line count (1 for Text, the wrap-expanded
|
||||
|
||||
Reference in new issue
Block a user