diff --git a/fj/src/lib.rs b/fj/src/lib.rs index 680d1926c..44f967bbc 100644 --- a/fj/src/lib.rs +++ b/fj/src/lib.rs @@ -16,7 +16,7 @@ mod syntax; pub mod prelude { pub use crate::syntax::{ - Rotate as _, Sketch as _, Sweep as _, Translate as _, Union as _, + Group as _, Rotate as _, Sketch as _, Sweep as _, Translate as _, }; } diff --git a/fj/src/shape_3d.rs b/fj/src/shape_3d.rs index 5c49d92e8..b9274089f 100644 --- a/fj/src/shape_3d.rs +++ b/fj/src/shape_3d.rs @@ -4,14 +4,14 @@ use crate::{Shape, Shape2d}; #[derive(Clone, Debug)] #[repr(C)] pub enum Shape3d { + /// A group of two 3-dimensional shapes + Group(Box), + /// A sweep of 2-dimensional shape along the z-axis Sweep(Sweep), /// A transformed 3-dimensional shape Transform(Box), - - /// The union of two 3-dimensional shapes - Union(Box), } impl From for Shape { @@ -20,6 +20,36 @@ impl From for Shape { } } +/// A group of two 3-dimensional shapes +/// +/// A group is a collection of disjoint shapes. It is not a union, in that the +/// shapes in the group are not allowed to touch or overlap. +/// +/// # Limitations +/// +/// Whether the shapes in the group touch or overlap is not currently checked. +#[derive(Clone, Debug)] +#[repr(C)] +pub struct Group { + /// The first of the shapes + pub a: Shape3d, + + /// The second of the shapes + pub b: Shape3d, +} + +impl From for Shape { + fn from(shape: Group) -> Self { + Self::Shape3d(Shape3d::Group(Box::new(shape))) + } +} + +impl From for Shape3d { + fn from(shape: Group) -> Self { + Self::Group(Box::new(shape)) + } +} + /// A transformed 3-dimensional shape /// /// # Limitations @@ -97,39 +127,3 @@ impl From for Shape3d { Self::Sweep(shape) } } - -/// The union of two 3-dimensional shapes -/// -/// # Limitations -/// -/// Support for unions is somewhat limited right now. A union of 2 distinct -/// shapes doesn't really create a new shape, but just an aggregation of the -/// two original shapes. -/// -/// This means, for example, that generating the triangle mesh of the union does -/// not result in a proper triangle mesh, but rather the two, possibly -/// intersecting, triangle meshes of the original shapes. -/// -/// See issue: -/// -#[derive(Clone, Debug)] -#[repr(C)] -pub struct Union { - /// The first of the shapes - pub a: Shape3d, - - /// The second of the shapes - pub b: Shape3d, -} - -impl From for Shape { - fn from(shape: Union) -> Self { - Self::Shape3d(Shape3d::Union(Box::new(shape))) - } -} - -impl From for Shape3d { - fn from(shape: Union) -> Self { - Self::Union(Box::new(shape)) - } -} diff --git a/fj/src/syntax.rs b/fj/src/syntax.rs index b62a693cf..7c809c713 100644 --- a/fj/src/syntax.rs +++ b/fj/src/syntax.rs @@ -70,23 +70,23 @@ where } } -pub trait Union { - fn union(&self, other: &Other) -> crate::Union +pub trait Group { + fn group(&self, other: &Other) -> crate::Group where Other: Clone + Into; } -impl Union for T +impl Group for T where T: Clone + Into, { - fn union(&self, other: &Other) -> crate::Union + fn group(&self, other: &Other) -> crate::Group where Other: Clone + Into, { let a = self.clone().into(); let b = other.clone().into(); - crate::Union { a, b } + crate::Group { a, b } } } diff --git a/models/csg-union-disjoint/README.md b/models/csg-union-disjoint/README.md deleted file mode 100644 index 344c75907..000000000 --- a/models/csg-union-disjoint/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Fornjot - Disjoint Union - -A model that demonstrates [constructive solid geometry](https://en.wikipedia.org/wiki/Constructive_solid_geometry) (CSG) functionality, specifically the union of two disjoint bodies. - -To display this model, run the following from the repository root: -``` sh -cargo run -- --model csg-union-disjoint -``` - -![Screenshot of the disjoint union model](csg-union-disjoint.png) diff --git a/models/csg-union-disjoint/Cargo.toml b/models/group/Cargo.toml similarity index 78% rename from models/csg-union-disjoint/Cargo.toml rename to models/group/Cargo.toml index 505071e7b..7910d2980 100644 --- a/models/csg-union-disjoint/Cargo.toml +++ b/models/group/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "csg-union-disjoint" +name = "group" version = "0.1.0" edition = "2021" diff --git a/models/group/README.md b/models/group/README.md new file mode 100644 index 000000000..395f59b5f --- /dev/null +++ b/models/group/README.md @@ -0,0 +1,10 @@ +# Fornjot - Group + +A model that demonstrates groups of two disjoint bodies. + +To display this model, run the following from the repository root: +``` sh +cargo run -- --model group +``` + +![Screenshot of the group model](group.png) diff --git a/models/csg-union-disjoint/csg-union-disjoint.png b/models/group/group.png similarity index 100% rename from models/csg-union-disjoint/csg-union-disjoint.png rename to models/group/group.png diff --git a/models/csg-union-disjoint/src/lib.rs b/models/group/src/lib.rs similarity index 84% rename from models/csg-union-disjoint/src/lib.rs rename to models/group/src/lib.rs index bda316c43..1c16bccec 100644 --- a/models/csg-union-disjoint/src/lib.rs +++ b/models/group/src/lib.rs @@ -15,7 +15,7 @@ pub extern "C" fn model(_: &HashMap) -> fj::Shape { let cube_a = fj::Sketch::from_points(vertices).sweep(1.0); let cube_b = cube_a.clone().translate([1.5, 0., 0.5]); - let disjoint_union = cube_a.union(&cube_b); + let group = cube_a.group(&cube_b); - disjoint_union.into() + group.into() } diff --git a/src/kernel/shapes/union.rs b/src/kernel/shapes/group.rs similarity index 93% rename from src/kernel/shapes/union.rs rename to src/kernel/shapes/group.rs index 0bcdcb2b2..fe63c48ff 100644 --- a/src/kernel/shapes/union.rs +++ b/src/kernel/shapes/group.rs @@ -15,18 +15,13 @@ use crate::{ use super::ToShape; -impl ToShape for fj::Union { +impl ToShape for fj::Group { fn to_shape(&self, tolerance: Scalar, debug_info: &mut DebugInfo) -> Shape { let mut shape = Shape::new(); let a = self.a.to_shape(tolerance, debug_info); let b = self.b.to_shape(tolerance, debug_info); - // This doesn't create a true union, as it doesn't eliminate, merge, or - // split faces. - // - // See issue: - // https://github.com/hannobraun/Fornjot/issues/42 copy_shape(a, &mut shape); copy_shape(b, &mut shape); diff --git a/src/kernel/shapes/mod.rs b/src/kernel/shapes/mod.rs index b3181a62d..700b07a0c 100644 --- a/src/kernel/shapes/mod.rs +++ b/src/kernel/shapes/mod.rs @@ -1,9 +1,9 @@ pub mod circle; pub mod difference_2d; +pub mod group; pub mod sketch; pub mod sweep; pub mod transform; -pub mod union; use crate::{ debug::DebugInfo, @@ -53,9 +53,9 @@ macro_rules! dispatch { $( fn $method(&self, $($arg_name: $arg_ty,)*) -> $ret { match self { + Self::Group(shape) => shape.$method($($arg_name,)*), Self::Sweep(shape) => shape.$method($($arg_name,)*), Self::Transform(shape) => shape.$method($($arg_name,)*), - Self::Union(shape) => shape.$method($($arg_name,)*), } } )*