Merge pull request #2265 from hannobraun/geometry

Prepare for moving `HalfEdge`'s `SurfacePath` to geometry layer
This commit is contained in:
Hanno Braun 2024-03-14 14:56:58 +01:00 committed by GitHub
commit 64784f5f23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 80 additions and 68 deletions

View File

@ -59,7 +59,7 @@ impl Geometry {
surface: Handle<Surface>,
geometry: SurfaceGeometry,
) {
self.surface.insert(surface.clone().into(), geometry);
self.surface.insert(surface.into(), geometry);
}
/// # Access the geometry of the provided surface

View File

@ -3,7 +3,7 @@ use itertools::Itertools;
use crate::{
objects::{Cycle, HalfEdge},
operations::{build::BuildHalfEdge, insert::Insert, update::UpdateCycle},
operations::{build::BuildHalfEdge, update::UpdateCycle},
Core,
};
@ -40,7 +40,7 @@ pub trait BuildCycle {
.map(Into::into)
.circular_tuple_windows()
.map(|(start, end)| {
HalfEdge::line_segment([start, end], None, core).insert(core)
HalfEdge::line_segment([start, end], None, core)
});
Cycle::new(edges)

View File

@ -29,15 +29,17 @@ pub trait BuildHalfEdge {
/// Create a half-edge from its sibling
fn from_sibling(
sibling: &HalfEdge,
sibling: &Handle<HalfEdge>,
start_vertex: Handle<Vertex>,
) -> HalfEdge {
core: &mut Core,
) -> Handle<HalfEdge> {
HalfEdge::new(
sibling.path(),
sibling.boundary().reverse(),
sibling.curve().clone(),
start_vertex,
)
.insert(core)
}
/// Create an arc
@ -50,7 +52,7 @@ pub trait BuildHalfEdge {
end: impl Into<Point<2>>,
angle_rad: impl Into<Scalar>,
core: &mut Core,
) -> HalfEdge {
) -> Handle<HalfEdge> {
let angle_rad = angle_rad.into();
if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU {
panic!("arc angle must be in the range (-2pi, 2pi) radians");
@ -63,7 +65,7 @@ pub trait BuildHalfEdge {
let boundary =
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
HalfEdge::unjoined(path, boundary, core)
HalfEdge::unjoined(path, boundary, core).insert(core)
}
/// Create a circle
@ -71,12 +73,12 @@ pub trait BuildHalfEdge {
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
core: &mut Core,
) -> HalfEdge {
) -> Handle<HalfEdge> {
let path = SurfacePath::circle_from_center_and_radius(center, radius);
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
HalfEdge::unjoined(path, boundary, core)
HalfEdge::unjoined(path, boundary, core).insert(core)
}
/// Create a line segment
@ -84,14 +86,14 @@ pub trait BuildHalfEdge {
points_surface: [impl Into<Point<2>>; 2],
boundary: Option<[Point<1>; 2]>,
core: &mut Core,
) -> HalfEdge {
) -> Handle<HalfEdge> {
let boundary =
boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from));
let path = SurfacePath::line_from_points_with_coords(
boundary.zip_ext(points_surface),
);
HalfEdge::unjoined(path, boundary, core)
HalfEdge::unjoined(path, boundary, core).insert(core)
}
}

View File

@ -10,7 +10,6 @@ use crate::{
use super::{
build::{BuildCycle, BuildHalfEdge, BuildRegion},
insert::Insert,
join::JoinCycle,
sweep::{SweepCache, SweepRegion},
update::{UpdateCycle, UpdateFace, UpdateRegion, UpdateShell},
@ -44,8 +43,7 @@ impl AddHole for Shell {
path: impl Into<Vector<3>>,
core: &mut Core,
) -> Self {
let entry =
HalfEdge::circle(location.position, radius, core).insert(core);
let entry = HalfEdge::circle(location.position, radius, core);
let hole = Region::empty(core)
.update_exterior(
|_, core| Cycle::empty().add_half_edges([entry.clone()], core),
@ -94,8 +92,7 @@ impl AddHole for Shell {
) -> Self {
let radius = radius.into();
let entry = HalfEdge::circle(entry_location.position, radius, core)
.insert(core);
let entry = HalfEdge::circle(entry_location.position, radius, core);
let path = {
let point = |location: &HoleLocation| {

View File

@ -87,8 +87,8 @@ impl JoinCycle for Cycle {
let half_edges = edges
.into_iter()
.circular_tuple_windows()
.map(|((prev_half_edge, _, _), (half_edge, curve, boundary))| {
HalfEdge::unjoined(curve, boundary, core)
.map(|((prev_half_edge, _, _), (half_edge, path, boundary))| {
HalfEdge::unjoined(path, boundary, core)
.update_curve(|_, _| half_edge.curve().clone(), core)
.update_start_vertex(
|_, _| prev_half_edge.start_vertex().clone(),

View File

@ -31,11 +31,10 @@ impl Reverse for Cycle {
impl ReverseCurveCoordinateSystems for Cycle {
fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self {
let edges = self.half_edges().iter().map(|edge| {
edge.reverse_curve_coordinate_systems(core)
.insert(core)
.derive_from(edge, core)
});
let edges = self
.half_edges()
.iter()
.map(|edge| edge.reverse_curve_coordinate_systems(core));
Cycle::new(edges)
}

View File

@ -1,9 +1,14 @@
use crate::{objects::HalfEdge, Core};
use crate::{
objects::HalfEdge,
operations::{derive::DeriveFrom, insert::Insert},
storage::Handle,
Core,
};
use super::ReverseCurveCoordinateSystems;
impl ReverseCurveCoordinateSystems for HalfEdge {
fn reverse_curve_coordinate_systems(&self, _: &mut Core) -> Self {
impl ReverseCurveCoordinateSystems for Handle<HalfEdge> {
fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self {
let path = self.path().reverse();
let boundary = self.boundary().reverse();
@ -13,5 +18,7 @@ impl ReverseCurveCoordinateSystems for HalfEdge {
self.curve().clone(),
self.start_vertex().clone(),
)
.insert(core)
.derive_from(self, core)
}
}

View File

@ -48,10 +48,12 @@ impl SplitEdge for Shell {
let siblings = {
let [sibling_a, sibling_b] = sibling.split_half_edge(point, core);
let sibling_b = sibling_b.update_start_vertex(
|_, _| half_edge_b.start_vertex().clone(),
core,
);
let sibling_b = sibling_b
.update_start_vertex(
|_, _| half_edge_b.start_vertex().clone(),
core,
)
.insert(core);
[sibling_a, sibling_b].map(|half_edge| {
half_edge.insert(core).derive_from(&sibling, core)
})

View File

@ -106,10 +106,12 @@ impl SplitFace for Shell {
None,
core,
)
.update_start_vertex(|_, _| b.start_vertex().clone(), core);
.update_start_vertex(|_, _| b.start_vertex().clone(), core)
.insert(core);
let dividing_half_edge_c_to_b = HalfEdge::from_sibling(
&dividing_half_edge_a_to_d,
d.start_vertex().clone(),
core,
);
let mut half_edges_of_face_starting_at_b =

View File

@ -3,6 +3,7 @@ use fj_math::Point;
use crate::{
objects::{HalfEdge, Vertex},
operations::insert::Insert,
storage::Handle,
Core,
};
@ -28,7 +29,7 @@ pub trait SplitHalfEdge {
&self,
point: impl Into<Point<1>>,
core: &mut Core,
) -> [HalfEdge; 2];
) -> [Handle<HalfEdge>; 2];
}
impl SplitHalfEdge for HalfEdge {
@ -36,7 +37,7 @@ impl SplitHalfEdge for HalfEdge {
&self,
point: impl Into<Point<1>>,
core: &mut Core,
) -> [HalfEdge; 2] {
) -> [Handle<HalfEdge>; 2] {
let point = point.into();
let [start, end] = self.boundary().inner;
@ -46,13 +47,15 @@ impl SplitHalfEdge for HalfEdge {
[start, point],
self.curve().clone(),
self.start_vertex().clone(),
);
)
.insert(core);
let b = HalfEdge::new(
self.path(),
[point, end],
self.curve().clone(),
Vertex::new().insert(core),
);
)
.insert(core);
[a, b]
}

View File

@ -1,10 +1,12 @@
use fj_math::Transform;
use crate::{objects::HalfEdge, Core};
use crate::{
objects::HalfEdge, operations::insert::Insert, storage::Handle, Core,
};
use super::{TransformCache, TransformObject};
impl TransformObject for HalfEdge {
impl TransformObject for Handle<HalfEdge> {
fn transform_with_cache(
&self,
transform: &Transform,
@ -24,6 +26,6 @@ impl TransformObject for HalfEdge {
.clone()
.transform_with_cache(transform, core, cache);
Self::new(path, boundary, curve, start_vertex)
HalfEdge::new(path, boundary, curve, start_vertex).insert(core)
}
}

View File

@ -9,13 +9,14 @@ use crate::{
};
/// Update a [`HalfEdge`]
pub trait UpdateHalfEdge {
pub trait UpdateHalfEdge: Sized {
/// Update the path of the edge
#[must_use]
fn update_path(
&self,
update: impl FnOnce(SurfacePath) -> SurfacePath,
) -> Self;
core: &mut Core,
) -> Handle<Self>;
/// Update the boundary of the edge
#[must_use]
@ -49,13 +50,17 @@ impl UpdateHalfEdge for HalfEdge {
fn update_path(
&self,
update: impl FnOnce(SurfacePath) -> SurfacePath,
) -> Self {
core: &mut Core,
) -> Handle<Self> {
let path = update(self.path());
HalfEdge::new(
update(self.path()),
path,
self.boundary(),
self.curve().clone(),
self.start_vertex().clone(),
)
.insert(core)
}
fn update_boundary(

View File

@ -429,9 +429,12 @@ mod tests {
|cycle, core| {
cycle.update_half_edge(
cycle.half_edges().nth_circular(0),
|edge, _| {
|edge, core| {
[edge
.update_path(|path| path.reverse())
.update_path(
|path| path.reverse(),
core,
)
.update_boundary(|boundary| {
boundary.reverse()
})]

View File

@ -186,8 +186,7 @@ mod tests {
fn should_find_clockwise_exterior_cycle() -> anyhow::Result<()> {
let mut core = Core::new();
let valid_outer_circle =
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core);
let valid_outer_circle = HalfEdge::circle([0., 0.], 1., &mut core);
let valid_exterior =
Cycle::new(vec![valid_outer_circle.clone()]).insert(&mut core);
let valid_sketch =
@ -199,8 +198,8 @@ mod tests {
let invalid_outer_circle = HalfEdge::from_sibling(
&valid_outer_circle,
Vertex::new().insert(&mut core),
)
.insert(&mut core);
&mut core,
);
let invalid_exterior =
Cycle::new(vec![invalid_outer_circle.clone()]).insert(&mut core);
let invalid_sketch =
@ -222,15 +221,13 @@ mod tests {
fn should_find_counterclockwise_interior_cycle() -> anyhow::Result<()> {
let mut core = Core::new();
let outer_circle =
HalfEdge::circle([0., 0.], 2., &mut core).insert(&mut core);
let inner_circle =
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core);
let outer_circle = HalfEdge::circle([0., 0.], 2., &mut core);
let inner_circle = HalfEdge::circle([0., 0.], 1., &mut core);
let cw_inner_circle = HalfEdge::from_sibling(
&inner_circle,
Vertex::new().insert(&mut core),
)
.insert(&mut core);
&mut core,
);
let exterior = Cycle::new(vec![outer_circle.clone()]).insert(&mut core);
let valid_interior =

View File

@ -202,10 +202,8 @@ mod tests {
&mut core,
),
Region::new(
Cycle::new(vec![
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core)
])
.insert(&mut core),
Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)])
.insert(&mut core),
vec![],
)
.insert(&mut core),
@ -249,10 +247,8 @@ mod tests {
let mut core = Core::new();
let shared_region = Region::new(
Cycle::new(vec![
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core)
])
.insert(&mut core),
Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)])
.insert(&mut core),
vec![],
)
.insert(&mut core);
@ -302,10 +298,8 @@ mod tests {
let mut core = Core::new();
let shared_cycle =
Cycle::new(vec![
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core)
])
.insert(&mut core);
Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)])
.insert(&mut core);
let invalid_solid = Solid::new(vec![Shell::new(vec![
Face::new(
@ -351,8 +345,7 @@ mod tests {
fn should_find_half_edge_multiple_references() -> anyhow::Result<()> {
let mut core = Core::new();
let shared_edge =
HalfEdge::circle([0., 0.], 1., &mut core).insert(&mut core);
let shared_edge = HalfEdge::circle([0., 0.], 1., &mut core);
let invalid_solid = Solid::new(vec![Shell::new(vec![Face::new(
Surface::surface_from_uv(