From eef8fd424cc0a4870838e3061d52e3381675b178 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 16 Oct 2023 11:52:11 +0200 Subject: [PATCH 1/3] Add `CurveBoundaries::empty` --- crates/fj-core/src/geometry/boundary/multiple.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fj-core/src/geometry/boundary/multiple.rs b/crates/fj-core/src/geometry/boundary/multiple.rs index 2c456edfb..6958bae8a 100644 --- a/crates/fj-core/src/geometry/boundary/multiple.rs +++ b/crates/fj-core/src/geometry/boundary/multiple.rs @@ -14,6 +14,11 @@ pub struct CurveBoundaries { } impl CurveBoundaries { + /// Create an empty instance of `CurveBoundaries` + pub fn empty() -> Self { + Self { inner: Vec::new() } + } + /// Transform `self` into the payload of the single boundary requested /// /// If there are no boundaries or multiple boundaries in `self`, or if the From 066c1aa1d8b3e5be6acebcea796f7a5eb2505725 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 16 Oct 2023 12:05:19 +0200 Subject: [PATCH 2/3] Add `CurveBoundaries::is_empty` --- crates/fj-core/src/geometry/boundary/multiple.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fj-core/src/geometry/boundary/multiple.rs b/crates/fj-core/src/geometry/boundary/multiple.rs index 6958bae8a..48433f91c 100644 --- a/crates/fj-core/src/geometry/boundary/multiple.rs +++ b/crates/fj-core/src/geometry/boundary/multiple.rs @@ -19,6 +19,11 @@ impl CurveBoundaries { Self { inner: Vec::new() } } + /// Indicate whether this `CurveBoundaries` instance is empty + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + /// Transform `self` into the payload of the single boundary requested /// /// If there are no boundaries or multiple boundaries in `self`, or if the From 4c3b92cc112b94592142973fa3bb208c17414c4e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 16 Oct 2023 12:08:38 +0200 Subject: [PATCH 3/3] Fix watertightness check requiring congruent edges It used to be that coincident `Edge`s needed to be fully congruent (https://github.com/hannobraun/fornjot/issues/1937). This limitation was largely removed, but it turns out, the water-tightness check was still an unrecognized holdover. Now the limitation has been removed from there too. --- crates/fj-core/src/validate/shell.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 58be7983d..84cb4dc04 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use fj_math::{Point, Scalar}; use crate::{ - geometry::SurfaceGeometry, + geometry::{CurveBoundaries, SurfaceGeometry}, objects::{Edge, Shell, Surface}, queries::{AllEdgesWithSurface, BoundingVerticesOfEdge}, storage::{Handle, HandleWrapper}, @@ -294,28 +294,28 @@ impl ShellValidationError { _: &ValidationConfig, errors: &mut Vec, ) { - let mut num_edges = BTreeMap::new(); + let mut unmatched_edges_by_curve = BTreeMap::new(); for face in shell.faces() { for cycle in face.region().all_cycles() { for edge in cycle.edges() { let curve = HandleWrapper::from(edge.curve().clone()); - let bounding_vertices = cycle - .bounding_vertices_of_edge(edge) - .expect("Cycle should provide bounds of its own edge") - .normalize(); - let edge = (curve, bounding_vertices); + let unmatched_edges = unmatched_edges_by_curve + .entry(curve) + .or_insert_with(CurveBoundaries::empty); - *num_edges.entry(edge).or_insert(0) += 1; + *unmatched_edges = unmatched_edges + .clone() + .symmetric_difference((edge.boundary(), ())); } } } - // 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()); + for unmatched_edges in unmatched_edges_by_curve.into_values() { + if !unmatched_edges.is_empty() { + errors.push(Self::NotWatertight.into()); + } } }