refactor(viewport): unify content-viewport clipping on the stencil path

Rectangular paper viewports now go through the same GPU stencil clip as
non-rectangular ones: viewport_clip_boundary_ndc returns the four rect
corners (a full-target mask) instead of nothing, so the render path has
no rect/non-rect special case — every content viewport carries a clip
boundary and draws with stencil reference 0xFF.

With a single clip path, the old per-wire / -image / -wipeout scissor
mechanism is fully dead and removed: compute_*_scissors, the
*_pixel_scissors buffers, the project_scissor helper, the per-pass
set_scissor_rect blocks, the vp_scissor field threaded through
WireModel / ImageModel / HatchModel and their GPU mirrors (WireGpu /
ImageGpu / WipeoutGpu / HatchWebGpu), from_run's scissor parameter, the
scissor grouping in build_wire_buffers, and the is_arena_eligible gate.
Net -245 lines across 54 files.

Rectangular viewports still clip exactly via their own render rectangle;
the stencil mask is a redundant full-target no-op there, kept only so
the clip code path stays uniform. XCLIP keeps its CPU wire clip.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-20 11:06:28 +03:00
1 parent c97c2a8250
commit 626e8091f7
54 files changed
+32 -277

No files matched your search

-6
View File
@@ -84,12 +84,6 @@ pub struct HatchModel {
pub angle_offset: f32,
/// Pattern scale multiplier (from DXF `pattern_scale`).
pub scale: f32,
/// Optional world-space XY rect [x0, y0, x1, y1] for paper-space
/// viewport clipping. When `Some`, the pipeline translates it into
/// a per-frame pixel scissor and clips this hatch's draw call to it,
/// preventing viewport-projected content from bleeding past the
/// viewport frame. Mirrors `WireModel.vp_scissor`.
pub vp_scissor: Option<[f32; 4]>,
/// Normalized draw-order depth in (0,1); higher draws on top. Fed to the
/// hatch pipeline as a small clip-z bias so this fill orders correctly
/// against other entity types. 0.0 for transient/preview hatches.
-6
View File
@@ -100,10 +100,6 @@ pub struct ImageModel {
/// Low residual paired with `corners` (double-single) so the GPU keeps
/// sub-unit precision at UTM-scale insertion points.
pub corners_low: [[f32; 3]; 4],
/// Optional world-space XY rect [x0, y0, x1, y1] for paper-space
/// viewport clipping. Mirrors `WireModel.vp_scissor` /
/// `HatchModel.vp_scissor`.
pub vp_scissor: Option<[f32; 4]>,
/// Normalized draw-order depth in (0,1); higher draws on top. Fed to the
/// image pipeline as a small clip-z bias so the raster orders correctly
/// against other entity types.
@@ -179,7 +175,6 @@ impl ImageModel {
opacity,
corners,
corners_low,
vp_scissor: None,
draw_depth: 0.0,
verts,
})
@@ -234,7 +229,6 @@ impl ImageModel {
opacity: 1.0,
corners,
corners_low,
vp_scissor: None,
draw_depth: 0.0,
verts,
})
-5
View File
@@ -86,9 +86,6 @@ pub struct WireModel {
/// share one interior phase (perpendicular dashes line up) yet each still
/// ends on a dash. `None` (the default) = per-wire A-type / from-start.
pub dash_align_end: Option<f32>,
/// Paper-space bounding box [x0, y0, x1, y1] for GPU scissor clipping.
/// Set only for viewport-projected wires in paper-space layouts.
pub vp_scissor: Option<[f32; 4]>,
/// Pre-triangulated solid fill: flat vertex list, 3 per triangle (world-offset applied).
/// Non-empty only for PolyfaceMesh / PolygonMesh entities.
pub fill_tris: Vec<[f32; 3]>,
@@ -196,7 +193,6 @@ impl WireModel {
plinegen: true,
dash_from_start: false,
dash_align_end: None,
vp_scissor: None,
fill_tris: vec![],
fill_tris_low: Vec::new(),
}
@@ -406,7 +402,6 @@ impl Default for WireModel {
plinegen: true,
dash_from_start: false,
dash_align_end: None,
vp_scissor: None,
fill_tris: Vec::new(),
fill_tris_low: Vec::new(),
fill_is_3d: false,