Skip to content

Commit

Permalink
Merge pull request #825 from hannobraun/fj
Browse files Browse the repository at this point in the history
Make group and transform operations work on all shapes
  • Loading branch information
hannobraun authored Jul 15, 2022
2 parents a1c6e4c + 6c310b7 commit 4e3b840
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 190 deletions.
11 changes: 5 additions & 6 deletions crates/fj-operations/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
objects::Solid,
objects::Face,
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::Aabb;

use super::Shape;

impl Shape for fj::Group {
type Brep = Solid;
type Brep = Vec<Face>;

fn compute_brep(
&self,
Expand All @@ -22,11 +22,10 @@ impl Shape for fj::Group {
let a = self.a.compute_brep(config, tolerance, debug_info)?;
let b = self.b.compute_brep(config, tolerance, debug_info)?;

faces.extend(a.into_inner().into_faces());
faces.extend(b.into_inner().into_faces());
faces.extend(a.into_inner());
faces.extend(b.into_inner());

let group = Solid::from_faces(faces);
validate(group, config)
validate(faces, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
45 changes: 11 additions & 34 deletions crates/fj-operations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mod transform;
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
objects::{Face, Sketch, Solid},
objects::{Face, Sketch},
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::Aabb;
Expand Down Expand Up @@ -69,20 +69,28 @@ impl Shape for fj::Shape {
.into_faces(),
config,
),
Self::Shape3d(shape) => validate(
Self::Group(shape) => {
shape.compute_brep(config, tolerance, debug_info)
}
Self::Sweep(shape) => validate(
shape
.compute_brep(config, tolerance, debug_info)?
.into_inner()
.into_faces(),
config,
),
Self::Transform(shape) => {
shape.compute_brep(config, tolerance, debug_info)
}
}
}

fn bounding_volume(&self) -> Aabb<3> {
match self {
Self::Shape2d(shape) => shape.bounding_volume(),
Self::Shape3d(shape) => shape.bounding_volume(),
Self::Group(shape) => shape.bounding_volume(),
Self::Sweep(shape) => shape.bounding_volume(),
Self::Transform(shape) => shape.bounding_volume(),
}
}
}
Expand Down Expand Up @@ -113,34 +121,3 @@ impl Shape for fj::Shape2d {
}
}
}

impl Shape for fj::Shape3d {
type Brep = Solid;

fn compute_brep(
&self,
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
match self {
Self::Group(shape) => {
shape.compute_brep(config, tolerance, debug_info)
}
Self::Sweep(shape) => {
shape.compute_brep(config, tolerance, debug_info)
}
Self::Transform(shape) => {
shape.compute_brep(config, tolerance, debug_info)
}
}
}

fn bounding_volume(&self) -> Aabb<3> {
match self {
Self::Group(shape) => shape.bounding_volume(),
Self::Sweep(shape) => shape.bounding_volume(),
Self::Transform(shape) => shape.bounding_volume(),
}
}
}
13 changes: 7 additions & 6 deletions crates/fj-operations/src/transform.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::{Tolerance, TransformObject},
objects::Solid,
algorithms::{transform_faces, Tolerance},
objects::Face,
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::{Aabb, Transform, Vector};

use super::Shape;

impl Shape for fj::Transform {
type Brep = Solid;
type Brep = Vec<Face>;

fn compute_brep(
&self,
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
let original = self
let mut faces = self
.shape
.compute_brep(config, tolerance, debug_info)?
.into_inner();

let transformed = original.transform(&make_transform(self));
validate(transformed, config)
transform_faces(&mut faces, &make_transform(self));

validate(faces, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
29 changes: 29 additions & 0 deletions crates/fj/src/group.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::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)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(C)]
pub struct Group {
/// The first of the shapes
pub a: Shape,

/// The second of the shapes
pub b: Shape,
}

impl From<Group> for Shape {
fn from(shape: Group) -> Self {
Self::Group(Box::new(shape))
}
}
18 changes: 14 additions & 4 deletions crates/fj/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
pub mod syntax;

mod angle;
mod group;
mod shape_2d;
mod shape_3d;
mod sweep;
mod transform;

pub use self::{angle::*, shape_2d::*, shape_3d::*};
pub use self::{
angle::*, group::Group, shape_2d::*, sweep::Sweep, transform::Transform,
};
pub use fj_proc::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
Expand All @@ -34,9 +38,15 @@ use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(C)]
pub enum Shape {
/// A group of two 3-dimensional shapes
Group(Box<Group>),

/// A 2D shape
Shape2d(Shape2d),

/// A 3D shape
Shape3d(Shape3d),
/// A sweep of 2-dimensional shape along the z-axis
Sweep(Sweep),

/// A transformed 3-dimensional shape
Transform(Box<Transform>),
}
134 changes: 0 additions & 134 deletions crates/fj/src/shape_3d.rs

This file was deleted.

39 changes: 39 additions & 0 deletions crates/fj/src/sweep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Shape, Shape2d};

/// A sweep of a 2-dimensional shape along straight path
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(C)]
pub struct Sweep {
/// The 2-dimensional shape being swept
shape: Shape2d,

/// The length and direction of the sweep
path: [f64; 3],
}

impl Sweep {
/// Create a `Sweep` along a straight path
pub fn from_path(shape: Shape2d, path: [f64; 3]) -> Self {
Self { shape, path }
}

/// Access the shape being swept
pub fn shape(&self) -> &Shape2d {
&self.shape
}

/// Access the path of the sweep
pub fn path(&self) -> [f64; 3] {
self.path
}
}

impl From<Sweep> for Shape {
fn from(shape: Sweep) -> Self {
Self::Sweep(shape)
}
}
Loading

0 comments on commit 4e3b840

Please sign in to comment.