Skip to content

Commit

Permalink
Merge pull request #629 from hannobraun/error
Browse files Browse the repository at this point in the history
Improve error handling in `fj-operations`
  • Loading branch information
hannobraun authored May 24, 2022
2 parents f99f6ee + 0fd7c4e commit 40b049f
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 40 deletions.
2 changes: 1 addition & 1 deletion crates/fj-app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn main() -> anyhow::Result<()> {

if let Some(path) = args.export {
let shape = model.load_once(&parameters)?;
let shape = shape_processor.process(&shape);
let shape = shape_processor.process(&shape)?;

export(&shape.mesh, &path)?;

Expand Down
10 changes: 7 additions & 3 deletions crates/fj-operations/src/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
geometry::Surface,
shape::Shape,
shape::{Shape, ValidationError},
topology::{Cycle, Edge, Face},
};
use fj_math::{Aabb, Point, Scalar};

use super::ToShape;

impl ToShape for fj::Circle {
fn to_shape(&self, _: Tolerance, _: &mut DebugInfo) -> Shape {
fn to_shape(
&self,
_: Tolerance,
_: &mut DebugInfo,
) -> Result<Shape, ValidationError> {
let mut shape = Shape::new();

// Circles have just a single round edge with no vertices. So none need
Expand All @@ -27,7 +31,7 @@ impl ToShape for fj::Circle {
.insert(Face::new(surface, cycles, Vec::new(), self.color()))
.unwrap();

shape
Ok(shape)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
27 changes: 16 additions & 11 deletions crates/fj-operations/src/difference_2d.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
shape::{Handle, Shape},
shape::{Handle, Shape, ValidationError, ValidationResult},
topology::{Cycle, Edge, Face},
};
use fj_math::Aabb;
Expand All @@ -13,7 +13,7 @@ impl ToShape for fj::Difference2d {
&self,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape {
) -> Result<Shape, ValidationError> {
// This method assumes that `b` is fully contained within `a`:
// https://github.com/hannobraun/Fornjot/issues/92

Expand All @@ -25,7 +25,8 @@ impl ToShape for fj::Difference2d {
// Can be cleaned up, once `each_ref` is stable:
// https://doc.rust-lang.org/std/primitive.array.html#method.each_ref
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(tolerance, debug_info).unwrap());

if let Some(face) = a.faces().next() {
// If there's at least one face to subtract from, we can proceed.
Expand All @@ -44,11 +45,12 @@ impl ToShape for fj::Difference2d {

for cycle in face.exteriors.as_handle() {
let cycle =
add_cycle(cycle.clone(), &mut difference, false);
add_cycle(cycle.clone(), &mut difference, false)?;
exteriors.push(cycle);
}
for cycle in face.interiors.as_handle() {
let cycle = add_cycle(cycle.clone(), &mut difference, true);
let cycle =
add_cycle(cycle.clone(), &mut difference, true)?;
interiors.push(cycle);
}
}
Expand All @@ -64,7 +66,8 @@ impl ToShape for fj::Difference2d {
);

for cycle in face.exteriors.as_handle() {
let cycle = add_cycle(cycle.clone(), &mut difference, true);
let cycle =
add_cycle(cycle.clone(), &mut difference, true)?;
interiors.push(cycle);
}
}
Expand All @@ -74,7 +77,7 @@ impl ToShape for fj::Difference2d {
.unwrap();
}

difference
Ok(difference)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand All @@ -89,12 +92,12 @@ fn add_cycle(
cycle: Handle<Cycle<3>>,
shape: &mut Shape,
reverse: bool,
) -> Handle<Cycle<3>> {
) -> ValidationResult<Cycle<3>> {
let mut edges = Vec::new();
for edge in cycle.get().edges() {
let curve = edge.curve();
let curve = if reverse { curve.reverse() } else { curve };
let curve = shape.insert(curve).unwrap();
let curve = shape.insert(curve)?;

let vertices = edge.vertices.clone().map(|vs| {
let mut vs = vs.map(|vertex| vertex.canonical());
Expand All @@ -106,13 +109,15 @@ fn add_cycle(
vs
});

let edge = shape.merge(Edge::new(curve, vertices)).unwrap();
let edge = shape.merge(Edge::new(curve, vertices))?;
edges.push(edge);
}

if reverse {
edges.reverse();
}

shape.insert(Cycle::new(edges)).unwrap()
let cycle = shape.insert(Cycle::new(edges))?;

Ok(cycle)
}
13 changes: 8 additions & 5 deletions crates/fj-operations/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{algorithms::Tolerance, shape::Shape};
use fj_kernel::{
algorithms::Tolerance,
shape::{Shape, ValidationError},
};
use fj_math::Aabb;

use super::ToShape;
Expand All @@ -9,16 +12,16 @@ impl ToShape for fj::Group {
&self,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape {
) -> Result<Shape, ValidationError> {
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(tolerance, debug_info)?;
let b = self.b.to_shape(tolerance, debug_info)?;

copy_shape(a, &mut shape);
copy_shape(b, &mut shape);

shape
Ok(shape)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
9 changes: 6 additions & 3 deletions crates/fj-operations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ mod sweep;
mod transform;

use fj_interop::debug::DebugInfo;
use fj_kernel::{algorithms::Tolerance, shape::Shape};
use fj_kernel::{
algorithms::Tolerance,
shape::{Shape, ValidationError},
};
use fj_math::Aabb;

/// Implemented for all operations from the [`fj`] crate
Expand All @@ -36,7 +39,7 @@ pub trait ToShape {
&self,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape;
) -> Result<Shape, ValidationError>;

/// Access the axis-aligned bounding box of a shape
///
Expand Down Expand Up @@ -88,6 +91,6 @@ dispatch! {
to_shape(
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape;
) -> Result<Shape, ValidationError>;
bounding_volume() -> Aabb<3>;
}
16 changes: 11 additions & 5 deletions crates/fj-operations/src/shape_processor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! API for processing shapes

use fj_interop::{debug::DebugInfo, mesh::Mesh};
use fj_kernel::algorithms::{triangulate, Tolerance};
use fj_kernel::{
algorithms::{triangulate, Tolerance},
shape::ValidationError,
};
use fj_math::{Aabb, Point, Scalar};

use crate::ToShape as _;
Expand All @@ -14,7 +17,10 @@ pub struct ShapeProcessor {

impl ShapeProcessor {
/// Process an [`fj::Shape`] into [`ProcessedShape`]
pub fn process(&self, shape: &fj::Shape) -> ProcessedShape {
pub fn process(
&self,
shape: &fj::Shape,
) -> Result<ProcessedShape, ValidationError> {
let aabb = shape.bounding_volume();

let tolerance = match self.tolerance {
Expand All @@ -37,16 +43,16 @@ impl ShapeProcessor {

let mut debug_info = DebugInfo::new();
let mesh = triangulate(
shape.to_shape(tolerance, &mut debug_info),
shape.to_shape(tolerance, &mut debug_info)?,
tolerance,
&mut debug_info,
);

ProcessedShape {
Ok(ProcessedShape {
aabb,
mesh,
debug_info,
}
})
}
}

Expand Down
13 changes: 10 additions & 3 deletions crates/fj-operations/src/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance, geometry::Surface, shape::Shape, topology::Face,
algorithms::Tolerance,
geometry::Surface,
shape::{Shape, ValidationError},
topology::Face,
};
use fj_math::{Aabb, Point};

use super::ToShape;

impl ToShape for fj::Sketch {
fn to_shape(&self, _: Tolerance, _: &mut DebugInfo) -> Shape {
fn to_shape(
&self,
_: Tolerance,
_: &mut DebugInfo,
) -> Result<Shape, ValidationError> {
let mut shape = Shape::new();

let surface = Surface::xy_plane();
Expand All @@ -22,7 +29,7 @@ impl ToShape for fj::Sketch {
.build()
.unwrap();

shape
Ok(shape)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
7 changes: 3 additions & 4 deletions crates/fj-operations/src/sweep.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::{sweep_shape, Tolerance},
shape::Shape,
shape::{Shape, ValidationError},
};
use fj_math::{Aabb, Vector};

Expand All @@ -12,14 +12,13 @@ impl ToShape for fj::Sweep {
&self,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape {
) -> Result<Shape, ValidationError> {
sweep_shape(
self.shape().to_shape(tolerance, debug_info),
self.shape().to_shape(tolerance, debug_info)?,
Vector::from(self.path()),
tolerance,
self.shape().color(),
)
.unwrap()
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
8 changes: 4 additions & 4 deletions crates/fj-operations/src/transform.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::{transform_shape, Tolerance},
shape::Shape,
shape::{Shape, ValidationError},
};
use fj_math::{Aabb, Transform, Vector};

Expand All @@ -12,13 +12,13 @@ impl ToShape for fj::Transform {
&self,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Shape {
let mut shape = self.shape.to_shape(tolerance, debug_info);
) -> Result<Shape, ValidationError> {
let mut shape = self.shape.to_shape(tolerance, debug_info)?;
let transform = transform(self);

transform_shape(&mut shape, &transform);

shape
Ok(shape)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-viewer/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn run(
let now = Instant::now();

if let Some(new_shape) = watcher.receive() {
let new_shape = shape_processor.process(&new_shape);
let new_shape = shape_processor.process(&new_shape).unwrap();
renderer.update_geometry(
(&new_shape.mesh).into(),
(&new_shape.debug_info).into(),
Expand Down

0 comments on commit 40b049f

Please sign in to comment.