Faces that a sheet fold or unfold moves keep their names: points on a moved panel are taken back through the panel they lie on to where the sheet held them before the feature, and named from the faces there. Un-ignores the #535 regression test. Fixes #535. Co-authored-by: jonaswre <jonas.wrede@beyondit.gmbh>
This commit is contained in:
1 parent
abff7a49bb
commit
9e2a1eb993
5 files changed
+71
-2
No files matched your search
@@ -1327,6 +1327,39 @@ impl SheetBody {
|
||||
v
|
||||
}
|
||||
|
||||
/// Where a world point of this sheet lay in `before`, the same sheet before a feature
|
||||
/// changed its folds: the point goes back to flat coordinates through the panel it lies on
|
||||
/// and is folded again the way `before` folded that material. A panel a fold made was part of
|
||||
/// the panel it was folded out of. `None` off every panel (on a bend).
|
||||
pub(crate) fn point_before(&self, before: &SheetBody, p: Vec3) -> Option<Vec3> {
|
||||
const TOL: f64 = 1e-4;
|
||||
for (pi, r) in self.panels() {
|
||||
let Some(inv) = mat_inverse(&self.world(pi)) else { continue };
|
||||
let q = apply_point(&inv, p);
|
||||
if q.z < -TOL || q.z > self.t + TOL {
|
||||
continue;
|
||||
}
|
||||
let q2 = Vec2::new(q.x, q.y);
|
||||
let pts = dedup(&r.outer.ccw().polyline(1e-3));
|
||||
if !point_in(&pts, q2) && !near_outline(&pts, q2, TOL) {
|
||||
continue;
|
||||
}
|
||||
// Panels `before` did not have yet came out of their parent's (bounded walk).
|
||||
let mut owner = pi;
|
||||
for _ in 0..self.flanges.len() {
|
||||
match owner {
|
||||
Some(i) if i >= before.flanges.len() => owner = self.flanges.get(i).and_then(|f| f.parent),
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
if owner.is_some_and(|i| i >= before.flanges.len()) {
|
||||
return None;
|
||||
}
|
||||
return Some(apply_point(&before.world(owner), q));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// The panel edge nearest a world point: (panel, edge a, edge b in flat coordinates, on the
|
||||
/// top face?, distance).
|
||||
pub fn edge_at(&self, p: Vec3) -> Option<(Option<usize>, Vec2, Vec2, bool, f64)> {
|
||||
@@ -2409,6 +2442,19 @@ fn merge_loops(polys: &[Vec<Vec2>], work: &mut FlatWork) -> Result<Vec<Vec<Vec2>
|
||||
Ok(loops)
|
||||
}
|
||||
|
||||
/// Whether `q` lies within `tol` of the closed polygon `poly`'s outline.
|
||||
fn near_outline(poly: &[Vec2], q: Vec2, tol: f64) -> bool {
|
||||
let m = poly.len();
|
||||
(0..m).any(|i| match (poly.get(i), poly.get((i + 1) % m)) {
|
||||
(Some(&a), Some(&b)) => {
|
||||
let d = b - a;
|
||||
let t = if d.len2() > 1e-18 { ((q - a).dot(d) / d.len2()).clamp(0.0, 1.0) } else { 0.0 };
|
||||
(a + d * t).dist(q) < tol
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn signed_area(p: &[Vec2]) -> f64 {
|
||||
let m = p.len();
|
||||
(0..m).filter_map(|i| Some(p.get(i)?.cross(*p.get((i + 1) % m)?))).sum::<f64>() / 2.0
|
||||
|
||||
Reference in new issue
Block a user