Skip to content

Commit

Permalink
Merge pull request #2237 from hannobraun/surface
Browse files Browse the repository at this point in the history
Don't expect `Surface`/`Handle<Surface>` where `SurfaceGeometry` will do
  • Loading branch information
hannobraun authored Feb 23, 2024
2 parents 1044d72 + 7cb44bf commit bf49a6c
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 143 deletions.
140 changes: 70 additions & 70 deletions crates/fj-core/src/algorithms/approx/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::collections::BTreeMap;
use fj_math::Point;

use crate::{
geometry::{CurveBoundary, GlobalPath, SurfacePath},
objects::{Curve, Surface},
geometry::{CurveBoundary, GlobalPath, SurfaceGeometry, SurfacePath},
objects::Curve,
storage::{Handle, HandleWrapper},
Core,
};
Expand All @@ -17,7 +17,7 @@ impl Approx
for (
&Handle<Curve>,
SurfacePath,
&Surface,
&SurfaceGeometry,
CurveBoundary<Point<1>>,
)
{
Expand Down Expand Up @@ -51,7 +51,7 @@ impl Approx

fn approx_curve(
path: &SurfacePath,
surface: &Surface,
surface: &SurfaceGeometry,
boundary: CurveBoundary<Point<1>>,
tolerance: impl Into<Tolerance>,
core: &mut Core,
Expand All @@ -62,63 +62,63 @@ fn approx_curve(
// This will probably all be unified eventually, as `SurfacePath` and
// `GlobalPath` grow APIs that are better suited to implementing this code
// in a more abstract way.
let points =
match (path, surface.geometry().u) {
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
todo!(
let points = match (path, surface.u) {
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
todo!(
"Approximating a circle on a curved surface not supported yet."
)
}
(SurfacePath::Circle(_), GlobalPath::Line(_)) => {
(path, boundary)
.approx_with_cache(tolerance, &mut (), core)
.into_iter()
.map(|(point_curve, point_surface)| {
// We're throwing away `point_surface` here, which is a
// bit weird, as we're recomputing it later (outside of
// this function).
//
// It should be fine though:
//
// 1. We're throwing this version away, so there's no
// danger of inconsistency between this and the later
// version.
// 2. This version should have been computed using the
// same path and parameters and the later version
// will be, so they should be the same anyway.
// 3. Not all other cases handled in this function have
// a surface point available, so it needs to be
// computed later anyway, in the general case.

let point_global =
surface.point_from_surface_coords(point_surface);
(point_curve, point_global)
})
.collect()
}
(SurfacePath::Line(line), _) => {
let range_u =
CurveBoundary::from(boundary.inner.map(|point_curve| {
[path.point_from_path_coords(point_curve).u]
}));

let approx_u = (surface.u, range_u).approx_with_cache(
tolerance,
&mut (),
core,
);

let mut points = Vec::new();
for (u, _) in approx_u {
let t = (u.t - line.origin().u) / line.direction().u;
let point_surface = path.point_from_path_coords([t]);
let point_global =
surface.point_from_surface_coords(point_surface);
points.push((u, point_global));
}
(SurfacePath::Circle(_), GlobalPath::Line(_)) => {
(path, boundary)
.approx_with_cache(tolerance, &mut (), core)
.into_iter()
.map(|(point_curve, point_surface)| {
// We're throwing away `point_surface` here, which is a
// bit weird, as we're recomputing it later (outside of
// this function).
//
// It should be fine though:
//
// 1. We're throwing this version away, so there's no
// danger of inconsistency between this and the later
// version.
// 2. This version should have been computed using the
// same path and parameters and the later version
// will be, so they should be the same anyway.
// 3. Not all other cases handled in this function have
// a surface point available, so it needs to be
// computed later anyway, in the general case.

let point_global = surface
.geometry()
.point_from_surface_coords(point_surface);
(point_curve, point_global)
})
.collect()
}
(SurfacePath::Line(line), _) => {
let range_u =
CurveBoundary::from(boundary.inner.map(|point_curve| {
[path.point_from_path_coords(point_curve).u]
}));

let approx_u = (surface.geometry().u, range_u)
.approx_with_cache(tolerance, &mut (), core);

let mut points = Vec::new();
for (u, _) in approx_u {
let t = (u.t - line.origin().u) / line.direction().u;
let point_surface = path.point_from_path_coords([t]);
let point_global = surface
.geometry()
.point_from_surface_coords(point_surface);
points.push((u, point_global));
}

points
}
};

points
}
};

let points = points
.into_iter()
Expand Down Expand Up @@ -183,14 +183,14 @@ impl CurveApproxCache {

#[cfg(test)]
mod tests {
use std::{f64::consts::TAU, ops::Deref};
use std::f64::consts::TAU;

use pretty_assertions::assert_eq;

use crate::{
algorithms::approx::{Approx, ApproxPoint},
geometry::{CurveBoundary, GlobalPath, SurfaceGeometry, SurfacePath},
objects::{Curve, Surface},
objects::Curve,
operations::insert::Insert,
Core,
};
Expand All @@ -203,10 +203,10 @@ mod tests {
let (surface_path, boundary) =
SurfacePath::line_from_points([[1., 1.], [2., 1.]]);
let boundary = CurveBoundary::from(boundary);
let surface = core.layers.objects.surfaces.xz_plane();
let surface = core.layers.objects.surfaces.xz_plane().geometry();

let tolerance = 1.;
let approx = (&curve, surface_path, surface.deref(), boundary)
let approx = (&curve, surface_path, &surface, boundary)
.approx(tolerance, &mut core);

assert_eq!(approx.points, vec![]);
Expand All @@ -220,10 +220,10 @@ mod tests {
let (surface_path, boundary) =
SurfacePath::line_from_points([[1., 1.], [2., 1.]]);
let boundary = CurveBoundary::from(boundary);
let surface = Surface::new(SurfaceGeometry {
let surface = SurfaceGeometry {
u: GlobalPath::circle_from_radius(1.),
v: [0., 0., 1.].into(),
});
};

let tolerance = 1.;
let approx = (&curve, surface_path, &surface, boundary)
Expand All @@ -243,10 +243,10 @@ mod tests {
([TAU], [TAU, 1.]),
]);
let boundary = CurveBoundary::from([[0.], [TAU]]);
let surface = Surface::new(SurfaceGeometry {
let surface = SurfaceGeometry {
u: global_path,
v: [0., 0., 1.].into(),
});
};

let tolerance = 1.;
let approx = (&curve, surface_path, &surface, boundary)
Expand All @@ -259,7 +259,7 @@ mod tests {
let point_surface =
surface_path.point_from_path_coords(point_local);
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
surface.point_from_surface_coords(point_surface);
ApproxPoint::new(point_local, point_global)
})
.collect::<Vec<_>>();
Expand All @@ -274,10 +274,10 @@ mod tests {
let surface_path =
SurfacePath::circle_from_center_and_radius([0., 0.], 1.);
let boundary = CurveBoundary::from([[0.], [TAU]]);
let surface = core.layers.objects.surfaces.xz_plane();
let surface = core.layers.objects.surfaces.xz_plane().geometry();

let tolerance = 1.;
let approx = (&curve, surface_path, surface.deref(), boundary)
let approx = (&curve, surface_path, &surface, boundary)
.approx(tolerance, &mut core);

let expected_approx = (&surface_path, boundary)
Expand All @@ -287,7 +287,7 @@ mod tests {
let point_surface =
surface_path.point_from_path_coords(point_local);
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
surface.point_from_surface_coords(point_surface);
ApproxPoint::new(point_local, point_global)
})
.collect::<Vec<_>>();
Expand Down
7 changes: 2 additions & 5 deletions crates/fj-core/src/algorithms/approx/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ use std::ops::Deref;

use fj_math::Segment;

use crate::{
objects::{Cycle, Surface},
Core,
};
use crate::{geometry::SurfaceGeometry, objects::Cycle, Core};

use super::{
edge::{HalfEdgeApprox, HalfEdgeApproxCache},
Approx, ApproxPoint, Tolerance,
};

impl Approx for (&Cycle, &Surface) {
impl Approx for (&Cycle, &SurfaceGeometry) {
type Approximation = CycleApprox;
type Cache = HalfEdgeApproxCache;

Expand Down
12 changes: 4 additions & 8 deletions crates/fj-core/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
//! approximations are usually used to build cycle approximations, and this way,
//! the caller doesn't have to deal with duplicate vertices.
use crate::{
objects::{HalfEdge, Surface},
Core,
};
use crate::{geometry::SurfaceGeometry, objects::HalfEdge, Core};

use super::{
curve::CurveApproxCache, vertex::VertexApproxCache, Approx, ApproxPoint,
Tolerance,
};

impl Approx for (&HalfEdge, &Surface) {
impl Approx for (&HalfEdge, &SurfaceGeometry) {
type Approximation = HalfEdgeApprox;
type Cache = HalfEdgeApproxCache;

Expand All @@ -33,9 +30,8 @@ impl Approx for (&HalfEdge, &Surface) {
{
Some(position) => position,
None => {
let position_global = surface
.geometry()
.point_from_surface_coords(start_position_surface);
let position_global =
surface.point_from_surface_coords(start_position_surface);
cache
.start_position
.insert(edge.start_vertex().clone(), position_global)
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-core/src/algorithms/approx/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ impl Approx for &Face {
// it have nothing to do with its curvature.

let exterior =
(self.region().exterior().deref(), self.surface().deref())
(self.region().exterior().deref(), &self.surface().geometry())
.approx_with_cache(tolerance, cache, core);

let mut interiors = BTreeSet::new();
for cycle in self.region().interiors() {
let cycle = (cycle.deref(), self.surface().deref())
let cycle = (cycle.deref(), &self.surface().geometry())
.approx_with_cache(tolerance, cache, core);
interiors.insert(cycle);
}
Expand Down
15 changes: 1 addition & 14 deletions crates/fj-core/src/algorithms/approx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::{

use fj_math::Point;

use crate::{objects::Surface, Core};
use crate::Core;

pub use self::tolerance::{InvalidTolerance, Tolerance};

Expand Down Expand Up @@ -79,19 +79,6 @@ impl<const D: usize> ApproxPoint<D> {
}
}

impl ApproxPoint<2> {
/// Create an instance of `ApproxPoint` from a surface point
pub fn from_surface_point(
point_surface: impl Into<Point<2>>,
surface: &Surface,
) -> Self {
let point_surface = point_surface.into();
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
ApproxPoint::new(point_surface, point_global)
}
}

impl<const D: usize> Eq for ApproxPoint<D> {}

impl<const D: usize> PartialEq for ApproxPoint<D> {
Expand Down
7 changes: 4 additions & 3 deletions crates/fj-core/src/operations/sweep/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use fj_interop::Color;
use fj_math::Vector;

use crate::{
objects::{Cycle, Face, Surface},
geometry::SurfaceGeometry,
objects::{Cycle, Face},
operations::{
build::BuildCycle, join::JoinCycle, sweep::half_edge::SweepHalfEdge,
},
Expand Down Expand Up @@ -37,7 +38,7 @@ pub trait SweepCycle {
/// operation is called in, and therefore falls outside of its scope.
fn sweep_cycle(
&self,
surface: &Surface,
surface: &SurfaceGeometry,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
Expand All @@ -48,7 +49,7 @@ pub trait SweepCycle {
impl SweepCycle for Cycle {
fn sweep_cycle(
&self,
surface: &Surface,
surface: &SurfaceGeometry,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
Expand Down
7 changes: 4 additions & 3 deletions crates/fj-core/src/operations/sweep/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use fj_interop::{ext::ArrayExt, Color};
use fj_math::{Point, Scalar, Vector};

use crate::{
objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex},
geometry::SurfaceGeometry,
objects::{Cycle, Face, HalfEdge, Region, Vertex},
operations::{
build::{BuildCycle, BuildHalfEdge},
insert::Insert,
Expand Down Expand Up @@ -37,7 +38,7 @@ pub trait SweepHalfEdge {
fn sweep_half_edge(
&self,
end_vertex: Handle<Vertex>,
surface: &Surface,
surface: &SurfaceGeometry,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
Expand All @@ -49,7 +50,7 @@ impl SweepHalfEdge for HalfEdge {
fn sweep_half_edge(
&self,
end_vertex: Handle<Vertex>,
surface: &Surface,
surface: &SurfaceGeometry,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
Expand Down
Loading

0 comments on commit bf49a6c

Please sign in to comment.