Skip to content

Commit

Permalink
Merge pull request #1664 from hannobraun/unify
Browse files Browse the repository at this point in the history
Unify `HalfEdge` and `PartialHalfEdge`
  • Loading branch information
hannobraun authored Mar 10, 2023
2 parents d0db03c + b3fbd96 commit 2add4db
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 130 deletions.
18 changes: 5 additions & 13 deletions crates/fj-kernel/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ mod tests {
builder::{CycleBuilder, HalfEdgeBuilder},
geometry::{curve::GlobalPath, surface::SurfaceGeometry},
insert::Insert,
objects::Surface,
partial::{PartialCycle, PartialHalfEdge, PartialObject},
objects::{HalfEdge, Surface},
partial::{PartialCycle, PartialObject},
services::Services,
};

Expand All @@ -285,10 +285,7 @@ mod tests {
&mut services.objects,
);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
};

let tolerance = 1.;
Expand All @@ -314,10 +311,7 @@ mod tests {
&mut services.objects,
);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
};

let tolerance = 1.;
Expand All @@ -338,14 +332,13 @@ mod tests {
v: [0., 0., 1.].into(),
})
.insert(&mut services.objects);
let half_edge = PartialHalfEdge::make_line_segment(
let half_edge = HalfEdge::make_line_segment(
[[0., 1.], [TAU, 1.]],
Some(range.boundary),
None,
None,
&mut services.objects,
)
.build(&mut services.objects);
);

let tolerance = 1.;
let approx = (&half_edge, surface.deref()).approx(tolerance);
Expand All @@ -369,8 +362,7 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xz_plane();
let half_edge = PartialHalfEdge::make_circle(1., &mut services.objects)
.build(&mut services.objects);
let half_edge = HalfEdge::make_circle(1., &mut services.objects);

let tolerance = 1.;
let approx = (&half_edge, surface.deref()).approx(tolerance);
Expand Down
8 changes: 4 additions & 4 deletions crates/fj-kernel/src/algorithms/intersect/curve_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ mod tests {
&mut services.objects,
);

half_edge.build(&mut services.objects)
half_edge
};

let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
Expand All @@ -119,7 +119,7 @@ mod tests {
&mut services.objects,
);

half_edge.build(&mut services.objects)
half_edge
};

let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
Expand All @@ -145,7 +145,7 @@ mod tests {
&mut services.objects,
);

half_edge.build(&mut services.objects)
half_edge
};

let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
Expand All @@ -166,7 +166,7 @@ mod tests {
&mut services.objects,
);

half_edge.build(&mut services.objects)
half_edge
};

let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
Expand Down
5 changes: 2 additions & 3 deletions crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
builder::{CycleBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{Face, HalfEdge, Objects, Surface, Vertex},
partial::{PartialFace, PartialHalfEdge, PartialObject},
partial::{PartialFace, PartialObject},
services::Service,
storage::Handle,
};
Expand Down Expand Up @@ -88,7 +88,7 @@ impl Sweep for (Handle<HalfEdge>, &Handle<Vertex>, &Surface, Color) {
.zip_ext(vertices)
.zip_ext(global_edges)
.map(|((((boundary, start), end), start_vertex), global_edge)| {
let half_edge = PartialHalfEdge::make_line_segment(
let half_edge = HalfEdge::make_line_segment(
[start, end],
Some(boundary),
Some(start_vertex),
Expand All @@ -104,7 +104,6 @@ impl Sweep for (Handle<HalfEdge>, &Handle<Vertex>, &Surface, Color) {
// And we're done creating the face! All that's left to do is build our
// return values.
let face = face.build(objects).insert(objects);
let edge_top = edge_top.build(objects);
(face, edge_top)
}
}
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/algorithms/sweep/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Sweep for Handle<Face> {
faces.push(face);

top_edges.push((
Partial::from(top_edge),
top_edge,
half_edge.curve(),
half_edge.boundary(),
));
Expand Down
25 changes: 13 additions & 12 deletions crates/fj-kernel/src/builder/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use fj_math::Point;
use crate::{
geometry::curve::Curve,
objects::{HalfEdge, Objects},
partial::{Partial, PartialCycle, PartialHalfEdge},
partial::PartialCycle,
services::Service,
storage::Handle,
};

use super::{HalfEdgeBuilder, ObjectArgument};
Expand All @@ -20,14 +21,14 @@ pub trait CycleBuilder {
///
/// If this is the first half-edge being added, it is connected to itself,
/// meaning its front and back vertices are the same.
fn add_half_edge(&mut self, half_edge: Partial<HalfEdge>);
fn add_half_edge(&mut self, half_edge: Handle<HalfEdge>);

/// Update cycle as a polygon from the provided points
fn update_as_polygon_from_points<O, P>(
&mut self,
points: O,
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
) -> O::SameSize<Handle<HalfEdge>>
where
O: ObjectArgument<P>,
P: Clone + Into<Point<2>>;
Expand All @@ -42,27 +43,27 @@ pub trait CycleBuilder {
&mut self,
edges: O,
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
) -> O::SameSize<Handle<HalfEdge>>
where
O: ObjectArgument<(Partial<HalfEdge>, Curve, [Point<1>; 2])>;
O: ObjectArgument<(Handle<HalfEdge>, Curve, [Point<1>; 2])>;
}

impl CycleBuilder for PartialCycle {
fn add_half_edge(&mut self, half_edge: Partial<HalfEdge>) {
fn add_half_edge(&mut self, half_edge: Handle<HalfEdge>) {
self.half_edges.push(half_edge);
}

fn update_as_polygon_from_points<O, P>(
&mut self,
points: O,
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
) -> O::SameSize<Handle<HalfEdge>>
where
O: ObjectArgument<P>,
P: Clone + Into<Point<2>>,
{
points.map_with_next(|start, end| {
let half_edge = PartialHalfEdge::make_line_segment(
let half_edge = HalfEdge::make_line_segment(
[start, end],
None,
None,
Expand All @@ -80,15 +81,15 @@ impl CycleBuilder for PartialCycle {
&mut self,
edges: O,
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
) -> O::SameSize<Handle<HalfEdge>>
where
O: ObjectArgument<(Partial<HalfEdge>, Curve, [Point<1>; 2])>,
O: ObjectArgument<(Handle<HalfEdge>, Curve, [Point<1>; 2])>,
{
edges.map_with_prev(|(_, curve, boundary), (prev, _, _)| {
let half_edge = PartialHalfEdge::make_half_edge(
let half_edge = HalfEdge::make_half_edge(
curve,
boundary,
Some(prev.read().start_vertex.clone()),
Some(prev.start_vertex().clone()),
None,
objects,
);
Expand Down
32 changes: 15 additions & 17 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ use crate::{
geometry::curve::Curve,
insert::Insert,
objects::{GlobalEdge, HalfEdge, Objects, Vertex},
partial::{Partial, PartialHalfEdge},
services::Service,
storage::Handle,
};

/// Builder API for [`PartialHalfEdge`]
/// Builder API for [`HalfEdge`]
pub trait HalfEdgeBuilder {
/// Create a circle
fn make_circle(
radius: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge>;
) -> Handle<HalfEdge>;

/// Create an arc
///
Expand All @@ -28,7 +27,7 @@ pub trait HalfEdgeBuilder {
end: impl Into<Point<2>>,
angle_rad: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge>;
) -> Handle<HalfEdge>;

/// Create a line segment
fn make_line_segment(
Expand All @@ -37,7 +36,7 @@ pub trait HalfEdgeBuilder {
start_vertex: Option<Handle<Vertex>>,
global_form: Option<Handle<GlobalEdge>>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge>;
) -> Handle<HalfEdge>;

/// Create a half-edge
fn make_half_edge(
Expand All @@ -46,14 +45,14 @@ pub trait HalfEdgeBuilder {
start_vertex: Option<Handle<Vertex>>,
global_form: Option<Handle<GlobalEdge>>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge>;
) -> Handle<HalfEdge>;
}

impl HalfEdgeBuilder for PartialHalfEdge {
impl HalfEdgeBuilder for HalfEdge {
fn make_circle(
radius: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge> {
) -> Handle<HalfEdge> {
let curve = Curve::circle_from_radius(radius);
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
Expand All @@ -66,7 +65,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
end: impl Into<Point<2>>,
angle_rad: impl Into<Scalar>,
objects: &mut Service<Objects>,
) -> Partial<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");
Expand All @@ -88,7 +87,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
start_vertex: Option<Handle<Vertex>>,
global_form: Option<Handle<GlobalEdge>>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge> {
) -> Handle<HalfEdge> {
let boundary =
boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from));
let curve = Curve::line_from_points_with_coords(
Expand All @@ -110,14 +109,13 @@ impl HalfEdgeBuilder for PartialHalfEdge {
start_vertex: Option<Handle<Vertex>>,
global_form: Option<Handle<GlobalEdge>>,
objects: &mut Service<Objects>,
) -> Partial<HalfEdge> {
Partial::from_partial(PartialHalfEdge {
) -> Handle<HalfEdge> {
HalfEdge::new(
curve,
boundary,
start_vertex: start_vertex
.unwrap_or_else(|| Vertex::new().insert(objects)),
global_form: global_form
.unwrap_or_else(|| GlobalEdge::new().insert(objects)),
})
start_vertex.unwrap_or_else(|| Vertex::new().insert(objects)),
global_form.unwrap_or_else(|| GlobalEdge::new().insert(objects)),
)
.insert(objects)
}
}
34 changes: 32 additions & 2 deletions crates/fj-kernel/src/partial/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,39 @@ mod wrapper;

pub use self::{
objects::{
cycle::PartialCycle, edge::PartialHalfEdge, face::PartialFace,
shell::PartialShell, sketch::PartialSketch, solid::PartialSolid,
cycle::PartialCycle, face::PartialFace, shell::PartialShell,
sketch::PartialSketch, solid::PartialSolid,
},
traits::{HasPartial, PartialObject},
wrapper::{FullToPartialCache, Partial},
};

use crate::storage::Handle;

/// Either a full or a partial object
///
/// # Implementation Note
///
/// This enum temporarily exists to aid in the transition towards a unified
/// object system. Issue:
/// <https://github.com/hannobraun/Fornjot/issues/1570>
#[derive(Clone, Debug)]
pub enum FullOrPartial<T: HasPartial + 'static> {
/// A full object
Full(Handle<T>),

/// A partial object
Partial(Partial<T>),
}

impl<T: HasPartial> From<Handle<T>> for FullOrPartial<T> {
fn from(object: Handle<T>) -> Self {
Self::Full(object)
}
}

impl<T: HasPartial> From<Partial<T>> for FullOrPartial<T> {
fn from(object: Partial<T>) -> Self {
Self::Partial(object)
}
}
22 changes: 7 additions & 15 deletions crates/fj-kernel/src/partial/objects/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::{
objects::{Cycle, HalfEdge, Objects},
partial::{FullToPartialCache, Partial, PartialObject},
partial::{FullToPartialCache, PartialObject},
services::Service,
storage::Handle,
};

/// A partial [`Cycle`]
#[derive(Clone, Debug)]
pub struct PartialCycle {
/// The half-edges that make up the cycle
pub half_edges: Vec<Partial<HalfEdge>>,
pub half_edges: Vec<Handle<HalfEdge>>,
}

impl PartialObject for PartialCycle {
Expand All @@ -20,22 +21,13 @@ impl PartialObject for PartialCycle {
}
}

fn from_full(cycle: &Self::Full, cache: &mut FullToPartialCache) -> Self {
fn from_full(cycle: &Self::Full, _: &mut FullToPartialCache) -> Self {
Self {
half_edges: cycle
.half_edges()
.cloned()
.map(|half_edge| Partial::from_full(half_edge, cache))
.collect(),
half_edges: cycle.half_edges().cloned().collect(),
}
}

fn build(self, objects: &mut Service<Objects>) -> Self::Full {
let half_edges = self
.half_edges
.into_iter()
.map(|half_edge| half_edge.build(objects));

Cycle::new(half_edges)
fn build(self, _: &mut Service<Objects>) -> Self::Full {
Cycle::new(self.half_edges)
}
}
Loading

0 comments on commit 2add4db

Please sign in to comment.