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

Add builder API for Curve and GlobalCurve #904

Merged
merged 6 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions crates/fj-kernel/src/algorithms/intersection/curve_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ impl CurveEdgeIntersection {
mod tests {
use fj_math::Point;

use crate::objects::{CurveKind, Edge, Surface};
use crate::objects::{Curve, Edge, Surface};

use super::CurveEdgeIntersection;

#[test]
fn compute_edge_in_front_of_curve_origin() {
let surface = Surface::xy_plane();
let curve = CurveKind::u_axis();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[1., -1.], [1., 1.]]);

let intersection = CurveEdgeIntersection::compute(&curve, &edge);
let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge);

assert_eq!(
intersection,
Expand All @@ -100,11 +100,11 @@ mod tests {
#[test]
fn compute_edge_behind_curve_origin() {
let surface = Surface::xy_plane();
let curve = CurveKind::u_axis();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., -1.], [-1., 1.]]);

let intersection = CurveEdgeIntersection::compute(&curve, &edge);
let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge);

assert_eq!(
intersection,
Expand All @@ -117,23 +117,23 @@ mod tests {
#[test]
fn compute_edge_parallel_to_curve() {
let surface = Surface::xy_plane();
let curve = CurveKind::u_axis();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., -1.], [1., -1.]]);

let intersection = CurveEdgeIntersection::compute(&curve, &edge);
let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge);

assert!(intersection.is_none());
}

#[test]
fn compute_edge_on_curve() {
let surface = Surface::xy_plane();
let curve = CurveKind::u_axis();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., 0.], [1., 0.]]);

let intersection = CurveEdgeIntersection::compute(&curve, &edge);
let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge);

assert_eq!(
intersection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ mod tests {

use crate::{
algorithms::TransformObject,
objects::{CurveKind, Surface},
objects::{Curve, Surface},
};

use super::SurfaceSurfaceIntersection;
Expand All @@ -163,15 +163,17 @@ mod tests {
None,
);

let expected_xy = CurveKind::u_axis();
let expected_xz = CurveKind::u_axis();
let expected_global = CurveKind::x_axis();
let expected_xy = Curve::build(xy).u_axis();
let expected_xz = Curve::build(xz).u_axis();

assert_eq!(
SurfaceSurfaceIntersection::compute(&xy, &xz),
Some(SurfaceSurfaceIntersection {
local_intersection_curves: [expected_xy, expected_xz],
global_intersection_curve: expected_global,
local_intersection_curves: [
*expected_xy.kind(),
*expected_xz.kind()
],
global_intersection_curve: *expected_xy.global().kind(),
})
);
}
Expand Down
77 changes: 77 additions & 0 deletions crates/fj-kernel/src/builder/curve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use fj_math::{Line, Point, Vector};

use crate::objects::{Curve, CurveKind, GlobalCurve, Surface};

/// API for building a [`Curve`]
pub struct CurveBuilder {
surface: Surface,
}

impl CurveBuilder {
/// Construct a new instance of [`CurveBuilder`]
///
/// Also see [`Curve::build`].
pub fn new(surface: Surface) -> Self {
Self { surface }
}

/// Create a line that represents the u-axis on the surface
pub fn u_axis(&self) -> Curve {
let a = Point::origin();
let b = a + Vector::unit_u();

self.line_from_points([a, b])
}

/// Create a line that represents the v-axis on the surface
pub fn v_axis(&self) -> Curve {
let a = Point::origin();
let b = a + Vector::unit_v();

self.line_from_points([a, b])
}

/// Create a line from the given points
pub fn line_from_points(&self, points: [impl Into<Point<2>>; 2]) -> Curve {
let points = points.map(Into::into);

let local = Line::from_points(points);
let global = Line::from_points(
points.map(|point| self.surface.point_from_surface_coords(point)),
);

Curve::new(
CurveKind::Line(local),
GlobalCurve::from_kind(CurveKind::Line(global)),
)
}
}

/// API for building a [`GlobalCurve`]
pub struct GlobalCurveBuilder;

impl GlobalCurveBuilder {
/// Create a line that represents the x-axis
pub fn x_axis(&self) -> GlobalCurve {
GlobalCurve::from_kind(CurveKind::x_axis())
}

/// Create a line that represents the y-axis
pub fn y_axis(&self) -> GlobalCurve {
GlobalCurve::from_kind(CurveKind::y_axis())
}

/// Create a line that represents the z-axis
pub fn z_axis(&self) -> GlobalCurve {
GlobalCurve::from_kind(CurveKind::z_axis())
}

/// Create a line from the given points
pub fn line_from_points(
&self,
points: [impl Into<Point<3>>; 2],
) -> GlobalCurve {
let line = Line::from_points(points);
GlobalCurve::from_kind(CurveKind::Line(line))
}
}
2 changes: 2 additions & 0 deletions crates/fj-kernel/src/builder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! API for building objects

mod curve;
mod cycle;
mod edge;
mod face;
mod solid;

pub use self::{
curve::{CurveBuilder, GlobalCurveBuilder},
cycle::CycleBuilder,
edge::EdgeBuilder,
face::{FaceBuilder, FacePolygon},
Expand Down
6 changes: 3 additions & 3 deletions crates/fj-kernel/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ impl<T> Iterator for Iter<T> {
#[cfg(test)]
mod tests {
use crate::objects::{
CurveKind, Cycle, Edge, Face, GlobalCurve, GlobalVertex, Sketch, Solid,
Surface, Vertex,
Cycle, Edge, Face, GlobalCurve, GlobalVertex, Sketch, Solid, Surface,
Vertex,
};

use super::ObjectIters as _;
Expand Down Expand Up @@ -384,7 +384,7 @@ mod tests {

#[test]
fn global_curve() {
let object = GlobalCurve::from_kind(CurveKind::x_axis());
let object = GlobalCurve::build().x_axis();

assert_eq!(0, object.cycle_iter().count());
assert_eq!(0, object.edge_iter().count());
Expand Down
32 changes: 14 additions & 18 deletions crates/fj-kernel/src/objects/curve.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use fj_math::{Circle, Line, Point, Transform, Vector};

use crate::builder::{CurveBuilder, GlobalCurveBuilder};

use super::Surface;

/// A curve, defined in local surface coordinates
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Curve {
Expand All @@ -8,6 +12,11 @@ pub struct Curve {
}

impl Curve {
/// Build a curve using [`CurveBuilder`]
pub fn build(surface: Surface) -> CurveBuilder {
CurveBuilder::new(surface)
}

/// Construct a new instance of `Curve`
pub fn new(kind: CurveKind<2>, global: GlobalCurve) -> Self {
Self { kind, global }
Expand All @@ -31,6 +40,11 @@ pub struct GlobalCurve {
}

impl GlobalCurve {
/// Build a curve using [`GlobalCurveBuilder`]
pub fn build() -> GlobalCurveBuilder {
GlobalCurveBuilder
}

/// Construct a `GlobalCurve` from a [`CurveKind<3>`]
pub fn from_kind(kind: CurveKind<3>) -> Self {
Self { kind }
Expand Down Expand Up @@ -110,24 +124,6 @@ impl<const D: usize> CurveKind<D> {
}
}

impl CurveKind<2> {
/// Construct a `Curve` that represents the u-axis
pub fn u_axis() -> Self {
Self::Line(Line {
origin: Point::origin(),
direction: Vector::unit_u(),
})
}

/// Construct a `Curve` that represents the v-axis
pub fn v_axis() -> Self {
Self::Line(Line {
origin: Point::origin(),
direction: Vector::unit_v(),
})
}
}

impl CurveKind<3> {
/// Construct a `Curve` that represents the x-axis
pub fn x_axis() -> Self {
Expand Down