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

Correctly define curve geometry when transforming curve #2382

Merged
merged 19 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
53 changes: 36 additions & 17 deletions crates/fj-core/src/operations/transform/curve.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
use fj_math::Transform;

use crate::{
operations::{geometry::UpdateCurveGeometry, insert::Insert},
operations::insert::Insert,
storage::Handle,
topology::Curve,
topology::{Curve, Surface},
Core,
};

use super::{TransformCache, TransformObject};

impl TransformObject for Handle<Curve> {
type Transformed = Self;
impl TransformObject for (&Handle<Curve>, &Handle<Surface>) {
type Transformed = Handle<Curve>;

fn transform_with_cache(
self,
_: &Transform,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self::Transformed {
cache
.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)
})
.clone()
let (curve, surface) = self;

// We don't actually need to transform the curve, as its geometry is
// locally defined on a surface. We need to transform that surface
// though, or what we do here will have no consequence.
//
// If this transformation is only one element in the transformation of
// a whole object graph, using the cache here ensures that the surface
// doesn't get transformed multiple times.
let transformed_surface = cache
.entry(surface)
.or_insert_with(|| surface.transform(transform, core))
.clone();
let transformed_curve = cache
.entry(curve)
.or_insert_with(|| Curve::new().insert(core))
.clone();

core.layers.geometry.define_curve(
transformed_curve.clone(),
transformed_surface,
core.layers
.geometry
.of_curve(curve)
.unwrap()
.local_on(surface)
.unwrap()
.clone(),
);

transformed_curve
}
}
21 changes: 13 additions & 8 deletions crates/fj-core/src/operations/transform/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
use fj_math::Transform;

use crate::{topology::Cycle, Core};
use crate::{
operations::insert::Insert,
storage::Handle,
topology::{Cycle, Surface},
Core,
};

use super::{TransformCache, TransformObject};

impl TransformObject for Cycle {
type Transformed = Self;
impl TransformObject for (&Handle<Cycle>, &Handle<Surface>) {
type Transformed = Handle<Cycle>;

fn transform_with_cache(
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self::Transformed {
let half_edges = self.half_edges().iter().map(|half_edge| {
half_edge
.clone()
.transform_with_cache(transform, core, cache)
let (cycle, surface) = self;

let half_edges = cycle.half_edges().iter().map(|half_edge| {
(half_edge, surface).transform_with_cache(transform, core, cache)
});

Self::new(half_edges)
Cycle::new(half_edges).insert(core)
}
}
26 changes: 15 additions & 11 deletions crates/fj-core/src/operations/transform/edge.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
use fj_math::Transform;

use crate::{
operations::insert::Insert, storage::Handle, topology::HalfEdge, Core,
operations::insert::Insert,
storage::Handle,
topology::{HalfEdge, Surface},
Core,
};

use super::{TransformCache, TransformObject};

impl TransformObject for Handle<HalfEdge> {
type Transformed = Self;
impl TransformObject for (&Handle<HalfEdge>, &Handle<Surface>) {
type Transformed = Handle<HalfEdge>;

fn transform_with_cache(
self,
transform: &Transform,
core: &mut Core,
cache: &mut TransformCache,
) -> Self::Transformed {
let curve = self
.curve()
.clone()
let (half_edge, surface) = self;

let curve = (half_edge.curve(), surface)
.transform_with_cache(transform, core, cache);
let start_vertex = self
let start_vertex = half_edge
.start_vertex()
.clone()
.transform_with_cache(transform, core, cache);

let half_edge = HalfEdge::new(curve, start_vertex).insert(core);
let transformed_half_edge =
HalfEdge::new(curve, start_vertex).insert(core);

core.layers.geometry.define_half_edge(
half_edge.clone(),
*core.layers.geometry.of_half_edge(&self),
transformed_half_edge.clone(),
*core.layers.geometry.of_half_edge(half_edge),
);

half_edge
transformed_half_edge
}
}
4 changes: 1 addition & 3 deletions crates/fj-core/src/operations/transform/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ impl TransformObject for Face {
.surface()
.clone()
.transform_with_cache(transform, core, cache);
let region = self
.region()
.clone()
let region = (self.region(), self.surface())
.transform_with_cache(transform, core, cache);

Self::new(surface, region)
Expand Down
23 changes: 14 additions & 9 deletions crates/fj-core/src/operations/transform/region.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
use crate::{topology::Region, Core};
use crate::{
operations::insert::Insert,
storage::Handle,
topology::{Region, Surface},
Core,
};

use super::TransformObject;

impl TransformObject for Region {
type Transformed = Self;
impl TransformObject for (&Handle<Region>, &Handle<Surface>) {
type Transformed = Handle<Region>;

fn transform_with_cache(
self,
transform: &fj_math::Transform,
core: &mut Core,
cache: &mut super::TransformCache,
) -> Self::Transformed {
let exterior = self
.exterior()
.clone()
let (region, surface) = self;

let exterior = (region.exterior(), surface)
.transform_with_cache(transform, core, cache);
let interiors = self.interiors().iter().cloned().map(|interior| {
interior.transform_with_cache(transform, core, cache)
let interiors = region.interiors().iter().map(|interior| {
(interior, surface).transform_with_cache(transform, core, cache)
});

Region::new(exterior, interiors)
Region::new(exterior, interiors).insert(core)
}
}
8 changes: 4 additions & 4 deletions crates/fj-core/src/operations/transform/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{

use super::{TransformCache, TransformObject};

impl TransformObject for Handle<Surface> {
type Transformed = Self;
impl TransformObject for &Handle<Surface> {
type Transformed = Handle<Surface>;

fn transform_with_cache(
self,
Expand All @@ -16,12 +16,12 @@ impl TransformObject for Handle<Surface> {
cache: &mut TransformCache,
) -> 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