Skip to content

Commit

Permalink
Merge pull request #904 from hannobraun/curve
Browse files Browse the repository at this point in the history
Add builder API for `Curve` and `GlobalCurve`
  • Loading branch information
hannobraun authored Aug 2, 2022
2 parents 45be3c4 + 0379fa2 commit 449a654
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 36 deletions.
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
14 changes: 8 additions & 6 deletions crates/fj-kernel/src/algorithms/intersection/surface_surface.rs
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

0 comments on commit 449a654

Please sign in to comment.