Skip to content

Commit

Permalink
Merge pull request hannobraun#2288 from hannobraun/geometry
Browse files Browse the repository at this point in the history
Complete migration of `HalfEdge` boundary to geometry layer
  • Loading branch information
hannobraun authored Mar 23, 2024
2 parents 2ebc613 + 53d1fb8 commit 5d3bab7
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 178 deletions.
66 changes: 33 additions & 33 deletions crates/fj-core/src/algorithms/approx/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@ use std::collections::BTreeMap;
use fj_math::Point;

use crate::{
geometry::{CurveBoundary, GlobalPath, SurfaceGeometry, SurfacePath},
geometry::{
CurveBoundary, GlobalPath, HalfEdgeGeometry, SurfaceGeometry,
SurfacePath,
},
objects::Curve,
storage::Handle,
Core,
};

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

impl Approx
for (
&Handle<Curve>,
SurfacePath,
&SurfaceGeometry,
CurveBoundary<Point<1>>,
)
{
impl Approx for (&Handle<Curve>, &HalfEdgeGeometry, &SurfaceGeometry) {
type Approximation = CurveApprox;
type Cache = CurveApproxCache;

Expand All @@ -30,20 +26,20 @@ impl Approx
cache: &mut Self::Cache,
core: &mut Core,
) -> Self::Approximation {
let (curve, surface_path, surface, boundary) = self;
let (curve, half_edge, surface) = self;

match cache.get(curve, boundary) {
match cache.get(curve, half_edge.boundary) {
Some(approx) => approx,
None => {
let approx = approx_curve(
&surface_path,
&half_edge.path,
surface,
boundary,
half_edge.boundary,
tolerance,
core,
);

cache.insert(curve.clone(), boundary, approx)
cache.insert(curve.clone(), half_edge.boundary, approx)
}
}
}
Expand Down Expand Up @@ -187,7 +183,10 @@ mod tests {

use crate::{
algorithms::approx::{Approx, ApproxPoint},
geometry::{CurveBoundary, GlobalPath, SurfaceGeometry, SurfacePath},
geometry::{
CurveBoundary, GlobalPath, HalfEdgeGeometry, SurfaceGeometry,
SurfacePath,
},
objects::Curve,
operations::insert::Insert,
Core,
Expand All @@ -198,14 +197,15 @@ mod tests {
let mut core = Core::new();

let curve = Curve::new().insert(&mut core);
let (surface_path, boundary) =
let (path, boundary) =
SurfacePath::line_from_points([[1., 1.], [2., 1.]]);
let boundary = CurveBoundary::from(boundary);
let half_edge = HalfEdgeGeometry { path, boundary };
let surface = core.layers.geometry.xz_plane();

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

assert_eq!(approx.points, vec![]);
}
Expand All @@ -215,17 +215,18 @@ mod tests {
let mut core = Core::new();

let curve = Curve::new().insert(&mut core);
let (surface_path, boundary) =
let (path, boundary) =
SurfacePath::line_from_points([[1., 1.], [2., 1.]]);
let boundary = CurveBoundary::from(boundary);
let half_edge = HalfEdgeGeometry { path, boundary };
let surface = SurfaceGeometry {
u: GlobalPath::circle_from_radius(1.),
v: [0., 0., 1.].into(),
};

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

assert_eq!(approx.points, vec![]);
}
Expand All @@ -236,26 +237,26 @@ mod tests {

let global_path = GlobalPath::circle_from_radius(1.);
let curve = Curve::new().insert(&mut core);
let surface_path = SurfacePath::line_from_points_with_coords([
let path = SurfacePath::line_from_points_with_coords([
([0.], [0., 1.]),
([TAU], [TAU, 1.]),
]);
let boundary = CurveBoundary::from([[0.], [TAU]]);
let half_edge = HalfEdgeGeometry { path, boundary };
let surface = SurfaceGeometry {
u: global_path,
v: [0., 0., 1.].into(),
};

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

let expected_approx = (global_path, boundary)
.approx(tolerance, &mut core)
.into_iter()
.map(|(point_local, _)| {
let point_surface =
surface_path.point_from_path_coords(point_local);
let point_surface = path.point_from_path_coords(point_local);
let point_global =
surface.point_from_surface_coords(point_surface);
ApproxPoint::new(point_local, point_global)
Expand All @@ -269,21 +270,20 @@ mod tests {
let mut core = Core::new();

let curve = Curve::new().insert(&mut core);
let surface_path =
SurfacePath::circle_from_center_and_radius([0., 0.], 1.);
let path = SurfacePath::circle_from_center_and_radius([0., 0.], 1.);
let boundary = CurveBoundary::from([[0.], [TAU]]);
let half_edge = HalfEdgeGeometry { path, boundary };
let surface = core.layers.geometry.xz_plane();

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

let expected_approx = (&surface_path, boundary)
let expected_approx = (&path, boundary)
.approx(tolerance, &mut core)
.into_iter()
.map(|(point_local, _)| {
let point_surface =
surface_path.point_from_path_coords(point_local);
let point_surface = path.point_from_path_coords(point_local);
let point_global =
surface.point_from_surface_coords(point_surface);
ApproxPoint::new(point_local, point_global)
Expand Down
3 changes: 1 addition & 2 deletions crates/fj-core/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ impl Approx for (&Handle<HalfEdge>, &SurfaceGeometry) {
let rest = {
let approx = (
half_edge.curve(),
core.layers.geometry.of_half_edge(half_edge).path,
&core.layers.geometry.of_half_edge(half_edge),
surface,
half_edge.boundary(),
)
.approx_with_cache(
tolerance,
Expand Down
9 changes: 4 additions & 5 deletions crates/fj-core/src/algorithms/bounding_volume/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ impl super::BoundingVolume<2> for Handle<HalfEdge> {
})
}
SurfacePath::Line(_) => {
let points = self.boundary().inner.map(|point_curve| {
geometry
.of_half_edge(self)
.path
.point_from_path_coords(point_curve)
let geometry = geometry.of_half_edge(self);

let points = geometry.boundary.inner.map(|point_curve| {
geometry.path.point_from_path_coords(point_curve)
});

Some(Aabb::<2>::from_points(points))
Expand Down
6 changes: 4 additions & 2 deletions crates/fj-core/src/objects/kinds/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ impl Cycle {
.next()
.expect("Invalid cycle: expected at least one edge");

let [a, b] = first.boundary().inner;
let geometry = geometry.of_half_edge(first);

let [a, b] = geometry.boundary.inner;
let edge_direction_positive = a < b;

let circle = match geometry.of_half_edge(first).path {
let circle = match geometry.path {
SurfacePath::Circle(circle) => circle,
SurfacePath::Line(_) => unreachable!(
"Invalid cycle: less than 3 edges, but not all are circles"
Expand Down
16 changes: 1 addition & 15 deletions crates/fj-core/src/objects/kinds/half_edge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use fj_math::Point;

use crate::{
geometry::CurveBoundary,
objects::{Curve, Vertex},
storage::Handle,
};
Expand Down Expand Up @@ -35,30 +32,19 @@ use crate::{
/// [`Shell`]: crate::objects::Shell
#[derive(Clone, Debug)]
pub struct HalfEdge {
boundary: CurveBoundary<Point<1>>,
curve: Handle<Curve>,
start_vertex: Handle<Vertex>,
}

impl HalfEdge {
/// Create an instance of `Edge`
pub fn new(
boundary: impl Into<CurveBoundary<Point<1>>>,
curve: Handle<Curve>,
start_vertex: Handle<Vertex>,
) -> Self {
pub fn new(curve: Handle<Curve>, start_vertex: Handle<Vertex>) -> Self {
Self {
boundary: boundary.into(),
curve,
start_vertex,
}
}

/// Access the boundary points of the edge on the curve
pub fn boundary(&self) -> CurveBoundary<Point<1>> {
self.boundary
}

/// Access the curve of the edge
pub fn curve(&self) -> &Handle<Curve> {
&self.curve
Expand Down
39 changes: 15 additions & 24 deletions crates/fj-core/src/operations/build/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use fj_interop::ext::ArrayExt;
use fj_math::{Arc, Point, Scalar};

use crate::{
geometry::{CurveBoundary, HalfEdgeGeometry, SurfacePath},
geometry::{HalfEdgeGeometry, SurfacePath},
objects::{Curve, HalfEdge, Vertex},
operations::{geometry::UpdateHalfEdgeGeometry, insert::Insert},
storage::Handle,
Expand All @@ -16,14 +16,11 @@ use crate::{
/// [module-level documentation]: super
pub trait BuildHalfEdge {
/// Create a half-edge that is not joined to a sibling
fn unjoined(
boundary: impl Into<CurveBoundary<Point<1>>>,
core: &mut Core,
) -> HalfEdge {
fn unjoined(core: &mut Core) -> HalfEdge {
let curve = Curve::new().insert(core);
let start_vertex = Vertex::new().insert(core);

HalfEdge::new(boundary, curve, start_vertex)
HalfEdge::new(curve, start_vertex)
}

/// Create a half-edge from its sibling
Expand All @@ -35,13 +32,9 @@ pub trait BuildHalfEdge {
let mut geometry = core.layers.geometry.of_half_edge(sibling);
geometry.boundary = geometry.boundary.reverse();

HalfEdge::new(
sibling.boundary().reverse(),
sibling.curve().clone(),
start_vertex,
)
.insert(core)
.set_geometry(geometry, &mut core.layers.geometry)
HalfEdge::new(sibling.curve().clone(), start_vertex)
.insert(core)
.set_geometry(geometry, &mut core.layers.geometry)
}

/// Create an arc
Expand All @@ -67,7 +60,7 @@ pub trait BuildHalfEdge {
let boundary =
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));

let half_edge = HalfEdge::unjoined(boundary, core).insert(core);
let half_edge = HalfEdge::unjoined(core).insert(core);
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
Expand All @@ -89,7 +82,7 @@ pub trait BuildHalfEdge {
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

let half_edge = HalfEdge::unjoined(boundary, core).insert(core);
let half_edge = HalfEdge::unjoined(core).insert(core);
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
Expand All @@ -113,15 +106,13 @@ pub trait BuildHalfEdge {
boundary.zip_ext(points_surface),
);

HalfEdge::unjoined(boundary, core)
.insert(core)
.set_geometry(
HalfEdgeGeometry {
path,
boundary: boundary.into(),
},
&mut core.layers.geometry,
)
HalfEdge::unjoined(core).insert(core).set_geometry(
HalfEdgeGeometry {
path,
boundary: boundary.into(),
},
&mut core.layers.geometry,
)
}
}

Expand Down
18 changes: 3 additions & 15 deletions crates/fj-core/src/operations/holes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ impl AddHole for Shell {
[Cycle::empty().add_joined_edges(
[(
entry.clone(),
core.layers
.geometry
.of_half_edge(&entry)
.path,
entry.boundary(),
core.layers.geometry.of_half_edge(&entry),
)],
core,
)],
Expand Down Expand Up @@ -142,11 +138,7 @@ impl AddHole for Shell {
[Cycle::empty().add_joined_edges(
[(
entry.clone(),
core.layers
.geometry
.of_half_edge(&entry)
.path,
entry.boundary(),
core.layers.geometry.of_half_edge(&entry),
)],
core,
)],
Expand All @@ -167,11 +159,7 @@ impl AddHole for Shell {
[Cycle::empty().add_joined_edges(
[(
exit.clone(),
core.layers
.geometry
.of_half_edge(exit)
.path,
exit.boundary(),
core.layers.geometry.of_half_edge(exit),
)],
core,
)],
Expand Down
Loading

0 comments on commit 5d3bab7

Please sign in to comment.