Merge pull request #2381 from hannobraun/transform

Make `TransformObject` trait more flexible
This commit is contained in:
Hanno Braun 2024-06-14 22:15:29 +02:00 committed by GitHub
commit 605e5241b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 75 additions and 38 deletions

View File

@ -52,7 +52,8 @@ impl SweepRegion for Region {
let mut faces = Vec::new(); 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( let top_exterior = sweep_cycle(
self.exterior(), self.exterior(),

View File

@ -10,14 +10,16 @@ use crate::{
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Handle<Curve> { impl TransformObject for Handle<Curve> {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
_: &Transform, _: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
cache cache
.entry(self) .entry(&self)
.or_insert_with(|| { .or_insert_with(|| {
// We don't actually need to transform the curve, as its // We don't actually need to transform the curve, as its
// geometry is locally defined on a surface. We need to set that // geometry is locally defined on a surface. We need to set that
@ -25,7 +27,7 @@ impl TransformObject for Handle<Curve> {
// represent the transformed curve. // represent the transformed curve.
Curve::new() Curve::new()
.insert(core) .insert(core)
.copy_geometry_from(self, &mut core.layers.geometry) .copy_geometry_from(&self, &mut core.layers.geometry)
}) })
.clone() .clone()
} }

View File

@ -5,16 +5,20 @@ use crate::{topology::Cycle, Core};
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Cycle { impl TransformObject for Cycle {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
let edges = self.half_edges().iter().map(|edge| { let half_edges = self.half_edges().iter().map(|half_edge| {
edge.clone().transform_with_cache(transform, core, cache) half_edge
.clone()
.transform_with_cache(transform, core, cache)
}); });
Self::new(edges) Self::new(half_edges)
} }
} }

View File

@ -7,12 +7,14 @@ use crate::{
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Handle<HalfEdge> { impl TransformObject for Handle<HalfEdge> {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
let curve = self let curve = self
.curve() .curve()
.clone() .clone()
@ -26,7 +28,7 @@ impl TransformObject for Handle<HalfEdge> {
core.layers.geometry.define_half_edge( core.layers.geometry.define_half_edge(
half_edge.clone(), half_edge.clone(),
*core.layers.geometry.of_half_edge(self), *core.layers.geometry.of_half_edge(&self),
); );
half_edge half_edge

View File

@ -5,12 +5,14 @@ use crate::{topology::Face, Core};
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Face { impl TransformObject for Face {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
let surface = self let surface = self
.surface() .surface()
.clone() .clone()

View File

@ -34,24 +34,35 @@ use super::derive::DeriveFrom;
/// More convenience methods can be added as required. The only reason this /// 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. /// hasn't been done so far, is that no one has put in the work yet.
pub trait TransformObject: Sized { pub trait TransformObject: Sized {
/// The result of the transformation
type Transformed;
/// Transform the object /// 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(); let mut cache = TransformCache::default();
self.transform_with_cache(transform, core, &mut cache) self.transform_with_cache(transform, core, &mut cache)
} }
/// Transform the object using the provided cache /// Transform the object using the provided cache
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self; ) -> Self::Transformed;
/// Translate the object /// Translate the object
/// ///
/// Convenience wrapper around [`TransformObject::transform`]. /// 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) self.transform(&Transform::translation(offset), core)
} }
@ -59,26 +70,31 @@ pub trait TransformObject: Sized {
/// ///
/// Convenience wrapper around [`TransformObject::transform`]. /// Convenience wrapper around [`TransformObject::transform`].
fn rotate( fn rotate(
&self, self,
axis_angle: impl Into<Vector<3>>, axis_angle: impl Into<Vector<3>>,
core: &mut Core, core: &mut Core,
) -> Self { ) -> Self::Transformed {
self.transform(&Transform::rotation(axis_angle), core) self.transform(&Transform::rotation(axis_angle), core)
} }
} }
impl<T> TransformObject for Handle<T> impl<T> TransformObject for Handle<T>
where where
T: Clone + Insert<Inserted = Handle<T>> + TransformObject + 'static, T: Clone
+ Insert<Inserted = Handle<T>>
+ TransformObject<Transformed = T>
+ 'static,
Handle<T>: Into<AnyObject<Stored>>, Handle<T>: Into<AnyObject<Stored>>,
{ {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
if let Some(object) = cache.get(self) { if let Some(object) = cache.get(&self) {
return object.clone(); return object.clone();
} }
@ -86,7 +102,7 @@ where
.clone_object() .clone_object()
.transform_with_cache(transform, core, cache) .transform_with_cache(transform, core, cache)
.insert(core) .insert(core)
.derive_from(self, core); .derive_from(&self, core);
cache.insert(self.clone(), transformed.clone()); cache.insert(self.clone(), transformed.clone());

View File

@ -3,12 +3,14 @@ use crate::{topology::Region, Core};
use super::TransformObject; use super::TransformObject;
impl TransformObject for Region { impl TransformObject for Region {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &fj_math::Transform, transform: &fj_math::Transform,
core: &mut Core, core: &mut Core,
cache: &mut super::TransformCache, cache: &mut super::TransformCache,
) -> Self { ) -> Self::Transformed {
let exterior = self let exterior = self
.exterior() .exterior()
.clone() .clone()

View File

@ -5,12 +5,14 @@ use crate::{topology::Shell, Core};
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Shell { impl TransformObject for Shell {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
let faces = self let faces = self
.faces() .faces()
.iter() .iter()

View File

@ -5,12 +5,14 @@ use crate::{topology::Solid, Core};
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Solid { impl TransformObject for Solid {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
let shells = let shells =
self.shells().iter().cloned().map(|shell| { self.shells().iter().cloned().map(|shell| {
shell.transform_with_cache(transform, core, cache) shell.transform_with_cache(transform, core, cache)

View File

@ -7,19 +7,21 @@ use crate::{
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Handle<Surface> { impl TransformObject for Handle<Surface> {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
transform: &Transform, transform: &Transform,
core: &mut Core, core: &mut Core,
cache: &mut TransformCache, cache: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
cache cache
.entry(self) .entry(&self)
.or_insert_with(|| { .or_insert_with(|| {
let surface = Surface::new().insert(core); let surface = Surface::new().insert(core);
let geometry = let geometry =
core.layers.geometry.of_surface(self).transform(transform); core.layers.geometry.of_surface(&self).transform(transform);
core.layers core.layers
.geometry .geometry
.define_surface(surface.clone(), geometry); .define_surface(surface.clone(), geometry);

View File

@ -5,12 +5,14 @@ use crate::{topology::Vertex, Core};
use super::{TransformCache, TransformObject}; use super::{TransformCache, TransformObject};
impl TransformObject for Vertex { impl TransformObject for Vertex {
type Transformed = Self;
fn transform_with_cache( fn transform_with_cache(
&self, self,
_: &Transform, _: &Transform,
_: &mut Core, _: &mut Core,
_: &mut TransformCache, _: &mut TransformCache,
) -> Self { ) -> Self::Transformed {
// There's nothing to actually transform here, as `Vertex` holds no // There's nothing to actually transform here, as `Vertex` holds no
// data. We still need this implementation though, as a new `Vertex` // data. We still need this implementation though, as a new `Vertex`
// object must be created to represent the new and transformed vertex. // object must be created to represent the new and transformed vertex.