Skip to content

Commit

Permalink
Merge pull request #1596 from hannobraun/surface
Browse files Browse the repository at this point in the history
Move reference to `Surface` from `Curve` to `HalfEdge`
  • Loading branch information
hannobraun authored Feb 17, 2023
2 parents c41f9cf + dd9b834 commit abef26e
Show file tree
Hide file tree
Showing 19 changed files with 117 additions and 159 deletions.
61 changes: 23 additions & 38 deletions crates/fj-kernel/src/algorithms/approx/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ use std::collections::BTreeMap;

use crate::{
geometry::path::{GlobalPath, SurfacePath},
objects::{Curve, GlobalCurve},
objects::{Curve, GlobalCurve, Surface},
storage::{Handle, ObjectId},
};

use super::{path::RangeOnPath, Approx, ApproxPoint, Tolerance};

impl Approx for (&Handle<Curve>, RangeOnPath) {
impl Approx for (&Handle<Curve>, &Surface, RangeOnPath) {
type Approximation = CurveApprox;
type Cache = CurveCache;

Expand All @@ -28,13 +28,14 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {
tolerance: impl Into<Tolerance>,
cache: &mut Self::Cache,
) -> Self::Approximation {
let (curve, range) = self;
let (curve, surface, range) = self;

let global_curve = curve.global_form().clone();
let global_curve_approx = match cache.get(global_curve.clone(), range) {
Some(approx) => approx,
None => {
let approx = approx_global_curve(curve, range, tolerance);
let approx =
approx_global_curve(curve, surface, range, tolerance);
cache.insert(global_curve, range, approx)
}
};
Expand All @@ -53,6 +54,7 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {

fn approx_global_curve(
curve: &Curve,
surface: &Surface,
range: RangeOnPath,
tolerance: impl Into<Tolerance>,
) -> GlobalCurveApprox {
Expand All @@ -62,7 +64,7 @@ fn approx_global_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 (curve.path(), curve.surface().geometry().u) {
let points = match (curve.path(), surface.geometry().u) {
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
todo!(
"Approximating a circle on a curved surface not supported yet."
Expand All @@ -88,8 +90,7 @@ fn approx_global_curve(
// surface point available, so it needs to be computed
// later anyway, in the general case.

let point_global = curve
.surface()
let point_global = surface
.geometry()
.point_from_surface_coords(point_surface);
(point_curve, point_global)
Expand All @@ -102,17 +103,15 @@ fn approx_global_curve(
[curve.path().point_from_path_coords(point_curve).u]
}));

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

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

Expand Down Expand Up @@ -211,7 +210,7 @@ impl GlobalCurveApprox {

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

use pretty_assertions::assert_eq;

Expand All @@ -220,7 +219,7 @@ mod tests {
builder::{CurveBuilder, SurfaceBuilder},
geometry::path::GlobalPath,
insert::Insert,
partial::{Partial, PartialCurve, PartialObject, PartialSurface},
partial::{PartialCurve, PartialObject, PartialSurface},
services::Services,
};

Expand All @@ -231,17 +230,14 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xz_plane();
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[1., 1.], [2., 1.]]);
let curve = curve
.build(&mut services.objects)
.insert(&mut services.objects);
let range = RangeOnPath::from([[0.], [1.]]);

let approx = (&curve, range).approx(1.);
let approx = (&curve, surface.deref(), range).approx(1.);

assert_eq!(approx, CurveApprox::empty());
}
Expand All @@ -256,17 +252,14 @@ mod tests {
)
.build(&mut services.objects)
.insert(&mut services.objects);
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[1., 1.], [1., 2.]]);
let curve = curve
.build(&mut services.objects)
.insert(&mut services.objects);
let range = RangeOnPath::from([[0.], [1.]]);

let approx = (&curve, range).approx(1.);
let approx = (&curve, surface.deref(), range).approx(1.);

assert_eq!(approx, CurveApprox::empty());
}
Expand All @@ -279,10 +272,7 @@ mod tests {
let surface = PartialSurface::from_axes(path, [0., 0., 1.])
.build(&mut services.objects)
.insert(&mut services.objects);
let mut curve = PartialCurve {
surface: Partial::from(surface.clone()),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[0., 1.], [1., 1.]]);
let curve = curve
.build(&mut services.objects)
Expand All @@ -291,7 +281,7 @@ mod tests {
let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;

let approx = (&curve, range).approx(tolerance);
let approx = (&curve, surface.deref(), range).approx(tolerance);

let expected_approx = (path, range)
.approx(tolerance)
Expand All @@ -312,27 +302,22 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xz_plane();
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_circle_from_radius(1.);
let curve = curve
.build(&mut services.objects)
.insert(&mut services.objects);

let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;
let approx = (&curve, range).approx(tolerance);
let approx = (&curve, surface.deref(), range).approx(tolerance);

let expected_approx = (curve.path(), range)
.approx(tolerance)
.into_iter()
.map(|(_, point_surface)| {
let point_global = curve
.surface()
.geometry()
.point_from_surface_coords(point_surface);
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
ApproxPoint::new(point_surface, point_global)
})
.collect::<Vec<_>>();
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-kernel/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//! approximations are usually used to build cycle approximations, and this way,
//! the caller doesn't have to call with duplicate vertices.
use std::ops::Deref;

use crate::{objects::HalfEdge, storage::Handle};

use super::{
Expand All @@ -30,8 +32,8 @@ impl Approx for &Handle<HalfEdge> {
self.start_vertex().global_form().position(),
)
.with_source((self.clone(), self.boundary()[0]));
let curve_approx =
(self.curve(), range).approx_with_cache(tolerance, cache);
let curve_approx = (self.curve(), self.surface().deref(), range)
.approx_with_cache(tolerance, cache);

HalfEdgeApprox {
first,
Expand Down
20 changes: 4 additions & 16 deletions crates/fj-kernel/src/algorithms/intersect/curve_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ mod tests {
let mut services = Services::new();

let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
Expand Down Expand Up @@ -118,10 +115,7 @@ mod tests {
let mut services = Services::new();

let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
Expand Down Expand Up @@ -149,10 +143,7 @@ mod tests {
let mut services = Services::new();

let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
Expand All @@ -175,10 +166,7 @@ mod tests {
let mut services = Services::new();

let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
Expand Down
5 changes: 1 addition & 4 deletions crates/fj-kernel/src/algorithms/intersect/curve_face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,7 @@ mod tests {

let surface = Partial::from(services.objects.surfaces.xy_plane());

let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[-3., 0.], [-2., 0.]]);
let curve = curve.build(&mut services.objects);

Expand Down
7 changes: 2 additions & 5 deletions crates/fj-kernel/src/algorithms/intersect/face_face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,8 @@ mod tests {
let intersection =
FaceFaceIntersection::compute([&a, &b], &mut services.objects);

let expected_curves = surfaces.map(|surface| {
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let expected_curves = surfaces.map(|_| {
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[0., 0.], [1., 0.]]);
curve
.build(&mut services.objects)
Expand Down
27 changes: 9 additions & 18 deletions crates/fj-kernel/src/algorithms/intersect/surface_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ impl SurfaceSurfaceIntersection {
// Adaptations were made to get the intersection curves in local
// coordinates for each surface.

let surfaces_and_planes = surfaces.map(|surface| {
let plane = plane_from_surface(&surface);
(surface, plane)
});
let [a, b] = surfaces_and_planes.clone().map(|(_, plane)| plane);
let planes = surfaces.map(|surface| plane_from_surface(&surface));

let (a_distance, a_normal) = a.constant_normal_form();
let (b_distance, b_normal) = b.constant_normal_form();
let [(a_distance, a_normal), (b_distance, b_normal)] =
planes.map(|plane| plane.constant_normal_form());

let direction = a_normal.cross(&b_normal);

Expand All @@ -57,11 +53,11 @@ impl SurfaceSurfaceIntersection {

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

let curves = surfaces_and_planes.map(|(surface, plane)| {
let curves = planes.map(|plane| {
let path = SurfacePath::Line(plane.project_line(&line));
let global_form = GlobalCurve.insert(objects);

Curve::new(surface, path, global_form).insert(objects)
Curve::new(path, global_form).insert(objects)
});

Some(Self {
Expand Down Expand Up @@ -92,7 +88,7 @@ mod tests {
algorithms::transform::TransformObject,
builder::CurveBuilder,
insert::Insert,
partial::{Partial, PartialCurve, PartialObject},
partial::{PartialCurve, PartialObject},
services::Services,
};

Expand Down Expand Up @@ -120,18 +116,13 @@ mod tests {
None,
);

let mut expected_xy = PartialCurve {
surface: Partial::from(xy.clone()),
..Default::default()
};
let mut expected_xy = PartialCurve::default();
expected_xy.update_as_u_axis();
let expected_xy = expected_xy
.build(&mut services.objects)
.insert(&mut services.objects);
let mut expected_xz = PartialCurve {
surface: Partial::from(xz.clone()),
..Default::default()
};

let mut expected_xz = PartialCurve::default();
expected_xz.update_as_u_axis();
let expected_xz = expected_xz
.build(&mut services.objects)
Expand Down
1 change: 1 addition & 0 deletions crates/fj-kernel/src/algorithms/reverse/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl Reverse for Handle<HalfEdge> {
};

HalfEdge::new(
self.surface().clone(),
self.curve().clone(),
vertices,
self.global_form().clone(),
Expand Down
Loading

0 comments on commit abef26e

Please sign in to comment.