Skip to content

Commit

Permalink
Merge pull request #1718 from hannobraun/build
Browse files Browse the repository at this point in the history
Extract build operations from builder API
  • Loading branch information
hannobraun authored Mar 23, 2023
2 parents b9b64f3 + 29c0203 commit f7b4ca8
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 98 deletions.
46 changes: 3 additions & 43 deletions crates/fj-kernel/src/builder/face.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use fj_interop::{ext::ArrayExt, mesh::Color};
use fj_math::Point;
use fj_interop::mesh::Color;

use crate::{
objects::{Cycle, Face, GlobalEdge, Objects, Surface},
objects::{Face, Objects, Surface},
operations::Insert,
services::Service,
storage::Handle,
};

use super::{CycleBuilder, HalfEdgeBuilder, SurfaceBuilder};
use super::CycleBuilder;

/// Builder API for [`Face`]
pub struct FaceBuilder {
Expand All @@ -28,45 +27,6 @@ impl FaceBuilder {
}
}

/// Create a triangle
pub fn triangle(
points: [impl Into<Point<3>>; 3],
edges: [Option<Handle<GlobalEdge>>; 3],
objects: &mut Service<Objects>,
) -> (Handle<Face>, [Handle<GlobalEdge>; 3]) {
let [a, b, c] = points.map(Into::into);

let surface =
SurfaceBuilder::plane_from_points([a, b, c]).insert(objects);
let (exterior, global_edges) = {
let half_edges = [[a, b], [b, c], [c, a]].zip_ext(edges).map(
|(points, global_form)| {
let mut builder =
HalfEdgeBuilder::line_segment_from_global_points(
points, &surface, None,
);

if let Some(global_form) = global_form {
builder = builder.with_global_form(global_form);
}

builder.build(objects).insert(objects)
},
);

let cycle = Cycle::new(half_edges.clone()).insert(objects);

let global_edges =
half_edges.map(|half_edge| half_edge.global_form().clone());

(cycle, global_edges)
};

let face = Face::new(surface, exterior, [], None).insert(objects);

(face, global_edges)
}

/// Replace the face's exterior cycle
pub fn with_exterior(mut self, exterior: CycleBuilder) -> Self {
self.exterior = exterior;
Expand Down
7 changes: 1 addition & 6 deletions crates/fj-kernel/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,5 @@
mod cycle;
mod edge;
mod face;
mod shell;
mod surface;

pub use self::{
cycle::CycleBuilder, edge::HalfEdgeBuilder, face::FaceBuilder,
shell::ShellBuilder, surface::SurfaceBuilder,
};
pub use self::{cycle::CycleBuilder, edge::HalfEdgeBuilder, face::FaceBuilder};
38 changes: 0 additions & 38 deletions crates/fj-kernel/src/builder/shell.rs

This file was deleted.

66 changes: 66 additions & 0 deletions crates/fj-kernel/src/operations/build/face.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use fj_interop::ext::ArrayExt;
use fj_math::Point;

use crate::{
builder::HalfEdgeBuilder,
objects::{Cycle, Face, GlobalEdge, Objects, Surface},
operations::Insert,
services::Service,
storage::Handle,
};

use super::BuildSurface;

/// Build a [`Face`]
pub trait BuildFace {
/// Build a triangle
fn triangle(
points: [impl Into<Point<3>>; 3],
edges: [Option<Handle<GlobalEdge>>; 3],
objects: &mut Service<Objects>,
) -> Triangle {
let [a, b, c] = points.map(Into::into);

let surface = Surface::plane_from_points([a, b, c]).insert(objects);
let (exterior, edges) = {
let half_edges = [[a, b], [b, c], [c, a]].zip_ext(edges).map(
|(points, global_form)| {
let mut builder =
HalfEdgeBuilder::line_segment_from_global_points(
points, &surface, None,
);

if let Some(global_form) = global_form {
builder = builder.with_global_form(global_form);
}

builder.build(objects).insert(objects)
},
);

let cycle = Cycle::new(half_edges.clone()).insert(objects);

let global_edges =
half_edges.map(|half_edge| half_edge.global_form().clone());

(cycle, global_edges)
};

let face = Face::new(surface, exterior, [], None);

Triangle { face, edges }
}
}

impl BuildFace for Face {}

/// A triangle
///
/// Returned by [`BuildFace::triangle`].
pub struct Triangle {
/// The face that forms the triangle
pub face: Face,

/// The edges of the triangle
pub edges: [Handle<GlobalEdge>; 3],
}
9 changes: 9 additions & 0 deletions crates/fj-kernel/src/operations/build/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod face;
mod shell;
mod surface;

pub use self::{
face::{BuildFace, Triangle},
shell::BuildShell,
surface::BuildSurface,
};
41 changes: 41 additions & 0 deletions crates/fj-kernel/src/operations/build/shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use fj_math::Point;

use crate::{
objects::{Face, Objects, Shell},
operations::Insert,
services::Service,
};

use super::{BuildFace, Triangle};

/// Build a [`Shell`]
pub trait BuildShell {
/// Build a tetrahedron from the provided points
fn tetrahedron(
points: [impl Into<Point<3>>; 4],
objects: &mut Service<Objects>,
) -> Shell {
let [a, b, c, d] = points.map(Into::into);

let Triangle {
face: base,
edges: [ab, bc, ca],
} = Face::triangle([a, b, c], [None, None, None], objects);
let Triangle {
face: side_a,
edges: [_, bd, da],
} = Face::triangle([a, b, d], [Some(ab), None, None], objects);
let Triangle {
face: side_b,
edges: [_, _, dc],
} = Face::triangle([c, a, d], [Some(ca), Some(da), None], objects);
let Triangle { face: side_c, .. } =
Face::triangle([b, c, d], [Some(bc), Some(dc), Some(bd)], objects);

let faces =
[base, side_a, side_b, side_c].map(|face| face.insert(objects));
Shell::new(faces)
}
}

impl BuildShell for Shell {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ use crate::{
objects::Surface,
};

/// Builder API for [`Surface`]
pub struct SurfaceBuilder {}

impl SurfaceBuilder {
/// Create a plane from the provided points
pub fn plane_from_points(points: [impl Into<Point<3>>; 3]) -> Surface {
/// Build a [`Surface`]
pub trait BuildSurface {
/// Build a plane from the provided points
fn plane_from_points(points: [impl Into<Point<3>>; 3]) -> Surface {
let [a, b, c] = points.map(Into::into);

let geometry = SurfaceGeometry {
Expand All @@ -21,3 +19,5 @@ impl SurfaceBuilder {
Surface::new(geometry)
}
}

impl BuildSurface for Surface {}
6 changes: 5 additions & 1 deletion crates/fj-kernel/src/operations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Operations to update shapes
mod build;
mod insert;

pub use self::insert::Insert;
pub use self::{
build::{BuildFace, BuildShell, BuildSurface, Triangle},
insert::Insert,
};
8 changes: 4 additions & 4 deletions crates/fj-kernel/src/validate/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ impl ShellValidationError {
mod tests {
use crate::{
assert_contains_err,
builder::{CycleBuilder, FaceBuilder, ShellBuilder},
builder::{CycleBuilder, FaceBuilder},
objects::Shell,
operations::Insert,
operations::{BuildShell, Insert},
services::Services,
validate::{shell::ShellValidationError, Validate, ValidationError},
};
Expand All @@ -204,7 +204,7 @@ mod tests {
fn coincident_not_identical() -> anyhow::Result<()> {
let mut services = Services::new();

let valid = ShellBuilder::tetrahedron(
let valid = Shell::tetrahedron(
[[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
&mut services.objects,
);
Expand Down Expand Up @@ -246,7 +246,7 @@ mod tests {
fn shell_not_watertight() -> anyhow::Result<()> {
let mut services = Services::new();

let valid = ShellBuilder::tetrahedron(
let valid = Shell::tetrahedron(
[[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
&mut services.objects,
);
Expand Down

0 comments on commit f7b4ca8

Please sign in to comment.