mirror of
https://github.com/hannobraun/Fornjot
synced 2025-05-06 02:48:27 +00:00
Merge pull request #2381 from hannobraun/transform
Make `TransformObject` trait more flexible
This commit is contained in:
commit
605e5241b2
@ -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(),
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user