forked from 1b-agent/opencadstudio-upstream
fix: restore paper-space viewport rendering as single full-canvas widget
Iced 0.14 batches all shader prepare() calls before any render() calls. Multiple ViewportPane widgets sharing the same Pipeline type overwrite each other's GPU buffers, causing the PaperSheet layer (full-canvas) to render the last viewport's model content — appearing full-screen. Fix: paper_canvas_view() now renders a single full-canvas PaperSheet widget. build_paper_sheet_primitive() is updated to include model-space content projected through each viewport's view matrix (via viewport_content_wires()), restoring the original working behaviour. ViewportPane::Paper mode and viewport_screen_rect() are kept with #[allow(dead_code)] — a per-viewport wgpu sub-renderer that accumulates data across frames could revive them in the future. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
592e3da6ac
commit
d1d4bb3d02
4 files changed
+33
-62
No files matched your search
+13
-52
@@ -457,61 +457,22 @@ impl H7CAD {
|
||||
|
||||
// ── Paper canvas ──────────────────────────────────────────────────────────
|
||||
//
|
||||
// In paper space, the main canvas is composed of:
|
||||
// 1. A full-size PaperSheet layer — renders paper-space entities (title blocks,
|
||||
// frames, borders) with the paper-space camera.
|
||||
// 2. One ViewportPane::Paper widget per Viewport entity, positioned at its
|
||||
// paper-space coordinates and sized to its paper-space dimensions.
|
||||
// Each renders model-space content through its own viewport camera.
|
||||
// 3. The existing selection_overlay / viewport_mouse / nav stack on top
|
||||
// (unchanged — mouse event routing stays the same).
|
||||
// Renders the full paper canvas as a single full-size shader widget using the
|
||||
// PaperSheet mode, which includes both paper-space entities (title blocks,
|
||||
// frames, borders) and model-space content projected through each viewport's
|
||||
// view matrix into paper-space coordinates.
|
||||
//
|
||||
// Note: A per-viewport widget approach (ViewportPane::Paper) was attempted but
|
||||
// does not work correctly because Iced 0.14 batches all shader prepare() calls
|
||||
// before any render() calls, causing widgets that share the same Pipeline type
|
||||
// to overwrite each other's GPU buffers. The CPU-projection approach used here
|
||||
// is the correct solution within Iced's shader framework.
|
||||
|
||||
fn paper_canvas_view<'a>(tab: &'a super::document::DocumentTab) -> Element<'a, Message> {
|
||||
let scene = &tab.scene;
|
||||
|
||||
// Layer 1: paper-space entities (title blocks, frames, paper boundary).
|
||||
let paper_sheet = shader(ViewportPane::paper_sheet(scene))
|
||||
shader(ViewportPane::paper_sheet(&tab.scene))
|
||||
.width(Fill)
|
||||
.height(Fill);
|
||||
|
||||
// Use the last-rendered canvas size to compute pixel positions.
|
||||
// On the very first frame this is (0,0); correct positions appear from
|
||||
// the second frame onward (imperceptible in practice).
|
||||
let (canvas_w, canvas_h) = scene.selection.borrow().vp_size;
|
||||
let vp_list = scene.viewport_list();
|
||||
|
||||
let mut layers = stack![paper_sheet];
|
||||
|
||||
for (handle, _, _) in &vp_list {
|
||||
let Some(rect) = scene.viewport_screen_rect(*handle, (canvas_w, canvas_h)) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Clamp to avoid zero-size or negative widgets.
|
||||
let w = rect.width.max(1.0);
|
||||
let h = rect.height.max(1.0);
|
||||
let x = rect.x.max(0.0);
|
||||
let y = rect.y.max(0.0);
|
||||
|
||||
// Layer 2+: one shader widget per viewport, positioned with Space offsets.
|
||||
let vp_widget = shader(ViewportPane::paper(scene, *handle))
|
||||
.width(iced::Length::Fixed(w))
|
||||
.height(iced::Length::Fixed(h));
|
||||
|
||||
let positioned = column![
|
||||
Space::new().height(iced::Length::Fixed(y)),
|
||||
row![
|
||||
Space::new().width(iced::Length::Fixed(x)),
|
||||
vp_widget,
|
||||
],
|
||||
]
|
||||
.width(Fill)
|
||||
.height(Fill);
|
||||
|
||||
layers = layers.push(positioned);
|
||||
}
|
||||
|
||||
layers.width(Fill).height(Fill).into()
|
||||
.height(Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
// ── Document tab bar ───────────────────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user