forked from 1b-agent/opencadstudio-upstream
fix(render): annotative scale representations + model-space linetype scale
Two rendering defects surfaced on the budweiser benchmark drawings, both tied to a drawing's annotation scale. Annotative scale representations. A drawing may materialise each annotation scale as its own object (here a block insert per scale, on a "0 @ <scale>" layer, each carrying a per-object AcDbContextData bound to one scale). Nothing filtered them, so every scale drew at once — a 1× copy stacked under a 10× one. Add annotative::annotative_offscale and apply it in the three paths that expand block content: the wire block-defn cache, the resident/top-level visibility gate (model space only — paper viewports use their per-viewport frozen scale layers), and the exploded-insert hatch/fill walk (filtered before normalize strips the handle). An object is shown when a representation matches the current scale; the off-scale ones are hidden. When the current scale is unsupported by any representation, fall back to the base "1:1" copy instead of hiding everything (the object must not vanish) or showing everything (the copies must not stack). Model-space linetype scale. PSLTSCALE (a paper-space flag) was applied to model-space linetypes via the annotation scale, so a drawing saved at e.g. CANNOSCALE 10:1 drew its linetypes 10× off. Thread a `paper_space` flag through tessellate_entity and gate the PSLTSCALE factor on it, so it only scales linetypes for content shown inside a paper-space viewport; model space keeps LTSCALE × CELTSCALE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
5e2b67c642
commit
d54fb9e2aa
5 files changed
+113
-2
No files matched your search
@@ -912,6 +912,14 @@ impl Scene {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
// Off-scale annotative representation (model space only — paper
|
||||
// viewports use their per-viewport frozen scale layers). Skips its
|
||||
// whole fill subtree, matching the wire path.
|
||||
if frozen.is_none()
|
||||
&& crate::scene::annotative::annotative_offscale(&self.document, &ins.common)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if !self.block_has_hatch(&ins.block_name, &mut hatch_block_memo)
|
||||
&& !self.block_has_wide_poly(&ins.block_name, &mut wide_block_memo)
|
||||
{
|
||||
@@ -942,6 +950,17 @@ impl Scene {
|
||||
.get(&ins.common.handle.value())
|
||||
.copied()
|
||||
.unwrap_or([0.0, 0.0]);
|
||||
// Drop off-scale annotative representations (e.g. a 10× copy on
|
||||
// layer "0 @ 10" when the current scale is 1:1) before `normalize`
|
||||
// strips their handle — otherwise their whole fill subtree stacks
|
||||
// under the current-scale copy. Model space only; paper viewports
|
||||
// use their per-viewport frozen scale layers. `explode` preserves
|
||||
// the child handle, so the membership lookup still resolves here.
|
||||
let offscale = |e: &EntityType| -> bool {
|
||||
frozen.is_none()
|
||||
&& matches!(e, EntityType::Insert(ni)
|
||||
if crate::scene::annotative::annotative_offscale(&self.document, &ni.common))
|
||||
};
|
||||
let mut stack: Vec<(
|
||||
EntityType,
|
||||
usize,
|
||||
@@ -950,6 +969,7 @@ impl Scene {
|
||||
(f32, f32),
|
||||
)> = explode_including_dims(ins, &self.document)
|
||||
.into_iter()
|
||||
.filter(|e| !offscale(e))
|
||||
.map(|e| (normalize(e), 0usize, ins_color, l0, (base_depth, half_gap)))
|
||||
.collect();
|
||||
while let Some((sub, depth, sub_ins_color, sub_l0, (d_base, d_half))) = stack.pop() {
|
||||
@@ -993,6 +1013,9 @@ impl Scene {
|
||||
* d_half;
|
||||
let nd_half = d_half / (block_count(&nins.block_name) as f32 + 1.0);
|
||||
for e in explode_including_dims(&nins, &self.document) {
|
||||
if offscale(&e) {
|
||||
continue;
|
||||
}
|
||||
stack.push((
|
||||
normalize(e),
|
||||
depth + 1,
|
||||
|
||||
Reference in new issue
Block a user