mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-08 13:01:52 +00:00
topology.brep_p2: take LiftCurve's Curve in #263's fillet_geom p2/p4; keep main's runner text
After merging #263, blend.fillet_geom_p2 and p4 still read LiftedCurve::curve as a BSplineCurve. Since660b3270it is a Curve (sm_ExtractIsoCurve's line or conic keeps its kind; upstream p3DCurve is an SmBSplineCurve either way): - fillet_geom_p2 UpdateGeometry: p3DCurve is held as a Curve; ReparametrizeWithArcLength (non-virtual SmBSplineCurve) runs on its B-spline base, DropCurve and SetCurve take the curve itself, and TestRailRailInterpolationCurve gets the B-spline base. - fillet_geom_p4: the useless Curve::from on the lifted rail curve. Also reverts dd7c6634's rustfmt of main's own runner text in query_face_p2 and topology_brep_p10 (main's text is kept; no hunk was in this PR's lines). Gate (main through95b823ed): fmt, clippy x2, wasm, solidcore tests 1481 ok; all 229 units failed=0, every report identical to the committed ones (blend.fillet_geom_p2 219/131, fillet_geom_p4 340/30, fillet_corner_p3 433/320, fillet_solver_p1 303/40 unchanged); difftest tests fail only main's two known tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xbnf2bFY8cTu4zUgAv9s85
This commit is contained in:
@@ -509,11 +509,7 @@ fn pc_block(pc: &PointClassification<EntityRef>) -> Vec<f64> {
|
||||
|
||||
/// The shim's `put_pc` block for a curve classification's point classification: only
|
||||
/// faces, edges and vertices have an export index (other objects are `-3, -1`).
|
||||
fn cc_pc_block(
|
||||
k: &Kernel,
|
||||
objects: &Objects<'_>,
|
||||
pc: &PointClassification<H>,
|
||||
) -> Result<Vec<f64>, HarnessError> {
|
||||
fn cc_pc_block(k: &Kernel, objects: &Objects<'_>, pc: &PointClassification<H>) -> Result<Vec<f64>, HarnessError> {
|
||||
let (kind, index) = match pc.object() {
|
||||
None => (0.0, -1.0),
|
||||
Some(H::Face(f)) => (1.0, f64::from(f.index())),
|
||||
@@ -781,16 +777,7 @@ fn rust(i: &Inputs) -> Result<Output, HarnessError> {
|
||||
let uv = Point2::new(a(0), a(1));
|
||||
let d1 = Extent2d::from_points(Point2::new(a(4), a(5)), Point2::new(a(6), a(7)));
|
||||
let d2 = Extent2d::from_points(Point2::new(a(9), a(10)), Point2::new(a(11), a(12)));
|
||||
match qf::classify_param_on_faces(
|
||||
&k,
|
||||
&mut b.clone(),
|
||||
uv,
|
||||
zone_tol3d(&k, *tol),
|
||||
f1,
|
||||
&d1,
|
||||
f2,
|
||||
&d2,
|
||||
) {
|
||||
match qf::classify_param_on_faces(&k, &mut b.clone(), uv, zone_tol3d(&k, *tol), f1, &d1, f2, &d2) {
|
||||
Ok(w) => Ok(Output::new().values("which", vec![f64::from(w)])),
|
||||
Err(e) => Ok(rust_err(&e)),
|
||||
}
|
||||
@@ -814,36 +801,21 @@ fn rust(i: &Inputs) -> Result<Output, HarnessError> {
|
||||
let line = match BSplineCurve::create_line_segment(u64::from(*dim), p, q) {
|
||||
Ok(line) => line,
|
||||
Err(SolidError::Upstream { code, .. }) => {
|
||||
return Ok(
|
||||
Output::new().values("curve_classification", vec![-3.0, f64::from(code)])
|
||||
)
|
||||
return Ok(Output::new().values("curve_classification", vec![-3.0, f64::from(code)]))
|
||||
}
|
||||
Err(e) => return Ok(rust_err(&e)),
|
||||
};
|
||||
let curve = Curve::from(line);
|
||||
let interval = curve.natural_interval();
|
||||
let objects = Objects { brep: b, curve };
|
||||
let mut cc: CurveClassification<H> = CurveClassification::with_curve_interval(
|
||||
&k,
|
||||
H::Curve,
|
||||
interval,
|
||||
zone_tol3d(&k, *tol),
|
||||
);
|
||||
let (status, modified) = match qf::curve_on_classify(
|
||||
&k,
|
||||
b,
|
||||
f,
|
||||
&objects,
|
||||
*do_pc,
|
||||
&mut cc,
|
||||
*big_gaps,
|
||||
*check3d,
|
||||
true,
|
||||
) {
|
||||
Ok(modified) => (0.0, modified),
|
||||
Err(SolidError::Upstream { code, .. }) => (f64::from(code), false),
|
||||
Err(e) => return Ok(rust_err(&e)),
|
||||
};
|
||||
let mut cc: CurveClassification<H> =
|
||||
CurveClassification::with_curve_interval(&k, H::Curve, interval, zone_tol3d(&k, *tol));
|
||||
let (status, modified) =
|
||||
match qf::curve_on_classify(&k, b, f, &objects, *do_pc, &mut cc, *big_gaps, *check3d, true) {
|
||||
Ok(modified) => (0.0, modified),
|
||||
Err(SolidError::Upstream { code, .. }) => (f64::from(code), false),
|
||||
Err(e) => return Ok(rust_err(&e)),
|
||||
};
|
||||
let mut o = vec![status, flag(modified), cc.size() as f64];
|
||||
for iv in cc.intervals() {
|
||||
o.extend([iv.interval.min(), iv.interval.max()]);
|
||||
|
||||
@@ -269,11 +269,7 @@ fn set_field(d: &mut BrepData, field: i64, index: i64, value: i64) -> Result<(),
|
||||
// an index past the array is a no-op
|
||||
match field {
|
||||
0 => d.faces.get_mut(i).into_iter().for_each(|r| r.surface = u),
|
||||
1 => d
|
||||
.faces
|
||||
.get_mut(i)
|
||||
.into_iter()
|
||||
.for_each(|r| r.start_loop = u),
|
||||
1 => d.faces.get_mut(i).into_iter().for_each(|r| r.start_loop = u),
|
||||
2 => d.loops.get_mut(i).into_iter().for_each(|r| r.start_eu = u),
|
||||
3 => d.loops.get_mut(i).into_iter().for_each(|r| r.vertex = u),
|
||||
4 => d.edgeuses.get_mut(i).into_iter().for_each(|r| r.edge = u),
|
||||
|
||||
@@ -366,6 +366,31 @@ fn corner_type(corner: FilletCornerId) -> Result<FilletCornerType> {
|
||||
)
|
||||
}
|
||||
|
||||
/// The `SmBSplineCurve` (base) of a curve kind derived from it (`SmLine`,
|
||||
/// `SmEllipse`/`SmCircle`, `SmHyperbola`, `SmParabola`), `None` for the others.
|
||||
const fn b_spline_base(c: &Curve) -> Option<&BSplineCurve> {
|
||||
match c.kind() {
|
||||
CurveKind::BSpline(b) => Some(b),
|
||||
CurveKind::Line(l) => Some(l.base()),
|
||||
CurveKind::Ellipse(e) => Some(e.base()),
|
||||
CurveKind::Hyperbola(h) => Some(h.base()),
|
||||
CurveKind::Parabola(p) => Some(p.base()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// [`b_spline_base`], mutably: the receiver of a non-virtual `SmBSplineCurve` method.
|
||||
fn b_spline_base_mut(c: &mut Curve) -> Option<&mut BSplineCurve> {
|
||||
match c.kind_mut() {
|
||||
CurveKind::BSpline(b) => Some(b),
|
||||
CurveKind::Line(l) => Some(l.base_mut()),
|
||||
CurveKind::Ellipse(e) => Some(e.base_mut()),
|
||||
CurveKind::Hyperbola(h) => Some(h.base_mut()),
|
||||
CurveKind::Parabola(p) => Some(p.base_mut()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// `SmFilletConcaveNxNCorner::TestRailRailInterpolationCurve` (unit
|
||||
/// `blend.fillet_corner_p1`).
|
||||
fn corner_test_rail_rail_interpolation_curve(
|
||||
@@ -1982,7 +2007,9 @@ impl FilletBrep {
|
||||
interpolate_endpts_and_tangents(start_pnt, end_pnt, &mut start_vec, &mut end_vec, 3)?
|
||||
};
|
||||
|
||||
let mut curve_3d: Option<BSplineCurve>;
|
||||
// p3DCurve, an SmBSplineCurve: a B-spline, or the line / conic iso curve
|
||||
// LiftCurve's sm_ExtractIsoCurve makes
|
||||
let mut curve_3d: Option<Curve>;
|
||||
let mut uv_curve: Option<Curve>;
|
||||
if create_crv_on_3d {
|
||||
// Compute UV-curve by projecting 3d curve onto the surface
|
||||
@@ -1994,10 +2021,7 @@ impl FilletBrep {
|
||||
return Err(SolidError::sm_err(OP));
|
||||
}
|
||||
uv_curve = uv_curves.into_iter().next();
|
||||
curve_3d = match c3.into_kind() {
|
||||
CurveKind::BSpline(b) => Some(b),
|
||||
_ => None,
|
||||
};
|
||||
curve_3d = Some(c3);
|
||||
} else {
|
||||
let mut uv = new_curve;
|
||||
// its status is ignored upstream
|
||||
@@ -2023,25 +2047,16 @@ impl FilletBrep {
|
||||
|
||||
// Reparametrize the curve with arc-length for non-blend type
|
||||
if fsg_type != FilletSurfaceGeneratorType::BlendCurve {
|
||||
c3.reparametrize_with_arc_length()?;
|
||||
b_spline_base_mut(&mut c3)
|
||||
.ok_or_else(|| SolidError::null_pointer(OP))?
|
||||
.reparametrize_with_arc_length()?;
|
||||
// Reproject the 3d curve back onto the surface
|
||||
let c3c = Curve::from(c3);
|
||||
let uv_curves = surface_drop_curve(
|
||||
k,
|
||||
face_srf,
|
||||
&uv_domain,
|
||||
&c3c,
|
||||
&c3c.natural_interval(),
|
||||
tol,
|
||||
)?;
|
||||
let uv_curves =
|
||||
surface_drop_curve(k, face_srf, &uv_domain, &c3, &c3.natural_interval(), tol)?;
|
||||
if uv_curves.len() != 1 {
|
||||
return Err(SolidError::sm_err(OP));
|
||||
}
|
||||
uv_curve = uv_curves.into_iter().next();
|
||||
c3 = match c3c.into_kind() {
|
||||
CurveKind::BSpline(b) => b,
|
||||
_ => return Err(SolidError::null_pointer(OP)),
|
||||
};
|
||||
}
|
||||
curve_3d = Some(c3);
|
||||
}
|
||||
@@ -2050,6 +2065,7 @@ impl FilletBrep {
|
||||
if corner_type(corner)? == FilletCornerType::NByNConcave {
|
||||
let c3 = curve_3d
|
||||
.as_ref()
|
||||
.and_then(b_spline_base)
|
||||
.ok_or_else(|| SolidError::null_pointer(OP))?;
|
||||
// Test and see if this edge intersects with the original corner
|
||||
if corner_test_rail_rail_interpolation_curve(corner, c3)? {
|
||||
@@ -2114,7 +2130,7 @@ impl FilletBrep {
|
||||
// set p3DCurve as this FilletEdge's geometry (side effect: the edge uses' UV
|
||||
// trim curves go), then the mate edge use's UV curve
|
||||
let curve_3d = curve_3d.ok_or_else(|| SolidError::null_pointer(OP))?;
|
||||
set_edge_curve(self.brep_mut(), e, Some(Curve::from(curve_3d)))?;
|
||||
set_edge_curve(self.brep_mut(), e, Some(curve_3d))?;
|
||||
let mate_eu = primary_edgeuse(self.brep(), e)?
|
||||
.and_then(|p| eu1::mate(self.brep(), p).ok().flatten())
|
||||
.ok_or_else(|| SolidError::null_pointer(OP))?;
|
||||
|
||||
@@ -2098,7 +2098,7 @@ impl FilletBrep {
|
||||
false,
|
||||
)?;
|
||||
let crv_ivl = lifted.curve.natural_interval();
|
||||
set_edge_curve(self.brep_mut(), rail, Some(Curve::from(lifted.curve)))?;
|
||||
set_edge_curve(self.brep_mut(), rail, Some(lifted.curve))?;
|
||||
edge::set_interval(self.brep_mut(), rail, &crv_ivl)?;
|
||||
self.set_edgeuse_uv_curve(mate, Some(Curve::from(new_uv_curve)), true, true)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user