Skip to content

Commit 1b0b171

Browse files
authored
Merge pull request #2428 from hannobraun/geom
Prepare `SurfaceGeom` for the transition to a more flexible geometry representation
2 parents 8146afd + 0dade0e commit 1b0b171

File tree

7 files changed

+59
-38
lines changed

7 files changed

+59
-38
lines changed

crates/fj-core/src/algorithms/approx/curve.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ fn approx_curve(
4848
boundary: CurveBoundary<Point<1>>,
4949
tolerance: impl Into<Tolerance>,
5050
) -> CurveApprox {
51-
let points = match (path, surface.u) {
51+
let SurfaceGeom::Basic { u, .. } = surface;
52+
let points = match (path, u) {
5253
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
5354
approx_circle_on_curved_surface()
5455
}
@@ -110,11 +111,10 @@ fn approx_line_on_any_surface(
110111
.map(|point_curve| [line.point_from_line_coords(point_curve).u]),
111112
);
112113

113-
let approx_u = match surface.u {
114-
GlobalPath::Circle(circle) => {
115-
approx_circle(&circle, range_u, tolerance)
116-
}
117-
GlobalPath::Line(line) => approx_line(&line),
114+
let SurfaceGeom::Basic { u, .. } = surface;
115+
let approx_u = match u {
116+
GlobalPath::Circle(circle) => approx_circle(circle, range_u, tolerance),
117+
GlobalPath::Line(line) => approx_line(line),
118118
};
119119

120120
let mut points = Vec::new();
@@ -216,7 +216,7 @@ mod tests {
216216

217217
#[test]
218218
fn approx_line_on_curved_surface_but_not_along_curve() {
219-
let surface = SurfaceGeom {
219+
let surface = SurfaceGeom::Basic {
220220
u: GlobalPath::circle_from_radius(1.),
221221
v: Vector::from([0., 0., 1.]),
222222
};
@@ -236,7 +236,7 @@ mod tests {
236236

237237
let circle = Circle::from_center_and_radius(Point::origin(), 1.);
238238
let global_path = GlobalPath::Circle(circle);
239-
let surface_geom = SurfaceGeom {
239+
let surface_geom = SurfaceGeom::Basic {
240240
u: global_path,
241241
v: Vector::from([0., 0., 1.]),
242242
};

crates/fj-core/src/algorithms/bounding_volume/face.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::Deref;
33
use fj_math::Aabb;
44

55
use crate::{
6-
geometry::{Geometry, GlobalPath},
6+
geometry::{Geometry, GlobalPath, SurfaceGeom},
77
topology::Face,
88
};
99

@@ -14,16 +14,17 @@ impl super::BoundingVolume<3> for &Face {
1414
.map(|aabb2| {
1515
let surface = geometry.of_surface(self.surface());
1616

17-
match surface.u {
17+
let SurfaceGeom::Basic { u, v } = surface;
18+
match u {
1819
GlobalPath::Circle(circle) => {
1920
// This is not the most precise way to calculate the
2021
// AABB, doing it for the whole circle, but it should
2122
// do.
2223

2324
let aabb_bottom = circle.aabb();
2425
let aabb_top = Aabb {
25-
min: aabb_bottom.min + surface.v,
26-
max: aabb_bottom.max + surface.v,
26+
min: aabb_bottom.min + *v,
27+
max: aabb_bottom.max + *v,
2728
};
2829

2930
aabb_bottom.merged(&aabb_top)

crates/fj-core/src/geometry/geometry.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,21 @@ impl Geometry {
4242

4343
self_.define_surface_inner(
4444
self_.xy_plane.clone(),
45-
SurfaceGeom {
45+
SurfaceGeom::Basic {
4646
u: GlobalPath::x_axis(),
4747
v: Vector::unit_y(),
4848
},
4949
);
5050
self_.define_surface_inner(
5151
self_.xz_plane.clone(),
52-
SurfaceGeom {
52+
SurfaceGeom::Basic {
5353
u: GlobalPath::x_axis(),
5454
v: Vector::unit_z(),
5555
},
5656
);
5757
self_.define_surface_inner(
5858
self_.yz_plane.clone(),
59-
SurfaceGeom {
59+
SurfaceGeom::Basic {
6060
u: GlobalPath::y_axis(),
6161
v: Vector::unit_z(),
6262
},

crates/fj-core/src/geometry/surface.rs

+34-17
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,23 @@ use super::GlobalPath;
66

77
/// The geometry that defines a surface
88
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
9-
pub struct SurfaceGeom {
10-
/// The u-axis of the surface
11-
pub u: GlobalPath,
12-
13-
/// The v-axis of the surface
14-
pub v: Vector<3>,
9+
pub enum SurfaceGeom {
10+
/// # Basic definition of surface geometry
11+
///
12+
/// ## Implementation Note
13+
///
14+
/// At the time of writing, this is the sole variant of `SurfaceGeom`.
15+
/// `SurfaceGeom` simply used to be a struct, identical to this variant.
16+
///
17+
/// This was changed as part of a transition to a new, less basic and more
18+
/// flexible, representation of surface geometry.
19+
Basic {
20+
/// The u-axis of the surface
21+
u: GlobalPath,
22+
23+
/// The v-axis of the surface
24+
v: Vector<3>,
25+
},
1526
}
1627

1728
impl SurfaceGeom {
@@ -21,7 +32,8 @@ impl SurfaceGeom {
2132
point: impl Into<Point<2>>,
2233
) -> Point<3> {
2334
let point = point.into();
24-
self.u.point_from_path_coords([point.u])
35+
let Self::Basic { u, .. } = self;
36+
u.point_from_path_coords([point.u])
2537
+ self.path_to_line().vector_from_line_coords([point.v])
2638
}
2739

@@ -31,31 +43,36 @@ impl SurfaceGeom {
3143
vector: impl Into<Vector<2>>,
3244
) -> Vector<3> {
3345
let vector = vector.into();
34-
self.u.vector_from_path_coords([vector.u])
46+
let Self::Basic { u, .. } = self;
47+
u.vector_from_path_coords([vector.u])
3548
+ self.path_to_line().vector_from_line_coords([vector.v])
3649
}
3750

3851
fn path_to_line(&self) -> Line<3> {
39-
Line::from_origin_and_direction(self.u.origin(), self.v)
52+
let Self::Basic { u, v } = self;
53+
Line::from_origin_and_direction(u.origin(), *v)
4054
}
4155

4256
/// Project the global point into the surface
4357
pub fn project_global_point(&self, point: impl Into<Point<3>>) -> Point<2> {
44-
let GlobalPath::Line(line) = self.u else {
58+
let Self::Basic { u, v } = self;
59+
60+
let GlobalPath::Line(line) = u else {
4561
todo!("Projecting point into non-plane surface is not supported")
4662
};
4763

48-
let plane =
49-
Plane::from_parametric(line.origin(), line.direction(), self.v);
64+
let plane = Plane::from_parametric(line.origin(), line.direction(), *v);
5065
plane.project_point(point)
5166
}
5267

5368
/// Transform the surface geometry
5469
#[must_use]
5570
pub fn transform(self, transform: &Transform) -> Self {
56-
let u = self.u.transform(transform);
57-
let v = transform.transform_vector(&self.v);
58-
Self { u, v }
71+
let Self::Basic { u, v } = self;
72+
73+
let u = u.transform(transform);
74+
let v = transform.transform_vector(&v);
75+
Self::Basic { u, v }
5976
}
6077
}
6178

@@ -68,7 +85,7 @@ mod tests {
6885

6986
#[test]
7087
fn point_from_surface_coords() {
71-
let surface = SurfaceGeom {
88+
let surface = SurfaceGeom::Basic {
7289
u: GlobalPath::Line(Line::from_origin_and_direction(
7390
Point::from([1., 1., 1.]),
7491
Vector::from([0., 2., 0.]),
@@ -84,7 +101,7 @@ mod tests {
84101

85102
#[test]
86103
fn vector_from_surface_coords() {
87-
let surface = SurfaceGeom {
104+
let surface = SurfaceGeom::Basic {
88105
u: GlobalPath::Line(Line::from_origin_and_direction(
89106
Point::from([1., 0., 0.]),
90107
Vector::from([0., 2., 0.]),

crates/fj-core/src/operations/build/surface.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub trait BuildSurface {
3535
core: &mut Core,
3636
) -> Handle<Surface> {
3737
Self::from_geometry(
38-
SurfaceGeom {
38+
SurfaceGeom::Basic {
3939
u: u.into(),
4040
v: v.into(),
4141
},

crates/fj-core/src/operations/sweep/path.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ impl SweepSurfacePath for SurfacePath {
3939
path: impl Into<Vector<3>>,
4040
core: &mut Core,
4141
) -> Handle<Surface> {
42-
match surface.u {
42+
let SurfaceGeom::Basic { u, .. } = surface;
43+
match u {
4344
GlobalPath::Circle(_) => {
4445
// Sweeping a `Curve` creates a `Surface`. The u-axis of that
4546
// `Surface` is a `GlobalPath`, which we are computing below.

crates/fj-core/src/operations/sweep/sketch.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use fj_math::{Scalar, Vector};
22

33
use crate::{
4-
geometry::GlobalPath,
4+
geometry::{GlobalPath, SurfaceGeom},
55
operations::{derive::DeriveFrom, insert::Insert, reverse::Reverse},
66
storage::Handle,
77
topology::{Face, Sketch, Solid, Surface},
@@ -45,17 +45,19 @@ impl SweepSketch for Sketch {
4545
.winding(&core.layers.geometry, self.surface())
4646
.is_ccw());
4747

48+
let SurfaceGeom::Basic { u, v } =
49+
core.layers.geometry.of_surface(&surface);
50+
4851
let is_negative_sweep = {
49-
let u = match core.layers.geometry.of_surface(&surface).u {
52+
let u = match u {
5053
GlobalPath::Circle(_) => todo!(
5154
"Sweeping sketch from a rounded surfaces is not \
5255
supported"
5356
),
5457
GlobalPath::Line(line) => line.direction(),
5558
};
56-
let v = core.layers.geometry.of_surface(&surface).v;
5759

58-
let normal = u.cross(&v);
60+
let normal = u.cross(v);
5961

6062
normal.dot(&path) < Scalar::ZERO
6163
};

0 commit comments

Comments
 (0)