Layouts: a viewport on a frozen layer hides its contents (fixes #395) (#396)

Freezing a viewport's own layer hid only its border; the model space
seen through it still showed on screen and in plots. As in AutoCAD, a
frozen viewport layer now hides the contents too, while turning the
layer off still hides only the border. The check is in the shared
layout path, so display, PDF/SVG/PNG export and plotting agree.

Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Valentin KleinandClaude Opus 5.5 authored and GitHub committed 2026-10-10 18:43:15 -04:00
1 parent 95dc3f22a7
commit 9e19a10b29
2 files changed
+48

No files matched your search

+4
View File
@@ -316,6 +316,10 @@ fn viewport(b: &mut Builder, d: &Drawing, e: &Entity, vp: &cadcraft_doc::Viewpor
if vp.id == 1 || !e.common.visible {
return;
}
// The viewport's layer frozen hides its contents too (layer off hides only the border).
if d.layer(&e.common.layer).is_some_and(|l| l.frozen) {
return;
}
// Border (on the viewport's layer; layer off hides only the border).
entity(b, &top_ctx(d, Mat3::IDENTITY, e.handle, &[], &[]), e);
if b.list.expanded >= MAX_BLOCK_EXPANSION {
@@ -0,0 +1,44 @@
//! A layout viewport whose own layer is frozen shows neither its border nor its contents, on
//! screen and when plotting; turned off, the layer hides only the border (issue #395).
use cadcraft_doc::{Circle, Common, Drawing, EntityKind, Space, Viewport};
use cadcraft_geom::{Vec2, Vec3};
use cadcraft_render::{DisplayList, Options, VIEWPORT_CONTENT, build, build_plot};
fn drawing() -> Drawing {
let mut d = Drawing::new_imperial();
d.add(&Space::Model, Common::default(), EntityKind::Circle(Circle { center: Vec3::ZERO, radius: 5.0 })).unwrap();
d.ensure_layer("VPORTS");
let vp = Viewport {
center: Vec3::new(5.0, 4.0, 0.0),
width: 8.0,
height: 6.0,
view_center: Vec2::ZERO,
view_height: 12.0,
id: 2,
locked: false,
frozen_layers: Vec::new(),
layer_colors: Vec::new(),
};
d.add(&Space::Paper("Layout1".into()), Common { layer: "VPORTS".into(), ..Default::default() }, EntityKind::Viewport(vp)).unwrap();
d
}
/// (contents drawn, border drawn) on screen and in a plot.
fn shown(d: &Drawing) -> [(bool, bool); 2] {
let space = Space::Paper("Layout1".into());
let parts = |l: DisplayList| (l.prims.iter().any(|p| p.handle == VIEWPORT_CONTENT), l.prims.iter().any(|p| p.handle != VIEWPORT_CONTENT));
[parts(build(d, &space, &Options::default())), parts(build_plot(d, &space, &Options::default()))]
}
#[test]
fn frozen_viewport_layer_hides_the_contents_off_only_the_border() {
let mut d = drawing();
assert_eq!(shown(&d), [(true, true); 2]);
d.layer_mut("VPORTS").unwrap().on = false;
assert_eq!(shown(&d), [(true, false); 2], "off: contents stay, border hidden");
let l = d.layer_mut("VPORTS").unwrap();
l.on = true;
l.frozen = true;
assert_eq!(shown(&d), [(false, false); 2], "frozen: contents hidden too");
}