From 6e8dd5bcd077ae264603e5ae6a76cb64294fe4a2 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:14:27 +0200 Subject: [PATCH 01/18] Add `CurveApprox` --- crates/fj-core/src/algorithms/approx/curve.rs | 5 ++++- crates/fj-core/src/algorithms/approx/curve/approx.rs | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 crates/fj-core/src/algorithms/approx/curve/approx.rs diff --git a/crates/fj-core/src/algorithms/approx/curve.rs b/crates/fj-core/src/algorithms/approx/curve.rs index 481dca730..8eb7f3bfe 100644 --- a/crates/fj-core/src/algorithms/approx/curve.rs +++ b/crates/fj-core/src/algorithms/approx/curve.rs @@ -1,6 +1,9 @@ //! Curve approximation +mod approx; mod cache; mod segment; -pub use self::{cache::CurveApproxCache, segment::CurveApproxSegment}; +pub use self::{ + approx::CurveApprox, cache::CurveApproxCache, segment::CurveApproxSegment, +}; diff --git a/crates/fj-core/src/algorithms/approx/curve/approx.rs b/crates/fj-core/src/algorithms/approx/curve/approx.rs new file mode 100644 index 000000000..18061c6dd --- /dev/null +++ b/crates/fj-core/src/algorithms/approx/curve/approx.rs @@ -0,0 +1,8 @@ +use super::CurveApproxSegment; + +/// Partial approximation of a curve +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] +pub struct CurveApprox { + /// The approximated segments that are part of this approximation + pub segments: Vec, +} From a93157403381a6d8a0f500030a0b390162343174 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:25:21 +0200 Subject: [PATCH 02/18] Refactor to prepare for follow-on change --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index d10e3bada..2bea017a0 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -26,16 +26,19 @@ impl CurveApproxCache { curve: &Handle, boundary: &CurveBoundary>, ) -> Option { - if let Some(approx) = self.inner.get(&(curve.clone().into(), *boundary)) + if let Some(approx) = + self.inner.get(&(curve.clone().into(), *boundary)).cloned() { - return Some(approx.clone()); + return Some(approx); } - if let Some(approx) = - self.inner.get(&(curve.clone().into(), boundary.reverse())) + if let Some(approx) = self + .inner + .get(&(curve.clone().into(), boundary.reverse())) + .cloned() { // If we have a cache entry for the reverse boundary, we need to use // that too! - return Some(approx.clone().reverse()); + return Some(approx.reverse()); } None From 9e895924256adadbec975f82ceb125d0efd63f12 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:32:22 +0200 Subject: [PATCH 03/18] Add `CurveApproxSegment::is_normalized` --- crates/fj-core/src/algorithms/approx/curve/segment.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index d0d8fcb05..3ae1abc63 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -20,6 +20,11 @@ pub struct CurveApproxSegment { } impl CurveApproxSegment { + /// Indicate whether the segment is normalized + pub fn is_normalized(&self) -> bool { + self.boundary.is_normalized() + } + /// Reverse the orientation of the approximation #[must_use] pub fn reverse(mut self) -> Self { From 541efad4c7bb1388eed7902ad23abddbc71e2497 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:34:51 +0200 Subject: [PATCH 04/18] Add `CurveApproxSegment::normalize` --- .../src/algorithms/approx/curve/segment.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index 3ae1abc63..714fd0eb8 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -32,6 +32,21 @@ impl CurveApproxSegment { self.points.reverse(); self } + + /// Normalize the segment + /// + /// Returns a new instance of this struct, which has the points of the + /// approximation in a defined order. This can be used to compare segments + /// while disregarding their direction. + #[must_use] + pub fn normalize(mut self) -> Self { + if !self.is_normalized() { + self.boundary = self.boundary.normalize(); + self.points.reverse(); + } + + self + } } impl Ord for CurveApproxSegment { From 9fbc04217006b9c1af73aa300389614a28b5d04e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:38:10 +0200 Subject: [PATCH 05/18] Always store curve approximations normalized This enables simplifications of the retrieval side. --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 2bea017a0..b46e9c636 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -50,6 +50,7 @@ impl CurveApproxCache { curve: Handle, new_segment: CurveApproxSegment, ) -> Option { + let new_segment = new_segment.normalize(); self.inner .insert((curve.into(), new_segment.boundary), new_segment) } From 7cf8d5e9afe3f8defb8061575fb9f8c626548a69 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:39:11 +0200 Subject: [PATCH 06/18] Refactor to simplify --- .../src/algorithms/approx/curve/cache.rs | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index b46e9c636..2e13c0554 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -26,22 +26,19 @@ impl CurveApproxCache { curve: &Handle, boundary: &CurveBoundary>, ) -> Option { - if let Some(approx) = - self.inner.get(&(curve.clone().into(), *boundary)).cloned() - { - return Some(approx); - } - if let Some(approx) = self - .inner - .get(&(curve.clone().into(), boundary.reverse())) - .cloned() - { - // If we have a cache entry for the reverse boundary, we need to use - // that too! - return Some(approx.reverse()); - } + let was_already_normalized = boundary.is_normalized(); + let normalized_boundary = boundary.normalize(); - None + self.inner + .get(&(curve.clone().into(), normalized_boundary)) + .cloned() + .map(|approx| { + if was_already_normalized { + approx + } else { + approx.reverse() + } + }) } /// Insert an approximated segment of the curve into the cache From e2d9a96cd0b2c00cabd0a02071580e54bf737947 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:54:41 +0200 Subject: [PATCH 07/18] Refactor to prepare for follow-on change --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 5 +++-- crates/fj-core/src/algorithms/approx/edge.rs | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 2e13c0554..493ca854c 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -46,9 +46,10 @@ impl CurveApproxCache { &mut self, curve: Handle, new_segment: CurveApproxSegment, - ) -> Option { + ) -> CurveApproxSegment { let new_segment = new_segment.normalize(); self.inner - .insert((curve.into(), new_segment.boundary), new_segment) + .insert((curve.into(), new_segment.boundary), new_segment.clone()) + .unwrap_or(new_segment) } } diff --git a/crates/fj-core/src/algorithms/approx/edge.rs b/crates/fj-core/src/algorithms/approx/edge.rs index 599de8e93..02609045c 100644 --- a/crates/fj-core/src/algorithms/approx/edge.rs +++ b/crates/fj-core/src/algorithms/approx/edge.rs @@ -253,9 +253,7 @@ impl EdgeApproxCache { handle: Handle, approx: CurveApproxSegment, ) -> CurveApproxSegment { - self.curve_approx - .insert(handle, approx.clone()) - .unwrap_or(approx) + self.curve_approx.insert(handle, approx) } } From b29aaf7a6c8538b3c73df1810834342eaad52d9f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:54:53 +0200 Subject: [PATCH 08/18] Improve formatting --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 493ca854c..e834d5dfd 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -48,6 +48,7 @@ impl CurveApproxCache { new_segment: CurveApproxSegment, ) -> CurveApproxSegment { let new_segment = new_segment.normalize(); + self.inner .insert((curve.into(), new_segment.boundary), new_segment.clone()) .unwrap_or(new_segment) From 69979a967b760e2a4bb86277660169f6505525d1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 10:57:49 +0200 Subject: [PATCH 09/18] Use `CurveApprox` in `CurveApproxCache` This only makes things more complicated for now, but it paves the way for making curve approximation caching more flexible. --- .../src/algorithms/approx/curve/cache.rs | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index e834d5dfd..fbe5b39a1 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -8,15 +8,13 @@ use crate::{ storage::{Handle, HandleWrapper}, }; -use super::CurveApproxSegment; +use super::{CurveApprox, CurveApproxSegment}; /// Cache for curve approximations #[derive(Default)] pub struct CurveApproxCache { - inner: BTreeMap< - (HandleWrapper, CurveBoundary>), - CurveApproxSegment, - >, + inner: + BTreeMap<(HandleWrapper, CurveBoundary>), CurveApprox>, } impl CurveApproxCache { @@ -32,13 +30,27 @@ impl CurveApproxCache { self.inner .get(&(curve.clone().into(), normalized_boundary)) .cloned() - .map(|approx| { + .map(|mut approx| { if was_already_normalized { approx } else { - approx.reverse() + for segment in &mut approx.segments { + *segment = segment.clone().reverse(); + } + approx } }) + .map(|approx| { + let mut segments = approx.segments.into_iter(); + let segment = segments + .next() + .expect("Empty approximations should not exist in cache"); + assert!( + segments.next().is_none(), + "Cached approximations should have exactly 1 segment" + ); + segment + }) } /// Insert an approximated segment of the curve into the cache @@ -49,8 +61,29 @@ impl CurveApproxCache { ) -> CurveApproxSegment { let new_segment = new_segment.normalize(); + // We assume that curve approximation segments never overlap, so so we + // don't have to do any merging of this segment with a possibly existing + // approximation for this curve. + // + // For now, this is a valid assumption, as it matches the uses of this + // method, due to documented limitations elsewhere in the system. + let approx = CurveApprox { + segments: vec![new_segment.clone()], + }; + self.inner - .insert((curve.into(), new_segment.boundary), new_segment.clone()) + .insert((curve.into(), new_segment.boundary), approx) + .map(|approx| { + let mut segments = approx.segments.into_iter(); + let segment = segments + .next() + .expect("Empty approximations should not exist in cache"); + assert!( + segments.next().is_none(), + "Cached approximations should have exactly 1 segment" + ); + segment + }) .unwrap_or(new_segment) } } From 5dd06cd99f28da391ab14890bada79b852961781 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:04:27 +0200 Subject: [PATCH 10/18] Add comment --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index fbe5b39a1..d1b86acc7 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -24,6 +24,10 @@ impl CurveApproxCache { curve: &Handle, boundary: &CurveBoundary>, ) -> Option { + // Approximations within the cache are all stored in normalized form. If + // the caller requests a non-normalized boundary, that means we need to + // adjust the result before we return it, so let's remember whether the + // normalization resulted in a reversal. let was_already_normalized = boundary.is_normalized(); let normalized_boundary = boundary.normalize(); From ed9608b1a5db4e704b180fb5c6f5e876675d12ce Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:06:09 +0200 Subject: [PATCH 11/18] Refactor to improve clarity --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index d1b86acc7..4f5b4f45e 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -24,6 +24,8 @@ impl CurveApproxCache { curve: &Handle, boundary: &CurveBoundary>, ) -> Option { + let curve = HandleWrapper::from(curve.clone()); + // Approximations within the cache are all stored in normalized form. If // the caller requests a non-normalized boundary, that means we need to // adjust the result before we return it, so let's remember whether the @@ -32,7 +34,7 @@ impl CurveApproxCache { let normalized_boundary = boundary.normalize(); self.inner - .get(&(curve.clone().into(), normalized_boundary)) + .get(&(curve, normalized_boundary)) .cloned() .map(|mut approx| { if was_already_normalized { From 5b48d3373e9642a22f4364b3753a0d02b6848bd6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:23:11 +0200 Subject: [PATCH 12/18] Return `CurveApprox` from `CurveApproxCache::get` --- .../src/algorithms/approx/curve/cache.rs | 22 +++++-------------- crates/fj-core/src/algorithms/approx/edge.rs | 12 +++++++++- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 4f5b4f45e..c645aad95 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -23,7 +23,7 @@ impl CurveApproxCache { &self, curve: &Handle, boundary: &CurveBoundary>, - ) -> Option { + ) -> Option { let curve = HandleWrapper::from(curve.clone()); // Approximations within the cache are all stored in normalized form. If @@ -33,10 +33,8 @@ impl CurveApproxCache { let was_already_normalized = boundary.is_normalized(); let normalized_boundary = boundary.normalize(); - self.inner - .get(&(curve, normalized_boundary)) - .cloned() - .map(|mut approx| { + self.inner.get(&(curve, normalized_boundary)).cloned().map( + |mut approx| { if was_already_normalized { approx } else { @@ -45,18 +43,8 @@ impl CurveApproxCache { } approx } - }) - .map(|approx| { - let mut segments = approx.segments.into_iter(); - let segment = segments - .next() - .expect("Empty approximations should not exist in cache"); - assert!( - segments.next().is_none(), - "Cached approximations should have exactly 1 segment" - ); - segment - }) + }, + ) } /// Insert an approximated segment of the curve into the cache diff --git a/crates/fj-core/src/algorithms/approx/edge.rs b/crates/fj-core/src/algorithms/approx/edge.rs index 02609045c..385acff1f 100644 --- a/crates/fj-core/src/algorithms/approx/edge.rs +++ b/crates/fj-core/src/algorithms/approx/edge.rs @@ -245,7 +245,17 @@ impl EdgeApproxCache { handle: Handle, boundary: CurveBoundary>, ) -> Option { - self.curve_approx.get(&handle, &boundary) + self.curve_approx.get(&handle, &boundary).map(|approx| { + let mut segments = approx.segments.into_iter(); + let segment = segments + .next() + .expect("Empty approximations should not exist in cache"); + assert!( + segments.next().is_none(), + "Cached approximations should have exactly 1 segment" + ); + segment + }) } fn insert_curve_approx( From 719ed0c9c524a43e68f24e11fb169d3a739f2f47 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:32:11 +0200 Subject: [PATCH 13/18] Make `normalize` better match its use case --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 4 ++-- crates/fj-core/src/algorithms/approx/curve/segment.rs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index c645aad95..a019d91bb 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -51,9 +51,9 @@ impl CurveApproxCache { pub fn insert( &mut self, curve: Handle, - new_segment: CurveApproxSegment, + mut new_segment: CurveApproxSegment, ) -> CurveApproxSegment { - let new_segment = new_segment.normalize(); + new_segment.normalize(); // We assume that curve approximation segments never overlap, so so we // don't have to do any merging of this segment with a possibly existing diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index 714fd0eb8..6f00c30ed 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -38,8 +38,7 @@ impl CurveApproxSegment { /// Returns a new instance of this struct, which has the points of the /// approximation in a defined order. This can be used to compare segments /// while disregarding their direction. - #[must_use] - pub fn normalize(mut self) -> Self { + pub fn normalize(&mut self) -> &mut Self { if !self.is_normalized() { self.boundary = self.boundary.normalize(); self.points.reverse(); From c73d119ce7b3eb57d3d07f56d03fc1e25062e6b7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:32:55 +0200 Subject: [PATCH 14/18] Update doc comment --- crates/fj-core/src/algorithms/approx/curve/segment.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index 6f00c30ed..31b934264 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -35,9 +35,8 @@ impl CurveApproxSegment { /// Normalize the segment /// - /// Returns a new instance of this struct, which has the points of the - /// approximation in a defined order. This can be used to compare segments - /// while disregarding their direction. + /// Puts the points of the approximation in a defined order. This can be + /// used to compare segments while disregarding their direction. pub fn normalize(&mut self) -> &mut Self { if !self.is_normalized() { self.boundary = self.boundary.normalize(); From 54628114fa7f13cd5451ba33a206b933bf221d68 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:34:01 +0200 Subject: [PATCH 15/18] Make `reverse` better match its use case --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 2 +- crates/fj-core/src/algorithms/approx/curve/segment.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index a019d91bb..0d01a880d 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -39,7 +39,7 @@ impl CurveApproxCache { approx } else { for segment in &mut approx.segments { - *segment = segment.clone().reverse(); + segment.reverse(); } approx } diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index 31b934264..d77d2cbb6 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -26,8 +26,7 @@ impl CurveApproxSegment { } /// Reverse the orientation of the approximation - #[must_use] - pub fn reverse(mut self) -> Self { + pub fn reverse(&mut self) -> &mut Self { self.boundary = self.boundary.reverse(); self.points.reverse(); self From 32bae975bbbdad83d35da771a808c58d4447a7ae Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:35:04 +0200 Subject: [PATCH 16/18] Refactor to simplify --- crates/fj-core/src/algorithms/approx/curve/cache.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 0d01a880d..9eac2f6c2 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -35,14 +35,13 @@ impl CurveApproxCache { self.inner.get(&(curve, normalized_boundary)).cloned().map( |mut approx| { - if was_already_normalized { - approx - } else { + if !was_already_normalized { for segment in &mut approx.segments { segment.reverse(); } - approx } + + approx }, ) } From c3ad019bf46d40347787a97d15907d9aed6855f4 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:36:34 +0200 Subject: [PATCH 17/18] Add `CurveApprox::reverse` --- crates/fj-core/src/algorithms/approx/curve/approx.rs | 11 +++++++++++ crates/fj-core/src/algorithms/approx/curve/cache.rs | 4 +--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve/approx.rs b/crates/fj-core/src/algorithms/approx/curve/approx.rs index 18061c6dd..f2ad1c484 100644 --- a/crates/fj-core/src/algorithms/approx/curve/approx.rs +++ b/crates/fj-core/src/algorithms/approx/curve/approx.rs @@ -6,3 +6,14 @@ pub struct CurveApprox { /// The approximated segments that are part of this approximation pub segments: Vec, } + +impl CurveApprox { + /// Reverse the approximation + pub fn reverse(&mut self) -> &mut Self { + for segment in &mut self.segments { + segment.reverse(); + } + + self + } +} diff --git a/crates/fj-core/src/algorithms/approx/curve/cache.rs b/crates/fj-core/src/algorithms/approx/curve/cache.rs index 9eac2f6c2..18411771d 100644 --- a/crates/fj-core/src/algorithms/approx/curve/cache.rs +++ b/crates/fj-core/src/algorithms/approx/curve/cache.rs @@ -36,9 +36,7 @@ impl CurveApproxCache { self.inner.get(&(curve, normalized_boundary)).cloned().map( |mut approx| { if !was_already_normalized { - for segment in &mut approx.segments { - segment.reverse(); - } + approx.reverse(); } approx From 62968aba3a8fc7671b687e48d6e0052c64355fca Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 6 Sep 2023 11:44:24 +0200 Subject: [PATCH 18/18] Reverse segment order in `CurveApprox::reverse` --- .../src/algorithms/approx/curve/approx.rs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/crates/fj-core/src/algorithms/approx/curve/approx.rs b/crates/fj-core/src/algorithms/approx/curve/approx.rs index f2ad1c484..63ab99b12 100644 --- a/crates/fj-core/src/algorithms/approx/curve/approx.rs +++ b/crates/fj-core/src/algorithms/approx/curve/approx.rs @@ -10,6 +10,8 @@ pub struct CurveApprox { impl CurveApprox { /// Reverse the approximation pub fn reverse(&mut self) -> &mut Self { + self.segments.reverse(); + for segment in &mut self.segments { segment.reverse(); } @@ -17,3 +19,56 @@ impl CurveApprox { self } } + +#[cfg(test)] +mod tests { + use crate::algorithms::approx::{curve::CurveApproxSegment, ApproxPoint}; + + use super::CurveApprox; + + #[test] + fn reverse() { + let mut approx = CurveApprox { + segments: vec![ + CurveApproxSegment { + boundary: [[0.1], [0.4]].into(), + points: vec![ + ApproxPoint::new([0.1], [0.1, 0.1, 0.1]), + ApproxPoint::new([0.4], [0.4, 0.4, 0.4]), + ], + }, + CurveApproxSegment { + boundary: [[0.6], [0.9]].into(), + points: vec![ + ApproxPoint::new([0.6], [0.6, 0.6, 0.6]), + ApproxPoint::new([0.9], [0.9, 0.9, 0.9]), + ], + }, + ], + }; + + approx.reverse(); + + assert_eq!( + approx, + CurveApprox { + segments: vec![ + CurveApproxSegment { + boundary: [[0.9], [0.6]].into(), + points: vec![ + ApproxPoint::new([0.9], [0.9, 0.9, 0.9]), + ApproxPoint::new([0.6], [0.6, 0.6, 0.6]), + ], + }, + CurveApproxSegment { + boundary: [[0.4], [0.1]].into(), + points: vec![ + ApproxPoint::new([0.4], [0.4, 0.4, 0.4]), + ApproxPoint::new([0.1], [0.1, 0.1, 0.1]), + ], + }, + ], + } + ) + } +}