Skip to content

Commit

Permalink
Merge pull request #1452 from hannobraun/builder
Browse files Browse the repository at this point in the history
Update old-style builder APIs
  • Loading branch information
hannobraun authored Dec 14, 2022
2 parents f78f1e0 + 3e405d2 commit 04ec62a
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 202 deletions.
30 changes: 14 additions & 16 deletions crates/fj-kernel/src/algorithms/sweep/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use fj_math::{Scalar, Vector};
use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
geometry::path::GlobalPath,
insert::Insert,
objects::{Face, Objects, Shell},
partial::{Partial, PartialObject, PartialShell},
services::Service,
storage::Handle,
};
Expand Down Expand Up @@ -74,7 +76,8 @@ impl Sweep for Handle<Face> {
}
}

Shell::builder().with_faces(faces).build(objects)
let faces = faces.into_iter().map(Partial::from).collect();
PartialShell { faces }.build(objects).insert(objects)
}
}

Expand All @@ -84,10 +87,9 @@ mod tests {

use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
builder::{FaceBuilder, HalfEdgeBuilder},
builder::{FaceBuilder, HalfEdgeBuilder, SketchBuilder},
insert::Insert,
objects::Sketch,
partial::{PartialFace, PartialHalfEdge, PartialObject},
partial::{PartialFace, PartialHalfEdge, PartialObject, PartialSketch},
services::Services,
};

Expand All @@ -103,13 +105,11 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xy_plane();
let solid = Sketch::builder()
.with_polygon_from_points(
surface.clone(),
TRIANGLE,
&mut services.objects,
)
let mut sketch = PartialSketch::default();
sketch.add_polygon_from_points(surface.clone(), TRIANGLE);
let solid = sketch
.build(&mut services.objects)
.insert(&mut services.objects)
.sweep(UP, &mut services.objects);

let mut bottom = PartialFace::default();
Expand Down Expand Up @@ -156,13 +156,11 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xy_plane();
let solid = Sketch::builder()
.with_polygon_from_points(
surface.clone(),
TRIANGLE,
&mut services.objects,
)
let mut sketch = PartialSketch::default();
sketch.add_polygon_from_points(surface.clone(), TRIANGLE);
let solid = sketch
.build(&mut services.objects)
.insert(&mut services.objects)
.sweep(DOWN, &mut services.objects);

let mut bottom = PartialFace::default();
Expand Down
5 changes: 4 additions & 1 deletion crates/fj-kernel/src/algorithms/sweep/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use fj_math::Vector;

use crate::{
insert::Insert,
objects::{Objects, Sketch, Solid},
partial::{Partial, PartialObject, PartialSolid},
services::Service,
storage::Handle,
};
Expand All @@ -25,6 +27,7 @@ impl Sweep for Handle<Sketch> {
shells.push(shell);
}

Solid::builder().with_shells(shells).build(objects)
let shells = shells.into_iter().map(Partial::from).collect();
PartialSolid { shells }.build(objects).insert(objects)
}
}
10 changes: 3 additions & 7 deletions crates/fj-kernel/src/builder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
//! API for building objects
// These are the old-style builders that need to be transferred to the partial
// object API. Issue:
// https://github.com/hannobraun/Fornjot/issues/1147
mod shell;
mod sketch;
mod solid;

// These are new-style builders that build on top of the partial object API.
mod curve;
mod cycle;
mod edge;
mod face;
mod shell;
mod sketch;
mod solid;
mod surface;
mod vertex;

Expand Down
97 changes: 39 additions & 58 deletions crates/fj-kernel/src/builder/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,25 @@ use crate::{
builder::{
FaceBuilder, HalfEdgeBuilder, SurfaceBuilder, SurfaceVertexBuilder,
},
insert::Insert,
objects::{Face, FaceSet, HalfEdge, Objects, Shell},
objects::{HalfEdge, Objects},
partial::{
Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject,
Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialShell,
PartialSurface, PartialSurfaceVertex,
},
services::Service,
storage::Handle,
};

/// API for building a [`Shell`]
///
/// Also see [`Shell::builder`].
pub struct ShellBuilder {
/// The faces that make up the [`Shell`]
pub faces: FaceSet,
/// Builder API for [`PartialShell`]
pub trait ShellBuilder {
/// Create a cube from the length of its edges
fn create_cube_from_edge_length(
edge_length: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Self;
}

impl ShellBuilder {
/// Build the [`Shell`] with the provided faces
pub fn with_faces(
mut self,
faces: impl IntoIterator<Item = Handle<Face>>,
) -> Self {
self.faces.extend(faces);
self
}

/// Create a cube from the length of its edges
pub fn with_cube_from_edge_length(
mut self,
impl ShellBuilder for PartialShell {
fn create_cube_from_edge_length(
edge_length: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Self {
Expand All @@ -49,7 +37,7 @@ impl ShellBuilder {
const Z: Scalar = Scalar::ZERO;
let h = edge_length / 2.;

let bottom = {
let bottom_face = {
let surface =
objects.surfaces.xy_plane().translate([Z, Z, -h], objects);

Expand All @@ -62,8 +50,8 @@ impl ShellBuilder {
face
};

let (sides, top_edges) = {
let surfaces = bottom
let (side_faces, top_edges) = {
let side_surfaces = bottom_face
.exterior
.read()
.half_edges
Expand All @@ -79,18 +67,17 @@ impl ShellBuilder {
});
let c = a + [Z, Z, edge_length];

Partial::from_partial(PartialSurface::plane_from_points([
a, b, c,
]))
let surface = PartialSurface::plane_from_points([a, b, c]);
Partial::from_partial(surface)
})
.collect::<Vec<_>>();

let bottoms = bottom
let bottom_edges = bottom_face
.exterior
.read()
.half_edges
.iter()
.zip(&surfaces)
.zip(&side_surfaces)
.map(|(half_edge, surface)| {
let global_edge = half_edge.read().global_form.clone();

Expand Down Expand Up @@ -119,10 +106,10 @@ impl ShellBuilder {
})
.collect::<Vec<_>>();

let sides_up = bottoms
let side_edges_up = bottom_edges
.clone()
.into_iter()
.zip(&surfaces)
.zip(&side_surfaces)
.map(|(bottom, surface): (Partial<HalfEdge>, _)| {
let from_surface = {
let [_, from] = &bottom.read().vertices;
Expand Down Expand Up @@ -153,15 +140,15 @@ impl ShellBuilder {
})
.collect::<Vec<_>>();

let sides_down = {
let mut sides_up_prev = sides_up.clone();
let side_edges_down = {
let mut sides_up_prev = side_edges_up.clone();
sides_up_prev.rotate_right(1);

bottoms
bottom_edges
.clone()
.into_iter()
.zip(sides_up_prev)
.zip(&surfaces)
.zip(&side_surfaces)
.map(
|((bottom, side_up_prev), surface): (
(_, Partial<HalfEdge>),
Expand Down Expand Up @@ -215,10 +202,10 @@ impl ShellBuilder {
.collect::<Vec<_>>()
};

let tops = sides_up
let top_edges = side_edges_up
.clone()
.into_iter()
.zip(sides_down.clone())
.zip(side_edges_down.clone())
.map(|(side_up, side_down): (_, Partial<HalfEdge>)| {
let [_, from] = side_up.read().vertices.clone();
let [to, _] = side_down.read().vertices.clone();
Expand Down Expand Up @@ -248,11 +235,11 @@ impl ShellBuilder {
})
.collect::<Vec<_>>();

let sides = bottoms
let side_faces = bottom_edges
.into_iter()
.zip(sides_up)
.zip(tops.clone())
.zip(sides_down)
.zip(side_edges_up)
.zip(top_edges.clone())
.zip(side_edges_down)
.map(|(((bottom, side_up), top), side_down)| {
let mut cycle = PartialCycle::default();
cycle.half_edges.extend([bottom, side_up, top, side_down]);
Expand All @@ -264,10 +251,10 @@ impl ShellBuilder {
})
.collect::<Vec<_>>();

(sides, tops)
(side_faces, top_edges)
};

let top = {
let top_face = {
let surface = Partial::from(
objects.surfaces.xy_plane().translate([Z, Z, h], objects),
);
Expand Down Expand Up @@ -340,19 +327,13 @@ impl ShellBuilder {
}
};

self.faces.extend(
[bottom]
PartialShell {
faces: [bottom_face]
.into_iter()
.chain(sides)
.chain([top])
.map(|face| face.build(objects).insert(objects)),
);

self
}

/// Build the [`Shell`]
pub fn build(self, objects: &mut Service<Objects>) -> Handle<Shell> {
Shell::new(self.faces).insert(objects)
.chain(side_faces)
.chain([top_face])
.map(Partial::from_partial)
.collect(),
}
}
}
51 changes: 16 additions & 35 deletions crates/fj-kernel/src/builder/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,31 @@
use fj_math::Point;

use crate::{
insert::Insert,
objects::{Face, FaceSet, Objects, Sketch, Surface},
partial::{PartialFace, PartialObject},
services::Service,
storage::Handle,
objects::Surface,
partial::{Partial, PartialFace, PartialSketch},
};

use super::FaceBuilder;

/// API for building a [`Sketch`]
///
/// Also see [`Sketch::builder`].
pub struct SketchBuilder {
/// The faces that make up the [`Sketch`]
pub faces: FaceSet,
/// Builder API for [`PartialSketch`]
pub trait SketchBuilder {
/// Add a polygon to the sketch, created from the provided points
fn add_polygon_from_points(
&mut self,
surface: impl Into<Partial<Surface>>,
points: impl IntoIterator<Item = impl Into<Point<2>>>,
);
}

impl SketchBuilder {
/// Build the [`Sketch`] with the provided faces
pub fn with_faces(
mut self,
faces: impl IntoIterator<Item = Handle<Face>>,
) -> Self {
self.faces.extend(faces);
self
}

/// Construct a polygon from a list of points
pub fn with_polygon_from_points(
mut self,
surface: Handle<Surface>,
impl SketchBuilder for PartialSketch {
fn add_polygon_from_points(
&mut self,
surface: impl Into<Partial<Surface>>,
points: impl IntoIterator<Item = impl Into<Point<2>>>,
objects: &mut Service<Objects>,
) -> Self {
) {
let mut face = PartialFace::default();
face.with_exterior_polygon_from_points(surface, points);
let face = face.build(objects).insert(objects);

self.faces.extend([face]);
self
}

/// Build the [`Sketch`]
pub fn build(self, objects: &mut Service<Objects>) -> Handle<Sketch> {
Sketch::new(self.faces).insert(objects)
self.faces.extend([Partial::from_partial(face)]);
}
}
Loading

0 comments on commit 04ec62a

Please sign in to comment.