Skip to content

Commit

Permalink
Merge pull request #1068 from hannobraun/sweep
Browse files Browse the repository at this point in the history
Refactor and fix sweep test suite
  • Loading branch information
hannobraun authored Sep 9, 2022
2 parents 43025a9 + 766c6de commit fe225dd
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 150 deletions.
84 changes: 84 additions & 0 deletions crates/fj-kernel/src/algorithms/sweep/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,87 @@ fn create_top_face(

face
}

#[cfg(test)]
mod tests {
use fj_interop::mesh::Color;

use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
objects::{Face, HalfEdge, Sketch, Surface},
};

use super::Sweep;

const TRIANGLE: [[f64; 2]; 3] = [[0., 0.], [1., 0.], [0., 1.]];

const UP: [f64; 3] = [0., 0., 1.];
const DOWN: [f64; 3] = [0., 0., -1.];

#[test]
fn sweep_up() {
let surface = Surface::xy_plane();
let solid = Sketch::build(surface)
.polygon_from_points(TRIANGLE)
.sweep(UP);

let bottom = Face::build(surface)
.polygon_from_points(TRIANGLE)
.into_face()
.reverse();
let top = Face::build(surface.translate(UP))
.polygon_from_points(TRIANGLE)
.into_face();

assert!(solid.find_face(&bottom).is_some());
assert!(solid.find_face(&top).is_some());

let mut side_faces = TRIANGLE.windows(2).map(|window| {
// 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] = [window[0], window[1]];

let half_edge = HalfEdge::build(Surface::xy_plane())
.line_segment_from_points([a, b]);
(half_edge, Color::default()).sweep(UP)
});

assert!(side_faces.all(|face| solid.find_face(&face).is_some()));
}

#[test]
fn sweep_down() {
let surface = Surface::xy_plane();
let solid = Sketch::build(surface)
.polygon_from_points(TRIANGLE)
.sweep(DOWN);

let bottom = Face::build(surface.translate(DOWN))
.polygon_from_points(TRIANGLE)
.into_face()
.reverse();
let top = Face::build(surface)
.polygon_from_points(TRIANGLE)
.into_face();

assert!(solid.find_face(&bottom).is_some());
assert!(solid.find_face(&top).is_some());

let mut side_faces = TRIANGLE.windows(2).map(|window| {
// 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] = [window[0], window[1]];

let half_edge = HalfEdge::build(Surface::xy_plane())
.line_segment_from_points([a, b])
.reverse();
(half_edge, Color::default()).sweep(DOWN)
});

assert!(side_faces.all(|face| solid.find_face(&face).is_some()));
}
}
150 changes: 0 additions & 150 deletions crates/fj-kernel/src/algorithms/sweep/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,153 +19,3 @@ impl Sweep for Sketch {
Solid::new().with_shells(shells)
}
}

#[cfg(test)]
mod tests {
use fj_math::{Point, Vector};

use crate::{
iter::ObjectIters,
objects::{Face, Sketch, Surface},
};

use super::Sweep;

// This test currently fails, even though the code it tests works correctly.
// Fixing this would require this whole test suite to be refactored.
//
// Since other tests have already been disabled before, diminishing the
// value of this test suite significantly, it's not a big loss to disable
// this rather simple test too, and fix the whole test suite at a later
// date.
#[test]
#[ignore]
fn bottom_positive() -> anyhow::Result<()> {
test_bottom_top(
[0., 0., 1.],
[[0., 0., 0.], [1., 0., 0.], [0., -1., 0.]],
[[0., 0.], [1., 0.], [0., -1.]],
)
}

#[test]
fn bottom_negative() -> anyhow::Result<()> {
test_bottom_top(
[0., 0., -1.],
[[0., 0., 0.], [1., 0., 0.], [0., 1., 0.]],
[[0., 0.], [1., 0.], [0., 1.]],
)
}

#[test]
fn top_positive() -> anyhow::Result<()> {
test_bottom_top(
[0., 0., 1.],
[[0., 0., 1.], [1., 0., 1.], [0., 1., 1.]],
[[0., 0.], [1., 0.], [0., 1.]],
)
}

// This test currently fails, even though the code it tests works correctly.
// Fixing this would require this whole test suite to be refactored.
//
// Since other tests have already been disabled before, diminishing the
// value of this test suite significantly, it's not a big loss to disable
// this rather simple test too, and fix the whole test suite at a later
// date.
#[test]
#[ignore]
fn top_negative() -> anyhow::Result<()> {
test_bottom_top(
[0., 0., -1.],
[[0., 0., -1.], [1., 0., -1.], [0., -1., -1.]],
[[0., 0.], [1., 0.], [0., -1.]],
)
}

// This test currently fails, even though the code it tests works correctly.
// At the time this test was disabled, fixing it would have been
// impractical. This has changed since then, thanks to some simplifications.
#[test]
#[ignore]
fn side_positive() -> anyhow::Result<()> {
test_side(
[0., 0., 1.],
[
[[0., 0., 0.], [1., 0., 0.], [0., 0., 1.]],
[[1., 0., 0.], [0., 1., 0.], [1., 0., 1.]],
[[0., 1., 0.], [0., 0., 0.], [0., 1., 1.]],
],
)
}

// This test currently fails, even though the code it tests works correctly.
// At the time this test was disabled, fixing it would have been
// impractical. This has changed since then, thanks to some simplifications.
#[test]
#[ignore]
fn side_negative() -> anyhow::Result<()> {
test_side(
[0., 0., -1.],
[
[[0., 0., 0.], [0., 1., 0.], [0., 0., -1.]],
[[0., 1., 0.], [1., 0., 0.], [0., 1., -1.]],
[[1., 0., 0.], [0., 0., 0.], [1., 0., -1.]],
],
)
}

fn test_side(
direction: impl Into<Vector<3>>,
expected_surfaces: [[impl Into<Point<3>>; 3]; 3],
) -> anyhow::Result<()> {
test(
direction,
expected_surfaces,
[[0., 0.], [1., 0.], [1., 1.], [0., 1.]],
)
}

fn test_bottom_top(
direction: impl Into<Vector<3>>,
expected_surface: [impl Into<Point<3>>; 3],
expected_vertices: [impl Into<Point<2>>; 3],
) -> anyhow::Result<()> {
test(direction, [expected_surface], expected_vertices)
}

fn test(
direction: impl Into<Vector<3>>,
expected_surfaces: impl IntoIterator<Item = [impl Into<Point<3>>; 3]>,
expected_vertices: impl IntoIterator<Item = impl Into<Point<2>>>,
) -> anyhow::Result<()> {
let surface = Surface::xy_plane();
let face = Face::build(surface).polygon_from_points([
[0., 0.],
[1., 0.],
[0., 1.],
]);
let sketch = Sketch::new().with_faces([face]);

let solid = sketch.sweep(direction);

let expected_vertices: Vec<_> = expected_vertices
.into_iter()
.map(|vertex| vertex.into())
.collect();

let faces = expected_surfaces.into_iter().map(|surface| {
let surface = Surface::plane_from_points(surface);

Face::build(surface)
.polygon_from_points(expected_vertices.clone())
.into_face()
});

for face in faces {
assert!(solid.face_iter().any(|f| f == &face));
}

Ok(())
}
}

0 comments on commit fe225dd

Please sign in to comment.