Skip to content

Commit

Permalink
Merge pull request #1663 from hannobraun/unify
Browse files Browse the repository at this point in the history
Make `PartialHalfEdge` mostly identical to `HalfEdge`
  • Loading branch information
hannobraun authored Mar 9, 2023
2 parents 42820b2 + 5427b55 commit d0db03c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 83 deletions.
24 changes: 8 additions & 16 deletions crates/fj-kernel/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,22 +338,14 @@ mod tests {
v: [0., 0., 1.].into(),
})
.insert(&mut services.objects);
let half_edge = {
let mut cycle = PartialCycle::new(&mut services.objects);

let [mut half_edge, _, _] = cycle.update_as_polygon_from_points(
[[0., 1.], [1., 1.], [1., 2.]],
&mut services.objects,
);

half_edge.write().boundary[0] = Some(range.boundary[0]);
half_edge.write().boundary[1] = Some(range.boundary[1]);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
};
let half_edge = PartialHalfEdge::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 Down
35 changes: 10 additions & 25 deletions crates/fj-kernel/src/algorithms/sweep/face.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::ops::Deref;

use fj_interop::ext::ArrayExt;
use fj_math::{Scalar, Vector};
use itertools::Itertools;

Expand Down Expand Up @@ -64,13 +63,6 @@ impl Sweep for Handle<Face> {
for (i, cycle) in bottom_face.all_cycles().cloned().enumerate() {
let cycle = cycle.reverse(objects);

let mut top_cycle = if i == 0 {
top_face.exterior.clone()
} else {
top_face.add_interior(objects)
};

let mut original_edges = Vec::new();
let mut top_edges = Vec::new();
for (half_edge, next) in
cycle.half_edges().cloned().circular_tuple_windows()
Expand All @@ -85,26 +77,19 @@ impl Sweep for Handle<Face> {

faces.push(face);

original_edges.push(half_edge);
top_edges.push(Partial::from(top_edge));
top_edges.push((
Partial::from(top_edge),
half_edge.curve(),
half_edge.boundary(),
));
}

let mut top_cycle = if i == 0 {
top_face.exterior.clone()
} else {
top_face.add_interior(objects)
};
top_cycle.write().connect_to_edges(top_edges, objects);

for (bottom, top) in original_edges
.into_iter()
.zip(top_cycle.write().half_edges.iter_mut())
{
top.write().curve = Some(bottom.curve());

let boundary = bottom.boundary();

for (top, bottom) in
top.write().boundary.each_mut_ext().zip_ext(boundary)
{
*top = Some(bottom);
}
}
}

let top_face = top_face.build(objects).insert(objects);
Expand Down
20 changes: 13 additions & 7 deletions crates/fj-kernel/src/builder/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use fj_math::Point;

use crate::{
geometry::curve::Curve,
objects::{HalfEdge, Objects},
partial::{Partial, PartialCycle, PartialHalfEdge},
services::Service,
Expand Down Expand Up @@ -43,7 +44,7 @@ pub trait CycleBuilder {
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
where
O: ObjectArgument<Partial<HalfEdge>>;
O: ObjectArgument<(Partial<HalfEdge>, Curve, [Point<1>; 2])>;
}

impl CycleBuilder for PartialCycle {
Expand Down Expand Up @@ -81,15 +82,20 @@ impl CycleBuilder for PartialCycle {
objects: &mut Service<Objects>,
) -> O::SameSize<Partial<HalfEdge>>
where
O: ObjectArgument<Partial<HalfEdge>>,
O: ObjectArgument<(Partial<HalfEdge>, Curve, [Point<1>; 2])>,
{
edges.map_with_prev(|_, prev| {
let mut edge: Partial<HalfEdge> = Partial::new(objects);
edge.write().start_vertex = prev.read().start_vertex.clone();
edges.map_with_prev(|(_, curve, boundary), (prev, _, _)| {
let half_edge = PartialHalfEdge::make_half_edge(
curve,
boundary,
Some(prev.read().start_vertex.clone()),
None,
objects,
);

self.add_half_edge(edge.clone());
self.add_half_edge(half_edge.clone());

edge
half_edge
})
}
}
4 changes: 2 additions & 2 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ impl HalfEdgeBuilder for PartialHalfEdge {
objects: &mut Service<Objects>,
) -> Partial<HalfEdge> {
Partial::from_partial(PartialHalfEdge {
curve: Some(curve),
boundary: boundary.map(Some),
curve,
boundary,
start_vertex: start_vertex
.unwrap_or_else(|| Vertex::new().insert(objects)),
global_form: global_form
Expand Down
47 changes: 14 additions & 33 deletions crates/fj-kernel/src/partial/objects/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use fj_math::Point;

use crate::{
geometry::curve::Curve,
insert::Insert,
objects::{GlobalEdge, HalfEdge, Objects, Vertex},
partial::{FullToPartialCache, PartialObject},
services::Service,
Expand All @@ -13,10 +12,10 @@ use crate::{
#[derive(Clone, Debug)]
pub struct PartialHalfEdge {
/// The curve that the half-edge is defined in
pub curve: Option<Curve>,
pub curve: Curve,

/// The boundary of the half-edge on the curve
pub boundary: [Option<Point<1>>; 2],
pub boundary: [Point<1>; 2],

/// The surface vertex where the half-edge starts
pub start_vertex: Handle<Vertex>,
Expand All @@ -25,48 +24,30 @@ pub struct PartialHalfEdge {
pub global_form: Handle<GlobalEdge>,
}

impl PartialHalfEdge {
/// Compute the surface position where the half-edge starts
pub fn start_position(&self) -> Option<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, _] = self.boundary;
start.and_then(|start| {
let curve = self.curve?;
Some(curve.point_from_path_coords(start))
})
}
}

impl PartialObject for PartialHalfEdge {
type Full = HalfEdge;

fn new(objects: &mut Service<Objects>) -> Self {
Self {
curve: None,
boundary: [None; 2],
start_vertex: Vertex::new().insert(objects),
global_form: GlobalEdge::new().insert(objects),
}
fn new(_: &mut Service<Objects>) -> Self {
// This method is no longer used, and since `PartialHalfEdge` will be
// replaced with `HalfEdge`, it will soon be removed.
unreachable!()
}

fn from_full(half_edge: &Self::Full, _: &mut FullToPartialCache) -> Self {
Self {
curve: Some(half_edge.curve()),
boundary: half_edge.boundary().map(Some),
curve: half_edge.curve(),
boundary: half_edge.boundary(),
start_vertex: half_edge.start_vertex().clone(),
global_form: half_edge.global_form().clone(),
}
}

fn build(self, _: &mut Service<Objects>) -> Self::Full {
let curve = self.curve.expect("Need path to build curve");
let boundary = self.boundary.map(|point| {
point.expect("Can't build `HalfEdge` without boundary positions")
});

HalfEdge::new(curve, boundary, self.start_vertex, self.global_form)
HalfEdge::new(
self.curve,
self.boundary,
self.start_vertex,
self.global_form,
)
}
}

0 comments on commit d0db03c

Please sign in to comment.