From 03606366f855a7f74805f08572a7215f38cdb126 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 21 Dec 2023 20:40:28 +0100 Subject: [PATCH 1/4] Convert tuple enum variant into struct variant --- crates/fj-core/src/validate/shell.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 622413a89..a2ec1ca8c 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -47,10 +47,16 @@ pub enum ShellValidationError { #[error( "`Shell` contains `HalfEdge`s that are coincident but are not \ siblings\n\ - Half-edge 1: {0:#?}\n\ - Half-edge 2: {1:#?}" + Half-edge 1: {half_edge_a:#?}\n\ + Half-edge 2: {half_edge_b:#?}" )] - CoincidentHalfEdgesAreNotSiblings(Handle, Handle), + CoincidentHalfEdgesAreNotSiblings { + /// The first half-edge + half_edge_a: Handle, + + /// The second half-edge + half_edge_b: Handle, + }, } impl ShellValidationError { @@ -226,10 +232,10 @@ impl ShellValidationError { .all(|d| d < config.distinct_min_distance) { errors.push( - Self::CoincidentHalfEdgesAreNotSiblings( - half_edge_a.clone(), - half_edge_b.clone(), - ) + Self::CoincidentHalfEdgesAreNotSiblings { + half_edge_a: half_edge_a.clone(), + half_edge_b: half_edge_b.clone(), + } .into(), ) } @@ -395,7 +401,7 @@ mod tests { assert_contains_err!( invalid, ValidationError::Shell( - ShellValidationError::CoincidentHalfEdgesAreNotSiblings(..) + ShellValidationError::CoincidentHalfEdgesAreNotSiblings { .. } ) ); From 3266a01077d194430c295d483e5869b63f2b661b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 21 Dec 2023 20:53:31 +0100 Subject: [PATCH 2/4] Add information about vertices to validation error --- crates/fj-core/src/validate/shell.rs | 44 ++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index a2ec1ca8c..e39f14105 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -1,10 +1,10 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, fmt}; use fj_math::{Point, Scalar}; use crate::{ - geometry::SurfaceGeometry, - objects::{HalfEdge, Shell, Surface}, + geometry::{CurveBoundary, SurfaceGeometry}, + objects::{HalfEdge, Shell, Surface, Vertex}, queries::{ AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, SiblingOfHalfEdge, }, @@ -47,10 +47,14 @@ pub enum ShellValidationError { #[error( "`Shell` contains `HalfEdge`s that are coincident but are not \ siblings\n\ + {vertices}\ Half-edge 1: {half_edge_a:#?}\n\ Half-edge 2: {half_edge_b:#?}" )] CoincidentHalfEdgesAreNotSiblings { + /// The vertices of the half-edges + vertices: Box, + /// The first half-edge half_edge_a: Handle, @@ -231,8 +235,19 @@ impl ShellValidationError { ) .all(|d| d < config.distinct_min_distance) { + let vertices = Box::new(CoincidentHalfEdgeVertices { + vertices: [half_edge_a, half_edge_b].map(|half_edge| { + shell + .bounding_vertices_of_half_edge(half_edge) + .expect( + "Expected half-edge to be part of shell", + ) + }), + }); + errors.push( Self::CoincidentHalfEdgesAreNotSiblings { + vertices, half_edge_a: half_edge_a.clone(), half_edge_b: half_edge_b.clone(), } @@ -254,6 +269,29 @@ pub struct CurveCoordinateSystemMismatch { pub distance: Scalar, } +#[derive(Clone, Debug)] +pub struct CoincidentHalfEdgeVertices { + pub vertices: [CurveBoundary; 2], +} + +impl fmt::Display for CoincidentHalfEdgeVertices { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let [a, b] = &self.vertices; + + if a != &b.clone().reverse() { + writeln!( + f, + "Vertices don't match.\n\ + \tHalf-edge 1 is bounded by `{a:?}`\n\ + \tHalf-edge 2 is bounded by `{b:?}`\n\ + \t(expecting same vertices, but in reverse order)" + )?; + } + + Ok(()) + } +} + /// Sample two edges at various (currently 3) points in 3D along them. /// /// Returns an [`Iterator`] of the distance at each sample. From f3a77af94ba13590524055f11bef4a75a3a7a159 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 21 Dec 2023 20:56:49 +0100 Subject: [PATCH 3/4] Add information about curves to validation error --- crates/fj-core/src/validate/shell.rs | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index e39f14105..1bdd22be0 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -4,7 +4,7 @@ use fj_math::{Point, Scalar}; use crate::{ geometry::{CurveBoundary, SurfaceGeometry}, - objects::{HalfEdge, Shell, Surface, Vertex}, + objects::{Curve, HalfEdge, Shell, Surface, Vertex}, queries::{ AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, SiblingOfHalfEdge, }, @@ -47,11 +47,15 @@ pub enum ShellValidationError { #[error( "`Shell` contains `HalfEdge`s that are coincident but are not \ siblings\n\ + {curves}\ {vertices}\ Half-edge 1: {half_edge_a:#?}\n\ Half-edge 2: {half_edge_b:#?}" )] CoincidentHalfEdgesAreNotSiblings { + /// The curves of the half-edges + curves: Box, + /// The vertices of the half-edges vertices: Box, @@ -235,6 +239,10 @@ impl ShellValidationError { ) .all(|d| d < config.distinct_min_distance) { + let curves = Box::new(CoincidentHalfEdgeCurves { + curves: [half_edge_a, half_edge_b] + .map(|half_edge| half_edge.curve().clone()), + }); let vertices = Box::new(CoincidentHalfEdgeVertices { vertices: [half_edge_a, half_edge_b].map(|half_edge| { shell @@ -247,6 +255,7 @@ impl ShellValidationError { errors.push( Self::CoincidentHalfEdgesAreNotSiblings { + curves, vertices, half_edge_a: half_edge_a.clone(), half_edge_b: half_edge_b.clone(), @@ -259,6 +268,29 @@ impl ShellValidationError { } } +#[derive(Clone, Debug)] +pub struct CoincidentHalfEdgeCurves { + pub curves: [Handle; 2], +} + +impl fmt::Display for CoincidentHalfEdgeCurves { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let [a, b] = &self.curves; + + if a.id() != b.id() { + writeln!( + f, + "Curves don't match.\n\ + \tHalf-edge 1 lies on {a:?}\n\ + \tHalf-edge 2 lies on {b:?}\n\ + \t(must be the same)" + )?; + } + + Ok(()) + } +} + #[derive(Clone, Debug)] pub struct CurveCoordinateSystemMismatch { pub half_edge_a: Handle, From a8ec30565f6406d707483ec8f92f3636696f95f7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 21 Dec 2023 21:09:01 +0100 Subject: [PATCH 4/4] Add info about boundaries to validation error --- crates/fj-core/src/validate/shell.rs | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/fj-core/src/validate/shell.rs b/crates/fj-core/src/validate/shell.rs index 1bdd22be0..55268ced2 100644 --- a/crates/fj-core/src/validate/shell.rs +++ b/crates/fj-core/src/validate/shell.rs @@ -47,12 +47,16 @@ pub enum ShellValidationError { #[error( "`Shell` contains `HalfEdge`s that are coincident but are not \ siblings\n\ + {boundaries}\ {curves}\ {vertices}\ Half-edge 1: {half_edge_a:#?}\n\ Half-edge 2: {half_edge_b:#?}" )] CoincidentHalfEdgesAreNotSiblings { + /// The boundaries of the half-edges + boundaries: Box, + /// The curves of the half-edges curves: Box, @@ -239,6 +243,10 @@ impl ShellValidationError { ) .all(|d| d < config.distinct_min_distance) { + let boundaries = Box::new(CoincidentHalfEdgeBoundaries { + boundaries: [half_edge_a, half_edge_b] + .map(|half_edge| half_edge.boundary()), + }); let curves = Box::new(CoincidentHalfEdgeCurves { curves: [half_edge_a, half_edge_b] .map(|half_edge| half_edge.curve().clone()), @@ -255,6 +263,7 @@ impl ShellValidationError { errors.push( Self::CoincidentHalfEdgesAreNotSiblings { + boundaries, curves, vertices, half_edge_a: half_edge_a.clone(), @@ -268,6 +277,29 @@ impl ShellValidationError { } } +#[derive(Clone, Debug)] +pub struct CoincidentHalfEdgeBoundaries { + pub boundaries: [CurveBoundary>; 2], +} + +impl fmt::Display for CoincidentHalfEdgeBoundaries { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let [a, b] = &self.boundaries; + + if a != &b.reverse() { + writeln!( + f, + "Boundaries don't match.\n\ + \tHalf-edge 1 has boundary `{a:?}`\n\ + \tHalf-edge 2 has boundary `{b:?}`\n\ + \t(expecting same boundary, but reversed)" + )?; + } + + Ok(()) + } +} + #[derive(Clone, Debug)] pub struct CoincidentHalfEdgeCurves { pub curves: [Handle; 2],