forked from 1b-agent/opencadstudio-upstream
feat(polyline): smooth per-segment taper for varying-width wide polylines
A wide polyline with per-vertex varying widths rendered at its widest edge (uniform-width ones were already exact). Draw the true taper instead. `WireModel.taper_widths` carries a per-point full band width. The wire instance (native slim + web fat) gains per-endpoint `world_hw_a/b`, and both wire shaders interpolate `mix(hw_a, hw_b, which_end)` so each segment's band narrows/widens linearly — depth-tested, and the linetype dash still applies. Alignment (widths must match the tessellated points) is solved by building both together: a new `TruckObject::TaperedLines(points, widths)`, filled by `common::tapered_band_points` (straight = endpoints, arc = 16 samples with the width lerped along it). to_truck routes a varying-width polyline here — LwPolyline before the PLINEGEN split, Polyline2D at its return — while a uniform-width one keeps the constant-band Contour path unchanged. `world_width` stays the widest edge as the PDF-stroke + zoom-floor fallback. Blocks fall back to the constant-widest band (`LocalWire` carries no taper_widths). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
a8aece1909
commit
b3016ca892
48 files changed
+322
-7
No files matched your search
+10
-3
@@ -61,6 +61,9 @@ struct InstanceIn {
|
||||
@location(13) align_total: f32,
|
||||
// World-space half-width for a wide-polyline band. 0 = normal wire.
|
||||
@location(14) world_half_width: f32,
|
||||
// Per-endpoint world half-width for a tapered band (0 = use the constant).
|
||||
@location(15) world_hw_a: f32,
|
||||
@location(16) world_hw_b: f32,
|
||||
}
|
||||
|
||||
// Draw-order depth bias: shifts clip-space z so 2D entities of different
|
||||
@@ -135,10 +138,14 @@ struct VertexOut {
|
||||
// `world_half_width / world_per_pixel` (pixels) so the band tracks zoom. A
|
||||
// normal wire (world_half_width == 0) uses the screen-pixel half-width,
|
||||
// honouring the LWDISPLAY toggle (off → collapse to a 1-pixel line).
|
||||
// A tapered band interpolates a per-endpoint world half-width across the
|
||||
// segment; a constant band uses `world_half_width`. Both clamp to a
|
||||
// half-pixel so a zoomed-out band stays a hairline instead of vanishing.
|
||||
let taper_hw = mix(in.world_hw_a, in.world_hw_b, which_end);
|
||||
var hw: f32;
|
||||
if in.world_half_width > 0.0 {
|
||||
// Clamp to a half-pixel so a zoomed-out band never drops below a
|
||||
// hairline (its centre-line) instead of vanishing.
|
||||
if taper_hw > 0.0 {
|
||||
hw = max(taper_hw / u.world_per_pixel, 0.5);
|
||||
} else if in.world_half_width > 0.0 {
|
||||
hw = max(in.world_half_width / u.world_per_pixel, 0.5);
|
||||
} else {
|
||||
hw = select(0.5, in.half_width, u.lwdisplay_enable > 0.5);
|
||||
|
||||
@@ -44,6 +44,10 @@ struct InstanceIn {
|
||||
@location(4) distance_a: f32,
|
||||
@location(5) distance_b: f32,
|
||||
@location(6) wire_id: u32,
|
||||
// Per-endpoint world half-width for a tapered band (0 = use the per-wire
|
||||
// constant `world_half_width`).
|
||||
@location(7) world_hw_a: f32,
|
||||
@location(8) world_hw_b: f32,
|
||||
}
|
||||
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
@@ -97,10 +101,15 @@ struct VertexOut {
|
||||
// by `world_half_width / world_per_pixel` (screen pixels) so the band grows
|
||||
// and shrinks with zoom. A normal wire (world_half_width == 0) uses the
|
||||
// screen-pixel half-width, honouring the LWDISPLAY toggle.
|
||||
// A tapered band carries a per-endpoint world half-width on the instance:
|
||||
// interpolate across the segment so the band narrows/widens smoothly. A
|
||||
// constant band uses the per-wire `world_half_width`. Both clamp to a
|
||||
// half-pixel so a zoomed-out band stays a hairline instead of vanishing.
|
||||
let taper_hw = mix(in.world_hw_a, in.world_hw_b, which_end);
|
||||
var hw: f32;
|
||||
if c.world_half_width > 0.0 {
|
||||
// Clamp to a half-pixel so a zoomed-out band never drops below a
|
||||
// hairline (its centre-line) instead of vanishing.
|
||||
if taper_hw > 0.0 {
|
||||
hw = max(taper_hw / u.world_per_pixel, 0.5);
|
||||
} else if c.world_half_width > 0.0 {
|
||||
hw = max(c.world_half_width / u.world_per_pixel, 0.5);
|
||||
} else {
|
||||
hw = select(0.5, c.half_width, u.lwdisplay_enable > 0.5);
|
||||
|
||||
Reference in new issue
Block a user