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. Since 660b3270 it 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 through 95b823ed): 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:
Christian Svensson
2026-10-20 08:15:46 +02:00
parent ae6c056c7c
commit da779c513e
4 changed files with 49 additions and 65 deletions
+11 -39
View File
@@ -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),
+36 -20
View File
@@ -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))?;
+1 -1
View File
@@ -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)?;
}