Skip to content

Commit

Permalink
Merge pull request #1022 from hannobraun/curve
Browse files Browse the repository at this point in the history
Reference `Surface` from `Curve`
  • Loading branch information
hannobraun authored Sep 1, 2022
2 parents 72be0d5 + 1a674cb commit 9248232
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 53 deletions.
16 changes: 8 additions & 8 deletions crates/fj-kernel/src/algorithms/intersect/curve_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ mod tests {
fn compute_edge_in_front_of_curve_origin() {
let surface = Surface::xy_plane();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[1., -1.], [1., 1.]]);
let edge = Edge::build(surface)
.line_segment_from_points([[1., -1.], [1., 1.]]);

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

Expand All @@ -101,8 +101,8 @@ mod tests {
fn compute_edge_behind_curve_origin() {
let surface = Surface::xy_plane();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., -1.], [-1., 1.]]);
let edge = Edge::build(surface)
.line_segment_from_points([[-1., -1.], [-1., 1.]]);

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

Expand All @@ -118,8 +118,8 @@ mod tests {
fn compute_edge_parallel_to_curve() {
let surface = Surface::xy_plane();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., -1.], [1., -1.]]);
let edge = Edge::build(surface)
.line_segment_from_points([[-1., -1.], [1., -1.]]);

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

Expand All @@ -130,8 +130,8 @@ mod tests {
fn compute_edge_on_curve() {
let surface = Surface::xy_plane();
let curve = Curve::build(surface).u_axis();
let edge = Edge::build()
.line_segment_from_points(&surface, [[-1., 0.], [1., 0.]]);
let edge = Edge::build(surface)
.line_segment_from_points([[-1., 0.], [1., 0.]]);

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

Expand Down
31 changes: 20 additions & 11 deletions crates/fj-kernel/src/algorithms/intersect/surface_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ impl SurfaceSurfaceIntersection {
// Adaptations were made to get the intersection curves in local
// coordinates for each surface.

let planes_parametric =
surfaces.map(PlaneParametric::extract_from_surface);
let [a, b] = planes_parametric
.map(|plane| PlaneConstantNormal::from_parametric_plane(&plane));
let planes_parametric = surfaces.map(|surface| {
let plane = PlaneParametric::extract_from_surface(surface);
(*surface, plane)
});
let [a, b] = planes_parametric.map(|(_, plane)| {
PlaneConstantNormal::from_parametric_plane(&plane)
});

let direction = a.normal.cross(&b.normal);

Expand All @@ -44,13 +47,13 @@ impl SurfaceSurfaceIntersection {

let line = Line::from_origin_and_direction(origin, direction);

let curves = planes_parametric.map(|plane| {
let curves = planes_parametric.map(|(surface, plane)| {
let local = project_line_into_plane(&line, &plane);
let global = CurveKind::Line(Line::from_origin_and_direction(
origin, direction,
));

Curve::new(local, GlobalCurve::from_kind(global))
Curve::new(surface, local, GlobalCurve::from_kind(global))
});

Some(Self {
Expand All @@ -69,16 +72,22 @@ struct PlaneParametric {

impl PlaneParametric {
pub fn extract_from_surface(surface: &Surface) -> Self {
let Surface::SweptCurve(surface) = surface;
let line = match surface.curve {
CurveKind::Line(line) => line,
_ => todo!("Only plane-plane intersection is currently supported."),
let (line, path) = {
let Surface::SweptCurve(surface) = surface;
let line = match surface.curve {
CurveKind::Line(line) => line,
_ => todo!(
"Only plane-plane intersection is currently supported."
),
};

(line, surface.path)
};

Self {
origin: line.origin(),
u: line.direction(),
v: surface.path,
v: path,
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion crates/fj-kernel/src/algorithms/reverse/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ impl Reverse for Curve {
/// orientation, which would then make it possible for curves to be without
/// direction. Then this implementation would not exist.
fn reverse(self) -> Self {
Curve::new(self.kind().reverse(), self.global().reverse())
Curve::new(
*self.surface(),
self.kind().reverse(),
self.global().reverse(),
)
}
}

Expand Down
6 changes: 5 additions & 1 deletion crates/fj-kernel/src/algorithms/reverse/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ fn reverse_local_coordinates_in_cycle<'r>(
}
};

Curve::new(local, *edge.curve().global())
Curve::new(
edge.curve().surface().reverse(),
local,
*edge.curve().global(),
)
};

let vertices = edge.vertices().map(|vertex| {
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn create_non_continuous_side_face(
let global =
GlobalCurve::from_kind(CurveKind::line_from_points(global));

Curve::new(local, global)
Curve::new(surface, local, global)
};

let vertices = VerticesOfEdge::from_vertices([
Expand Down
11 changes: 4 additions & 7 deletions crates/fj-kernel/src/algorithms/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ pub trait TransformObject: Sized {

impl TransformObject for Curve {
fn transform(self, transform: &Transform) -> Self {
// Don't need to transform `self.kind`, as that's in local form.
let surface = self.surface().transform(transform);
let global = self.global().transform(transform);

Curve::new(*self.kind(), global)
// Don't need to transform `self.kind`, as that's in local form.
Curve::new(surface, *self.kind(), global)
}
}

Expand All @@ -52,11 +53,7 @@ impl TransformObject for Cycle {

impl TransformObject for Edge {
fn transform(self, transform: &Transform) -> Self {
let curve = Curve::new(
*self.curve().kind(),
self.curve().global().transform(transform),
);

let curve = self.curve().transform(transform);
let vertices =
self.vertices().map(|vertex| vertex.transform(transform));

Expand Down
1 change: 1 addition & 0 deletions crates/fj-kernel/src/builder/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl CurveBuilder {
);

Curve::new(
self.surface,
CurveKind::Line(local),
GlobalCurve::from_kind(CurveKind::Line(global)),
)
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/builder/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl CycleBuilder {
let points = [points[0], points[1]];

edges.push(
Edge::build().line_segment_from_points(&self.surface, points),
Edge::build(self.surface).line_segment_from_points(points),
);
}

Expand Down
18 changes: 13 additions & 5 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ use crate::objects::{
};

/// API for building an [`Edge`]
pub struct EdgeBuilder;
pub struct EdgeBuilder {
surface: Surface,
}

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

/// Create a circle from the given radius
pub fn circle_from_radius(&self, radius: Scalar) -> Edge {
let curve_local = CurveKind::Circle(Circle::new(
Expand All @@ -24,21 +33,20 @@ impl EdgeBuilder {
)));

Edge::from_curve_and_vertices(
Curve::new(curve_local, curve_global),
Curve::new(self.surface, curve_local, curve_global),
VerticesOfEdge::none(),
)
}

/// Create a line segment from two points
pub fn line_segment_from_points(
&self,
surface: &Surface,
points: [impl Into<Point<2>>; 2],
) -> Edge {
let points = points.map(Into::into);

let global_vertices = points.map(|position| {
let position = surface.point_from_surface_coords(position);
let position = self.surface.point_from_surface_coords(position);
GlobalVertex::from_position(position)
});

Expand All @@ -51,7 +59,7 @@ impl EdgeBuilder {
GlobalCurve::from_kind(kind)
};

Curve::new(curve_local, curve_global)
Curve::new(self.surface, curve_local, curve_global)
};

let vertices = {
Expand Down
18 changes: 8 additions & 10 deletions crates/fj-kernel/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,10 +396,8 @@ mod tests {

#[test]
fn edge() {
let object = Edge::build().line_segment_from_points(
&Surface::xy_plane(),
[[0., 0.], [1., 0.]],
);
let object = Edge::build(Surface::xy_plane())
.line_segment_from_points([[0., 0.], [1., 0.]]);

assert_eq!(1, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
Expand Down Expand Up @@ -474,17 +472,17 @@ mod tests {
fn shell() {
let object = Shell::build().cube_from_edge_length(1.);

assert_eq!(20, object.curve_iter().count());
assert_eq!(24, object.curve_iter().count());
assert_eq!(6, object.cycle_iter().count());
assert_eq!(20, object.edge_iter().count());
assert_eq!(24, object.edge_iter().count());
assert_eq!(6, object.face_iter().count());
assert_eq!(18, object.global_curve_iter().count());
assert_eq!(8, object.global_vertex_iter().count());
assert_eq!(1, object.shell_iter().count());
assert_eq!(0, object.sketch_iter().count());
assert_eq!(0, object.solid_iter().count());
assert_eq!(6, object.surface_iter().count());
assert_eq!(40, object.vertex_iter().count());
assert_eq!(48, object.vertex_iter().count());
}

#[test]
Expand Down Expand Up @@ -514,17 +512,17 @@ mod tests {
fn solid() {
let object = Solid::build().cube_from_edge_length(1.);

assert_eq!(20, object.curve_iter().count());
assert_eq!(24, object.curve_iter().count());
assert_eq!(6, object.cycle_iter().count());
assert_eq!(20, object.edge_iter().count());
assert_eq!(24, object.edge_iter().count());
assert_eq!(6, object.face_iter().count());
assert_eq!(18, object.global_curve_iter().count());
assert_eq!(8, object.global_vertex_iter().count());
assert_eq!(1, object.shell_iter().count());
assert_eq!(0, object.sketch_iter().count());
assert_eq!(1, object.solid_iter().count());
assert_eq!(6, object.surface_iter().count());
assert_eq!(40, object.vertex_iter().count());
assert_eq!(48, object.vertex_iter().count());
}

#[test]
Expand Down
18 changes: 16 additions & 2 deletions crates/fj-kernel/src/objects/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::Surface;
/// A curve, defined in local surface coordinates
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Curve {
surface: Surface,
kind: CurveKind<2>,
global: GlobalCurve,
}
Expand All @@ -18,8 +19,21 @@ impl Curve {
}

/// Construct a new instance of `Curve`
pub fn new(kind: CurveKind<2>, global: GlobalCurve) -> Self {
Self { kind, global }
pub fn new(
surface: Surface,
kind: CurveKind<2>,
global: GlobalCurve,
) -> Self {
Self {
surface,
kind,
global,
}
}

/// Access the surface that this curve is defined in
pub fn surface(&self) -> &Surface {
&self.surface
}

/// Access the kind of this curve
Expand Down
6 changes: 3 additions & 3 deletions crates/fj-kernel/src/objects/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;

use crate::{algorithms::reverse::Reverse, builder::EdgeBuilder};

use super::{Curve, GlobalCurve, GlobalVertex, Vertex};
use super::{Curve, GlobalCurve, GlobalVertex, Surface, Vertex};

/// An edge
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
Expand All @@ -14,8 +14,8 @@ pub struct Edge {

impl Edge {
/// Build an edge using [`EdgeBuilder`]
pub fn build() -> EdgeBuilder {
EdgeBuilder
pub fn build(surface: Surface) -> EdgeBuilder {
EdgeBuilder::new(surface)
}

/// Create a new instance of `Edge`
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-kernel/src/validation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ mod tests {

use crate::{
objects::{
Curve, CurveKind, Edge, GlobalCurve, GlobalVertex, Vertex,
Curve, CurveKind, Edge, GlobalCurve, GlobalVertex, Surface, Vertex,
VerticesOfEdge,
},
validation::{validate, ValidationConfig, ValidationError},
Expand All @@ -146,7 +146,7 @@ mod tests {
let curve_local = CurveKind::line_from_points([[0., 0.], [1., 0.]]);
let curve_global =
GlobalCurve::from_kind(CurveKind::line_from_points([a, b]));
Curve::new(curve_local, curve_global)
Curve::new(Surface::xy_plane(), curve_local, curve_global)
};

let a = GlobalVertex::from_position(a);
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-operations/src/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Shape for fj::Sketch {
// Circles have just a single round edge with no vertices. So
// none need to be added here.

let edge = Edge::build()
let edge = Edge::build(surface)
.circle_from_radius(Scalar::from_f64(circle.radius()));
let cycle = Cycle::new(surface).with_edges([edge]);

Expand Down

0 comments on commit 9248232

Please sign in to comment.