Skip to content

Commit

Permalink
Merge pull request hannobraun#2287 from hannobraun/geometry
Browse files Browse the repository at this point in the history
Add redundant definition of `HalfEdge`'s `CurveBoundary` to geometry layer
  • Loading branch information
hannobraun authored Mar 23, 2024
2 parents 4b74964 + f750a16 commit 2ebc613
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 53 deletions.
2 changes: 1 addition & 1 deletion crates/fj-core/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Approx for (&Handle<HalfEdge>, &SurfaceGeometry) {
.layers
.geometry
.of_half_edge(half_edge)
.start_position(half_edge.boundary());
.start_position();
let start_position =
match cache.start_position.get(half_edge.start_vertex()) {
Some(position) => position,
Expand Down
19 changes: 14 additions & 5 deletions crates/fj-core/src/geometry/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,28 @@ pub struct HalfEdgeGeometry {
/// really belong here. It exists here for practical reasons that are,
/// hopefully, temporary.
pub path: SurfacePath,

/// # The boundary of the half-edge on its curve
pub boundary: CurveBoundary<Point<1>>,
}

impl HalfEdgeGeometry {
/// Update the boundary
pub fn with_boundary(
mut self,
boundary: impl Into<CurveBoundary<Point<1>>>,
) -> Self {
self.boundary = boundary.into();
self
}

/// Compute the surface position where the half-edge starts
pub fn start_position(
&self,
boundary: CurveBoundary<Point<1>>,
) -> Point<2> {
pub fn start_position(&self) -> Point<2> {
// Computing the surface position from the curve position is fine.
// `HalfEdge` "owns" its start position. There is no competing code that
// could compute the surface position from slightly different data.

let [start, _] = boundary.inner;
let [start, _] = self.boundary.inner;
self.path.point_from_path_coords(start)
}
}
4 changes: 1 addition & 3 deletions crates/fj-core/src/objects/kinds/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ impl Cycle {

for (a, b) in self.half_edges().pairs() {
let [a, b] = [a, b].map(|half_edge| {
geometry
.of_half_edge(half_edge)
.start_position(half_edge.boundary())
geometry.of_half_edge(half_edge).start_position()
});

sum += (b.u - a.u) * (b.v + a.v);
Expand Down
36 changes: 25 additions & 11 deletions crates/fj-core/src/operations/build/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ pub trait BuildHalfEdge {
start_vertex: Handle<Vertex>,
core: &mut Core,
) -> Handle<HalfEdge> {
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(
core.layers.geometry.of_half_edge(sibling),
&mut core.layers.geometry,
)
.set_geometry(geometry, &mut core.layers.geometry)
}

/// Create an arc
Expand All @@ -68,9 +68,13 @@ pub trait BuildHalfEdge {
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));

let half_edge = HalfEdge::unjoined(boundary, core).insert(core);
core.layers
.geometry
.define_half_edge(half_edge.clone(), HalfEdgeGeometry { path });
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
path,
boundary: boundary.into(),
},
);

half_edge
}
Expand All @@ -86,9 +90,13 @@ pub trait BuildHalfEdge {
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

let half_edge = HalfEdge::unjoined(boundary, core).insert(core);
core.layers
.geometry
.define_half_edge(half_edge.clone(), HalfEdgeGeometry { path });
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
path,
boundary: boundary.into(),
},
);

half_edge
}
Expand All @@ -107,7 +115,13 @@ pub trait BuildHalfEdge {

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

Expand Down
2 changes: 1 addition & 1 deletion crates/fj-core/src/operations/join/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl JoinCycle for Cycle {
)
.insert(core)
.set_geometry(
HalfEdgeGeometry { path },
HalfEdgeGeometry { path, boundary },
&mut core.layers.geometry,
)
})
Expand Down
8 changes: 4 additions & 4 deletions crates/fj-core/src/operations/reverse/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ impl Reverse for Cycle {
.half_edges()
.pairs()
.map(|(current, next)| {
let mut geometry = core.layers.geometry.of_half_edge(current);
geometry.boundary = geometry.boundary.reverse();

HalfEdge::new(
current.boundary().reverse(),
current.curve().clone(),
next.start_vertex().clone(),
)
.insert(core)
.derive_from(current, core)
.set_geometry(
core.layers.geometry.of_half_edge(current),
&mut core.layers.geometry,
)
.set_geometry(geometry, &mut core.layers.geometry)
})
.collect::<Vec<_>>();

Expand Down
10 changes: 5 additions & 5 deletions crates/fj-core/src/operations/reverse/edge.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{
geometry::HalfEdgeGeometry,
objects::HalfEdge,
operations::{derive::DeriveFrom, insert::Insert},
storage::Handle,
Expand All @@ -10,11 +9,12 @@ use super::ReverseCurveCoordinateSystems;

impl ReverseCurveCoordinateSystems for Handle<HalfEdge> {
fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self {
let path = core.layers.geometry.of_half_edge(self).path.reverse();
let boundary = self.boundary().reverse();
let mut geometry = core.layers.geometry.of_half_edge(self);
geometry.path = geometry.path.reverse();
geometry.boundary = geometry.boundary.reverse();

let half_edge = HalfEdge::new(
boundary,
geometry.boundary,
self.curve().clone(),
self.start_vertex().clone(),
)
Expand All @@ -23,7 +23,7 @@ impl ReverseCurveCoordinateSystems for Handle<HalfEdge> {

core.layers
.geometry
.define_half_edge(half_edge.clone(), HalfEdgeGeometry { path });
.define_half_edge(half_edge.clone(), geometry);

half_edge
}
Expand Down
10 changes: 2 additions & 8 deletions crates/fj-core/src/operations/split/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,8 @@ impl SplitFace for Shell {
let dividing_half_edge_a_to_d = {
let half_edge = HalfEdge::line_segment(
[
core.layers
.geometry
.of_half_edge(&b)
.start_position(b.boundary()),
core.layers
.geometry
.of_half_edge(&d)
.start_position(d.boundary()),
core.layers.geometry.of_half_edge(&b).start_position(),
core.layers.geometry.of_half_edge(&d).start_position(),
],
None,
core,
Expand Down
29 changes: 18 additions & 11 deletions crates/fj-core/src/operations/split/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use fj_math::Point;

use crate::{
objects::{HalfEdge, Vertex},
operations::{derive::DeriveFrom, insert::Insert},
operations::{
derive::DeriveFrom, geometry::UpdateHalfEdgeGeometry, insert::Insert,
},
storage::Handle,
Core,
};
Expand Down Expand Up @@ -48,22 +50,27 @@ impl SplitHalfEdge for Handle<HalfEdge> {
self.start_vertex().clone(),
)
.insert(core)
.derive_from(self, core);
.derive_from(self, core)
.set_geometry(
core.layers
.geometry
.of_half_edge(self)
.with_boundary([start, point]),
&mut core.layers.geometry,
);
let b = HalfEdge::new(
[point, end],
self.curve().clone(),
Vertex::new().insert(core),
)
.insert(core)
.derive_from(self, core);

core.layers.geometry.define_half_edge(
a.clone(),
core.layers.geometry.of_half_edge(self),
);
core.layers.geometry.define_half_edge(
b.clone(),
core.layers.geometry.of_half_edge(self),
.derive_from(self, core)
.set_geometry(
core.layers
.geometry
.of_half_edge(self)
.with_boundary([point, end]),
&mut core.layers.geometry,
);

[a, b]
Expand Down
2 changes: 2 additions & 0 deletions crates/fj-core/src/validate/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ mod tests {
.geometry
.of_half_edge(half_edge);
geometry.path = geometry.path.reverse();
geometry.boundary =
geometry.boundary.reverse();

[HalfEdge::new(
half_edge.boundary().reverse(),
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-core/src/validate/solid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl SolidValidationError {
.map(|(h, s)| {
(
s.point_from_surface_coords(
geometry.of_half_edge(&h).start_position(h.boundary()),
geometry.of_half_edge(&h).start_position(),
),
h.start_vertex().clone(),
)
Expand Down
5 changes: 2 additions & 3 deletions crates/fj-core/src/validation/checks/half_edge_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ impl ValidationCheck<Cycle> for AdjacentHalfEdgesNotConnected {
.path
.point_from_path_coords(end)
};
let start_pos_of_second_half_edge = geometry
.of_half_edge(second)
.start_position(second.boundary());
let start_pos_of_second_half_edge =
geometry.of_half_edge(second).start_position();

let distance_between_positions = (end_pos_of_first_half_edge
- start_pos_of_second_half_edge)
Expand Down

0 comments on commit 2ebc613

Please sign in to comment.