Skip to content

Commit

Permalink
Merge pull request #1871 from hannobraun/aabb
Browse files Browse the repository at this point in the history
Compute AABB from boundary representation
  • Loading branch information
hannobraun authored Jun 12, 2023
2 parents d789adb + d720fbb commit ebcb223
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 3 deletions.
18 changes: 18 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use fj_math::Aabb;

use crate::objects::Cycle;

impl super::BoundingVolume<2> for Cycle {
fn aabb(&self) -> Option<Aabb<2>> {
let mut aabb: Option<Aabb<2>> = None;

for half_edge in self.half_edges() {
let new_aabb = half_edge
.aabb()
.expect("`HalfEdge` can always compute AABB");
aabb = Some(aabb.map_or(new_aabb, |aabb| aabb.merged(&new_aabb)));
}

aabb
}
}
13 changes: 13 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/edge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use fj_math::Aabb;

use crate::objects::HalfEdge;

impl super::BoundingVolume<2> for HalfEdge {
fn aabb(&self) -> Option<Aabb<2>> {
let points = self.boundary().map(|point_curve| {
self.curve().point_from_path_coords(point_curve)
});

Some(Aabb::<2>::from_points(points))
}
}
24 changes: 24 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/face.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use fj_math::Aabb;

use crate::{geometry::curve::GlobalPath, objects::Face};

impl super::BoundingVolume<3> for Face {
fn aabb(&self) -> Option<Aabb<3>> {
self.exterior().aabb().map(|aabb2| {
let surface = self.surface().geometry();

match surface.u {
GlobalPath::Circle(_) => {
// I don't currently have an example model to test this
// with. This should change soon, and then this will panic
// and can be addressed.
todo!("Computing AABB of curved face is not supported yet")
}
GlobalPath::Line(_) => Aabb {
min: surface.point_from_surface_coords(aabb2.min),
max: surface.point_from_surface_coords(aabb2.max),
},
}
})
}
}
17 changes: 17 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Compute a bounding volume for an object
mod cycle;
mod edge;
mod face;
mod shell;
mod solid;

use fj_math::Aabb;

/// Compute a bounding volume for an object
pub trait BoundingVolume<const D: usize> {
/// Compute an axis-aligned bounding box (AABB)
///
/// Return `None`, if no AABB can be computed (if the object is empty).
fn aabb(&self) -> Option<Aabb<D>>;
}
19 changes: 19 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use fj_math::Aabb;

use crate::objects::Shell;

impl super::BoundingVolume<3> for Shell {
fn aabb(&self) -> Option<Aabb<3>> {
let mut aabb: Option<Aabb<3>> = None;

for face in self.faces() {
let new_aabb = face.aabb();
aabb = aabb.map_or(new_aabb, |aabb| match new_aabb {
Some(new_aabb) => Some(aabb.merged(&new_aabb)),
None => Some(aabb),
});
}

aabb
}
}
19 changes: 19 additions & 0 deletions crates/fj-core/src/algorithms/bounding_volume/solid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use fj_math::Aabb;

use crate::objects::Solid;

impl super::BoundingVolume<3> for Solid {
fn aabb(&self) -> Option<Aabb<3>> {
let mut aabb: Option<Aabb<3>> = None;

for shell in self.shells() {
let new_aabb = shell.aabb();
aabb = aabb.map_or(new_aabb, |aabb| match new_aabb {
Some(new_aabb) => Some(aabb.merged(&new_aabb)),
None => Some(aabb),
});
}

aabb
}
}
1 change: 1 addition & 0 deletions crates/fj-core/src/algorithms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! on their respective purpose.
pub mod approx;
pub mod bounding_volume;
pub mod intersect;
pub mod reverse;
pub mod sweep;
Expand Down
13 changes: 10 additions & 3 deletions crates/fj/src/handle_model.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::ops::Deref;

use fj_core::algorithms::{approx::Tolerance, triangulate::Triangulate};
use fj_core::algorithms::{
approx::Tolerance, bounding_volume::BoundingVolume,
triangulate::Triangulate,
};
use fj_interop::model::Model;
use fj_math::Aabb;
use fj_math::{Aabb, Point};

use crate::Args;

Expand All @@ -20,7 +23,12 @@ pub fn handle_model<M>(
) -> Result
where
for<'r> (&'r M, Tolerance): Triangulate,
M: BoundingVolume<3>,
{
let aabb = model.aabb().unwrap_or(Aabb {
min: Point::origin(),
max: Point::origin(),
});
let mesh = (model.deref(), tolerance.into()).triangulate();

let args = Args::parse();
Expand All @@ -29,7 +37,6 @@ where
return Ok(());
}

let aabb = Aabb::<3>::from_points(mesh.vertices());
let model = Model { mesh, aabb };

crate::window::display(model, false)?;
Expand Down

0 comments on commit ebcb223

Please sign in to comment.