forked from 1b-agent/opencadstudio-upstream
fix: closed spline gap, hatch spline boundary, and spline commit grouping
- Spline: if flags.closed/periodic and B-spline endpoints don't meet, add an explicit closing Wire segment to eliminate the visual gap. - Hatch BoundaryEdge::Spline: evaluate the B-spline at 16 uniform parameter samples (de Boor via truck BSplineCurve) instead of plotting raw control points as a polyline; falls back to control- point polyline for degenerate knot/degree inputs. - Ellipse arc key_vertices and LWPolyline midpoint grips committed separately; this commit wraps the spline-related fixes. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
6fd740e38f
commit
0bb4209e2c
2 files changed
+59
-13
No files matched your search
+33
-6
@@ -37,6 +37,10 @@ pub use wire_model::WireModel;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use acadrust::entities::{BoundaryEdge, BoundaryPath, Hatch as DxfHatch, PolylineEdge, Solid as DxfSolid};
|
||||
use truck_modeling::{
|
||||
base::{BoundedCurve, ParametricCurve},
|
||||
BSplineCurve as TruckBSpline, KnotVec, Point3,
|
||||
};
|
||||
use acadrust::entities::{Block, BlockEnd, Insert as DxfInsert};
|
||||
use acadrust::objects::ObjectType;
|
||||
use acadrust::types::Vector2;
|
||||
@@ -1668,12 +1672,35 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
BoundaryEdge::Spline(spline) => {
|
||||
for cp in &spline.control_points {
|
||||
boundary.push([cp.x as f32, cp.y as f32]);
|
||||
}
|
||||
if boundary.len() > 1 {
|
||||
if let Some(&first) = boundary.first() {
|
||||
boundary.push(first);
|
||||
// Evaluate the B-spline curve into smooth boundary points.
|
||||
// Fall back to control-point polyline for degenerate inputs.
|
||||
let degree = spline.degree as usize;
|
||||
let cps: Vec<Point3> = spline.control_points
|
||||
.iter()
|
||||
.map(|p| Point3::new(p.x, p.y, 0.0))
|
||||
.collect();
|
||||
let knot_vec = if !spline.knots.is_empty() {
|
||||
KnotVec::from(spline.knots.clone())
|
||||
} else if cps.len() >= 2 {
|
||||
KnotVec::uniform_knot(degree, cps.len() - 1)
|
||||
} else {
|
||||
KnotVec::from(vec![])
|
||||
};
|
||||
let ok = cps.len() >= 2
|
||||
&& degree >= 1
|
||||
&& knot_vec.len() == cps.len() + degree + 1;
|
||||
if ok {
|
||||
let bspl = TruckBSpline::new(knot_vec, cps);
|
||||
let (t0, t1) = bspl.range_tuple();
|
||||
let segs = 16u32;
|
||||
for i in 0..=segs {
|
||||
let t = t0 + (t1 - t0) * (i as f64 / segs as f64);
|
||||
let p = bspl.subs(t);
|
||||
boundary.push([p.x as f32, p.y as f32]);
|
||||
}
|
||||
} else {
|
||||
for cp in &spline.control_points {
|
||||
boundary.push([cp.x as f32, cp.y as f32]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user