From e3c962bdd10b7eb327d4a4d9af8b4d9ecd04d8b5 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 28 May 2026 18:28:18 +0300 Subject: [PATCH] fix(viewport): adapt entity colours to visible bg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `model_wires_for_viewport` was tessellating with `self.bg_color` (the model bg), so model content rendered inside a paper-layout viewport adapted to a dark bg even though the transparent shader now reveals the PaperCanvas sheet behind it — white wires stayed white on a light sheet. Pass the paper bg in a paper layout. Wire cache also needed an explicit invalidation when the bg or the active layout changes; otherwise the cached, already-adapted wires were returned against the new bg unchanged. - BACKGROUND command bumps `geometry_epoch` after both branches - new `Scene::set_current_layout` setter bumps on actual change; layout switch + history restore use it --- src/app/commands.rs | 6 ++++++ src/app/history.rs | 6 +++++- src/app/update.rs | 2 +- src/scene/mod.rs | 25 ++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/app/commands.rs b/src/app/commands.rs index 4fd5cc098..1990093dd 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -51,6 +51,11 @@ impl OpenCADStudio { self.tabs[i].bg_color = None; self.tabs[i].scene.bg_color = [0.11, 0.11, 0.11, 1.0]; } + // Wire colour adaptation (`adapt_to_bg`) reads the bg + // at tessellation time, so the cached wires need to + // refresh — otherwise a light→dark bg flip leaves + // black lines invisible against the new bg. + self.tabs[i].scene.bump_geometry(); self.command_line .push_output("Background reset to default."); } else if args.len() >= 3 { @@ -64,6 +69,7 @@ impl OpenCADStudio { self.tabs[i].bg_color = Some([r, g, b, 1.0]); self.tabs[i].scene.bg_color = [r, g, b, 1.0]; } + self.tabs[i].scene.bump_geometry(); self.command_line.push_output(&format!( "Background: rgb({}, {}, {})", args[0], args[1], args[2] diff --git a/src/app/history.rs b/src/app/history.rs index 5d22b83b2..5382b0dbb 100644 --- a/src/app/history.rs +++ b/src/app/history.rs @@ -32,7 +32,11 @@ impl OpenCADStudio { pub(super) fn restore_history_snapshot(&mut self, i: usize, snapshot: HistorySnapshot) { self.tabs[i].scene.document = snapshot.document; - self.tabs[i].scene.current_layout = snapshot.current_layout; + self.tabs[i].scene.set_current_layout(snapshot.current_layout); + // Force a re-tessellation: the cached wires were keyed against the + // outgoing document / layout and would be returned unchanged + // otherwise (`set_current_layout` only bumps on actual change). + self.tabs[i].scene.bump_geometry(); self.tabs[i].scene.selected = snapshot .selected .into_iter() diff --git a/src/app/update.rs b/src/app/update.rs index 3b9c87300..20e30ff44 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -3501,7 +3501,7 @@ impl OpenCADStudio { self.layout_rename_state = None; self.layout_context_menu = None; self.tabs[i].scene.active_viewport = None; - self.tabs[i].scene.current_layout = name; + self.tabs[i].scene.set_current_layout(name); self.tabs[i].scene.deselect_all(); self.tabs[i].scene.restore_saved_camera(); self.tabs[i].last_synced_camera_gen = self.tabs[i].scene.camera_generation; diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 2b354730b..bf69df43d 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -721,6 +721,17 @@ impl Scene { self.geometry_epoch = GEOMETRY_EPOCH.fetch_add(1, Ordering::Relaxed); } + /// Switch the active layout. Bumps `geometry_epoch` so the wire cache + /// re-tessellates — `render_style`'s `adapt_to_bg` picks the model or + /// paper background depending on `current_layout`, so cached wires + /// from the previous layout would be coloured against the wrong bg. + pub fn set_current_layout(&mut self, name: String) { + if self.current_layout != name { + self.current_layout = name; + self.bump_geometry(); + } + } + /// Returns true if this viewport should display model-space content /// (i.e. it is a user viewport, not the sheet/overall viewport). /// @@ -4839,6 +4850,18 @@ impl Scene { let model_block = self.model_space_block_handle(); let blk_cache = self.block_cache_arc(); + // The visible background inside a paper-layout content viewport is + // the PaperCanvas sheet showing through the transparent shader, + // not the model bg. Adapt entity colours to the paper bg in that + // case so white wires on a light sheet turn black (and vice + // versa). In a Model layout this is unreachable in practice + // (active_viewport is a paper concept), but fall back to model bg + // just to stay consistent with the rest of the renderer. + let bg = if self.current_layout == "Model" { + self.bg_color + } else { + self.paper_bg_color + }; self.document .entities() @@ -4878,7 +4901,7 @@ impl Scene { &self.selected, self.active_viewport, self.world_offset, - self.bg_color, + bg, vp_anno_scale, e, Some(&blk_cache),