From 1d64674ff4af9e7eab3cb9d06e88ae73fbf9e5d8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 14:11:39 +0200 Subject: [PATCH 1/9] Add `validation` module It's empty, for now, but I've added some documentation. --- crates/fj-kernel/src/lib.rs | 1 + crates/fj-kernel/src/validation/mod.rs | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 crates/fj-kernel/src/validation/mod.rs diff --git a/crates/fj-kernel/src/lib.rs b/crates/fj-kernel/src/lib.rs index f2f344afc..fd58d7887 100644 --- a/crates/fj-kernel/src/lib.rs +++ b/crates/fj-kernel/src/lib.rs @@ -92,3 +92,4 @@ pub mod builder; pub mod geometry; pub mod objects; pub mod shape; +pub mod validation; diff --git a/crates/fj-kernel/src/validation/mod.rs b/crates/fj-kernel/src/validation/mod.rs new file mode 100644 index 000000000..5d27d336c --- /dev/null +++ b/crates/fj-kernel/src/validation/mod.rs @@ -0,0 +1,25 @@ +//! Infrastructure for validating shapes +//! +//! Validation enforces various constraints about shapes and the objects that +//! constitute them. These constraints fall into 4 categories: +//! +//! - **Coherence:** Local forms of objects must be consistent with their +//! canonical forms. +//! - **Geometric:** Comprises various object-specific constraints, for example +//! edges or faces might not be allowed to intersect. +//! - **Structural:** All other objects that an object references must be part +//! of the same shape. +//! - **Uniqueness:** Objects within a shape must be unique. +//! +//! Please note that not all of these validation categories are fully +//! implemented, as of this writing. +//! +//! # Implementation Note +//! +//! There is an ongoing effort to abolish [`Shape`] and replace it with a much +//! simpler data structure: +//! https://github.com/hannobraun/Fornjot/issues/697 +//! +//! Once completed, this would make structural and uniqueness validation moot. +//! +//! [`Shape`]: crate::shape::Shape From 7c207a1fbbc219d14ae1174528886703ff9b1511 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 14:12:41 +0200 Subject: [PATCH 2/9] Remove redundant documentation This is now documented in the `validation` module. --- crates/fj-kernel/src/shape/validate/mod.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/crates/fj-kernel/src/shape/validate/mod.rs b/crates/fj-kernel/src/shape/validate/mod.rs index 6882d9da5..429661337 100644 --- a/crates/fj-kernel/src/shape/validate/mod.rs +++ b/crates/fj-kernel/src/shape/validate/mod.rs @@ -128,32 +128,18 @@ pub type ValidationResult = Result, ValidationError>; #[derive(Debug, thiserror::Error)] pub enum ValidationError { /// Coherence validation failed - /// - /// Coherence validation verifies, that local forms of an objects are - /// consistent with their canonical forms. #[error("Coherence validation failed")] Coherence(#[from] CoherenceIssues), /// Geometric validation failed - /// - /// Geometric validation verifies, that various geometric constraints of an - /// object are upheld. For example, edges or faces might not be allowed to - /// intersect. #[error("Geometric validation failed")] Geometric, /// Structural validation failed - /// - /// Structural validation verifies, that all the object that an object - /// refers to are already part of the shape. #[error("Structural validation failed")] Structural(#[from] StructuralIssues), /// Uniqueness validation failed - /// - /// Uniqueness validation verifies, that an object is unique. Uniqueness is - /// only required for topological objects, as there's no harm in geometric - /// objects being duplicated. #[error("Uniqueness validation failed")] Uniqueness(#[from] UniquenessIssues), } From c42df3a6b4a2c451a7ea503e1150e18323ec0fb2 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:17:03 +0200 Subject: [PATCH 3/9] Make `#[cfg(test)]` methods generally available There's not really any drawback any more, and having them be conditionally available would cause some problems with the next step. --- crates/fj-kernel/src/shape/validate/mod.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/fj-kernel/src/shape/validate/mod.rs b/crates/fj-kernel/src/shape/validate/mod.rs index 429661337..3ce0e3153 100644 --- a/crates/fj-kernel/src/shape/validate/mod.rs +++ b/crates/fj-kernel/src/shape/validate/mod.rs @@ -146,7 +146,6 @@ pub enum ValidationError { impl ValidationError { /// Indicate whether validation found a missing curve - #[cfg(test)] pub fn missing_curve(&self, curve: &Handle>) -> bool { if let Self::Structural(StructuralIssues { missing_curve, .. }) = self { return missing_curve.as_ref() == Some(curve); @@ -156,7 +155,6 @@ impl ValidationError { } /// Indicate whether validation found a missing vertex - #[cfg(test)] pub fn missing_vertex(&self, vertex: &Handle) -> bool { if let Self::Structural(StructuralIssues { missing_vertices, .. @@ -169,7 +167,6 @@ impl ValidationError { } /// Indicate whether validation found a missing edge - #[cfg(test)] pub fn missing_edge(&self, edge: &Handle>) -> bool { if let Self::Structural(StructuralIssues { missing_edges, .. }) = self { return missing_edges.contains(edge); @@ -179,7 +176,6 @@ impl ValidationError { } /// Indicate whether validation found a missing surface - #[cfg(test)] pub fn missing_surface(&self, surface: &Handle) -> bool { if let Self::Structural(StructuralIssues { missing_surface, .. @@ -192,7 +188,6 @@ impl ValidationError { } /// Indicate whether validation found a missing cycle - #[cfg(test)] pub fn missing_cycle(&self, cycle: &Handle>) -> bool { if let Self::Structural(StructuralIssues { missing_cycles, .. }) = self { From c9fa93830720b922c2175d23f265c28282f524f1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:21:16 +0200 Subject: [PATCH 4/9] Move `ValidationError` to new `validation` module --- crates/fj-kernel/src/algorithms/sweep.rs | 3 +- crates/fj-kernel/src/algorithms/transform.rs | 3 +- crates/fj-kernel/src/builder.rs | 3 +- crates/fj-kernel/src/shape/api.rs | 10 ++- crates/fj-kernel/src/shape/mod.rs | 2 +- crates/fj-kernel/src/shape/object.rs | 8 +- crates/fj-kernel/src/shape/update.rs | 4 +- crates/fj-kernel/src/shape/validate/mod.rs | 80 +------------------- crates/fj-kernel/src/validation/mod.rs | 80 ++++++++++++++++++++ crates/fj-operations/src/circle.rs | 3 +- crates/fj-operations/src/difference_2d.rs | 3 +- crates/fj-operations/src/group.rs | 3 +- crates/fj-operations/src/lib.rs | 3 +- crates/fj-operations/src/shape_processor.rs | 2 +- crates/fj-operations/src/sketch.rs | 3 +- crates/fj-operations/src/sweep.rs | 3 +- crates/fj-operations/src/transform.rs | 3 +- 17 files changed, 118 insertions(+), 98 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/sweep.rs b/crates/fj-kernel/src/algorithms/sweep.rs index af00299b7..da7995101 100644 --- a/crates/fj-kernel/src/algorithms/sweep.rs +++ b/crates/fj-kernel/src/algorithms/sweep.rs @@ -4,7 +4,8 @@ use fj_math::{Line, Scalar, Transform, Triangle, Vector}; use crate::{ objects::{Curve, Cycle, Edge, Face, Surface, SweptCurve, Vertex}, - shape::{Handle, LocalForm, Mapping, Shape, ValidationError}, + shape::{Handle, LocalForm, Mapping, Shape}, + validation::ValidationError, }; use super::{transform_shape, CycleApprox, Tolerance}; diff --git a/crates/fj-kernel/src/algorithms/transform.rs b/crates/fj-kernel/src/algorithms/transform.rs index 45a0c9a5a..9a237305b 100644 --- a/crates/fj-kernel/src/algorithms/transform.rs +++ b/crates/fj-kernel/src/algorithms/transform.rs @@ -2,7 +2,8 @@ use fj_math::Transform; use crate::{ objects::{Curve, Face, Surface, Vertex}, - shape::{Shape, ValidationError}, + shape::Shape, + validation::ValidationError, }; /// Transform the geometry of the shape diff --git a/crates/fj-kernel/src/builder.rs b/crates/fj-kernel/src/builder.rs index 7e62f59b7..b977fffae 100644 --- a/crates/fj-kernel/src/builder.rs +++ b/crates/fj-kernel/src/builder.rs @@ -4,7 +4,8 @@ use fj_math::{Circle, Line, Point, Scalar, Vector}; use crate::{ objects::{Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge}, - shape::{Handle, LocalForm, Shape, ValidationError, ValidationResult}, + shape::{Handle, LocalForm, Shape, ValidationResult}, + validation::ValidationError, }; /// API for building a [`Vertex`] diff --git a/crates/fj-kernel/src/shape/api.rs b/crates/fj-kernel/src/shape/api.rs index 7070a83cf..dc82f6e82 100644 --- a/crates/fj-kernel/src/shape/api.rs +++ b/crates/fj-kernel/src/shape/api.rs @@ -1,10 +1,13 @@ use fj_math::Scalar; -use crate::objects::{Curve, Cycle, Edge, Face, Surface, Vertex}; +use crate::{ + objects::{Curve, Cycle, Edge, Face, Surface, Vertex}, + validation::ValidationError, +}; use super::{ stores::{Store, Stores}, - Handle, Iter, Mapping, Object, Update, ValidationError, ValidationResult, + Handle, Iter, Mapping, Object, Update, ValidationResult, }; /// The boundary representation of a shape @@ -293,7 +296,8 @@ mod tests { use crate::{ objects::{Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge}, - shape::{Handle, LocalForm, Shape, ValidationError, ValidationResult}, + shape::{Handle, LocalForm, Shape, ValidationResult}, + validation::ValidationError, }; #[test] diff --git a/crates/fj-kernel/src/shape/mod.rs b/crates/fj-kernel/src/shape/mod.rs index 21182ac6d..f633b3df7 100644 --- a/crates/fj-kernel/src/shape/mod.rs +++ b/crates/fj-kernel/src/shape/mod.rs @@ -19,6 +19,6 @@ pub use self::{ update::Update, validate::{ CoherenceIssues, CoherenceMismatch, DuplicateEdge, StructuralIssues, - UniquenessIssues, ValidationError, ValidationResult, + UniquenessIssues, ValidationResult, }, }; diff --git a/crates/fj-kernel/src/shape/object.rs b/crates/fj-kernel/src/shape/object.rs index a85bc20d2..b5a382ef5 100644 --- a/crates/fj-kernel/src/shape/object.rs +++ b/crates/fj-kernel/src/shape/object.rs @@ -1,10 +1,10 @@ -use crate::objects::{ - Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge, +use crate::{ + objects::{Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge}, + validation::ValidationError, }; use super::{ - validate::Validate, Handle, LocalForm, Mapping, Shape, ValidationError, - ValidationResult, + validate::Validate, Handle, LocalForm, Mapping, Shape, ValidationResult, }; /// Marker trait for geometric and topological objects diff --git a/crates/fj-kernel/src/shape/update.rs b/crates/fj-kernel/src/shape/update.rs index a90de3268..9651a1a5b 100644 --- a/crates/fj-kernel/src/shape/update.rs +++ b/crates/fj-kernel/src/shape/update.rs @@ -1,6 +1,8 @@ use fj_math::Scalar; -use super::{stores::Stores, validate::Validate as _, Object, ValidationError}; +use crate::validation::ValidationError; + +use super::{stores::Stores, validate::Validate as _, Object}; /// API to update a `Shape` /// diff --git a/crates/fj-kernel/src/shape/validate/mod.rs b/crates/fj-kernel/src/shape/validate/mod.rs index 3ce0e3153..2e18185c6 100644 --- a/crates/fj-kernel/src/shape/validate/mod.rs +++ b/crates/fj-kernel/src/shape/validate/mod.rs @@ -10,7 +10,10 @@ pub use self::{ use fj_math::Scalar; -use crate::objects::{Curve, Cycle, Edge, Face, Surface, Vertex}; +use crate::{ + objects::{Curve, Cycle, Edge, Face, Surface, Vertex}, + validation::ValidationError, +}; use super::{stores::Stores, Handle, Object}; @@ -122,78 +125,3 @@ impl Validate for Face { /// Returned by the various `add_` methods of the [`Shape`] API pub type ValidationResult = Result, ValidationError>; - -/// An error that can occur during a validation -#[allow(clippy::large_enum_variant)] -#[derive(Debug, thiserror::Error)] -pub enum ValidationError { - /// Coherence validation failed - #[error("Coherence validation failed")] - Coherence(#[from] CoherenceIssues), - - /// Geometric validation failed - #[error("Geometric validation failed")] - Geometric, - - /// Structural validation failed - #[error("Structural validation failed")] - Structural(#[from] StructuralIssues), - - /// Uniqueness validation failed - #[error("Uniqueness validation failed")] - Uniqueness(#[from] UniquenessIssues), -} - -impl ValidationError { - /// Indicate whether validation found a missing curve - pub fn missing_curve(&self, curve: &Handle>) -> bool { - if let Self::Structural(StructuralIssues { missing_curve, .. }) = self { - return missing_curve.as_ref() == Some(curve); - } - - false - } - - /// Indicate whether validation found a missing vertex - pub fn missing_vertex(&self, vertex: &Handle) -> bool { - if let Self::Structural(StructuralIssues { - missing_vertices, .. - }) = self - { - return missing_vertices.contains(vertex); - } - - false - } - - /// Indicate whether validation found a missing edge - pub fn missing_edge(&self, edge: &Handle>) -> bool { - if let Self::Structural(StructuralIssues { missing_edges, .. }) = self { - return missing_edges.contains(edge); - } - - false - } - - /// Indicate whether validation found a missing surface - pub fn missing_surface(&self, surface: &Handle) -> bool { - if let Self::Structural(StructuralIssues { - missing_surface, .. - }) = self - { - return missing_surface.as_ref() == Some(surface); - } - - false - } - - /// Indicate whether validation found a missing cycle - pub fn missing_cycle(&self, cycle: &Handle>) -> bool { - if let Self::Structural(StructuralIssues { missing_cycles, .. }) = self - { - return missing_cycles.contains(cycle); - } - - false - } -} diff --git a/crates/fj-kernel/src/validation/mod.rs b/crates/fj-kernel/src/validation/mod.rs index 5d27d336c..d9667659a 100644 --- a/crates/fj-kernel/src/validation/mod.rs +++ b/crates/fj-kernel/src/validation/mod.rs @@ -23,3 +23,83 @@ //! Once completed, this would make structural and uniqueness validation moot. //! //! [`Shape`]: crate::shape::Shape + +use crate::{ + objects::{Curve, Cycle, Edge, Surface, Vertex}, + shape::{CoherenceIssues, Handle, StructuralIssues, UniquenessIssues}, +}; + +/// An error that can occur during a validation +#[allow(clippy::large_enum_variant)] +#[derive(Debug, thiserror::Error)] +pub enum ValidationError { + /// Coherence validation failed + #[error("Coherence validation failed")] + Coherence(#[from] CoherenceIssues), + + /// Geometric validation failed + #[error("Geometric validation failed")] + Geometric, + + /// Structural validation failed + #[error("Structural validation failed")] + Structural(#[from] StructuralIssues), + + /// Uniqueness validation failed + #[error("Uniqueness validation failed")] + Uniqueness(#[from] UniquenessIssues), +} + +impl ValidationError { + /// Indicate whether validation found a missing curve + pub fn missing_curve(&self, curve: &Handle>) -> bool { + if let Self::Structural(StructuralIssues { missing_curve, .. }) = self { + return missing_curve.as_ref() == Some(curve); + } + + false + } + + /// Indicate whether validation found a missing vertex + pub fn missing_vertex(&self, vertex: &Handle) -> bool { + if let Self::Structural(StructuralIssues { + missing_vertices, .. + }) = self + { + return missing_vertices.contains(vertex); + } + + false + } + + /// Indicate whether validation found a missing edge + pub fn missing_edge(&self, edge: &Handle>) -> bool { + if let Self::Structural(StructuralIssues { missing_edges, .. }) = self { + return missing_edges.contains(edge); + } + + false + } + + /// Indicate whether validation found a missing surface + pub fn missing_surface(&self, surface: &Handle) -> bool { + if let Self::Structural(StructuralIssues { + missing_surface, .. + }) = self + { + return missing_surface.as_ref() == Some(surface); + } + + false + } + + /// Indicate whether validation found a missing cycle + pub fn missing_cycle(&self, cycle: &Handle>) -> bool { + if let Self::Structural(StructuralIssues { missing_cycles, .. }) = self + { + return missing_cycles.contains(cycle); + } + + false + } +} diff --git a/crates/fj-operations/src/circle.rs b/crates/fj-operations/src/circle.rs index 7d1c56827..5099cd999 100644 --- a/crates/fj-operations/src/circle.rs +++ b/crates/fj-operations/src/circle.rs @@ -2,7 +2,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face, Surface}, - shape::{LocalForm, Shape, ValidationError}, + shape::{LocalForm, Shape}, + validation::ValidationError, }; use fj_math::{Aabb, Point, Scalar}; diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index 414873b8b..f9f8b1474 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -2,7 +2,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face}, - shape::{LocalForm, Shape, ValidationError}, + shape::{LocalForm, Shape}, + validation::ValidationError, }; use fj_math::Aabb; diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index 99ffc75fd..c085e0f87 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -1,7 +1,6 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ - algorithms::Tolerance, - shape::{Shape, ValidationError}, + algorithms::Tolerance, shape::Shape, validation::ValidationError, }; use fj_math::Aabb; diff --git a/crates/fj-operations/src/lib.rs b/crates/fj-operations/src/lib.rs index 71a445b8b..f8146c0b3 100644 --- a/crates/fj-operations/src/lib.rs +++ b/crates/fj-operations/src/lib.rs @@ -27,8 +27,7 @@ mod transform; use fj_interop::debug::DebugInfo; use fj_kernel::{ - algorithms::Tolerance, - shape::{Shape, ValidationError}, + algorithms::Tolerance, shape::Shape, validation::ValidationError, }; use fj_math::Aabb; diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index d3693da84..1e3ae1636 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -3,7 +3,7 @@ use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::{ algorithms::{triangulate, InvalidTolerance, Tolerance}, - shape::ValidationError, + validation::ValidationError, }; use fj_math::{Aabb, Point, Scalar}; diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index f9f24256c..6abcbd554 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -2,7 +2,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, objects::{Face, Surface}, - shape::{Shape, ValidationError}, + shape::Shape, + validation::ValidationError, }; use fj_math::{Aabb, Point}; diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index ca5f05df6..1564fcea1 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -1,7 +1,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{sweep_shape, Tolerance}, - shape::{Shape, ValidationError}, + shape::Shape, + validation::ValidationError, }; use fj_math::{Aabb, Vector}; diff --git a/crates/fj-operations/src/transform.rs b/crates/fj-operations/src/transform.rs index 68b9c413c..9682a30ae 100644 --- a/crates/fj-operations/src/transform.rs +++ b/crates/fj-operations/src/transform.rs @@ -1,7 +1,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{transform_shape, Tolerance}, - shape::{Shape, ValidationError}, + shape::Shape, + validation::ValidationError, }; use fj_math::{Aabb, Transform, Vector}; From 42a8293a7853feb4418885d0bddf9fa0abe7867c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 14:19:04 +0200 Subject: [PATCH 5/9] Add new validation infrastructure Nothing is actually validated yet using the new infrastructure. It's just a placeholder, and as a next step, in can be hooked into all the places that require validation. The actual validation code can be migrated from the old infrastructure later, piece by piece. --- crates/fj-kernel/src/validation/mod.rs | 63 +++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/validation/mod.rs b/crates/fj-kernel/src/validation/mod.rs index d9667659a..c4b52f5c0 100644 --- a/crates/fj-kernel/src/validation/mod.rs +++ b/crates/fj-kernel/src/validation/mod.rs @@ -24,11 +24,72 @@ //! //! [`Shape`]: crate::shape::Shape +use std::ops::Deref; + +use fj_math::Scalar; + use crate::{ objects::{Curve, Cycle, Edge, Surface, Vertex}, - shape::{CoherenceIssues, Handle, StructuralIssues, UniquenessIssues}, + shape::{ + CoherenceIssues, Handle, Shape, StructuralIssues, UniquenessIssues, + }, }; +/// Validate the given [`Shape`] +pub fn validate( + shape: Shape, + _: &Config, +) -> Result, ValidationError> { + Ok(Validated(shape)) +} + +/// Configuration required for the validation process +#[derive(Debug, Clone, Copy)] +pub struct Config { + /// The minimum distance between distinct objects + /// + /// Objects whose distance is less than the value defined in this field, are + /// considered identical. + pub distinct_min_distance: Scalar, + + /// The maximum distance between identical objects + /// + /// Objects that are considered identical might still have a distance + /// between them, due to inaccuracies of the numerical representation. If + /// that distance is less than the one defined in this field, can not be + /// considered identical. + pub identical_max_distance: Scalar, +} + +impl Default for Config { + fn default() -> Self { + Self { + distinct_min_distance: Scalar::from_f64(5e-7), // 0.5 µm, + identical_max_distance: Scalar::from_f64(5e-14), + } + } +} + +/// Wrapper around an object that indicates the object has been validated +/// +/// Returned by implementations of `Validate`. +pub struct Validated(T); + +impl Validated { + /// Consume this instance of `Validated` and return the wrapped object + pub fn into_inner(self) -> T { + self.0 + } +} + +impl Deref for Validated { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + /// An error that can occur during a validation #[allow(clippy::large_enum_variant)] #[derive(Debug, thiserror::Error)] From 5b490e692ca7618753c24362264d27c3fe7edd35 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:09:43 +0200 Subject: [PATCH 6/9] Simplify function invocations --- crates/fj-operations/src/shape_processor.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index 1e3ae1636..a43f373cd 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -39,11 +39,8 @@ impl ShapeProcessor { }; let mut debug_info = DebugInfo::new(); - let mesh = triangulate( - shape.to_shape(tolerance, &mut debug_info)?, - tolerance, - &mut debug_info, - ); + let shape = shape.to_shape(tolerance, &mut debug_info)?; + let mesh = triangulate(shape, tolerance, &mut debug_info); Ok(ProcessedShape { aabb, From 976d7f132b7a5a761836f2ea85c4392ea99a3989 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:11:28 +0200 Subject: [PATCH 7/9] Pass `validation::Config` into `ToShape::to_shape` This is part of the migration to the new validation infrastructure. --- crates/fj-operations/src/circle.rs | 3 ++- crates/fj-operations/src/difference_2d.rs | 6 ++++-- crates/fj-operations/src/group.rs | 9 ++++++--- crates/fj-operations/src/lib.rs | 6 +++++- crates/fj-operations/src/shape_processor.rs | 5 +++-- crates/fj-operations/src/sketch.rs | 3 ++- crates/fj-operations/src/sweep.rs | 5 +++-- crates/fj-operations/src/transform.rs | 5 +++-- 8 files changed, 28 insertions(+), 14 deletions(-) diff --git a/crates/fj-operations/src/circle.rs b/crates/fj-operations/src/circle.rs index 5099cd999..72dc10a2f 100644 --- a/crates/fj-operations/src/circle.rs +++ b/crates/fj-operations/src/circle.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face, Surface}, shape::{LocalForm, Shape}, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::{Aabb, Point, Scalar}; @@ -12,6 +12,7 @@ use super::ToShape; impl ToShape for fj::Circle { fn to_shape( &self, + _: &validation::Config, _: Tolerance, _: &mut DebugInfo, ) -> Result { diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index f9f8b1474..42b2dafb8 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face}, shape::{LocalForm, Shape}, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::Aabb; @@ -12,6 +12,7 @@ use super::ToShape; impl ToShape for fj::Difference2d { fn to_shape( &self, + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result { @@ -27,7 +28,8 @@ impl ToShape for fj::Difference2d { // - https://doc.rust-lang.org/std/primitive.array.html#method.each_ref // - https://doc.rust-lang.org/std/primitive.array.html#method.try_map let [a, b] = self.shapes(); - let [a, b] = [a, b].map(|shape| shape.to_shape(tolerance, debug_info)); + let [a, b] = + [a, b].map(|shape| shape.to_shape(config, tolerance, debug_info)); let [a, b] = [a?, b?]; if let Some(face) = a.faces().next() { diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index c085e0f87..952fd713e 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -1,6 +1,8 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ - algorithms::Tolerance, shape::Shape, validation::ValidationError, + algorithms::Tolerance, + shape::Shape, + validation::{self, ValidationError}, }; use fj_math::Aabb; @@ -9,13 +11,14 @@ use super::ToShape; impl ToShape for fj::Group { fn to_shape( &self, + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result { let mut shape = Shape::new(); - let a = self.a.to_shape(tolerance, debug_info)?; - let b = self.b.to_shape(tolerance, debug_info)?; + let a = self.a.to_shape(config, tolerance, debug_info)?; + let b = self.b.to_shape(config, tolerance, debug_info)?; shape.merge_shape(&a)?; shape.merge_shape(&b)?; diff --git a/crates/fj-operations/src/lib.rs b/crates/fj-operations/src/lib.rs index f8146c0b3..50f743ab0 100644 --- a/crates/fj-operations/src/lib.rs +++ b/crates/fj-operations/src/lib.rs @@ -27,7 +27,9 @@ mod transform; use fj_interop::debug::DebugInfo; use fj_kernel::{ - algorithms::Tolerance, shape::Shape, validation::ValidationError, + algorithms::Tolerance, + shape::Shape, + validation::{self, ValidationError}, }; use fj_math::Aabb; @@ -36,6 +38,7 @@ pub trait ToShape { /// Compute the boundary representation of the shape fn to_shape( &self, + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result; @@ -88,6 +91,7 @@ macro_rules! dispatch { dispatch! { to_shape( + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result; diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index a43f373cd..3e2a6aebf 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -3,7 +3,7 @@ use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::{ algorithms::{triangulate, InvalidTolerance, Tolerance}, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::{Aabb, Point, Scalar}; @@ -38,8 +38,9 @@ impl ShapeProcessor { Some(user_defined_tolerance) => user_defined_tolerance, }; + let config = validation::Config::default(); let mut debug_info = DebugInfo::new(); - let shape = shape.to_shape(tolerance, &mut debug_info)?; + let shape = shape.to_shape(&config, tolerance, &mut debug_info)?; let mesh = triangulate(shape, tolerance, &mut debug_info); Ok(ProcessedShape { diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 6abcbd554..51389be1f 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Face, Surface}, shape::Shape, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::{Aabb, Point}; @@ -12,6 +12,7 @@ use super::ToShape; impl ToShape for fj::Sketch { fn to_shape( &self, + _: &validation::Config, _: Tolerance, _: &mut DebugInfo, ) -> Result { diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 1564fcea1..0d7625d72 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -2,7 +2,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{sweep_shape, Tolerance}, shape::Shape, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::{Aabb, Vector}; @@ -11,11 +11,12 @@ use super::ToShape; impl ToShape for fj::Sweep { fn to_shape( &self, + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result { sweep_shape( - self.shape().to_shape(tolerance, debug_info)?, + self.shape().to_shape(config, tolerance, debug_info)?, Vector::from(self.path()), tolerance, self.shape().color(), diff --git a/crates/fj-operations/src/transform.rs b/crates/fj-operations/src/transform.rs index 9682a30ae..7f0780d1d 100644 --- a/crates/fj-operations/src/transform.rs +++ b/crates/fj-operations/src/transform.rs @@ -2,7 +2,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{transform_shape, Tolerance}, shape::Shape, - validation::ValidationError, + validation::{self, ValidationError}, }; use fj_math::{Aabb, Transform, Vector}; @@ -11,10 +11,11 @@ use super::ToShape; impl ToShape for fj::Transform { fn to_shape( &self, + config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result { - let mut shape = self.shape.to_shape(tolerance, debug_info)?; + let mut shape = self.shape.to_shape(config, tolerance, debug_info)?; let transform = transform(self); transform_shape(&mut shape, &transform)?; From 73de00b5731130e5d4ca339e01f4d9255ce2c064 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:30:38 +0200 Subject: [PATCH 8/9] Simplify function invocation --- crates/fj-operations/src/sweep.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 0d7625d72..13e60a5c0 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -15,12 +15,11 @@ impl ToShape for fj::Sweep { tolerance: Tolerance, debug_info: &mut DebugInfo, ) -> Result { - sweep_shape( - self.shape().to_shape(config, tolerance, debug_info)?, - Vector::from(self.path()), - tolerance, - self.shape().color(), - ) + let shape = self.shape().to_shape(config, tolerance, debug_info)?; + let path = Vector::from(self.path()); + let color = self.shape().color(); + + sweep_shape(shape, path, tolerance, color) } fn bounding_volume(&self) -> Aabb<3> { From 79d8d2b36e8778175c5cb821dc661b379124890b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Mon, 20 Jun 2022 15:41:34 +0200 Subject: [PATCH 9/9] Enforce validation in `ToShape::to_shape` --- crates/fj-operations/src/circle.rs | 8 +++++--- crates/fj-operations/src/difference_2d.rs | 6 ++++-- crates/fj-operations/src/group.rs | 6 ++++-- crates/fj-operations/src/lib.rs | 6 +++--- crates/fj-operations/src/shape_processor.rs | 2 +- crates/fj-operations/src/sketch.rs | 8 +++++--- crates/fj-operations/src/sweep.rs | 9 ++++++--- crates/fj-operations/src/transform.rs | 9 ++++++--- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/crates/fj-operations/src/circle.rs b/crates/fj-operations/src/circle.rs index 72dc10a2f..a9b49b0b0 100644 --- a/crates/fj-operations/src/circle.rs +++ b/crates/fj-operations/src/circle.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face, Surface}, shape::{LocalForm, Shape}, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::{Aabb, Point, Scalar}; @@ -12,10 +12,10 @@ use super::ToShape; impl ToShape for fj::Circle { fn to_shape( &self, - _: &validation::Config, + config: &validation::Config, _: Tolerance, _: &mut DebugInfo, - ) -> Result { + ) -> Result, ValidationError> { let mut shape = Shape::new(); // Circles have just a single round edge with no vertices. So none need @@ -38,6 +38,8 @@ impl ToShape for fj::Circle { self.color(), ))?; + let shape = validate(shape, config)?; + Ok(shape) } diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index 42b2dafb8..553ed672a 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face}, shape::{LocalForm, Shape}, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::Aabb; @@ -15,7 +15,7 @@ impl ToShape for fj::Difference2d { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result { + ) -> Result, ValidationError> { // This method assumes that `b` is fully contained within `a`: // https://github.com/hannobraun/Fornjot/issues/92 @@ -81,6 +81,8 @@ impl ToShape for fj::Difference2d { ))?; } + let difference = validate(difference, config)?; + Ok(difference) } diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index 952fd713e..230c5fd70 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -2,7 +2,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, shape::Shape, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::Aabb; @@ -14,7 +14,7 @@ impl ToShape for fj::Group { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result { + ) -> Result, ValidationError> { let mut shape = Shape::new(); let a = self.a.to_shape(config, tolerance, debug_info)?; @@ -23,6 +23,8 @@ impl ToShape for fj::Group { shape.merge_shape(&a)?; shape.merge_shape(&b)?; + let shape = validate(shape, config)?; + Ok(shape) } diff --git a/crates/fj-operations/src/lib.rs b/crates/fj-operations/src/lib.rs index 50f743ab0..f19d2f086 100644 --- a/crates/fj-operations/src/lib.rs +++ b/crates/fj-operations/src/lib.rs @@ -29,7 +29,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::Tolerance, shape::Shape, - validation::{self, ValidationError}, + validation::{self, Validated, ValidationError}, }; use fj_math::Aabb; @@ -41,7 +41,7 @@ pub trait ToShape { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result; + ) -> Result, ValidationError>; /// Access the axis-aligned bounding box of a shape /// @@ -94,6 +94,6 @@ dispatch! { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result; + ) -> Result, ValidationError>; bounding_volume() -> Aabb<3>; } diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index 3e2a6aebf..23e1af55e 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -41,7 +41,7 @@ impl ShapeProcessor { let config = validation::Config::default(); let mut debug_info = DebugInfo::new(); let shape = shape.to_shape(&config, tolerance, &mut debug_info)?; - let mesh = triangulate(shape, tolerance, &mut debug_info); + let mesh = triangulate(shape.into_inner(), tolerance, &mut debug_info); Ok(ProcessedShape { aabb, diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 51389be1f..387ae08ca 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -3,7 +3,7 @@ use fj_kernel::{ algorithms::Tolerance, objects::{Face, Surface}, shape::Shape, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::{Aabb, Point}; @@ -12,10 +12,10 @@ use super::ToShape; impl ToShape for fj::Sketch { fn to_shape( &self, - _: &validation::Config, + config: &validation::Config, _: Tolerance, _: &mut DebugInfo, - ) -> Result { + ) -> Result, ValidationError> { let mut shape = Shape::new(); let surface = Surface::xy_plane(); @@ -26,6 +26,8 @@ impl ToShape for fj::Sketch { .with_color(self.color()) .build()?; + let shape = validate(shape, config)?; + Ok(shape) } diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 13e60a5c0..36aca4e15 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -2,7 +2,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{sweep_shape, Tolerance}, shape::Shape, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::{Aabb, Vector}; @@ -14,12 +14,15 @@ impl ToShape for fj::Sweep { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result { + ) -> Result, ValidationError> { let shape = self.shape().to_shape(config, tolerance, debug_info)?; let path = Vector::from(self.path()); let color = self.shape().color(); - sweep_shape(shape, path, tolerance, color) + let swept = sweep_shape(shape.into_inner(), path, tolerance, color)?; + let swept = validate(swept, config)?; + + Ok(swept) } fn bounding_volume(&self) -> Aabb<3> { diff --git a/crates/fj-operations/src/transform.rs b/crates/fj-operations/src/transform.rs index 7f0780d1d..6b0b530f8 100644 --- a/crates/fj-operations/src/transform.rs +++ b/crates/fj-operations/src/transform.rs @@ -2,7 +2,7 @@ use fj_interop::debug::DebugInfo; use fj_kernel::{ algorithms::{transform_shape, Tolerance}, shape::Shape, - validation::{self, ValidationError}, + validation::{self, validate, Validated, ValidationError}, }; use fj_math::{Aabb, Transform, Vector}; @@ -14,11 +14,14 @@ impl ToShape for fj::Transform { config: &validation::Config, tolerance: Tolerance, debug_info: &mut DebugInfo, - ) -> Result { - let mut shape = self.shape.to_shape(config, tolerance, debug_info)?; + ) -> Result, ValidationError> { + let shape = self.shape.to_shape(config, tolerance, debug_info)?; + let mut shape = shape.into_inner(); + let transform = transform(self); transform_shape(&mut shape, &transform)?; + let shape = validate(shape, config)?; Ok(shape) }