fix(scene): render baked block geometry for Dimension and Table
AutoCAD bakes a per-instance block with the final, displayed geometry into Dimension and Table entities (typically *D### / *T###, but custom names also occur — sample-file-H uses DIMBLOCK*-4NP). The block's text already encodes DIMTXT * DIMSCALE (or the table's scale factor), so synthesising the entity from the dim/table style on top of that double-applies the scale. When the referenced block exists with content, render it directly: - Dimension: dim.base.block_name -> block_record - Table: block_record_handle -> block_record The synthesis fallback stays in place for files where the block is missing or empty. Fixes sample-file-H.dwg dimensions rendering at 60000 instead of 200 (DIMTXT=199.196 * DIMSCALE=304.8). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
62876b1081
commit
eab72062f9
2 changed files with 95 additions and 0 deletions
|
|
@ -464,6 +464,59 @@ pub fn tessellate_dimension(
|
|||
anno_scale: f32,
|
||||
) -> Vec<WireModel> {
|
||||
let name = handle.value().to_string();
|
||||
|
||||
// ── Anonymous-block fast path ───────────────────────────────────────────
|
||||
//
|
||||
// AutoCAD bakes each dimension's final geometry (extension lines, dim
|
||||
// line, arrows, text MText) into a per-instance block — usually named
|
||||
// `*D<n>`, but some authoring tools use a custom name like
|
||||
// `DIMBLOCK###-4NP`. When that block exists we render its contents
|
||||
// directly: the text height inside the block is the FINAL displayed
|
||||
// height (DIMTXT × DIMSCALE already applied at creation), so
|
||||
// synthesising it from the dim style would double-apply DIMSCALE.
|
||||
let dim_block_name = &dim.base().block_name;
|
||||
if !dim_block_name.trim().is_empty() {
|
||||
if let Some(br) = document
|
||||
.block_records
|
||||
.iter()
|
||||
.find(|br| br.name.eq_ignore_ascii_case(dim_block_name))
|
||||
{
|
||||
if !br.entity_handles.is_empty() {
|
||||
let mut wires: Vec<WireModel> =
|
||||
Vec::with_capacity(br.entity_handles.len());
|
||||
for &eh in &br.entity_handles {
|
||||
let Some(sub) = document.get_entity(eh) else { continue };
|
||||
// Inherit dim's color + line weight when the sub-entity is
|
||||
// ByBlock; ByLayer stays on its own layer.
|
||||
let sub_color = if selected {
|
||||
WireModel::SELECTED
|
||||
} else {
|
||||
entity_color
|
||||
};
|
||||
let mut wire = tessellate(
|
||||
document,
|
||||
handle,
|
||||
sub,
|
||||
selected,
|
||||
sub_color,
|
||||
0.0,
|
||||
[0.0; 8],
|
||||
line_weight_px,
|
||||
world_offset,
|
||||
// Sub-entities are already baked at the final WCS
|
||||
// size; don't re-apply anno_scale.
|
||||
1.0,
|
||||
);
|
||||
wire.name = name.clone();
|
||||
wires.push(wire);
|
||||
}
|
||||
if !wires.is_empty() {
|
||||
return wires;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let style_name = &dim.base().style_name;
|
||||
let style = document.dim_styles.iter().find(|s| {
|
||||
s.name.eq_ignore_ascii_case(style_name)
|
||||
|
|
|
|||
Loading…
Reference in a new issue