Skip to content

Commit

Permalink
Store HalfEdge path in geometry layer
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Mar 18, 2024
1 parent 03a7cd1 commit c7906ad
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 18 deletions.
31 changes: 30 additions & 1 deletion crates/fj-core/src/geometry/half_edge.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
use super::SurfacePath;

/// The geometry of a half-edge
#[derive(Copy, Clone)]
pub struct HalfEdgeGeometry {}
pub struct HalfEdgeGeometry {
/// # The path of the half-edge
///
/// ## Implementation Note
///
/// Currently, all curve-related geometry is defined locally, in terms of
/// the surface that the curve is on (or purely in 2D, if there is no
/// surface associated with this geometry). However, curves exist globally,
/// independently of surfaces. Half-edges in multiple surfaces can refer to
/// the same curve, and in fact, that is the whole reason for their
/// existence as a topological object.
///
/// This contradiction, globally defined curves but locally defined curve
/// geometry, is the reason that this curve geometry is defined right here,
/// associated with a locally existing half-edge. (And, I might add,
/// redundantly so, as multiple half-edges within the same surface context
/// can refer to the same curve.)
///
/// Instead, it should be possible to define curve geometry *either* locally
/// or globally. Then that respective definition can be associated with the
/// curve (and possibly, in addition, a surface). How exactly that is going
/// to work is up in the air.
///
/// The point of all this exposition is to clarify that this field doesn't
/// really belong here. It exists here for practical reasons that are,
/// hopefully, temporary.
pub path: SurfacePath,
}
36 changes: 30 additions & 6 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, SurfacePath},
geometry::{CurveBoundary, HalfEdgeGeometry, SurfacePath},
objects::{Curve, HalfEdge, Vertex},
operations::insert::Insert,
storage::Handle,
Expand Down Expand Up @@ -33,13 +33,22 @@ pub trait BuildHalfEdge {
start_vertex: Handle<Vertex>,
core: &mut Core,
) -> Handle<HalfEdge> {
HalfEdge::new(
let half_edge = HalfEdge::new(
sibling.path(),
sibling.boundary().reverse(),
sibling.curve().clone(),
start_vertex,
)
.insert(core)
.insert(core);

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

half_edge
}

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

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

half_edge
}

/// Create a circle
Expand All @@ -78,7 +92,12 @@ pub trait BuildHalfEdge {
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

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

half_edge
}

/// Create a line segment
Expand All @@ -93,7 +112,12 @@ pub trait BuildHalfEdge {
boundary.zip_ext(points_surface),
);

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

half_edge
}
}

Expand Down
12 changes: 9 additions & 3 deletions crates/fj-core/src/operations/geometry/half_edge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_math::Point;

use crate::{
geometry::{CurveBoundary, SurfacePath},
geometry::{CurveBoundary, HalfEdgeGeometry, SurfacePath},
objects::HalfEdge,
operations::insert::Insert,
storage::Handle,
Expand Down Expand Up @@ -35,13 +35,19 @@ impl UpdateHalfEdgeGeometry for Handle<HalfEdge> {
) -> Self {
let path = update(self.path());

HalfEdge::new(
let half_edge = HalfEdge::new(
path,
self.boundary(),
self.curve().clone(),
self.start_vertex().clone(),
)
.insert(core)
.insert(core);

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

half_edge
}

fn update_boundary(
Expand Down
13 changes: 11 additions & 2 deletions crates/fj-core/src/operations/join/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use fj_math::Point;
use itertools::Itertools;

use crate::{
geometry::{CurveBoundary, SurfacePath},
geometry::{CurveBoundary, HalfEdgeGeometry, SurfacePath},
objects::{Cycle, HalfEdge},
operations::{
build::BuildHalfEdge,
insert::Insert,
update::{UpdateCycle, UpdateHalfEdge},
},
storage::Handle,
Expand Down Expand Up @@ -88,12 +89,20 @@ impl JoinCycle for Cycle {
.into_iter()
.circular_tuple_windows()
.map(|((prev_half_edge, _, _), (half_edge, path, boundary))| {
HalfEdge::unjoined(path, boundary, core)
let half_edge = HalfEdge::unjoined(path, boundary, core)
.update_curve(|_, _| half_edge.curve().clone(), core)
.update_start_vertex(
|_, _| prev_half_edge.start_vertex().clone(),
core,
)
.insert(core);

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

half_edge
})
.collect::<Vec<_>>();
self.add_half_edges(half_edges, core)
Expand Down
14 changes: 12 additions & 2 deletions crates/fj-core/src/operations/reverse/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{
geometry::HalfEdgeGeometry,
objects::{Cycle, HalfEdge},
operations::{derive::DeriveFrom, insert::Insert},
Core,
Expand All @@ -12,14 +13,23 @@ impl Reverse for Cycle {
.half_edges()
.pairs()
.map(|(current, next)| {
HalfEdge::new(
let half_edge = HalfEdge::new(
current.path(),
current.boundary().reverse(),
current.curve().clone(),
next.start_vertex().clone(),
)
.insert(core)
.derive_from(current, core)
.derive_from(current, core);

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

half_edge
})
.collect::<Vec<_>>();

Expand Down
11 changes: 9 additions & 2 deletions crates/fj-core/src/operations/reverse/edge.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{
geometry::HalfEdgeGeometry,
objects::HalfEdge,
operations::{derive::DeriveFrom, insert::Insert},
storage::Handle,
Expand All @@ -12,13 +13,19 @@ impl ReverseCurveCoordinateSystems for Handle<HalfEdge> {
let path = self.path().reverse();
let boundary = self.boundary().reverse();

HalfEdge::new(
let half_edge = HalfEdge::new(
path,
boundary,
self.curve().clone(),
self.start_vertex().clone(),
)
.insert(core)
.derive_from(self, core)
.derive_from(self, core);

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

half_edge
}
}
10 changes: 10 additions & 0 deletions crates/fj-core/src/operations/split/half_edge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use fj_math::Point;

use crate::{
geometry::HalfEdgeGeometry,
objects::{HalfEdge, Vertex},
operations::insert::Insert,
storage::Handle,
Expand Down Expand Up @@ -57,6 +58,15 @@ impl SplitHalfEdge for HalfEdge {
)
.insert(core);

core.layers.geometry.define_half_edge(
a.clone(),
HalfEdgeGeometry { path: self.path() },
);
core.layers.geometry.define_half_edge(
b.clone(),
HalfEdgeGeometry { path: self.path() },
);

[a, b]
}
}
12 changes: 10 additions & 2 deletions crates/fj-core/src/operations/transform/edge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use fj_math::Transform;

use crate::{
objects::HalfEdge, operations::insert::Insert, storage::Handle, Core,
geometry::HalfEdgeGeometry, objects::HalfEdge, operations::insert::Insert,
storage::Handle, Core,
};

use super::{TransformCache, TransformObject};
Expand All @@ -26,6 +27,13 @@ impl TransformObject for Handle<HalfEdge> {
.clone()
.transform_with_cache(transform, core, cache);

HalfEdge::new(path, boundary, curve, start_vertex).insert(core)
let half_edge =
HalfEdge::new(path, boundary, curve, start_vertex).insert(core);

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

half_edge
}
}

0 comments on commit c7906ad

Please sign in to comment.