diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index b44061526..43b3953d7 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -10,10 +10,7 @@ use std::time::Instant; use anyhow::anyhow; use fj_host::{Model, Parameters}; -use fj_interop::{debug::DebugInfo, mesh::Mesh}; -use fj_kernel::algorithms::{triangulate, Tolerance}; -use fj_math::{Aabb, Point, Scalar}; -use fj_operations::ToShape as _; +use fj_operations::shape_processor::ShapeProcessor; use futures::executor::block_on; use tracing::{trace, warn}; use tracing_subscriber::fmt::format; @@ -117,7 +114,11 @@ fn main() -> anyhow::Result<()> { if let Some(new_shape) = watcher.receive() { let new_shape = shape_processor.process(&new_shape); - new_shape.update_geometry(&mut renderer); + renderer.update_geometry( + (&new_shape.mesh).into(), + (&new_shape.debug_info).into(), + new_shape.aabb, + ); if camera.is_none() { camera = Some(Camera::new(&new_shape.aabb)); @@ -220,60 +221,3 @@ fn main() -> anyhow::Result<()> { } }); } - -struct ShapeProcessor { - tolerance: Option, -} - -impl ShapeProcessor { - fn process(&self, shape: &fj::Shape) -> ProcessedShape { - let aabb = shape.bounding_volume(); - - let tolerance = match self.tolerance { - None => { - // Compute a reasonable default for the tolerance value. To do - // this, we just look at the smallest non-zero extent of the - // bounding box and divide that by some value. - let mut min_extent = Scalar::MAX; - for extent in aabb.size().components { - if extent > Scalar::ZERO && extent < min_extent { - min_extent = extent; - } - } - - let tolerance = min_extent / Scalar::from_f64(1000.); - Tolerance::from_scalar(tolerance).unwrap() - } - Some(user_defined_tolerance) => user_defined_tolerance, - }; - - let mut debug_info = DebugInfo::new(); - let mesh = triangulate( - shape.to_shape(tolerance, &mut debug_info), - tolerance, - &mut debug_info, - ); - - ProcessedShape { - aabb, - mesh, - debug_info, - } - } -} - -struct ProcessedShape { - aabb: Aabb<3>, - mesh: Mesh>, - debug_info: DebugInfo, -} - -impl ProcessedShape { - fn update_geometry(&self, renderer: &mut Renderer) { - renderer.update_geometry( - (&self.mesh).into(), - (&self.debug_info).into(), - self.aabb, - ); - } -} diff --git a/fj-operations/src/lib.rs b/fj-operations/src/lib.rs index f1b51cb95..7e1e78811 100644 --- a/fj-operations/src/lib.rs +++ b/fj-operations/src/lib.rs @@ -6,6 +6,8 @@ #![deny(missing_docs)] +pub mod shape_processor; + mod circle; mod difference_2d; mod group; diff --git a/fj-operations/src/shape_processor.rs b/fj-operations/src/shape_processor.rs new file mode 100644 index 000000000..c9041cdae --- /dev/null +++ b/fj-operations/src/shape_processor.rs @@ -0,0 +1,65 @@ +//! API for processing shapes + +use fj_interop::{debug::DebugInfo, mesh::Mesh}; +use fj_kernel::algorithms::{triangulate, Tolerance}; +use fj_math::{Aabb, Point, Scalar}; + +use crate::ToShape as _; + +/// Processes an [`fj::Shape`] into a [`ProcessedShape`] +pub struct ShapeProcessor { + /// The tolerance value used for creating the triangle mesh + pub tolerance: Option, +} + +impl ShapeProcessor { + /// Process an [`fj::Shape`] into [`ProcessedShape`] + pub fn process(&self, shape: &fj::Shape) -> ProcessedShape { + let aabb = shape.bounding_volume(); + + let tolerance = match self.tolerance { + None => { + // Compute a reasonable default for the tolerance value. To do + // this, we just look at the smallest non-zero extent of the + // bounding box and divide that by some value. + let mut min_extent = Scalar::MAX; + for extent in aabb.size().components { + if extent > Scalar::ZERO && extent < min_extent { + min_extent = extent; + } + } + + let tolerance = min_extent / Scalar::from_f64(1000.); + Tolerance::from_scalar(tolerance).unwrap() + } + Some(user_defined_tolerance) => user_defined_tolerance, + }; + + let mut debug_info = DebugInfo::new(); + let mesh = triangulate( + shape.to_shape(tolerance, &mut debug_info), + tolerance, + &mut debug_info, + ); + + ProcessedShape { + aabb, + mesh, + debug_info, + } + } +} + +/// A processed shape +/// +/// Created by [`ShapeProcessor::process`]. +pub struct ProcessedShape { + /// The axis-aligned bounding box of the shape + pub aabb: Aabb<3>, + + /// The triangle mesh that approximates the original shape + pub mesh: Mesh>, + + /// The debug info generated while processing the shape + pub debug_info: DebugInfo, +}