From 85b5cd0408b6cddb9201fae58280ef9c024c5f89 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 08:51:19 +0200 Subject: [PATCH 01/20] Update doc comments --- crates/fj-core/src/operations/update/edge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/update/edge.rs b/crates/fj-core/src/operations/update/edge.rs index d065cee69..3bf00ecc1 100644 --- a/crates/fj-core/src/operations/update/edge.rs +++ b/crates/fj-core/src/operations/update/edge.rs @@ -5,11 +5,11 @@ use crate::{ /// Update a [`HalfEdge`] pub trait UpdateHalfEdge { - /// Update the start vertex of the half-edge + /// Replace the start vertex of the half-edge #[must_use] fn replace_start_vertex(&self, start_vertex: Handle) -> Self; - /// Update the global form of the half-edge + /// Replace the global form of the half-edge #[must_use] fn replace_global_form(&self, global_form: Handle) -> Self; } From 85e6d1e451d9a119c8d561cac045bda76c1fea39 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 08:52:41 +0200 Subject: [PATCH 02/20] Add `UpdateHalfEdge::replace_curve` --- crates/fj-core/src/operations/update/edge.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/update/edge.rs b/crates/fj-core/src/operations/update/edge.rs index 3bf00ecc1..b67dfee78 100644 --- a/crates/fj-core/src/operations/update/edge.rs +++ b/crates/fj-core/src/operations/update/edge.rs @@ -1,10 +1,14 @@ use crate::{ - objects::{GlobalEdge, HalfEdge, Vertex}, + objects::{Curve, GlobalEdge, HalfEdge, Vertex}, storage::Handle, }; /// Update a [`HalfEdge`] pub trait UpdateHalfEdge { + /// Replace the curve of the half-edge + #[must_use] + fn replace_curve(&self, curve: Handle) -> Self; + /// Replace the start vertex of the half-edge #[must_use] fn replace_start_vertex(&self, start_vertex: Handle) -> Self; @@ -15,6 +19,16 @@ pub trait UpdateHalfEdge { } impl UpdateHalfEdge for HalfEdge { + fn replace_curve(&self, curve: Handle) -> Self { + HalfEdge::new( + self.path(), + self.boundary(), + curve, + self.start_vertex().clone(), + self.global_form().clone(), + ) + } + fn replace_start_vertex(&self, start_vertex: Handle) -> Self { HalfEdge::new( self.path(), From 5dd79f7e96c0bb7cbfe9d8e12a10654410ad542b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:15:02 +0200 Subject: [PATCH 03/20] Take curve into account when joining edges --- crates/fj-core/src/operations/join/cycle.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 4782300e2..ae95d1e04 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -115,6 +115,7 @@ impl JoinCycle for Cycle { .expect("Expected this cycle to contain edge"); let this_joined = half_edge + .replace_curve(half_edge_other.curve().clone()) .replace_start_vertex(vertex_a) .replace_global_form(half_edge_other.global_form().clone()) .insert(services); From a168e93dabbba4b5712eeda6675b8182323fbc10 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:17:02 +0200 Subject: [PATCH 04/20] Take curve into account in validation test --- crates/fj-core/src/validate/shell.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index dfd6a62be..8fd19a81f 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -210,7 +210,7 @@ impl ShellValidationError { mod tests { use crate::{ assert_contains_err, - objects::{GlobalEdge, Shell}, + objects::{Curve, GlobalEdge, Shell}, operations::{ BuildShell, Insert, UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateRegion, UpdateShell, @@ -237,9 +237,13 @@ mod tests { .update_exterior(|cycle| { cycle .update_nth_half_edge(0, |half_edge| { + let curve = + Curve::new().insert(&mut services); let global_form = GlobalEdge::new().insert(&mut services); + half_edge + .replace_curve(curve) .replace_global_form(global_form) .insert(&mut services) }) From 0ca3a6e5cfaa9e6ea40de096558e693960849c29 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:05:36 +0200 Subject: [PATCH 05/20] Improve formatting --- crates/fj-core/src/algorithms/sweep/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/algorithms/sweep/mod.rs index 583b3b7fb..30340e721 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/algorithms/sweep/mod.rs @@ -47,6 +47,7 @@ pub trait Sweep: Sized { pub struct SweepCache { /// Cache for global vertices pub global_vertex: BTreeMap>, + /// Cache for global edges pub global_edge: BTreeMap>, } From 7d5643c5175c593ac84928656e9d9b680f99792c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:06:03 +0200 Subject: [PATCH 06/20] Update struct field name --- crates/fj-core/src/algorithms/sweep/mod.rs | 2 +- crates/fj-core/src/algorithms/sweep/vertex.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/algorithms/sweep/mod.rs index 30340e721..c820a9afe 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/algorithms/sweep/mod.rs @@ -46,7 +46,7 @@ pub trait Sweep: Sized { #[derive(Default)] pub struct SweepCache { /// Cache for global vertices - pub global_vertex: BTreeMap>, + pub vertices: BTreeMap>, /// Cache for global edges pub global_edge: BTreeMap>, diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/algorithms/sweep/vertex.rs index bb4ad6ba0..49f8574fa 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/algorithms/sweep/vertex.rs @@ -20,7 +20,7 @@ impl Sweep for Handle { ) -> Self::Swept { let a = self.clone(); let b = cache - .global_vertex + .vertices .entry(self.id()) .or_insert_with(|| Vertex::new().insert(services)) .clone(); From bfa29a16d506eae3b3e33119cb2c4295818513f1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:06:15 +0200 Subject: [PATCH 07/20] Improve struct field name --- crates/fj-core/src/algorithms/sweep/mod.rs | 2 +- crates/fj-core/src/algorithms/sweep/vertex.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/algorithms/sweep/mod.rs index c820a9afe..c67eda268 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/algorithms/sweep/mod.rs @@ -49,5 +49,5 @@ pub struct SweepCache { pub vertices: BTreeMap>, /// Cache for global edges - pub global_edge: BTreeMap>, + pub global_edges: BTreeMap>, } diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/algorithms/sweep/vertex.rs index 49f8574fa..2dfac0a7e 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/algorithms/sweep/vertex.rs @@ -27,7 +27,7 @@ impl Sweep for Handle { let vertices = [a, b]; let global_edge = cache - .global_edge + .global_edges .entry(self.id()) .or_insert_with(|| GlobalEdge::new().insert(services)) .clone(); From 1794bd8943ea9c6a98eaf59871981ac4a6e53cc4 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:06:35 +0200 Subject: [PATCH 08/20] Update doc comment --- crates/fj-core/src/algorithms/sweep/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/algorithms/sweep/mod.rs index c67eda268..8f6da8b30 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/algorithms/sweep/mod.rs @@ -45,7 +45,7 @@ pub trait Sweep: Sized { /// See [`Sweep`]. #[derive(Default)] pub struct SweepCache { - /// Cache for global vertices + /// Cache for vertices pub vertices: BTreeMap>, /// Cache for global edges From 09b4ef2903b0b020a99cf2d0aae7437f8ba7a01c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:06:59 +0200 Subject: [PATCH 09/20] Add cache for curves to `SweepCache` --- crates/fj-core/src/algorithms/sweep/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/algorithms/sweep/mod.rs index 8f6da8b30..3f759e9e5 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/algorithms/sweep/mod.rs @@ -11,7 +11,7 @@ use std::collections::BTreeMap; use fj_math::Vector; use crate::{ - objects::{GlobalEdge, Vertex}, + objects::{Curve, GlobalEdge, Vertex}, services::Services, storage::{Handle, ObjectId}, }; @@ -45,6 +45,9 @@ pub trait Sweep: Sized { /// See [`Sweep`]. #[derive(Default)] pub struct SweepCache { + /// Cache for curves + pub curves: BTreeMap>, + /// Cache for vertices pub vertices: BTreeMap>, From 0835fb8d37c3501f63f0f2e3c79293326d149985 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:07:58 +0200 Subject: [PATCH 10/20] Remove outdated comment `GlobalEdge` no longer has any vertices. --- crates/fj-core/src/algorithms/sweep/vertex.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/algorithms/sweep/vertex.rs index 2dfac0a7e..1caaaff76 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/algorithms/sweep/vertex.rs @@ -32,9 +32,6 @@ impl Sweep for Handle { .or_insert_with(|| GlobalEdge::new().insert(services)) .clone(); - // The vertices of the returned `GlobalEdge` are in normalized order, - // which means the order can't be relied upon by the caller. Return the - // ordered vertices in addition. (global_edge, vertices) } } From 79ea1a0f6292a72f3e29efb4bb919cd6def1811e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:08:32 +0200 Subject: [PATCH 11/20] Update formatting --- crates/fj-core/src/algorithms/sweep/vertex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/algorithms/sweep/vertex.rs index 1caaaff76..c733f48ad 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/algorithms/sweep/vertex.rs @@ -24,8 +24,8 @@ impl Sweep for Handle { .entry(self.id()) .or_insert_with(|| Vertex::new().insert(services)) .clone(); - let vertices = [a, b]; + let global_edge = cache .global_edges .entry(self.id()) From 8273ad27124319d4c79da143d27db6f48b1a43b5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:10:09 +0200 Subject: [PATCH 12/20] Create curve when sweeping vertex --- crates/fj-core/src/algorithms/sweep/edge.rs | 4 ++-- crates/fj-core/src/algorithms/sweep/vertex.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index 929011469..e10d25347 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -29,9 +29,9 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { // the global vertices and edges. let (vertices, global_edges) = { let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); - let (edge_up, [_, c]) = + let (_, edge_up, [_, c]) = b.clone().sweep_with_cache(path, cache, services); - let (edge_down, [_, d]) = + let (_, edge_down, [_, d]) = a.clone().sweep_with_cache(path, cache, services); ( diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/algorithms/sweep/vertex.rs index c733f48ad..e61982bd3 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/algorithms/sweep/vertex.rs @@ -1,7 +1,7 @@ use fj_math::Vector; use crate::{ - objects::{GlobalEdge, Vertex}, + objects::{Curve, GlobalEdge, Vertex}, operations::Insert, services::Services, storage::Handle, @@ -10,7 +10,7 @@ use crate::{ use super::{Sweep, SweepCache}; impl Sweep for Handle { - type Swept = (Handle, [Self; 2]); + type Swept = (Handle, Handle, [Self; 2]); fn sweep_with_cache( self, @@ -18,6 +18,12 @@ impl Sweep for Handle { cache: &mut SweepCache, services: &mut Services, ) -> Self::Swept { + let curve = cache + .curves + .entry(self.id()) + .or_insert_with(|| Curve::new().insert(services)) + .clone(); + let a = self.clone(); let b = cache .vertices @@ -32,6 +38,6 @@ impl Sweep for Handle { .or_insert_with(|| GlobalEdge::new().insert(services)) .clone(); - (global_edge, vertices) + (curve, global_edge, vertices) } } From c92de0eec5fb36fae1f45097be840e8241e6dbe6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:25:43 +0200 Subject: [PATCH 13/20] Take curves into account when sweeping edge --- crates/fj-core/src/algorithms/sweep/edge.rs | 72 +++++++++++++-------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/algorithms/sweep/edge.rs index e10d25347..0d0c74125 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/algorithms/sweep/edge.rs @@ -27,11 +27,11 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { // Next, we need to define the boundaries of the face. Let's start with // the global vertices and edges. - let (vertices, global_edges) = { + let (vertices, global_edges, curves) = { let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); - let (_, edge_up, [_, c]) = + let (curve_up, edge_up, [_, c]) = b.clone().sweep_with_cache(path, cache, services); - let (_, edge_down, [_, d]) = + let (curve_down, edge_down, [_, d]) = a.clone().sweep_with_cache(path, cache, services); ( @@ -42,6 +42,12 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { None, Some(edge_down), ], + [ + Some(edge.curve().clone()), + Some(curve_up), + None, + Some(curve_down), + ], ) }; @@ -78,34 +84,46 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { .zip_ext(surface_points) .zip_ext(surface_points_next) .zip_ext(vertices) + .zip_ext(curves) .zip_ext(global_edges) - .map(|((((boundary, start), end), start_vertex), global_edge)| { - let half_edge = { - let half_edge = HalfEdge::line_segment( - [start, end], - Some(boundary), - services, - ) - .replace_start_vertex(start_vertex); - - let half_edge = if let Some(global_edge) = global_edge { - half_edge.replace_global_form(global_edge) - } else { - half_edge + .map( + |( + ((((boundary, start), end), start_vertex), curve), + global_edge, + )| { + let half_edge = { + let half_edge = HalfEdge::line_segment( + [start, end], + Some(boundary), + services, + ) + .replace_start_vertex(start_vertex); + + let half_edge = if let Some(curve) = curve { + half_edge.replace_curve(curve) + } else { + half_edge + }; + + let half_edge = if let Some(global_edge) = global_edge { + half_edge.replace_global_form(global_edge) + } else { + half_edge + }; + + half_edge.insert(services) }; - half_edge.insert(services) - }; - - exterior = Some( - exterior - .take() - .unwrap() - .add_half_edges([half_edge.clone()]), - ); + exterior = Some( + exterior + .take() + .unwrap() + .add_half_edges([half_edge.clone()]), + ); - half_edge - }); + half_edge + }, + ); let region = Region::new(exterior.unwrap().insert(services), [], color) .insert(services); From 9df5901e13f8f2457883ede1a383b42291875bba Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:24:51 +0200 Subject: [PATCH 14/20] Take curve into account when adding joined edges --- crates/fj-core/src/operations/join/cycle.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index ae95d1e04..316880f52 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -71,6 +71,7 @@ impl JoinCycle for Cycle { self.add_half_edges(edges.into_iter().circular_tuple_windows().map( |((prev, _, _), (half_edge, curve, boundary))| { HalfEdge::unjoined(curve, boundary, services) + .replace_curve(half_edge.curve().clone()) .replace_start_vertex(prev.start_vertex().clone()) .replace_global_form(half_edge.global_form().clone()) .insert(services) From dd0c94413d1800cc811c0b228d519f36d774e6bb Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 17 Jul 2023 11:36:59 +0200 Subject: [PATCH 15/20] Make variable name more specific I'm about to add another one here. --- crates/fj-core/src/validate/shell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 8fd19a81f..ea4038524 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -127,10 +127,10 @@ impl ShellValidationError { // data-structure like an octree. for (edge_a, surface_a) in &edges_and_surfaces { for (edge_b, surface_b) in &edges_and_surfaces { - let identical = + let identical_according_to_global_form = edge_a.global_form().id() == edge_b.global_form().id(); - match identical { + match identical_according_to_global_form { true => { // All points on identical curves should be within // identical_max_distance, so we shouldn't have any From a2f2a7c1e74474a80c2b4fde9129da2632e73884 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 18 Jul 2023 11:00:16 +0200 Subject: [PATCH 16/20] Add `BoundingVertices::normalize` --- crates/fj-core/src/geometry/bounding_vertices.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/fj-core/src/geometry/bounding_vertices.rs b/crates/fj-core/src/geometry/bounding_vertices.rs index 75cb891e4..1ad037dfb 100644 --- a/crates/fj-core/src/geometry/bounding_vertices.rs +++ b/crates/fj-core/src/geometry/bounding_vertices.rs @@ -10,6 +10,18 @@ pub struct BoundingVertices { pub inner: [HandleWrapper; 2], } +impl BoundingVertices { + /// Normalize the bounding vertices + /// + /// Returns a new instance of this struct, which has the vertices in a + /// defined order. This can be used to compare bounding vertices while + /// disregarding their order. + pub fn normalize(mut self) -> Self { + self.inner.sort(); + self + } +} + impl From<[Handle; 2]> for BoundingVertices { fn from(vertices: [Handle; 2]) -> Self { Self { From 80c9aab83d24345f640efb92d85f220fa70cef31 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:27:02 +0200 Subject: [PATCH 17/20] Update shell validation test in terms of curve --- crates/fj-core/src/validate/shell.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index ea4038524..feef8995a 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -5,6 +5,7 @@ use fj_math::{Point, Scalar}; use crate::{ geometry::SurfaceGeometry, objects::{HalfEdge, Shell, Surface}, + queries::BoundingVerticesOfEdge, storage::{Handle, ObjectId}, }; @@ -130,7 +131,31 @@ impl ShellValidationError { let identical_according_to_global_form = edge_a.global_form().id() == edge_b.global_form().id(); - match identical_according_to_global_form { + let identical_according_to_curve = { + let on_same_curve = + edge_a.curve().id() == edge_b.curve().id(); + + let have_same_boundary = { + let bounding_vertices_of = |edge| { + shell + .bounding_vertices_of_edge(edge) + .expect("Expected edge to be part of shell") + .normalize() + }; + + bounding_vertices_of(edge_a) + == bounding_vertices_of(edge_b) + }; + + on_same_curve && have_same_boundary + }; + + assert_eq!( + identical_according_to_curve, + identical_according_to_global_form, + ); + + match identical_according_to_curve { true => { // All points on identical curves should be within // identical_max_distance, so we shouldn't have any From ee8e755b5913362d9b2b65051082736bd667c041 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:48:35 +0200 Subject: [PATCH 18/20] Derive `Ord` for `BoundingVertices` --- crates/fj-core/src/geometry/bounding_vertices.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/geometry/bounding_vertices.rs b/crates/fj-core/src/geometry/bounding_vertices.rs index 1ad037dfb..218a6237a 100644 --- a/crates/fj-core/src/geometry/bounding_vertices.rs +++ b/crates/fj-core/src/geometry/bounding_vertices.rs @@ -4,7 +4,7 @@ use crate::{ }; /// The bounding vertices of an edge -#[derive(Eq, PartialEq)] +#[derive(Eq, PartialEq, Ord, PartialOrd)] pub struct BoundingVertices { /// The bounding vertices pub inner: [HandleWrapper; 2], From bc6a5e2e37fc504c42a6ee28c1120a25b074a99f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:49:00 +0200 Subject: [PATCH 19/20] Derive `Debug` for `BoundingVertices` --- crates/fj-core/src/geometry/bounding_vertices.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-core/src/geometry/bounding_vertices.rs b/crates/fj-core/src/geometry/bounding_vertices.rs index 218a6237a..fd6afb6d4 100644 --- a/crates/fj-core/src/geometry/bounding_vertices.rs +++ b/crates/fj-core/src/geometry/bounding_vertices.rs @@ -4,7 +4,7 @@ use crate::{ }; /// The bounding vertices of an edge -#[derive(Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct BoundingVertices { /// The bounding vertices pub inner: [HandleWrapper; 2], From 0de5fde1a7f679ff1d64709b600d5c4a95af67bc Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 19 Jul 2023 09:27:02 +0200 Subject: [PATCH 20/20] Update shell validation test in terms of curve --- crates/fj-core/src/validate/shell.rs | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index feef8995a..0c1452722 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, iter::repeat}; +use std::{ + collections::{BTreeMap, HashMap}, + iter::repeat, +}; use fj_math::{Point, Scalar}; @@ -6,7 +9,7 @@ use crate::{ geometry::SurfaceGeometry, objects::{HalfEdge, Shell, Surface}, queries::BoundingVerticesOfEdge, - storage::{Handle, ObjectId}, + storage::{Handle, HandleWrapper, ObjectId}, }; use super::{Validate, ValidationConfig, ValidationError}; @@ -211,6 +214,32 @@ impl ShellValidationError { _: &ValidationConfig, errors: &mut Vec, ) { + let mut num_edges = BTreeMap::new(); + + for face in shell.faces() { + for cycle in face.region().all_cycles() { + for half_edge in cycle.half_edges() { + let curve = HandleWrapper::from(half_edge.curve().clone()); + let bounding_vertices = cycle + .bounding_vertices_of_edge(half_edge) + .expect( + "Cycle should provide bounds of its own half-edge", + ) + .normalize(); + + let edge = (curve, bounding_vertices); + + *num_edges.entry(edge).or_insert(0) += 1; + } + } + } + + // Every edge should have exactly one matching edge that shares a curve + // and boundary. + if num_edges.into_values().any(|num| num != 2) { + errors.push(Self::NotWatertight.into()); + } + let mut half_edge_to_faces: HashMap = HashMap::new(); for face in shell.faces() {