mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-08 04:52:10 +00:00
Merge pull request #2264 from MarkusReichart/fix/refine-cc-outside-parameter
fix: a refined parameter outside the range is an answer, opt-in (WR-663, fork 8ea6a20)
This commit is contained in:
@@ -78,16 +78,16 @@
|
||||
//! are wired; [`SolidError::Unported`] is propagated from what they reach.
|
||||
//! - **Statuses passed on (WR-663).** With the opt-in
|
||||
//! `Kernel::fixes.query_statuses_pass_on` the statuses SMLib drops are passed on, as the
|
||||
//! fork (tangency-labs/smlib 8311f8e): `sm_RefineCCSolutions` (its local intersections
|
||||
//! and `Inversion`s), the degenerate `ApproximateCurve`'s `EditParameterization`,
|
||||
//! fork (tangency-labs/smlib 8311f8e): `sm_RefineCCSolutions` (its local intersections;
|
||||
//! its `Inversion`s not, tangency-labs/smlib 8ea6a20), the degenerate `ApproximateCurve`'s `EditParameterization`,
|
||||
//! `ClassifyIntersectingRangeSolution`, `SmCPGlobalSolver::LocalSolve` and
|
||||
//! `GlobalPointSolve`'s `SolveIt`.
|
||||
|
||||
use crate::curve::curve::knots_ignoring_status;
|
||||
use crate::curve::curve::p2::{
|
||||
add_to_curve, evaluate_continuity, find_test_params, flush_crv, inversion_passed_on, output,
|
||||
pop_stack, proj_signed_angle, push_point, stack_look, test_step, CpGlobalSolver, Curve,
|
||||
CurveKind, CurvePropertyType, TessStepResult, BSPLINE_CURVE_TYPE, CRV_ON_SURF_TYPE,
|
||||
add_to_curve, evaluate_continuity, find_test_params, flush_crv, output, pop_stack,
|
||||
proj_signed_angle, push_point, stack_look, test_step, CpGlobalSolver, Curve, CurveKind,
|
||||
CurvePropertyType, TessStepResult, BSPLINE_CURVE_TYPE, CRV_ON_SURF_TYPE,
|
||||
};
|
||||
use crate::curve::curve::p3::{eval_n, local_curve_intersect, PointSolveOptions};
|
||||
use crate::curve::curve::p4::proj_dist;
|
||||
@@ -249,9 +249,13 @@ where
|
||||
if x.deviation < end.solution_value {
|
||||
// Do not allow big shifts. [140915b]
|
||||
let inv1 = sol_ivl1.inversion(x.my_param);
|
||||
inversion_passed_on(&inv1, pass_on)?;
|
||||
let inv2 = sol_ivl2.inversion(x.other_param);
|
||||
inversion_passed_on(&inv2, pass_on)?;
|
||||
// The fork (tangency-labs/smlib 8ea6a20): a refined parameter outside the
|
||||
// range is an answer, which the shift limit judges. Only a zero-length
|
||||
// range gives no fraction, and then the end stays where it is.
|
||||
if pass_on && (inv1.parameter.is_none() || inv2.parameter.is_none()) {
|
||||
continue;
|
||||
}
|
||||
let mut frac1 = inv1.parameter.unwrap_or(UNDEF_DOUBLE);
|
||||
let mut frac2 = inv2.parameter.unwrap_or(UNDEF_DOUBLE);
|
||||
if reverse1 {
|
||||
|
||||
@@ -201,12 +201,12 @@ use crate::curve::offset_curve::OffsetCurve;
|
||||
use crate::curve::parabola::Parabola;
|
||||
use crate::curve::projected_curve::ProjectedCurve;
|
||||
use crate::curve::tangent_field::TangentFieldCurve;
|
||||
use crate::error::{ignore_or_pass_on, ignored, ignored_or_pass_on, Result, SolidError, SM_ERR};
|
||||
use crate::error::{ignore_or_pass_on, ignored, ignored_or_pass_on, Result, SolidError};
|
||||
use crate::geom::a_object::{self, AObject, CacheStore};
|
||||
use crate::geom::attribute::{AttributeStore, ObjectKey};
|
||||
use crate::geom::axis2_placement::Axis2Placement;
|
||||
use crate::geom::context::{Context, IdentitySlot};
|
||||
use crate::geom::extent1d::{Extent1d, Inversion};
|
||||
use crate::geom::extent1d::Extent1d;
|
||||
use crate::geom::extent2d::Extent2d;
|
||||
use crate::geom::extent3d::Extent3d;
|
||||
use crate::geom::geom_utility::p1::{
|
||||
@@ -2281,22 +2281,6 @@ pub fn base_ends<C: CurveEvaluate + ?Sized>(k: &Kernel, curve: &C) -> Result<End
|
||||
})
|
||||
}
|
||||
|
||||
/// The status of `Inversion` (`SM_ERR` when `v` is outside the interval or the
|
||||
/// interval has no length) at a site where SMLib drops it and the fork passes it on
|
||||
/// (`SER`, tangency-labs/smlib 8311f8e): with the opt-in
|
||||
/// [`crate::kernel::UpstreamFixes::query_statuses_pass_on`] (`pass_on`) a failed
|
||||
/// inversion is returned; without it the status is dropped, as upstream.
|
||||
pub(crate) fn inversion_passed_on(inv: &Inversion, pass_on: bool) -> Result<()> {
|
||||
if pass_on && !inv.is_success() {
|
||||
return Err(SolidError::Upstream {
|
||||
operation: "geom::extent1d::Extent1d::inversion",
|
||||
code: SM_ERR,
|
||||
entity: None,
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The outcome of [`ignored_or_soft`].
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Soft<T> {
|
||||
@@ -4477,19 +4461,6 @@ mod tests {
|
||||
b
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2009_inversion_status_is_passed_on() {
|
||||
// tangency-labs/smlib 8311f8e (sm_RefineCCSolutions `SER(Inversion)`): a value
|
||||
// outside the interval (or one that a zero-length interval cannot map) is
|
||||
// SM_ERR with the opt-in fix and dropped without it.
|
||||
let ivl = Extent1d::from_min_max(0.0, 1.0);
|
||||
assert!(inversion_passed_on(&ivl.inversion(0.5), true).is_ok());
|
||||
assert!(inversion_passed_on(&ivl.inversion(2.0), true).is_err());
|
||||
assert!(inversion_passed_on(&ivl.inversion(2.0), false).is_ok());
|
||||
let flat = Extent1d::from_min_max(1.0, 1.0);
|
||||
assert!(inversion_passed_on(&flat.inversion(2.0), true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluation_copy_keeps_nested_knots_flags_and_owners() {
|
||||
use crate::curve::projected_curve::OwnsCurve;
|
||||
|
||||
@@ -105,3 +105,27 @@ fn issue_948_difference_of_two_ruled_skins_fails_as_upstream() {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// WR-663 with the fork's tangency-labs/smlib@8ea6a20: a refined end past a curve/curve range
|
||||
/// no longer aborts the intersection. The difference still fails, as the pinned C++ and the
|
||||
/// fork do, but where the default path does, not in `Extent1d::inversion`.
|
||||
#[test]
|
||||
fn a_refined_parameter_outside_the_range_does_not_abort_the_intersection() {
|
||||
let data = sections(MIN7);
|
||||
let mut k = Kernel::default();
|
||||
k.fixes.query_statuses_pass_on = true;
|
||||
let outer = ruled_skin(&mut k, &data[0].1);
|
||||
let inner = ruled_skin(&mut k, &data[1].1);
|
||||
match boolean_difference(&mut k, outer, inner) {
|
||||
Err(SolidError::Upstream {
|
||||
operation, code, ..
|
||||
}) => {
|
||||
assert_eq!(code, SM_ERR);
|
||||
assert_eq!(operation, "topology::brep::p6");
|
||||
}
|
||||
other => panic!(
|
||||
"expected the default path's SM_ERR, got {:?}",
|
||||
other.map(|_| "a body")
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
Updates: WR-663
|
||||
|
||||
#### WR-663 (update, 2026-11-01). A refined parameter outside the range is an answer, not a failed status
|
||||
- **What changes:** with `Kernel::fixes.query_statuses_pass_on`, `sm_RefineCCSolutions` no longer returns the status of `Inversion`. A refined end just past the solution's range keeps its fraction, and the shift limit judges it. Only a zero-length range gives no fraction, and then the end stays where it was. With the flag off nothing changes.
|
||||
- **How found:** this site took 8311f8e's `SER(Inversion)` from the fork, but not the fork's later tangency-labs/smlib@8ea6a20 (9b93b88 before cherry-picking), which takes it back out. The fork at d01d7b0 has `(void)sSolIvl1.Inversion(..)` and `bHaveFracs`. The port's `SM_ERR` aborted the whole curve/curve intersection as `geom::extent1d::Extent1d::inversion`.
|
||||
- **Confirmed:** in the Rust port.
|
||||
- #948's `min7.txt`: with this flag alone the difference failed in `Extent1d::inversion`, earlier than the default path. It now fails where the default path does, in `topology::brep::p6`. The fork fails that difference with 1001 too, so this does not fix #948.
|
||||
- The order-2 round of the pipe on a plate (#2252's `pipe_on_plate_g2`), on #2260's head 9f3cdcfbc with every fix on except `geometric_g2_continuity`: `Extent1d::inversion` 1001 before, built after. Volume 40258.543608517 against the fork case's 40258.5435962825 (3.0e-10 relative), seams G2. That case needs #2260's generator, so it is not a test here.
|
||||
- The fork's C++ was run only as far as #948's status (d01d7b0 built from `source/SMLib` and `source/SM_API`).
|
||||
Reference in New Issue
Block a user