Skip to content

Commit

Permalink
Remove sweep tests
Browse files Browse the repository at this point in the history
Those tests are a constant thorn in my side. They resist every
refactoring I do, and always need to be carefully massaged to keep
working. I'm facing another of those moments, and I have enough.

The results of the sweep are somewhat easy to inspect manually, and in
combination with validation checks and export validation, it should be
easy enough to keep the sweep code under control, despite the lack of
direct automated testing.

This is not ideal, of course. But I need to make progress. And since the
sweep code will likely not survive the coming clean-ups in its current
form anyway, it probably makes more sense to build up a new test suite
in parallel to whatever the rewritten sweep code ends up being.
  • Loading branch information
hannobraun committed Feb 27, 2023
1 parent bdab868 commit 213635a
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 337 deletions.
141 changes: 0 additions & 141 deletions crates/fj-kernel/src/algorithms/sweep/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,144 +142,3 @@ impl Sweep for (Handle<HalfEdge>, &Handle<SurfaceVertex>, &Surface, Color) {
(face, edge_top)
}
}

#[cfg(test)]
mod tests {
use std::ops::Deref;

use fj_interop::{ext::ArrayExt, mesh::Color};
use fj_math::Point;
use pretty_assertions::assert_eq;

use crate::{
algorithms::sweep::Sweep,
builder::HalfEdgeBuilder,
insert::Insert,
partial::{
Partial, PartialCycle, PartialFace, PartialHalfEdge, PartialObject,
},
services::Services,
};

#[test]
fn sweep() {
let mut services = Services::new();

let surface = services.objects.surfaces.xy_plane();

let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points([[0., 0.], [1., 0.]]);
half_edge.infer_vertex_positions_if_necessary(&surface.geometry());

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

let (face, _) = (
half_edge.clone(),
half_edge.surface_vertices()[1],
surface.deref(),
Color::default(),
)
.sweep([0., 0., 1.], &mut services.objects);

let expected_face = {
let surface = services.objects.surfaces.xz_plane();

let bottom = {
let mut half_edge = PartialHalfEdge::default();
half_edge
.update_as_line_segment_from_points([[0., 0.], [1., 0.]]);

half_edge
};
let side_up = {
let mut side_up = PartialHalfEdge::default();

{
let [back, front] = side_up.surface_vertices.each_mut_ext();

*back = bottom.surface_vertices[1].clone();

let mut front = front.write();
front.position = Some([1., 1.].into());
}

side_up.infer_global_form();
side_up.update_as_line_segment();

side_up
};
let top = {
let mut top = PartialHalfEdge::default();

{
let [back, front] = top.boundary.each_mut_ext();
let [back_surface, front_surface] =
top.surface_vertices.each_mut_ext();

*back = Some(Point::from([1.]));
*back_surface = side_up.surface_vertices[1].clone();

*front = Some(Point::from([0.]));
let mut front_surface = front_surface.write();
front_surface.position = Some([0., 1.].into());
}

top.infer_global_form();
top.update_as_line_segment();
top.infer_vertex_positions_if_necessary(&surface.geometry());

Partial::from(
top.build(&mut services.objects)
.insert(&mut services.objects),
)
.read()
.clone()
};
let side_down = {
let mut side_down = PartialHalfEdge::default();

let [back, front] = side_down.boundary.each_mut_ext();
let [back_surface, front_surface] =
side_down.surface_vertices.each_mut_ext();

*back = Some(Point::from([1.]));
*front = Some(Point::from([0.]));

*back_surface = top.surface_vertices[1].clone();
*front_surface = bottom.surface_vertices[0].clone();

side_down.infer_global_form();
side_down.update_as_line_segment();
side_down
.infer_vertex_positions_if_necessary(&surface.geometry());

Partial::from(
side_down
.build(&mut services.objects)
.insert(&mut services.objects),
)
.read()
.clone()
};

let mut cycle = PartialCycle::default();
cycle.half_edges.extend(
[bottom, side_up, top, side_down].map(Partial::from_partial),
);

let face = PartialFace {
surface: Partial::from(surface),
exterior: Partial::from_partial(cycle),
..Default::default()
};
face.build(&mut services.objects)
.insert(&mut services.objects)
};

assert_eq!(face, expected_face);
}
}
196 changes: 0 additions & 196 deletions crates/fj-kernel/src/algorithms/sweep/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,199 +135,3 @@ impl Sweep for Handle<Face> {
PartialShell { faces }.build(objects).insert(objects)
}
}

#[cfg(test)]
mod tests {
use std::ops::Deref;

use fj_interop::{ext::SliceExt, mesh::Color};

use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
builder::{CycleBuilder, HalfEdgeBuilder, SketchBuilder},
insert::Insert,
partial::{
Partial, PartialFace, PartialHalfEdge, PartialObject, PartialSketch,
},
services::Services,
};

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 mut services = Services::new();

let surface = services.objects.surfaces.xy_plane();
let sketch = {
let mut sketch = PartialSketch::default();

let mut face = sketch.add_face();
face.write().surface = Partial::from(surface.clone());
face.write()
.exterior
.write()
.update_as_polygon_from_points(TRIANGLE);

sketch
};
let solid = sketch
.build(&mut services.objects)
.insert(&mut services.objects)
.sweep(UP, &mut services.objects);

let bottom = {
let mut bottom = PartialFace {
surface: Partial::from(surface.clone()),
..Default::default()
};

bottom
.exterior
.write()
.update_as_polygon_from_points(TRIANGLE);

bottom
.build(&mut services.objects)
.insert(&mut services.objects)
.reverse(&mut services.objects)
};
let top = {
let surface = surface.clone().translate(UP, &mut services.objects);

let mut top = PartialFace {
surface: Partial::from(surface),
..Default::default()
};

top.exterior.write().update_as_polygon_from_points(TRIANGLE);

top.build(&mut services.objects)
.insert(&mut services.objects)
};

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

let triangle = TRIANGLE.as_slice();
let side_faces = triangle.array_windows_ext().map(|&[a, b]| {
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points([a, b]);
half_edge
.infer_vertex_positions_if_necessary(&surface.geometry());

half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
};
let (face, _) = (
half_edge.clone(),
half_edge.surface_vertices()[1],
surface.deref(),
Color::default(),
)
.sweep(UP, &mut services.objects);
face
});

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

#[test]
fn sweep_down() {
let mut services = Services::new();

let surface = services.objects.surfaces.xy_plane();
let sketch = {
let mut sketch = PartialSketch::default();

let mut face = sketch.add_face();
face.write().surface = Partial::from(surface.clone());
face.write()
.exterior
.write()
.update_as_polygon_from_points(TRIANGLE);

sketch
};
let solid = sketch
.build(&mut services.objects)
.insert(&mut services.objects)
.sweep(DOWN, &mut services.objects);

let bottom = {
let surface =
surface.clone().translate(DOWN, &mut services.objects);

let mut bottom = PartialFace {
surface: Partial::from(surface),
..Default::default()
};

bottom
.exterior
.write()
.update_as_polygon_from_points(TRIANGLE);

bottom
.build(&mut services.objects)
.insert(&mut services.objects)
.reverse(&mut services.objects)
};
let top = {
let mut top = PartialFace {
surface: Partial::from(surface.clone()),
..Default::default()
};

top.exterior.write().update_as_polygon_from_points(TRIANGLE);

top.build(&mut services.objects)
.insert(&mut services.objects)
};

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

let triangle = TRIANGLE.as_slice();
let side_faces = triangle.array_windows_ext().map(|&[a, b]| {
let half_edge = {
let mut half_edge = PartialHalfEdge::default();
half_edge.update_as_line_segment_from_points([a, b]);
half_edge
.infer_vertex_positions_if_necessary(&surface.geometry());

half_edge.boundary =
[half_edge.boundary[1], half_edge.boundary[0]];
half_edge.surface_vertices = [
half_edge.surface_vertices[1].clone(),
half_edge.surface_vertices[0].clone(),
];

half_edge
.build(&mut services.objects)
.insert(&mut services.objects)
};
let (face, _) = (
half_edge.clone(),
half_edge.surface_vertices()[1],
surface.deref(),
Color::default(),
)
.sweep(DOWN, &mut services.objects);
face
});

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

0 comments on commit 213635a

Please sign in to comment.