1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! # Fornjot CAD Operations
//!
//! This library is part of the [Fornjot] ecosystem. Fornjot is an open-source,
//! code-first CAD application; and collection of libraries that make up the CAD
//! application, but can be used independently.
//!
//! This library is an internal component of Fornjot. It is not relevant to end
//! users that just want to create CAD models.
//!
//! Fornjot models use the [`fj`] crate to define a shape. This crate provides
//! the connection between [`fj`] and the Fornjot kernel. It translates those
//! operations into terms the kernel can understand.
//!
//! [Fornjot]: https://www.fornjot.app/
//! [`fj`]: https://crates.io/crates/fj
#![warn(missing_docs)]
pub mod shape_processor;
mod difference_2d;
mod group;
mod sketch;
mod sweep;
mod transform;
use fj_interop::debug::DebugInfo;
use fj_kernel::{
objects::{FaceSet, Objects, Sketch},
services::Service,
};
use fj_math::Aabb;
/// Implemented for all operations from the [`fj`] crate
pub trait Shape {
/// The type that is used for the shape's boundary representation
type Brep;
/// Compute the boundary representation of the shape
fn compute_brep(
&self,
objects: &mut Service<Objects>,
debug_info: &mut DebugInfo,
) -> Self::Brep;
/// Access the axis-aligned bounding box of a shape
///
/// If a shape is empty, its [`Aabb`]'s `min` and `max` points must be equal
/// (but are otherwise not specified).
fn bounding_volume(&self) -> Aabb<3>;
}
impl Shape for fj::Shape {
type Brep = FaceSet;
fn compute_brep(
&self,
objects: &mut Service<Objects>,
debug_info: &mut DebugInfo,
) -> Self::Brep {
match self {
Self::Shape2d(shape) => {
shape.compute_brep(objects, debug_info).faces().clone()
}
Self::Group(shape) => shape.compute_brep(objects, debug_info),
Self::Sweep(shape) => shape
.compute_brep(objects, debug_info)
.shells()
.map(|shell| shell.faces().clone())
.reduce(|mut a, b| {
a.extend(b);
a
})
.unwrap_or_default(),
Self::Transform(shape) => shape.compute_brep(objects, debug_info),
}
}
fn bounding_volume(&self) -> Aabb<3> {
match self {
Self::Shape2d(shape) => shape.bounding_volume(),
Self::Group(shape) => shape.bounding_volume(),
Self::Sweep(shape) => shape.bounding_volume(),
Self::Transform(shape) => shape.bounding_volume(),
}
}
}
impl Shape for fj::Shape2d {
type Brep = Sketch;
fn compute_brep(
&self,
objects: &mut Service<Objects>,
debug_info: &mut DebugInfo,
) -> Self::Brep {
match self {
Self::Difference(shape) => shape.compute_brep(objects, debug_info),
Self::Sketch(shape) => shape.compute_brep(objects, debug_info),
}
}
fn bounding_volume(&self) -> Aabb<3> {
match self {
Self::Difference(shape) => shape.bounding_volume(),
Self::Sketch(shape) => shape.bounding_volume(),
}
}
}