Merge pull request #732 from hannobraun/sweep

Fully decouple sweep algorithm from `Shape`
This commit is contained in:
Hanno Braun 2022-06-28 16:29:53 +02:00 committed by GitHub
commit e8c79ab0c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 23 deletions

View File

@ -12,17 +12,17 @@ use super::{CycleApprox, Tolerance};
/// Create a solid by sweeping a sketch /// Create a solid by sweeping a sketch
pub fn sweep( pub fn sweep(
source: Shape, source: Vec<Face>,
path: impl Into<Vector<3>>, path: impl Into<Vector<3>>,
tolerance: Tolerance, tolerance: Tolerance,
color: [u8; 4], color: [u8; 4],
) -> Shape { ) -> Vec<Face> {
let path = path.into(); let path = path.into();
let is_sweep_along_negative_direction = let is_sweep_along_negative_direction =
path.dot(&Vector::from([0., 0., 1.])) < Scalar::ZERO; path.dot(&Vector::from([0., 0., 1.])) < Scalar::ZERO;
let mut target = Shape::new(); let mut target = Vec::new();
for face in source.face_iter() { for face in source.face_iter() {
create_bottom_faces( create_bottom_faces(
@ -59,8 +59,10 @@ pub fn sweep(
fn create_bottom_faces( fn create_bottom_faces(
face: &Face, face: &Face,
is_sweep_along_negative_direction: bool, is_sweep_along_negative_direction: bool,
target: &mut Shape, target: &mut Vec<Face>,
) { ) {
let mut tmp = Shape::new();
let mut surface = face.surface(); let mut surface = face.surface();
let mut exteriors = face.brep().exteriors.clone(); let mut exteriors = face.brep().exteriors.clone();
@ -73,7 +75,7 @@ fn create_bottom_faces(
interiors = reverse_local_coordinates_in_cycle(&interiors); interiors = reverse_local_coordinates_in_cycle(&interiors);
}; };
let surface = target.insert(surface); let surface = tmp.insert(surface);
let face = Face::new( let face = Face::new(
surface, surface,
@ -81,14 +83,14 @@ fn create_bottom_faces(
interiors.as_local_form().cloned(), interiors.as_local_form().cloned(),
face.color(), face.color(),
); );
target.merge(face); target.push(face);
} }
fn create_top_face( fn create_top_face(
face: &Face, face: &Face,
path: Vector<3>, path: Vector<3>,
is_sweep_along_negative_direction: bool, is_sweep_along_negative_direction: bool,
target: &mut Shape, target: &mut Vec<Face>,
) { ) {
let mut surface = face.surface(); let mut surface = face.surface();
@ -110,7 +112,7 @@ fn create_top_face(
interiors = reverse_local_coordinates_in_cycle(&interiors); interiors = reverse_local_coordinates_in_cycle(&interiors);
}; };
let surface = target.insert(surface); let surface = tmp.insert(surface);
let face = Face::new( let face = Face::new(
surface, surface,
@ -118,7 +120,7 @@ fn create_top_face(
interiors.as_local_form().cloned(), interiors.as_local_form().cloned(),
face.color(), face.color(),
); );
target.merge(face); target.push(face);
} }
fn reverse_local_coordinates_in_cycle(cycles: &CyclesInFace) -> CyclesInFace { fn reverse_local_coordinates_in_cycle(cycles: &CyclesInFace) -> CyclesInFace {
@ -230,8 +232,10 @@ fn create_non_continuous_side_face(
is_sweep_along_negative_direction: bool, is_sweep_along_negative_direction: bool,
vertices_bottom: [Vertex; 2], vertices_bottom: [Vertex; 2],
color: [u8; 4], color: [u8; 4],
target: &mut Shape, target: &mut Vec<Face>,
) { ) {
let mut tmp = Shape::new();
let vertices = { let vertices = {
let vertices_top = vertices_bottom.map(|vertex| { let vertices_top = vertices_bottom.map(|vertex| {
let point = vertex.point + path; let point = vertex.point + path;
@ -246,14 +250,14 @@ fn create_non_continuous_side_face(
[a, b, d, c] [a, b, d, c]
}; };
vertices.map(|vertex| target.get_handle_or_insert(vertex)) vertices.map(|vertex| tmp.get_handle_or_insert(vertex))
}; };
let surface = { let surface = {
let [a, b, _, c] = vertices.clone().map(|vertex| vertex.get().point); let [a, b, _, c] = vertices.clone().map(|vertex| vertex.get().point);
Surface::plane_from_points([a, b, c]) Surface::plane_from_points([a, b, c])
}; };
let surface = target.get_handle_or_insert(surface); let surface = tmp.get_handle_or_insert(surface);
let cycle = { let cycle = {
let [a, b, c, d] = vertices; let [a, b, c, d] = vertices;
@ -277,7 +281,7 @@ fn create_non_continuous_side_face(
let global = [a, b].map(|vertex| vertex.1.get().point); let global = [a, b].map(|vertex| vertex.1.get().point);
let global = Curve::line_from_points(global); let global = Curve::line_from_points(global);
let global = target.get_handle_or_insert(global); let global = tmp.get_handle_or_insert(global);
LocalForm::new(local, global) LocalForm::new(local, global)
}; };
@ -297,7 +301,7 @@ fn create_non_continuous_side_face(
curve: LocalForm::canonical_only(curve.canonical()), curve: LocalForm::canonical_only(curve.canonical()),
vertices, vertices,
}; };
let global = target.get_handle_or_insert(global); let global = tmp.get_handle_or_insert(global);
LocalForm::new(local, global) LocalForm::new(local, global)
}; };
@ -310,7 +314,7 @@ fn create_non_continuous_side_face(
let global = let global =
Cycle::new(local.edges.iter().map(|edge| edge.canonical())); Cycle::new(local.edges.iter().map(|edge| edge.canonical()));
let global = target.get_handle_or_insert(global); let global = tmp.get_handle_or_insert(global);
LocalForm::new(local, global) LocalForm::new(local, global)
}; };
@ -319,7 +323,7 @@ fn create_non_continuous_side_face(
}; };
let face = Face::new(surface, [cycle], [], color); let face = Face::new(surface, [cycle], [], color);
target.get_handle_or_insert(face); target.push(face);
} }
fn create_continuous_side_face( fn create_continuous_side_face(
@ -327,7 +331,7 @@ fn create_continuous_side_face(
path: Vector<3>, path: Vector<3>,
tolerance: Tolerance, tolerance: Tolerance,
color: [u8; 4], color: [u8; 4],
target: &mut Shape, target: &mut Vec<Face>,
) { ) {
let translation = Transform::translation(path); let translation = Transform::translation(path);
@ -353,7 +357,7 @@ fn create_continuous_side_face(
side_face.push(([v0, v2, v3].into(), color)); side_face.push(([v0, v2, v3].into(), color));
} }
target.insert(Face::Triangles(side_face)); target.push(Face::Triangles(side_face));
} }
#[cfg(test)] #[cfg(test)]
@ -455,11 +459,13 @@ mod tests {
let mut shape = Shape::new(); let mut shape = Shape::new();
let _sketch = Face::builder(Surface::xy_plane(), &mut shape) let sketch = Face::builder(Surface::xy_plane(), &mut shape)
.with_exterior_polygon([[0., 0.], [1., 0.], [0., 1.]]) .with_exterior_polygon([[0., 0.], [1., 0.], [0., 1.]])
.build(); .build()
.get();
let solid = super::sweep(shape, direction, tolerance, [255, 0, 0, 255]); let solid =
super::sweep(vec![sketch], direction, tolerance, [255, 0, 0, 255]);
let expected_vertices: Vec<_> = expected_vertices let expected_vertices: Vec<_> = expected_vertices
.into_iter() .into_iter()

View File

@ -1,6 +1,7 @@
use fj_interop::debug::DebugInfo; use fj_interop::debug::DebugInfo;
use fj_kernel::{ use fj_kernel::{
algorithms::{sweep, Tolerance}, algorithms::{sweep, Tolerance},
iter::ObjectIters,
shape::Shape, shape::Shape,
validation::{validate, Validated, ValidationConfig, ValidationError}, validation::{validate, Validated, ValidationConfig, ValidationError},
}; };
@ -19,8 +20,15 @@ impl ToShape for fj::Sweep {
let path = Vector::from(self.path()); let path = Vector::from(self.path());
let color = self.shape().color(); let color = self.shape().color();
let swept = sweep(shape.into_inner(), path, tolerance, color); let shape = shape.face_iter().collect::<Vec<_>>();
let swept = validate(swept, config)?; let swept = sweep(shape, path, tolerance, color);
let mut shape = Shape::new();
for face in swept {
shape.merge(face);
}
let swept = validate(shape, config)?;
Ok(swept) Ok(swept)
} }