mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 10:35:58 +00:00
sew: a folded pcurve has no piece shorter than it lifts onto its edge
A folded edge's Hermite pcurve on a bend's form breaks where the edge's angle crosses a
quarter. At the 120 degree corner with flanges at 60 and 90 degrees under a tear, an edge
starts 3.25e-12 of its parameter short of a quarter: the crossing was kept as a break
(breaks within 1e-12 of the parameter merged), the pieces halved to 1.6e-12, and SMLib,
given knots 1.6e-12 apart, handed the pcurve back with 15 equal knots at degree 7 ("SMLib
export: pcurve: loop 0 use 1: given pcurve: portable B-rep: knot multiplicity"). A crossing
whose point on the edge lies within the pcurve's lift accuracy (FOLD_TOL of the edge's size)
of the previous break is that break; the end is never merged into the start.
Fixes sheet::tests::every_pair_of_angles_is_torn_or_keeps_its_notch (torn pairs 37, 37, 27).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -493,13 +493,19 @@ fn folded_pcurve(label: &b::Surface, form: Option<&b::Surface>, curve: &b::Curve
|
||||
}
|
||||
}
|
||||
breaks.push((t1, *angles.last()?));
|
||||
// A crossing within rounding of another break (or of an end) is that break.
|
||||
let size = points.iter().fold(1.0f64, |m, h| [h[0], h[1], h[2]].iter().fold(m, |m, c| m.max((c / h[3]).abs())));
|
||||
// A crossing within rounding of another break (or of an end), or nearer to it on the edge
|
||||
// than the pcurve lifts onto the edge (`FOLD_TOL`), is that break; the end never goes into
|
||||
// the start. An edge starting 3e-12 of its parameter short of a quarter had pieces 1.6e-12
|
||||
// long, whose knots SMLib took as one, past a multiplicity of the degree + 1.
|
||||
let close = 1e-12 * (t1 - t0).abs().max(1.0);
|
||||
let lifts = |a: f64, b: f64| matches!((edge.point(a), edge.point(b)), (Some(p), Some(q)) if p.dist(q) <= FOLD_TOL * size);
|
||||
let mut kept: Vec<(f64, f64)> = Vec::with_capacity(breaks.len());
|
||||
for (i, b) in breaks.iter().enumerate() {
|
||||
let is_end = i + 1 == breaks.len();
|
||||
let both_ends = is_end && kept.len() == 1;
|
||||
match kept.last_mut() {
|
||||
Some(last) if (b.0 - last.0).abs() <= close => {
|
||||
Some(last) if (b.0 - last.0).abs() <= close || (!both_ends && lifts(last.0, b.0)) => {
|
||||
if is_end {
|
||||
*last = *b;
|
||||
}
|
||||
@@ -535,7 +541,6 @@ fn folded_pcurve(label: &b::Surface, form: Option<&b::Surface>, curve: &b::Curve
|
||||
};
|
||||
Some([0, 1, 2, 3].map(|k| [u[k], h[k]]))
|
||||
};
|
||||
let size = points.iter().fold(1.0f64, |m, h| [h[0], h[1], h[2]].iter().fold(m, |m, c| m.max((c / h[3]).abs())));
|
||||
let mut pieces = 1usize;
|
||||
while pieces * breaks.len() <= FOLD_PIECES {
|
||||
let mut knots2 = vec![t0; 8];
|
||||
|
||||
Reference in New Issue
Block a user