Skip to content

Commit

Permalink
Merge pull request #2381 from hannobraun/transform
Browse files Browse the repository at this point in the history
Make `TransformObject` trait more flexible
  • Loading branch information
hannobraun authored Jun 14, 2024
2 parents b5559bf + 5716bb7 commit 605e524
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 38 deletions.
3 changes: 2 additions & 1 deletion crates/fj-core/src/operations/sweep/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ impl SweepRegion for Region {

let mut faces = Vec::new();

let top_surface = bottom_surface.translate(path, core).insert(core);
let top_surface =
bottom_surface.clone().translate(path, core).insert(core);

let top_exterior = sweep_cycle(
self.exterior(),
Expand Down
10 changes: 6 additions & 4 deletions crates/fj-core/src/operations/transform/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,24 @@ use crate::{
use super::{TransformCache, TransformObject};

impl TransformObject for Handle<Curve> {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
_: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
cache
.entry(self)
.entry(&self)
.or_insert_with(|| {
// We don't actually need to transform the curve, as its
// geometry is locally defined on a surface. We need to set that
// geometry for the new object though, that we created here to
// represent the transformed curve.
Curve::new()
.insert(core)
.copy_geometry_from(self, &mut core.layers.geometry)
.copy_geometry_from(&self, &mut core.layers.geometry)
})
.clone()
}
Expand Down
14 changes: 9 additions & 5 deletions crates/fj-core/src/operations/transform/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ use crate::{topology::Cycle, Core};
use super::{TransformCache, TransformObject};

impl TransformObject for Cycle {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
let edges = self.half_edges().iter().map(|edge| {
edge.clone().transform_with_cache(transform, core, cache)
) -> Self::Transformed {
let half_edges = self.half_edges().iter().map(|half_edge| {
half_edge
.clone()
.transform_with_cache(transform, core, cache)
});

Self::new(edges)
Self::new(half_edges)
}
}
8 changes: 5 additions & 3 deletions crates/fj-core/src/operations/transform/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ use crate::{
use super::{TransformCache, TransformObject};

impl TransformObject for Handle<HalfEdge> {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
let curve = self
.curve()
.clone()
Expand All @@ -26,7 +28,7 @@ impl TransformObject for Handle<HalfEdge> {

core.layers.geometry.define_half_edge(
half_edge.clone(),
*core.layers.geometry.of_half_edge(self),
*core.layers.geometry.of_half_edge(&self),
);

half_edge
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/operations/transform/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use crate::{topology::Face, Core};
use super::{TransformCache, TransformObject};

impl TransformObject for Face {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
let surface = self
.surface()
.clone()
Expand Down
38 changes: 27 additions & 11 deletions crates/fj-core/src/operations/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,59 +34,75 @@ use super::derive::DeriveFrom;
/// More convenience methods can be added as required. The only reason this
/// hasn't been done so far, is that no one has put in the work yet.
pub trait TransformObject: Sized {
/// The result of the transformation
type Transformed;

/// Transform the object
fn transform(&self, transform: &Transform, core: &mut Core) -> Self {
fn transform(
self,
transform: &Transform,
core: &mut Core,
) -> Self::Transformed {
let mut cache = TransformCache::default();
self.transform_with_cache(transform, core, &mut cache)
}

/// Transform the object using the provided cache
fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self;
) -> Self::Transformed;

/// Translate the object
///
/// Convenience wrapper around [`TransformObject::transform`].
fn translate(&self, offset: impl Into<Vector<3>>, core: &mut Core) -> Self {
fn translate(
self,
offset: impl Into<Vector<3>>,
core: &mut Core,
) -> Self::Transformed {
self.transform(&Transform::translation(offset), core)
}

/// Rotate the object
///
/// Convenience wrapper around [`TransformObject::transform`].
fn rotate(
&self,
self,
axis_angle: impl Into<Vector<3>>,
core: &mut Core,
) -> Self {
) -> Self::Transformed {
self.transform(&Transform::rotation(axis_angle), core)
}
}

impl<T> TransformObject for Handle<T>
where
T: Clone + Insert<Inserted = Handle<T>> + TransformObject + 'static,
T: Clone
+ Insert<Inserted = Handle<T>>
+ TransformObject<Transformed = T>
+ 'static,
Handle<T>: Into<AnyObject<Stored>>,
{
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
if let Some(object) = cache.get(self) {
) -> Self::Transformed {
if let Some(object) = cache.get(&self) {
return object.clone();
}

let transformed = self
.clone_object()
.transform_with_cache(transform, core, cache)
.insert(core)
.derive_from(self, core);
.derive_from(&self, core);

cache.insert(self.clone(), transformed.clone());

Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/operations/transform/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use crate::{topology::Region, Core};
use super::TransformObject;

impl TransformObject for Region {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &fj_math::Transform,
core: &mut Core,
cache: &mut super::TransformCache,
) -> Self {
) -> Self::Transformed {
let exterior = self
.exterior()
.clone()
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/operations/transform/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use crate::{topology::Shell, Core};
use super::{TransformCache, TransformObject};

impl TransformObject for Shell {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
let faces = self
.faces()
.iter()
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/operations/transform/solid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use crate::{topology::Solid, Core};
use super::{TransformCache, TransformObject};

impl TransformObject for Solid {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
let shells =
self.shells().iter().cloned().map(|shell| {
shell.transform_with_cache(transform, core, cache)
Expand Down
10 changes: 6 additions & 4 deletions crates/fj-core/src/operations/transform/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ use crate::{
use super::{TransformCache, TransformObject};

impl TransformObject for Handle<Surface> {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
cache
.entry(self)
.entry(&self)
.or_insert_with(|| {
let surface = Surface::new().insert(core);

let geometry =
core.layers.geometry.of_surface(self).transform(transform);
core.layers.geometry.of_surface(&self).transform(transform);
core.layers
.geometry
.define_surface(surface.clone(), geometry);
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/operations/transform/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use crate::{topology::Vertex, Core};
use super::{TransformCache, TransformObject};

impl TransformObject for Vertex {
type Transformed = Self;

fn transform_with_cache(
&self,
self,
_: &Transform,
_: &mut Core,
_: &mut TransformCache,
) -> Self {
) -> Self::Transformed {
// There's nothing to actually transform here, as `Vertex` holds no
// data. We still need this implementation though, as a new `Vertex`
// object must be created to represent the new and transformed vertex.
Expand Down

0 comments on commit 605e524

Please sign in to comment.