Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make TransformObject trait more flexible #2381

Merged
merged 4 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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