forked from 1b-agent/opencadstudio-upstream
fix(polyline): spline-fit 2D polylines draw the curve, not the frame
A curve-/spline-fit heavy polyline stores both the fitted curve points (vertex flag 8 / 1) and the spline-frame control points (flag 16), which only SPLFRAME is meant to show. Chaining every stored vertex drew spokes from the curve to the control frame — stray points on the curve and, on wide polylines, a blobbed band (#408). drawn_vertices2d now drops the control points whenever fit data is present (falling back to the stored vertices when it is not) and feeds the wire, the wide-band fills and the tapered band alike, so snapping no longer lands on frame points either. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
8ff7b6b25c
commit
1546c1dc30
1 file changed
+35
-4
@@ -166,8 +166,37 @@ impl Transformable for Polyline {
|
||||
|
||||
// ── Polyline2D (heavy 2D polyline with bulge) ─────────────────────────────────
|
||||
|
||||
/// The vertices a curve-/spline-fit 2D polyline actually DRAWS: the
|
||||
/// fit-generated points (VertexFlags 8 / 1) plus any unflagged originals,
|
||||
/// with the spline-frame CONTROL points (flag 16) dropped — those are editing
|
||||
/// scaffolding shown only under SPLFRAME, and chaining through them draws
|
||||
/// spokes across the fitted curve (#408). `None` = no fit data, draw the
|
||||
/// stored vertices as-is. A fit-flagged polyline whose fit points are missing
|
||||
/// falls back to the stored vertices rather than drawing nothing.
|
||||
pub fn drawn_vertices2d(
|
||||
pl: &Polyline2D,
|
||||
) -> Option<Vec<acadrust::entities::Vertex2D>> {
|
||||
use acadrust::entities::polyline::VertexFlags;
|
||||
let has_fit = pl.vertices.iter().any(|v| {
|
||||
v.flags.bits()
|
||||
& (VertexFlags::SPLINE_VERTEX.bits() | VertexFlags::EXTRA_VERTEX.bits())
|
||||
!= 0
|
||||
});
|
||||
if !has_fit {
|
||||
return None;
|
||||
}
|
||||
let kept: Vec<_> = pl
|
||||
.vertices
|
||||
.iter()
|
||||
.filter(|v| v.flags.bits() & VertexFlags::SPLINE_CONTROL.bits() == 0)
|
||||
.cloned()
|
||||
.collect();
|
||||
(kept.len() >= 2).then_some(kept)
|
||||
}
|
||||
|
||||
fn tessellate_polyline2d(pl: &Polyline2D) -> TruckEntity {
|
||||
let verts = &pl.vertices;
|
||||
let filtered = drawn_vertices2d(pl);
|
||||
let verts: &[acadrust::entities::Vertex2D] = filtered.as_deref().unwrap_or(&pl.vertices);
|
||||
if verts.is_empty() {
|
||||
return TruckEntity {
|
||||
pick_tris: Vec::new(),
|
||||
@@ -355,8 +384,9 @@ fn tapered_band_verts_2d(
|
||||
pl: &acadrust::entities::Polyline2D,
|
||||
) -> Option<Vec<([f64; 2], f64, f64, f64)>> {
|
||||
let d = pl.start_width.max(pl.end_width);
|
||||
let band: Vec<([f64; 2], f64, f64, f64)> = pl
|
||||
.vertices
|
||||
let filtered = drawn_vertices2d(pl);
|
||||
let verts: &[acadrust::entities::Vertex2D] = filtered.as_deref().unwrap_or(&pl.vertices);
|
||||
let band: Vec<([f64; 2], f64, f64, f64)> = verts
|
||||
.iter()
|
||||
.map(|v| {
|
||||
let sw = if v.start_width > 1e-9 { v.start_width } else { d };
|
||||
@@ -835,7 +865,8 @@ pub(crate) fn wide_fills(pl: &acadrust::entities::Polyline2D) -> ([f64; 2], Vec<
|
||||
// The stored widths are the band's FULL width and `polyline_segment_fill`
|
||||
// offsets ±hw about the centreline — halve them. See `lwpolyline::wide_fills`.
|
||||
let hw_default = pl.start_width.max(pl.end_width) as f32 * 0.5;
|
||||
let verts = &pl.vertices;
|
||||
let filtered = drawn_vertices2d(pl);
|
||||
let verts: &[acadrust::entities::Vertex2D] = filtered.as_deref().unwrap_or(&pl.vertices);
|
||||
let n = verts.len();
|
||||
if n < 2 {
|
||||
return ([0.0; 2], vec![]);
|
||||
|
||||
Reference in new issue
Block a user