Skip to content

Commit

Permalink
Merge pull request #1636 from hannobraun/vertex
Browse files Browse the repository at this point in the history
Add `PartialHalfEdge::start_position`
  • Loading branch information
hannobraun authored Mar 1, 2023
2 parents f6f85d4 + 2716e4b commit 5fcb7a1
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 136 deletions.
49 changes: 24 additions & 25 deletions crates/fj-kernel/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,12 @@ mod tests {

use crate::{
algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint},
builder::{HalfEdgeBuilder, SurfaceBuilder},
builder::{CycleBuilder, HalfEdgeBuilder, SurfaceBuilder},
geometry::curve::GlobalPath,
insert::Insert,
partial::{PartialHalfEdge, PartialObject, PartialSurface},
partial::{
PartialCycle, PartialHalfEdge, PartialObject, PartialSurface,
},
services::Services,
};

Expand All @@ -244,17 +246,16 @@ mod tests {

let surface = services.objects.surfaces.xz_plane();
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
let mut cycle = PartialCycle::default();

half_edge.update_as_line_segment_from_points(
[[1., 1.], [2., 1.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([[1., 1.], [2., 1.], [1., 2.]]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
Expand All @@ -277,17 +278,16 @@ mod tests {
.build(&mut services.objects)
.insert(&mut services.objects);
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
let mut cycle = PartialCycle::default();

half_edge.update_as_line_segment_from_points(
[[1., 1.], [2., 1.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([[1., 1.], [2., 1.], [1., 2.]]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
Expand All @@ -310,21 +310,20 @@ mod tests {
.build(&mut services.objects)
.insert(&mut services.objects);
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
let mut cycle = PartialCycle::default();

half_edge.update_as_line_segment_from_points(
[[0., 1.], [1., 1.]],
half_edge.end_vertex.clone(),
);
let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([[0., 1.], [1., 1.], [1., 2.]]);

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

half_edge.infer_vertex_positions_if_necessary(
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

let half_edge = half_edge.read().clone();
half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
Expand Down
64 changes: 34 additions & 30 deletions crates/fj-kernel/src/algorithms/intersect/curve_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ mod tests {
use fj_math::Point;

use crate::{
builder::HalfEdgeBuilder,
builder::{CycleBuilder, HalfEdgeBuilder},
geometry::curve::Curve,
partial::{PartialHalfEdge, PartialObject},
partial::PartialCycle,
services::Services,
};

Expand All @@ -87,14 +87,13 @@ mod tests {
let surface = services.objects.surfaces.xy_plane();
let curve = Curve::u_axis();
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[[1., -1.], [1., 1.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([[1., -1.], [1., 1.], [0., 1.]]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
Expand All @@ -117,14 +116,17 @@ mod tests {
let surface = services.objects.surfaces.xy_plane();
let curve = Curve::u_axis();
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[[-1., -1.], [-1., 1.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([
[-1., -1.],
[-1., 1.],
[0., 1.],
]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
Expand All @@ -147,14 +149,17 @@ mod tests {
let surface = services.objects.surfaces.xy_plane();
let curve = Curve::u_axis();
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[[-1., -1.], [1., -1.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([
[-1., -1.],
[1., -1.],
[1., 1.],
]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
Expand All @@ -172,14 +177,13 @@ mod tests {
let surface = services.objects.surfaces.xy_plane();
let curve = Curve::u_axis();
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[[-1., 0.], [1., 0.]],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] = cycle
.update_as_polygon_from_points([[-1., 0.], [1., 0.], [1., 1.]]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
Expand Down
3 changes: 1 addition & 2 deletions crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ impl Sweep for (Handle<HalfEdge>, &Handle<SurfaceVertex>, &Surface, Color) {
.into_iter()
.circular_tuple_windows()
{
edge.write()
.update_as_line_segment(next.read().start_vertex.clone());
edge.write().update_as_line_segment(next.clone());
}

// Finally, we can make sure that all edges refer to the correct global
Expand Down
4 changes: 1 addition & 3 deletions crates/fj-kernel/src/builder/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ impl CycleBuilder for PartialCycle {
for (mut half_edge, next) in
self.half_edges.iter().cloned().circular_tuple_windows()
{
half_edge
.write()
.update_as_line_segment(next.read().start_vertex.clone());
half_edge.write().update_as_line_segment(next.clone());
}
}

Expand Down
61 changes: 22 additions & 39 deletions crates/fj-kernel/src/builder/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,13 @@ pub trait HalfEdgeBuilder {
fn update_as_arc(
&mut self,
angle_rad: impl Into<Scalar>,
next_vertex: Partial<SurfaceVertex>,
next_half_edge: Partial<HalfEdge>,
);

/// Update partial half-edge to be a line segment, from the given points
fn update_as_line_segment_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
next_vertex: Partial<SurfaceVertex>,
) -> Curve;

/// Update partial half-edge to be a line segment
fn update_as_line_segment(
&mut self,
next_vertex: Partial<SurfaceVertex>,
next_half_edge: Partial<HalfEdge>,
) -> Curve;

/// Infer the global form of the half-edge
Expand Down Expand Up @@ -104,17 +97,18 @@ impl HalfEdgeBuilder for PartialHalfEdge {
fn update_as_arc(
&mut self,
angle_rad: impl Into<Scalar>,
mut next_vertex: Partial<SurfaceVertex>,
mut next_half_edge: Partial<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");
}
let [start, end] = [&self.start_vertex, &next_vertex].map(|vertex| {
vertex
.read()
.position
.expect("Can't infer arc without surface position")
let [start, end] = [
&self.start_position(),
&next_half_edge.read().start_position(),
]
.map(|position| {
position.expect("Can't infer arc without surface position")
});

let arc = fj_math::Arc::from_endpoints_and_angle(start, end, angle_rad);
Expand All @@ -128,42 +122,31 @@ impl HalfEdgeBuilder for PartialHalfEdge {
for ((point_boundary, surface_vertex), point_curve) in self
.boundary
.each_mut_ext()
.zip_ext([&mut self.start_vertex, &mut next_vertex])
.zip_ext([
&mut self.start_vertex,
&mut next_half_edge.write().start_vertex,
])
.zip_ext([a_curve, b_curve])
{
*point_boundary = Some(point_curve);
surface_vertex.write().position =
Some(path.point_from_path_coords(point_curve));
}

self.infer_global_form(next_vertex);
}

fn update_as_line_segment_from_points(
&mut self,
points: [impl Into<Point<2>>; 2],
mut next_vertex: Partial<SurfaceVertex>,
) -> Curve {
for (vertex, point) in
[&mut self.start_vertex, &mut next_vertex].zip_ext(points)
{
let mut surface_form = vertex.write();
surface_form.position = Some(point.into());
}

self.update_as_line_segment(next_vertex)
self.infer_global_form(next_half_edge.read().start_vertex.clone());
}

fn update_as_line_segment(
&mut self,
next_vertex: Partial<SurfaceVertex>,
next_half_edge: Partial<HalfEdge>,
) -> Curve {
let boundary = self.boundary;
let points_surface = [&self.start_vertex, &next_vertex].map(|vertex| {
vertex
.read()
.position
.expect("Can't infer line segment without surface position")
let points_surface = [
&self.start_position(),
&next_half_edge.read().start_position(),
]
.map(|position| {
position.expect("Can't infer line segment without surface position")
});

let path = if let [Some(start), Some(end)] = boundary {
Expand All @@ -186,7 +169,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
path
};

self.infer_global_form(next_vertex);
self.infer_global_form(next_half_edge.read().start_vertex.clone());

path
}
Expand Down
31 changes: 15 additions & 16 deletions crates/fj-kernel/src/objects/full/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ mod tests {
use pretty_assertions::assert_eq;

use crate::{
builder::HalfEdgeBuilder,
partial::{PartialHalfEdge, PartialObject},
builder::{CycleBuilder, HalfEdgeBuilder},
partial::PartialCycle,
services::Services,
};

Expand All @@ -190,29 +190,28 @@ mod tests {

let a = [0., 0.];
let b = [1., 0.];
let c = [0., 1.];

let a_to_b = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[a, b],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] =
cycle.update_as_polygon_from_points([a, b, c]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
};
let b_to_a = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points(
[b, a],
half_edge.end_vertex.clone(),
);
half_edge.infer_vertex_positions_if_necessary(
let mut cycle = PartialCycle::default();

let [mut half_edge, next_half_edge, _] =
cycle.update_as_polygon_from_points([b, a, c]);
half_edge.write().infer_vertex_positions_if_necessary(
&surface.geometry(),
half_edge.end_vertex.clone(),
next_half_edge.read().start_vertex.clone(),
);

half_edge.build(&mut services.objects)
Expand Down
7 changes: 7 additions & 0 deletions crates/fj-kernel/src/partial/objects/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ pub struct PartialHalfEdge {
pub global_form: Partial<GlobalEdge>,
}

impl PartialHalfEdge {
/// Compute the surface position where the half-edge starts
pub fn start_position(&self) -> Option<Point<2>> {
self.start_vertex.read().position
}
}

impl PartialObject for PartialHalfEdge {
type Full = HalfEdge;

Expand Down
Loading

0 comments on commit 5fcb7a1

Please sign in to comment.