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

Avoid creating duplicate GlobalCurves when transforming half-edge #1152

Merged
merged 10 commits into from
Sep 28, 2022
27 changes: 27 additions & 0 deletions crates/fj-kernel/src/algorithms/transform/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use fj_math::Transform;

use crate::{
objects::{Curve, GlobalCurve},
partial::{PartialCurve, PartialGlobalCurve},
stores::{Handle, Stores},
};

Expand All @@ -26,3 +27,29 @@ impl TransformObject for Handle<GlobalCurve> {
))
}
}

impl TransformObject for PartialCurve {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let surface = self
.surface
.map(|surface| surface.transform(transform, stores));
let global_form = self
.global_form
.map(|global_form| global_form.transform(transform, stores));

// Don't need to transform `self.path`, as that's defined in surface
// coordinates, and thus transforming `surface` takes care of it.
Self {
surface,
path: self.path,
global_form,
}
}
}

impl TransformObject for PartialGlobalCurve {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let path = self.path.map(|path| path.transform(transform, stores));
Self { path }
}
}
30 changes: 27 additions & 3 deletions crates/fj-kernel/src/algorithms/transform/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use fj_math::Transform;

use crate::{
objects::{GlobalEdge, HalfEdge},
partial::{HasPartial, PartialGlobalEdge},
stores::Stores,
};

Expand All @@ -12,10 +13,22 @@ impl TransformObject for HalfEdge {
let curve = self.curve().clone().transform(transform, stores);
let vertices = self
.vertices()
// The `clone` can be replaced with `each_ref`, once that is stable:
// https://doc.rust-lang.org/std/primitive.array.html#method.each_ref
.clone()
.map(|vertex| vertex.transform(transform, stores));
let global_form =
self.global_form().clone().transform(transform, stores);
.map(|vertex| {
vertex
.to_partial()
.transform(transform, stores)
.with_curve(curve.clone())
.build(stores)
});
let global_form = self
.global_form()
.to_partial()
.transform(transform, stores)
.with_curve(curve.global_form().clone())
.build(stores);

Self::new(curve, vertices, global_form)
}
Expand All @@ -31,3 +44,14 @@ impl TransformObject for GlobalEdge {
Self::new(curve, vertices)
}
}

impl TransformObject for PartialGlobalEdge {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let curve = self.curve.map(|curve| curve.transform(transform, stores));
let vertices = self.vertices.map(|vertices| {
vertices.map(|vertex| vertex.transform(transform, stores))
});

Self { curve, vertices }
}
}
20 changes: 19 additions & 1 deletion crates/fj-kernel/src/algorithms/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ mod vertex;

use fj_math::{Transform, Vector};

use crate::stores::Stores;
use crate::{
partial::{HasPartial, MaybePartial},
stores::Stores,
};

/// Transform an object
///
Expand Down Expand Up @@ -45,3 +48,18 @@ pub trait TransformObject: Sized {
self.transform(&Transform::rotation(axis_angle), stores)
}
}

impl<T> TransformObject for MaybePartial<T>
where
T: HasPartial + TransformObject,
T::Partial: TransformObject,
{
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
match self {
Self::Full(full) => Self::Full(full.transform(transform, stores)),
Self::Partial(partial) => {
Self::Partial(partial.transform(transform, stores))
}
}
}
}
51 changes: 51 additions & 0 deletions crates/fj-kernel/src/algorithms/transform/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use fj_math::Transform;

use crate::{
objects::{GlobalVertex, SurfaceVertex, Vertex},
partial::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex},
stores::Stores,
};

Expand Down Expand Up @@ -36,3 +37,53 @@ impl TransformObject for GlobalVertex {
Self::from_position(position)
}
}

impl TransformObject for PartialVertex {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let curve = self.curve.map(|curve| curve.transform(transform, stores));
let surface_form = self
.surface_form
.map(|surface_form| surface_form.transform(transform, stores));
let global_form = self
.global_form
.map(|global_form| global_form.transform(transform, stores));

// Don't need to transform `self.position`, as that is in curve
// coordinates and thus transforming the curve takes care of it.
Self {
position: self.position,
curve,
surface_form,
global_form,
}
}
}

impl TransformObject for PartialSurfaceVertex {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let surface = self
.surface
.map(|surface| surface.transform(transform, stores));
let global_form = self
.global_form
.map(|global_form| global_form.transform(transform, stores));

// Don't need to transform `self.position`, as that is in surface
// coordinates and thus transforming the surface takes care of it.
Self {
position: self.position,
surface,
global_form,
}
}
}

impl TransformObject for PartialGlobalVertex {
fn transform(self, transform: &Transform, _: &Stores) -> Self {
let position = self
.position
.map(|position| transform.transform_point(&position));

Self { position }
}
}