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 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(),

View File

@ -10,14 +10,16 @@ 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
@ -25,7 +27,7 @@ impl TransformObject for Handle<Curve> {
// 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()
}

View File

@ -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)
}
}

View File

@ -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()
@ -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

View File

@ -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()

View File

@ -34,24 +34,35 @@ 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)
}
@ -59,26 +70,31 @@ pub trait TransformObject: Sized {
///
/// 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();
}
@ -86,7 +102,7 @@ where
.clone_object()
.transform_with_cache(transform, core, cache)
.insert(core)
.derive_from(self, core);
.derive_from(&self, core);
cache.insert(self.clone(), transformed.clone());

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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);

View File

@ -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.