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

Extend vertex builder API #1120

Merged
merged 12 commits into from
Sep 20, 2022
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/algorithms/sweep/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ mod tests {

let surface = Surface::xz_plane();
let curve = Curve::builder(&stores, surface).u_axis();
let vertex = Vertex::builder(curve).from_point([0.]);
let vertex = Vertex::builder([0.], curve).build();

let half_edge = (vertex, surface).sweep([0., 0., 1.], &stores);

Expand Down
4 changes: 2 additions & 2 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<'a> HalfEdgeBuilder<'a> {
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

let global_vertex = GlobalVertex::builder()
.from_curve_and_position(&curve, a_curve);
.build_from_curve_and_position(&curve, a_curve);

let surface_vertices = [a_curve, b_curve].map(|point_curve| {
let point_surface =
Expand Down Expand Up @@ -66,7 +66,7 @@ impl<'a> HalfEdgeBuilder<'a> {

let global_vertices = points.map(|position| {
GlobalVertex::builder()
.from_surface_and_position(&self.surface, position)
.build_from_surface_and_position(&self.surface, position)
});

let surface_vertices = {
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ pub use self::{
shell::ShellBuilder,
sketch::SketchBuilder,
solid::SolidBuilder,
vertex::{GlobalVertexBuilder, VertexBuilder},
vertex::{GlobalVertexBuilder, SurfaceVertexBuilder, VertexBuilder},
};
92 changes: 78 additions & 14 deletions crates/fj-kernel/src/builder/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,90 @@ use crate::objects::{Curve, GlobalVertex, Surface, SurfaceVertex, Vertex};
///
/// Also see [`Vertex::builder`].
pub struct VertexBuilder {
/// The position of the [`Vertex`] on the [`Curve`]
pub position: Point<1>,

/// The curve that the [`Vertex`] is defined in
pub curve: Curve,

/// The surface form of the [`Vertex`]
///
/// Can be provided to the builder, if already available, or computed from
/// the position on the [`Curve`].
pub surface_form: Option<SurfaceVertex>,

/// The global form of the [`Vertex`]
///
/// Can be provided to the builder, if already available, or acquired
/// through the surface form.
pub global_form: Option<GlobalVertex>,
}

impl VertexBuilder {
/// Build the [`Vertex`] with the provided surface form
pub fn with_surface_form(mut self, surface_form: SurfaceVertex) -> Self {
self.surface_form = Some(surface_form);
self
}

/// Build the [`Vertex`] with the provided global form
pub fn with_global_form(mut self, global_form: GlobalVertex) -> Self {
self.global_form = Some(global_form);
self
}

/// Build a vertex from a curve position
pub fn from_point(&self, point: impl Into<Point<1>>) -> Vertex {
let point = point.into();
let &surface = self.curve.surface();
pub fn build(self) -> Vertex {
let surface_form = self.surface_form.unwrap_or_else(|| {
SurfaceVertexBuilder {
position: self
.curve
.path()
.point_from_path_coords(self.position),
surface: *self.curve.surface(),
global_form: self.global_form,
}
.build()
});

let global_form =
GlobalVertex::builder().from_curve_and_position(&self.curve, point);
let global_form = *surface_form.global_form();

Vertex::new(self.position, self.curve, surface_form, global_form)
}
}

/// API for building a [`SurfaceVertex`]
///
/// Also see [`SurfaceVertex::builder`].
pub struct SurfaceVertexBuilder {
/// The position of the [`SurfaceVertex`] on the [`Surface`]
pub position: Point<2>,

/// The surface that the [`SurfaceVertex`] is defined in
pub surface: Surface,

/// The global form of the [`SurfaceVertex`]
///
/// Can be provided to the builder, if already available, or computed from
/// the position on the [`Surface`].
pub global_form: Option<GlobalVertex>,
}

impl SurfaceVertexBuilder {
/// Build the [`SurfaceVertex`] with the provided global form
pub fn with_global_form(mut self, global_form: GlobalVertex) -> Self {
self.global_form = Some(global_form);
self
}

let surface_form = SurfaceVertex::new(
self.curve.path().point_from_path_coords(point),
surface,
global_form,
);
/// Finish building the [`SurfaceVertex`]
pub fn build(self) -> SurfaceVertex {
let global_form = self.global_form.unwrap_or_else(|| {
GlobalVertex::builder()
.build_from_surface_and_position(&self.surface, self.position)
});

Vertex::new([0.], self.curve.clone(), surface_form, global_form)
SurfaceVertex::new(self.position, self.surface, global_form)
}
}

Expand All @@ -36,17 +100,17 @@ pub struct GlobalVertexBuilder;

impl GlobalVertexBuilder {
/// Build a [`GlobalVertex`] from a curve and a position on that curve
pub fn from_curve_and_position(
pub fn build_from_curve_and_position(
&self,
curve: &Curve,
position: impl Into<Point<1>>,
) -> GlobalVertex {
let position_surface = curve.path().point_from_path_coords(position);
self.from_surface_and_position(curve.surface(), position_surface)
self.build_from_surface_and_position(curve.surface(), position_surface)
}

/// Build a [`GlobalVertex`] from a surface and a position on that surface
pub fn from_surface_and_position(
pub fn build_from_surface_and_position(
&self,
surface: &Surface,
position: impl Into<Point<2>>,
Expand Down
28 changes: 25 additions & 3 deletions crates/fj-kernel/src/objects/vertex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use fj_math::Point;
use pretty_assertions::assert_eq;

use crate::builder::{GlobalVertexBuilder, VertexBuilder};
use crate::builder::{
GlobalVertexBuilder, SurfaceVertexBuilder, VertexBuilder,
};

use super::{Curve, Surface};

Expand All @@ -20,8 +22,16 @@ pub struct Vertex {

impl Vertex {
/// Build a `Vertex` using [`VertexBuilder`]
pub fn builder(curve: Curve) -> VertexBuilder {
VertexBuilder { curve }
pub fn builder(
position: impl Into<Point<1>>,
curve: Curve,
) -> VertexBuilder {
VertexBuilder {
position: position.into(),
curve,
surface_form: None,
global_form: None,
}
}

/// Construct an instance of `Vertex`
Expand Down Expand Up @@ -80,6 +90,18 @@ pub struct SurfaceVertex {
}

impl SurfaceVertex {
/// Build a `SurfaceVertex` using [`SurfaceVertexBuilder`]
pub fn builder(
position: impl Into<Point<2>>,
surface: Surface,
) -> SurfaceVertexBuilder {
SurfaceVertexBuilder {
position: position.into(),
surface,
global_form: None,
}
}

/// Construct a new instance of `SurfaceVertex`
pub fn new(
position: impl Into<Point<2>>,
Expand Down