Skip to content

Commit

Permalink
Merge pull request #1360 from hannobraun/replace
Browse files Browse the repository at this point in the history
Implement `Replace` operation for partial object API
  • Loading branch information
hannobraun authored Nov 16, 2022
2 parents 0467dae + 6622fd3 commit ccaef87
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 78 deletions.
86 changes: 51 additions & 35 deletions crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ mod tests {
builder::HalfEdgeBuilder,
insert::Insert,
objects::{Cycle, Face, HalfEdge, Objects},
partial::{HasPartial, PartialSurfaceVertex, PartialVertex},
partial::{HasPartial, PartialSurfaceVertex, PartialVertex, Replace},
};

#[test]
Expand Down Expand Up @@ -228,26 +228,34 @@ mod tests {
)
.build(&objects)?
.insert(&objects)?;
let side_up = HalfEdge::partial()
.with_surface(surface.clone())
.with_back_vertex(PartialVertex {
surface_form: bottom.front().surface_form().clone().into(),
..Default::default()
})
.with_front_vertex(PartialVertex {
surface_form: PartialSurfaceVertex {
position: Some([1., 1.].into()),
let side_up = {
let mut side_up = HalfEdge::partial();
side_up.replace(surface.clone());
side_up
.with_back_vertex(PartialVertex {
surface_form: bottom
.front()
.surface_form()
.clone()
.into(),
..Default::default()
}
.into(),
..Default::default()
})
.update_as_line_segment()
.build(&objects)?
.insert(&objects)?;
let top = HalfEdge::partial()
.with_surface(surface.clone())
.with_back_vertex(PartialVertex {
})
.with_front_vertex(PartialVertex {
surface_form: PartialSurfaceVertex {
position: Some([1., 1.].into()),
..Default::default()
}
.into(),
..Default::default()
})
.update_as_line_segment()
.build(&objects)?
.insert(&objects)?
};
let top = {
let mut top = HalfEdge::partial();
top.replace(surface.clone());
top.with_back_vertex(PartialVertex {
surface_form: PartialSurfaceVertex {
position: Some([0., 1.].into()),
..Default::default()
Expand All @@ -262,21 +270,29 @@ mod tests {
.update_as_line_segment()
.build(&objects)?
.insert(&objects)?
.reverse(&objects)?;
let side_down = HalfEdge::partial()
.with_surface(surface)
.with_back_vertex(PartialVertex {
surface_form: bottom.back().surface_form().clone().into(),
..Default::default()
})
.with_front_vertex(PartialVertex {
surface_form: top.front().surface_form().clone().into(),
..Default::default()
})
.update_as_line_segment()
.build(&objects)?
.insert(&objects)?
.reverse(&objects)?;
.reverse(&objects)?
};
let side_down = {
let mut side_down = HalfEdge::partial();
side_down.replace(surface);
side_down
.with_back_vertex(PartialVertex {
surface_form: bottom
.back()
.surface_form()
.clone()
.into(),
..Default::default()
})
.with_front_vertex(PartialVertex {
surface_form: top.front().surface_form().clone().into(),
..Default::default()
})
.update_as_line_segment()
.build(&objects)?
.insert(&objects)?
.reverse(&objects)?
};

let cycle = objects
.cycles
Expand Down
9 changes: 4 additions & 5 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
objects::{Curve, Objects, Surface, Vertex, VerticesInNormalizedOrder},
partial::{
MaybePartial, MergeWith, PartialGlobalEdge, PartialHalfEdge,
PartialSurfaceVertex, PartialVertex,
PartialSurfaceVertex, PartialVertex, Replace,
},
storage::Handle,
validate::ValidationError,
Expand Down Expand Up @@ -94,7 +94,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
}

fn update_as_line_segment_from_points(
self,
mut self,
surface: Handle<Surface>,
points: [impl Into<Point<2>>; 2],
) -> Self {
Expand All @@ -111,9 +111,8 @@ impl HalfEdgeBuilder for PartialHalfEdge {
}
});

self.with_surface(surface)
.with_vertices(vertices)
.update_as_line_segment()
self.replace(surface);
self.with_vertices(vertices).update_as_line_segment()
}

fn update_as_line_segment(self) -> Self {
Expand Down
26 changes: 25 additions & 1 deletion crates/fj-kernel/src/partial/maybe_partial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use fj_math::Point;

use crate::{
geometry::{path::SurfacePath, surface::SurfaceGeometry},
get::Get,
insert::Insert,
objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Expand All @@ -11,7 +12,7 @@ use crate::{
validate::{Validate, ValidationError},
};

use super::{HasPartial, MergeWith, Partial};
use super::{HasPartial, MergeWith, Partial, Replace};

/// Can be used everywhere either a partial or full objects are accepted
///
Expand Down Expand Up @@ -125,6 +126,29 @@ where
}
}

impl<T, R> Replace<R> for MaybePartial<T>
where
T: HasPartial + Get<R>,
T::Partial: Replace<R>,
{
fn replace(&mut self, object: Handle<R>) -> &mut Self {
match self {
Self::Full(full) => {
if full.get().id() != object.id() {
let mut partial = full.to_partial();
partial.replace(object);
*self = Self::Partial(partial);
}
}
Self::Partial(partial) => {
partial.replace(object);
}
}

self
}
}

impl<T> From<Handle<T>> for MaybePartial<T>
where
T: HasPartial,
Expand Down
2 changes: 2 additions & 0 deletions crates/fj-kernel/src/partial/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
mod maybe_partial;
mod merge;
mod objects;
mod replace;
mod traits;

pub use self::{
Expand All @@ -50,5 +51,6 @@ pub use self::{
surface::PartialSurface,
vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex},
},
replace::Replace,
traits::{HasPartial, Partial},
};
9 changes: 8 additions & 1 deletion crates/fj-kernel/src/partial/objects/curve.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
geometry::path::SurfacePath,
objects::{Curve, GlobalCurve, Objects, Surface},
partial::{MaybePartial, MergeWith},
partial::{MaybePartial, MergeWith, Replace},
storage::Handle,
validate::ValidationError,
};
Expand Down Expand Up @@ -46,6 +46,13 @@ impl MergeWith for PartialCurve {
}
}

impl Replace<Surface> for PartialCurve {
fn replace(&mut self, surface: Handle<Surface>) -> &mut Self {
self.surface = Some(surface);
self
}
}

impl From<&Curve> for PartialCurve {
fn from(curve: &Curve) -> Self {
Self {
Expand Down
12 changes: 8 additions & 4 deletions crates/fj-kernel/src/partial/objects/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{
builder::HalfEdgeBuilder,
objects::{Cycle, HalfEdge, Objects, Surface},
partial::{MaybePartial, MergeWith, PartialHalfEdge, PartialVertex},
partial::{
MaybePartial, MergeWith, PartialHalfEdge, PartialVertex, Replace,
},
storage::Handle,
validate::ValidationError,
};
Expand Down Expand Up @@ -56,9 +58,11 @@ impl PartialCycle {
pub fn with_surface(mut self, surface: Option<Handle<Surface>>) -> Self {
if let Some(surface) = surface {
for half_edge in &mut self.half_edges {
*half_edge = half_edge.clone().update_partial(|half_edge| {
half_edge.with_surface(surface.clone())
});
*half_edge =
half_edge.clone().update_partial(|mut half_edge| {
half_edge.replace(surface.clone());
half_edge
});
}
}
self
Expand Down
38 changes: 13 additions & 25 deletions crates/fj-kernel/src/partial/objects/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Surface, Vertex,
},
partial::{MaybePartial, MergeWith, PartialCurve, PartialVertex},
partial::{MaybePartial, MergeWith, PartialCurve, PartialVertex, Replace},
storage::Handle,
validate::ValidationError,
};
Expand All @@ -27,30 +27,6 @@ pub struct PartialHalfEdge {
}

impl PartialHalfEdge {
/// Update the partial half-edge with the given surface
pub fn with_surface(mut self, surface: Handle<Surface>) -> Self {
self.curve = self.curve.update_partial(|mut curve| {
curve.surface = Some(surface.clone());
curve
});

self.vertices = self.vertices.map(|vertex| {
vertex.update_partial(|mut vertex| {
let surface_form = vertex.surface_form.clone().update_partial(
|mut surface_vertex| {
surface_vertex.surface = Some(surface.clone());
surface_vertex
},
);

vertex.surface_form = surface_form;
vertex
})
});

self
}

/// Update the partial half-edge with the given curve
pub fn with_curve(mut self, curve: impl Into<MaybePartial<Curve>>) -> Self {
self.curve = curve.into();
Expand Down Expand Up @@ -127,6 +103,18 @@ impl MergeWith for PartialHalfEdge {
}
}

impl Replace<Surface> for PartialHalfEdge {
fn replace(&mut self, surface: Handle<Surface>) -> &mut Self {
self.curve.replace(surface.clone());

for vertex in &mut self.vertices {
vertex.replace(surface.clone());
}

self
}
}

impl From<&HalfEdge> for PartialHalfEdge {
fn from(half_edge: &HalfEdge) -> Self {
let [back_vertex, front_vertex] =
Expand Down
16 changes: 15 additions & 1 deletion crates/fj-kernel/src/partial/objects/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use fj_math::Point;
use crate::{
builder::GlobalVertexBuilder,
objects::{Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex},
partial::{MaybePartial, MergeWith},
partial::{MaybePartial, MergeWith, Replace},
storage::Handle,
validate::ValidationError,
};
Expand Down Expand Up @@ -67,6 +67,13 @@ impl MergeWith for PartialVertex {
}
}

impl Replace<Surface> for PartialVertex {
fn replace(&mut self, surface: Handle<Surface>) -> &mut Self {
self.surface_form.replace(surface);
self
}
}

impl From<&Vertex> for PartialVertex {
fn from(vertex: &Vertex) -> Self {
Self {
Expand Down Expand Up @@ -129,6 +136,13 @@ impl MergeWith for PartialSurfaceVertex {
}
}

impl Replace<Surface> for PartialSurfaceVertex {
fn replace(&mut self, surface: Handle<Surface>) -> &mut Self {
self.surface = Some(surface);
self
}
}

impl From<&SurfaceVertex> for PartialSurfaceVertex {
fn from(surface_vertex: &SurfaceVertex) -> Self {
Self {
Expand Down
20 changes: 20 additions & 0 deletions crates/fj-kernel/src/partial/replace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::storage::Handle;

/// Recursively replace a (partial) object referenced by another partial object
pub trait Replace<T> {
/// Recursively replace the referenced object
fn replace(&mut self, object: Handle<T>) -> &mut Self;
}

impl<T, R, const N: usize> Replace<T> for [R; N]
where
R: Replace<T>,
{
fn replace(&mut self, object: Handle<T>) -> &mut Self {
for item in self.iter_mut() {
item.replace(object.clone());
}

self
}
}
15 changes: 9 additions & 6 deletions crates/fj-operations/src/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use fj_kernel::{
builder::{FaceBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{Cycle, Face, HalfEdge, Objects, Sketch},
partial::HasPartial,
partial::{HasPartial, Replace},
validate::ValidationError,
};
use fj_math::{Aabb, Point};
Expand All @@ -27,11 +27,14 @@ impl Shape for fj::Sketch {
// Circles have just a single round edge with no vertices. So
// none need to be added here.

let half_edge = HalfEdge::partial()
.with_surface(surface)
.update_as_circle_from_radius(circle.radius(), objects)?
.build(objects)?
.insert(objects)?;
let half_edge = {
let mut half_edge = HalfEdge::partial();
half_edge.replace(surface);
half_edge
.update_as_circle_from_radius(circle.radius(), objects)?
.build(objects)?
.insert(objects)?
};
let cycle = objects.cycles.insert(Cycle::new([half_edge]))?;

Face::partial()
Expand Down

0 comments on commit ccaef87

Please sign in to comment.