diff --git a/crates/kernel/src/body.rs b/crates/kernel/src/body.rs index e2ac5f5c..2e07cd46 100644 --- a/crates/kernel/src/body.rs +++ b/crates/kernel/src/body.rs @@ -1326,6 +1326,10 @@ impl Body { /// The reference mesher's angular display mesh: what [`Body::display_mesh_angular`] falls /// back to when no plan can be made. pub fn reference_display_mesh_angular(&self, tol: f64, angle: f64) -> Result { + crate::profile::timed(crate::profile::Kind::Tessellate, || self.reference_display_mesh_angular_untimed(tol, angle)) + } + + fn reference_display_mesh_angular_untimed(&self, tol: f64, angle: f64) -> Result { if let Some((shared, t)) = self.display_of.as_deref() && let Some(placed) = shared.mesh.get_or_init(|| shared.original.reference_display_mesh_angular(tol, angle).ok()).as_ref().and_then(|m| placed_mesh(m, t)) diff --git a/crates/kernel/src/polybool.rs b/crates/kernel/src/polybool.rs index 951c3216..665765c1 100644 --- a/crates/kernel/src/polybool.rs +++ b/crates/kernel/src/polybool.rs @@ -343,6 +343,10 @@ fn faceted_polys(b: &Body, tol: f64, operand: usize) -> Option> { /// triangles of `b`; an edge between facets of one face of `a`, or between triangles of `b`, /// has no origin. pub fn faceted_boolean(a: &Body, b: &Mesh, op: BoolOp, tol: f64) -> Result> { + crate::profile::timed(crate::profile::Kind::Boolean, || faceted_boolean_untimed(a, b, op, tol)) +} + +fn faceted_boolean_untimed(a: &Body, b: &Mesh, op: BoolOp, tol: f64) -> Result> { a.require_brep("a boolean")?; if !(tol.is_finite() && tol > 0.0) { return Err(KernelError::Invalid("facet tolerance".into())); diff --git a/crates/kernel/src/profile.rs b/crates/kernel/src/profile.rs index 56dfbcf4..5d1cea89 100644 --- a/crates/kernel/src/profile.rs +++ b/crates/kernel/src/profile.rs @@ -133,4 +133,18 @@ mod tests { let st = STATE.with(Cell::get); assert!(!st.on && !st.busy); } + #[test] + fn a_faceted_boolean_is_boolean_time_and_a_reference_mesh_tessellation() { + use crate::{BoolOp, box_solid, faceted_boolean}; + use solidcraft_geom::Vec3; + let a = box_solid(Vec3::ZERO, Vec3::new(10.0, 10.0, 10.0)).unwrap(); + let tool = box_solid(Vec3::new(5.0, 5.0, 5.0), Vec3::new(15.0, 15.0, 15.0)).unwrap().tessellate(0.1).unwrap(); + // The thread groove's route: the faceting it does first is the boolean's time too. + let (r, t) = capture(|| faceted_boolean(&a, &tool, BoolOp::Cut, 0.01)); + assert!(r.unwrap().is_some()); + assert!(t.boolean_ms > 0.0 && t.tessellate_ms == 0.0, "{t:?}"); + let (m, t) = capture(|| a.reference_display_mesh_angular(0.01, crate::DISPLAY_ANGLE)); + assert!(!m.unwrap().triangles.is_empty()); + assert!(t.tessellate_ms > 0.0 && t.boolean_ms == 0.0, "{t:?}"); + } }