diff --git a/Cargo.lock b/Cargo.lock index 9ec23e34e..afeac1e16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -796,6 +796,7 @@ dependencies = [ "fj-interop", "fj-kernel", "fj-math", + "thiserror", ] [[package]] diff --git a/crates/fj-operations/Cargo.toml b/crates/fj-operations/Cargo.toml index 5838307cb..78cad1ade 100644 --- a/crates/fj-operations/Cargo.toml +++ b/crates/fj-operations/Cargo.toml @@ -12,6 +12,9 @@ keywords = ["cad", "programmatic", "code-cad"] categories = ["encoding", "mathematics", "rendering"] +[dependencies] +thiserror = "1.0.31" + [dependencies.fj] version = "0.6.0" path = "../fj" diff --git a/crates/fj-operations/src/circle.rs b/crates/fj-operations/src/circle.rs index ac643c5af..ac1c4dd3e 100644 --- a/crates/fj-operations/src/circle.rs +++ b/crates/fj-operations/src/circle.rs @@ -21,15 +21,12 @@ impl ToShape for fj::Circle { // to be added here. let edge = Edge::builder(&mut shape) - .build_circle(Scalar::from_f64(self.radius())) - .unwrap(); - shape.insert(Cycle::new(vec![edge])).unwrap(); + .build_circle(Scalar::from_f64(self.radius()))?; + shape.insert(Cycle::new(vec![edge]))?; let cycles = shape.cycles(); - let surface = shape.insert(Surface::xy_plane()).unwrap(); - shape - .insert(Face::new(surface, cycles, Vec::new(), self.color())) - .unwrap(); + let surface = shape.insert(Surface::xy_plane())?; + shape.insert(Face::new(surface, cycles, Vec::new(), self.color()))?; Ok(shape) } diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index d10823a8d..f39df6da0 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -22,11 +22,12 @@ impl ToShape for fj::Difference2d { let mut exteriors = Vec::new(); let mut interiors = Vec::new(); - // Can be cleaned up, once `each_ref` is stable: - // https://doc.rust-lang.org/std/primitive.array.html#method.each_ref + // Can be cleaned up, once `each_ref` and `try_map` are stable: + // - 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).unwrap()); + let [a, b] = [a, b].map(|shape| shape.to_shape(tolerance, debug_info)); + let [a, b] = [a?, b?]; if let Some(face) = a.faces().next() { // If there's at least one face to subtract from, we can proceed. @@ -72,9 +73,12 @@ impl ToShape for fj::Difference2d { } } - difference - .merge(Face::new(surface, exteriors, interiors, self.color())) - .unwrap(); + difference.merge(Face::new( + surface, + exteriors, + interiors, + self.color(), + ))?; } Ok(difference) diff --git a/crates/fj-operations/src/group.rs b/crates/fj-operations/src/group.rs index 30f0aac23..99ffc75fd 100644 --- a/crates/fj-operations/src/group.rs +++ b/crates/fj-operations/src/group.rs @@ -18,8 +18,8 @@ impl ToShape for fj::Group { let a = self.a.to_shape(tolerance, debug_info)?; let b = self.b.to_shape(tolerance, debug_info)?; - copy_shape(a, &mut shape); - copy_shape(b, &mut shape); + shape.merge_shape(&a)?; + shape.merge_shape(&b)?; Ok(shape) } @@ -31,9 +31,3 @@ impl ToShape for fj::Group { a.merged(&b) } } - -fn copy_shape(orig: Shape, target: &mut Shape) { - for face_orig in orig.faces() { - target.merge(face_orig.get()).unwrap(); - } -} diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index bb4855fe2..8d26eb010 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -2,7 +2,7 @@ use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::{ - algorithms::{triangulate, Tolerance}, + algorithms::{triangulate, InvalidTolerance, Tolerance}, shape::ValidationError, }; use fj_math::{Aabb, Point, Scalar}; @@ -17,10 +17,7 @@ pub struct ShapeProcessor { impl ShapeProcessor { /// Process an [`fj::Shape`] into [`ProcessedShape`] - pub fn process( - &self, - shape: &fj::Shape, - ) -> Result { + pub fn process(&self, shape: &fj::Shape) -> Result { let aabb = shape.bounding_volume(); let tolerance = match self.tolerance { @@ -36,7 +33,7 @@ impl ShapeProcessor { } let tolerance = min_extent / Scalar::from_f64(1000.); - Tolerance::from_scalar(tolerance).unwrap() + Tolerance::from_scalar(tolerance)? } Some(user_defined_tolerance) => user_defined_tolerance, }; @@ -69,3 +66,15 @@ pub struct ProcessedShape { /// The debug info generated while processing the shape pub debug_info: DebugInfo, } + +/// A shape processing error +#[derive(Debug, thiserror::Error)] +pub enum Error { + /// Error converting to shape + #[error("Error converting to shape")] + ToShape(#[from] ValidationError), + + /// Model has zero size + #[error("Model has an zero size")] + Extent(#[from] InvalidTolerance), +} diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 43cdc85b1..1100fc540 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -26,8 +26,7 @@ impl ToShape for fj::Sketch { Face::builder(surface, &mut shape) .with_exterior_polygon(points) - .build() - .unwrap(); + .build()?; Ok(shape) }