From 6d3e738b6524975a317dafebb7bb4a0bd9716c62 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Sat, 9 Apr 2022 11:56:50 +0200 Subject: [PATCH 1/2] Don't use `CycleApprox` in `Polygon` `Polygon` doesn't know of or care about approximations. It cares about its polygonal chain. So this change makes sense from a conceptual perspective. It also makes sense from a practical perspective, as this enables some simplifications of `Polygon`, which should further improve its testability. --- fj-kernel/src/algorithms/triangulation/mod.rs | 9 +++++++-- fj-kernel/src/algorithms/triangulation/polygon.rs | 10 +++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fj-kernel/src/algorithms/triangulation/mod.rs b/fj-kernel/src/algorithms/triangulation/mod.rs index d8ae78144..bacb48f01 100644 --- a/fj-kernel/src/algorithms/triangulation/mod.rs +++ b/fj-kernel/src/algorithms/triangulation/mod.rs @@ -35,8 +35,13 @@ pub fn triangulate( }) .collect(); let face_as_polygon = Polygon::new(surface) - .with_exterior(approx.exterior) - .with_interiors(approx.interiors); + .with_exterior(approx.exterior.points) + .with_interiors( + approx + .interiors + .into_iter() + .map(|interior| interior.points), + ); let mut triangles = delaunay(points); triangles.retain(|triangle| { diff --git a/fj-kernel/src/algorithms/triangulation/polygon.rs b/fj-kernel/src/algorithms/triangulation/polygon.rs index dabad39b3..c86ed3f15 100644 --- a/fj-kernel/src/algorithms/triangulation/polygon.rs +++ b/fj-kernel/src/algorithms/triangulation/polygon.rs @@ -1,11 +1,11 @@ use std::collections::BTreeSet; use fj_debug::{DebugInfo, TriangleEdgeCheck}; -use fj_math::{Point, Scalar, Segment}; +use fj_math::{Point, PolyChain, Scalar, Segment}; use parry2d_f64::query::{Ray as Ray2, RayCast as _}; use parry3d_f64::query::Ray as Ray3; -use crate::{algorithms::CycleApprox, geometry::Surface}; +use crate::geometry::Surface; pub struct Polygon { surface: Surface, @@ -22,13 +22,13 @@ impl Polygon { } } - pub fn with_exterior(self, exterior: impl Into) -> Self { + pub fn with_exterior(self, exterior: impl Into>) -> Self { self.with_approx(exterior) } pub fn with_interiors( mut self, - interiors: impl IntoIterator>, + interiors: impl IntoIterator>>, ) -> Self { for interior in interiors { self = self.with_approx(interior); @@ -37,7 +37,7 @@ impl Polygon { self } - fn with_approx(mut self, approx: impl Into) -> Self { + fn with_approx(mut self, approx: impl Into>) -> Self { for segment in approx.into().segments() { let segment = segment.points().map(|point| { // Can't panic, unless the approximation wrongfully generates From 02643a735f78a95538442c4f61a56f243a27aae3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Sat, 9 Apr 2022 15:02:02 +0200 Subject: [PATCH 2/2] Move point conversion out of `Polygon` It doesn't need to know about any of that. That it does, only makes testing it more complicated. --- fj-kernel/src/algorithms/triangulation/mod.rs | 24 +++++++++++++------ .../src/algorithms/triangulation/polygon.rs | 16 +++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/fj-kernel/src/algorithms/triangulation/mod.rs b/fj-kernel/src/algorithms/triangulation/mod.rs index bacb48f01..611380552 100644 --- a/fj-kernel/src/algorithms/triangulation/mod.rs +++ b/fj-kernel/src/algorithms/triangulation/mod.rs @@ -35,13 +35,23 @@ pub fn triangulate( }) .collect(); let face_as_polygon = Polygon::new(surface) - .with_exterior(approx.exterior.points) - .with_interiors( - approx - .interiors - .into_iter() - .map(|interior| interior.points), - ); + .with_exterior(approx.exterior.points.into_iter().map( + |point| { + // Can't panic, unless the approximation wrongfully + // generates points that are not in the surface. + surface.point_model_to_surface(point).native() + }, + )) + .with_interiors(approx.interiors.into_iter().map( + |interior| { + interior.points.into_iter().map(|point| { + // Can't panic, unless the approximation + // wrongfully generates points that are not in + // the surface. + surface.point_model_to_surface(point).native() + }) + }, + )); let mut triangles = delaunay(points); triangles.retain(|triangle| { diff --git a/fj-kernel/src/algorithms/triangulation/polygon.rs b/fj-kernel/src/algorithms/triangulation/polygon.rs index c86ed3f15..7ee76fa53 100644 --- a/fj-kernel/src/algorithms/triangulation/polygon.rs +++ b/fj-kernel/src/algorithms/triangulation/polygon.rs @@ -22,13 +22,13 @@ impl Polygon { } } - pub fn with_exterior(self, exterior: impl Into>) -> Self { + pub fn with_exterior(self, exterior: impl Into>) -> Self { self.with_approx(exterior) } pub fn with_interiors( mut self, - interiors: impl IntoIterator>>, + interiors: impl IntoIterator>>, ) -> Self { for interior in interiors { self = self.with_approx(interior); @@ -37,18 +37,14 @@ impl Polygon { self } - fn with_approx(mut self, approx: impl Into>) -> Self { + fn with_approx(mut self, approx: impl Into>) -> Self { for segment in approx.into().segments() { let segment = segment.points().map(|point| { - // Can't panic, unless the approximation wrongfully generates - // points that are not in the surface. - let point = self.surface.point_model_to_surface(point); - - if point.native() > self.max { - self.max = point.native(); + if point > self.max { + self.max = point; } - point.native() + point }); let edge = Segment::from(segment);