fix: booleans with whole-turn round faces read from STEP are exact instead of failing (#1892)
Thanks @NOWN-DEV.
This commit is contained in:
1 parent
962070e955
commit
c38992fc09
6 files changed
+233
-4
No files matched your search
Vendored
+6
@@ -53,6 +53,12 @@ Changes:
|
||||
farther from the leader's point than the curve's tolerance (the projection settled on another
|
||||
part of a surface, such as the far side of a small hole) is dropped for the search from
|
||||
nothing, as before. `crates/kernel/src/issue_1038_tests.rs` holds it to that search.
|
||||
- `decorators/revolved_curve.rs`: a point on a revolved surface's seam (angle 0, the same place
|
||||
as 2π) takes the end of the period nearer the hinted angle. The angle was decided by the sign of
|
||||
a cross product that is rounding noise there, so a boundary followed point by point could come
|
||||
back to the seam at the other end of the period and fold its parameter polygon over itself (no
|
||||
intersection loop then lay inside the face). `crates/kernel/src/seam_faces_tests.rs` holds it
|
||||
to a cone read from STEP.
|
||||
|
||||
## truck-stepio 0.3.0 (Apache-2.0, © RICOS Co. Ltd., https://github.com/ricosjp/truck)
|
||||
|
||||
|
||||
+28
-4
@@ -82,6 +82,20 @@ impl Revolution {
|
||||
}
|
||||
}
|
||||
|
||||
/// SolidCraft: the angle of a point on the seam, where 0 and 2π are the same place, taken at the end
|
||||
/// of the period nearer the hint's angle. [`Revolution::proj_angle`] decides it by the sign of a cross
|
||||
/// product that is rounding noise there, so a boundary followed point by point could come back to
|
||||
/// the seam at the other end of the period from where it left, and its parameter polygon folded
|
||||
/// over itself (a whole turn of a cylinder had no area, and no intersection loop lay inside it).
|
||||
fn seam_side(angle: f64, hint: Option<f64>) -> f64 {
|
||||
const SEAM: f64 = 1.0e-7;
|
||||
match hint {
|
||||
Some(h) if angle < SEAM && h > PI => angle + 2.0 * PI,
|
||||
Some(h) if angle > 2.0 * PI - SEAM && h < PI => angle - 2.0 * PI,
|
||||
_ => angle,
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: ParametricCurve3D> ParametricSurface for RevolutedCurve<C> {
|
||||
type Point = Point3;
|
||||
type Vector = Vector3;
|
||||
@@ -330,14 +344,19 @@ impl<C: ParametricCurve3D + BoundedCurve> SearchParameter<D2> for RevolutedCurve
|
||||
revolution: self.revolution,
|
||||
};
|
||||
let p = self.revolution.proj_point(point);
|
||||
let hint0 = match hint.into() {
|
||||
let hint = hint.into();
|
||||
let hint_angle = match hint {
|
||||
SPHint2D::Parameter(_, y) => Some(y),
|
||||
_ => None,
|
||||
};
|
||||
let hint0 = match hint {
|
||||
SPHint2D::Parameter(x, _) => SPHint1D::Parameter(x),
|
||||
SPHint2D::Range((x0, _), (x1, _)) => SPHint1D::Range(x0, x1),
|
||||
SPHint2D::None => SPHint1D::None,
|
||||
};
|
||||
let t = proj_curve.search_parameter(p, hint0, trials)?;
|
||||
let p = self.curve.subs(t);
|
||||
let ang = self.revolution.proj_angle(p, point);
|
||||
let ang = seam_side(self.revolution.proj_angle(p, point), hint_angle);
|
||||
match self.subs(t, ang).near(&point) {
|
||||
true => Some((t, ang)),
|
||||
false => None,
|
||||
@@ -377,14 +396,19 @@ impl<C: ParametricCurve3D + BoundedCurve> SearchNearestParameter<D2> for Revolut
|
||||
revolution: self.revolution,
|
||||
};
|
||||
let p = self.revolution.proj_point(point);
|
||||
let hint0 = match hint.into() {
|
||||
let hint = hint.into();
|
||||
let hint_angle = match hint {
|
||||
SPHint2D::Parameter(_, y) => Some(y),
|
||||
_ => None,
|
||||
};
|
||||
let hint0 = match hint {
|
||||
SPHint2D::Parameter(x, _) => SPHint1D::Parameter(x),
|
||||
SPHint2D::Range((x0, _), (x1, _)) => SPHint1D::Range(x0, x1),
|
||||
SPHint2D::None => SPHint1D::None,
|
||||
};
|
||||
let t = proj_curve.search_nearest_parameter(p, hint0, trials)?;
|
||||
let p = self.curve.subs(t);
|
||||
Some((t, self.revolution.proj_angle(p, point)))
|
||||
Some((t, seam_side(self.revolution.proj_angle(p, point), hint_angle)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user