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

Implement Replace operation for partial object API #1360

Merged
merged 12 commits into from
Nov 16, 2022
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