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

Reference Surface from Curve #1022

Merged
merged 5 commits into from
Sep 1, 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
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