forked from 1b-agent/opencadstudio-upstream
fix(dimension): custom arrow blocks keep their polyline width
The width of a wide polyline lives on the wire as a GPU band, which the custom-arrow extraction dropped, so the arrow drew as a hairline. Fixes #1130 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
a94d1cfd17
commit
805979ea36
1 file changed
+49
-6
@@ -2658,12 +2658,19 @@ fn append_custom_arrow_leaf(
|
||||
true,
|
||||
);
|
||||
for wire in wires {
|
||||
append_custom_wire_points(
|
||||
&wire.points,
|
||||
&wire.points_low,
|
||||
codec::types::Vector3::ZERO,
|
||||
lines,
|
||||
);
|
||||
// A wide polyline's width rides on the wire as a GPU band; an arrow
|
||||
// keeps only geometry, so turn the band into fill or it draws hairline.
|
||||
// (#1130)
|
||||
if wire.world_width > 0.0 || wire.taper_widths.iter().any(|width| *width > 0.0) {
|
||||
append_custom_band(&wire, fill);
|
||||
} else {
|
||||
append_custom_wire_points(
|
||||
&wire.points,
|
||||
&wire.points_low,
|
||||
codec::types::Vector3::ZERO,
|
||||
lines,
|
||||
);
|
||||
}
|
||||
append_custom_fill_points(
|
||||
&wire.fill_tris,
|
||||
&wire.fill_tris_low,
|
||||
@@ -2760,6 +2767,42 @@ fn append_custom_hatch_geometry(
|
||||
);
|
||||
}
|
||||
|
||||
/// Triangles covering a wide polyline's band, one quad per segment.
|
||||
// ponytail: no join wedges at corners; add miters if a thick arrow shows notches.
|
||||
fn append_custom_band(wire: &WireModel, fill: &mut Vec<[f32; 3]>) {
|
||||
let at = |index: usize| {
|
||||
let point = wire.points[index];
|
||||
let low = wire.points_low.get(index).copied().unwrap_or([0.0; 3]);
|
||||
(!point[0].is_nan()).then(|| {
|
||||
[
|
||||
point[0] as f64 + low[0] as f64,
|
||||
point[1] as f64 + low[1] as f64,
|
||||
point[2] as f64 + low[2] as f64,
|
||||
]
|
||||
})
|
||||
};
|
||||
let half = |index: usize| {
|
||||
wire.taper_widths.get(index).copied().unwrap_or(wire.world_width).max(0.0) as f64 * 0.5
|
||||
};
|
||||
for index in 0..wire.points.len().saturating_sub(1) {
|
||||
let (Some(a), Some(b)) = (at(index), at(index + 1)) else {
|
||||
continue;
|
||||
};
|
||||
let (dx, dy) = (b[0] - a[0], b[1] - a[1]);
|
||||
let length = dx.hypot(dy);
|
||||
if length <= 0.0 {
|
||||
continue;
|
||||
}
|
||||
let (nx, ny) = (-dy / length, dx / length);
|
||||
let (ha, hb) = (half(index), half(index + 1));
|
||||
let corner = |p: [f64; 3], h: f64, side: f64| {
|
||||
[(p[0] + nx * h * side) as f32, (p[1] + ny * h * side) as f32, p[2] as f32]
|
||||
};
|
||||
let quad = [corner(a, ha, 1.0), corner(a, ha, -1.0), corner(b, hb, -1.0), corner(b, hb, 1.0)];
|
||||
fill.extend([quad[0], quad[1], quad[2], quad[0], quad[2], quad[3]]);
|
||||
}
|
||||
}
|
||||
|
||||
fn append_custom_wire_points(
|
||||
points: &[[f32; 3]],
|
||||
points_low: &[[f32; 3]],
|
||||
|
||||
Reference in new issue
Block a user