Skip to content

Commit

Permalink
Make use of Vertex sweep in Edge sweep
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Sep 2, 2022
1 parent 1603aba commit ae2bb10
Showing 1 changed file with 95 additions and 43 deletions.
138 changes: 95 additions & 43 deletions crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use fj_interop::mesh::Color;
use fj_math::{Point, Transform, Triangle};
use fj_math::{Line, Point, Scalar, Transform, Triangle};

use crate::{
algorithms::{
approx::{Approx, Tolerance},
reverse::Reverse,
},
objects::{
Curve, CurveKind, Cycle, Edge, Face, GlobalCurve, Surface, Vertex,
VerticesOfEdge,
Curve, CurveKind, Cycle, Edge, Face, GlobalCurve, GlobalEdge, Surface,
Vertex, VerticesOfEdge,
},
};

Expand Down Expand Up @@ -42,8 +42,6 @@ fn create_non_continuous_side_face(
tolerance: Tolerance,
color: Color,
) -> Face {
let vertices_bottom = edge.vertices().get_or_panic();

let edge = if path.is_negative_direction() {
edge.reverse()
} else {
Expand All @@ -52,59 +50,113 @@ fn create_non_continuous_side_face(

let surface = edge.curve().sweep(path, tolerance, color);

let vertices = {
let vertices_bottom = vertices_bottom.map(|vertex| *vertex.global());
// We can't use the edge we're sweeping from as the bottom edge, as that is
// not defined in the right surface. Let's create a new bottom edge, by
// swapping the surface of the original.
let bottom_edge = {
let vertices = edge.vertices().get_or_panic();

let vertices_top = vertices_bottom.map(|vertex| {
let side_edge = vertex.sweep(path, tolerance, color);
let [_, &vertex_top] = side_edge.vertices().get_or_panic();
vertex_top
});
let curve = {
let points = vertices.map(|vertex| {
(vertex.position(), [vertex.position().t, Scalar::ZERO])
});
let kind =
CurveKind::Line(Line::from_points_with_line_coords(points));

Curve::new(surface, kind, *edge.curve().global())
};

let [[a, b], [c, d]] = [vertices_bottom, vertices_top];
let vertices = {
let vertices = vertices.map(|vertex| {
Vertex::new(vertex.position(), curve, *vertex.global())
});
VerticesOfEdge::from_vertices(vertices)
};

if path.is_negative_direction() {
[b, a, c, d]
} else {
[a, b, d, c]
}
Edge::new(curve, vertices, *edge.global())
};

let cycle = {
let [a, b, c, d] = vertices;
let side_edges = bottom_edge
.vertices()
.get_or_panic()
.map(|&vertex| (vertex, surface).sweep(path, tolerance, color));

let mut vertices =
vec![([0., 0.], a), ([1., 0.], b), ([1., 1.], c), ([0., 1.], d)];
if let Some(vertex) = vertices.first().cloned() {
vertices.push(vertex);
}
let top_edge = {
let bottom_vertices = bottom_edge.vertices().get_or_panic();
let points_surface = bottom_vertices
.map(|vertex| Point::from([vertex.position().t, Scalar::ONE]));

let mut edges = Vec::new();
for vertices in vertices.windows(2) {
// Can't panic, as we passed `2` to `windows`.
//
// Can be cleaned up, once `array_windows` is stable"
// https://doc.rust-lang.org/std/primitive.slice.html#method.array_windows
let [a, b] = [&vertices[0], &vertices[1]];
let global_vertices = side_edges.map(|edge| {
let [_, vertex] = edge.vertices().get_or_panic();
*vertex.global()
});

let curve = {
let local = CurveKind::line_from_points([a.0, b.0]);
let curve = {
let [a_curve, b_curve] =
bottom_vertices.map(|vertex| vertex.position());
let [a_surface, b_surface] = points_surface;
let [a_global, b_global] =
global_vertices.map(|vertex| vertex.position());

let global = [a, b].map(|vertex| vertex.1.position());
let global =
GlobalCurve::from_kind(CurveKind::line_from_points(global));
let global = {
let line = Line::from_points_with_line_coords([
(a_curve, a_global),
(b_curve, b_global),
]);

Curve::new(surface, local, global)
GlobalCurve::from_kind(CurveKind::Line(line))
};

let vertices = VerticesOfEdge::from_vertices([
Vertex::new(Point::from([0.]), curve, a.1),
Vertex::new(Point::from([1.]), curve, b.1),
let line = Line::from_points_with_line_coords([
(a_curve, a_surface),
(b_curve, b_surface),
]);

let edge = Edge::from_curve_and_vertices(curve, vertices);
Curve::new(surface, CurveKind::Line(line), global)
};

let global = {
GlobalEdge::new(
*curve.global(),
VerticesOfEdge::from_vertices(global_vertices),
)
};

let vertices = {
// Can be cleaned up, once `zip` is stable:
// https://doc.rust-lang.org/std/primitive.array.html#method.zip
let [a_bottom, b_bottom] = bottom_vertices;
let [a_global, b_global] = global_vertices;
let vertices = [(a_bottom, a_global), (b_bottom, b_global)];

vertices.map(|(bottom, global)| {
Vertex::new(bottom.position(), curve, global)
})
};

Edge::new(curve, VerticesOfEdge::from_vertices(vertices), global)
};

let cycle = {
let a = bottom_edge;
let [d, b] = side_edges;
let c = top_edge;

let mut edges = [a, b, c, d];

// Make sure that edges are oriented correctly.
let mut i = 0;
while i < edges.len() {
let j = (i + 1) % edges.len();

let [_, prev_last] = edges[i].vertices().get_or_panic();
let [next_first, _] = edges[j].vertices().get_or_panic();

if prev_last.global() != next_first.global() {
edges[j] = edges[j].reverse();
}

edges.push(edge);
i += 1;
}

Cycle::new(surface, edges)
Expand Down

0 comments on commit ae2bb10

Please sign in to comment.