- paper_limits() falls back to A4 landscape (297×210mm) even when no
Layout object exists in the document
- paper_bg_color default changed to white [1,1,1,1] (paper surface color)
- PaperCanvas::draw() fills canvas with dark desk color first, then draws
the paper area rectangle in paper_bg_color so the sheet is clearly
visible against the desk background
- view.rs container background uses the fixed desk color instead of
paper_bg_color so it no longer conflicts with the paper-surface color
- BACKGROUND RESET for paper space now resets to white instead of dark gray
- Removed unused PaperSheet variant, paper_sheet() constructor,
build_paper_sheet_primitive() and associated match arms (dead code
after 2D canvas replacement)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a paper-space viewport is activated (double-click / MSPACE command),
it is now rendered through its own dedicated PaperViewportPipeline rather
than the CPU-projection approach used for inactive viewports.
Architecture:
- PaperSheet widget (full-canvas): renders paper entities + CPU-projected
content of all viewports *except* the active one.
- PaperViewportPane widget (Fixed w×h, positioned at viewport screen rect):
renders the active viewport with a true 3D camera derived from the
viewport's view_direction/view_target/view_height.
PaperViewportPipeline is a newtype of Pipeline. Having a distinct type
gives it its own Iced storage entry (keyed by TypeId), preventing the
shared prepare() overwrite that broke the earlier per-viewport approach.
Changes:
- render.rs: PaperViewportPipeline, PaperViewportPrimitive newtypes;
build_active_viewport_primitive(); build_paper_sheet_primitive() now
excludes active_viewport from CPU projection.
- viewport_pane.rs: PaperViewportPane<'a> with shader::Program impl.
- mod.rs: viewport_content_wires() gains exclude_vp parameter;
viewport_screen_rect() is no longer dead code.
- view.rs: paper_canvas_view() overlays PaperViewportPane when MSPACE
is active.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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 <noreply@anthropic.com>
- Remove Scene: shader::Program<Msg> impl; all GPU rendering now goes
through ViewportPane which supports three modes:
Model — full model-space view (unchanged behaviour)
PaperSheet — paper-space entities only, using the paper camera
Paper — model content through a specific viewport's own camera
- Add Scene helper methods (render.rs):
build_primitive / build_paper_sheet_primitive / build_viewport_primitive
update_viewcube_state / viewcube_mouse_interaction
- Add Scene helpers (mod.rs):
paper_sheet_wires() — paper entities without viewport projection
camera_for_viewport() — derive Camera from Viewport entity data
model_wires_for_viewport() — model wires filtered by per-viewport frozen layers
viewport_screen_rect() — paper-space → pixel rect mapping
- Add paper_canvas_view() in view.rs:
Stack of PaperSheet + one Paper widget per Viewport entity,
positioned with Space offsets from viewport_screen_rect()
- Update VIEWPORT_WIDGET_PLAN.md: mark Steps 1–4 done, document remaining work
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MSAA and depth textures are now sized to the shader widget's clip
bounds instead of the full surface. The resolve writes to a matching
clip-sized intermediate texture; a blit pass (blit.wgsl, viewport
trick) then copies the result to the exact clip region of the surface
target, leaving all other widgets untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All main render pipelines (wire, hatch, image, mesh) now use 4×
multisampling. Drawing passes render to a dedicated MSAA color buffer;
a final empty resolve pass transfers the anti-aliased result to the
iced surface target. The ViewCube renders post-resolve at 1× to avoid
pipeline incompatibility. Depth buffer also upgraded to 4× MSAA.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously wipeout solid fills were part of the hatch pass (pass 1),
drawn before wires (pass 5), so all wires appeared on top of the
wipeout. This fix moves wipeout fills into a dedicated pass 6 that
runs after wires, so the background-colored polygon correctly covers
the lines/text beneath it — matching AutoCAD behaviour.
- Scene.wipeout_models() separated from synced_hatch_models()
- Primitive.wipeout_hatches populated via wipeout_models()
- Pipeline.gpu_wipeouts + upload_wipeouts() + pass 6 after wires
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/io/plot_style.rs: PlotStyleTable and PlotStyleEntry data structures;
CTB reader (deflate/zlib decompressed text format) with ACI→RGB and
ACI→lineweight lookup; CTB writer (zlib compressed); LW_TABLE constant
- src/io/pdf_export.rs: accept optional PlotStyleTable; apply ACI color
and lineweight overrides during PDF rendering
- src/scene/wire_model.rs: add `aci: u8` field to carry ACI index
- src/scene/render.rs: render_style() now returns ACI alongside RGBA
- src/scene/mod.rs + tessellate.rs: propagate aci through wire building
- app: PlotStyleLoad/Loaded/Clear messages and handlers;
PLOTSTYLE LOAD | CLEAR | STATUS command; active_plot_style state on H7CAD
- flate2 added as dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ribbon.rs → ribbon/mod.rs + ribbon/widgets.rs
Extracted all rendering helpers, button styles, colour constants,
layout constants and dropdown position calculators into widgets.rs.
- scene/mod.rs → scene/mod.rs + scene/selection.rs + scene/render.rs
Moved SelectionState into selection.rs; moved CameraState, Primitive,
shader::Program/Primitive impls, render_style and resolve_pattern
into render.rs, reducing mod.rs from 1323 to ~1030 lines.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>