Skip to content

Commit

Permalink
Merge pull request #2103 from hannobraun/sweep
Browse files Browse the repository at this point in the history
Move `sweep` to `operations`; do some clean-up
  • Loading branch information
hannobraun authored Nov 20, 2023
2 parents d36fdba + e2df073 commit 9e9004c
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 103 deletions.
1 change: 0 additions & 1 deletion crates/fj-core/src/algorithms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@
pub mod approx;
pub mod bounding_volume;
pub mod intersect;
pub mod sweep;
pub mod transform;
pub mod triangulate;
1 change: 1 addition & 0 deletions crates/fj-core/src/operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ pub mod merge;
pub mod replace;
pub mod reverse;
pub mod split;
pub mod sweep;
pub mod update;
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ use crate::{
build::BuildCycle, insert::Insert, join::JoinCycle, reverse::Reverse,
},
services::Services,
storage::Handle,
};

use super::{Sweep, SweepCache};

impl Sweep for Handle<Face> {
type Swept = Handle<Shell>;
impl Sweep for &Face {
type Swept = Shell;

fn sweep_with_cache(
self,
Expand All @@ -41,7 +40,7 @@ impl Sweep for Handle<Face> {

let mut faces = Vec::new();

let bottom_face = bottom_face(self, path, services);
let bottom_face = bottom_face(self, path, services).insert(services);
faces.push(bottom_face.clone());

let top_surface =
Expand All @@ -65,12 +64,14 @@ impl Sweep for Handle<Face> {

let (side_face, top_edge) = (
bottom_half_edge.deref(),
bottom_half_edge_next.start_vertex(),
bottom_half_edge_next.start_vertex().clone(),
bottom_face.surface().deref(),
bottom_face.region().color(),
)
.sweep_with_cache(path, cache, services);

let side_face = side_face.insert(services);

faces.push(side_face);

top_edges.push((
Expand Down Expand Up @@ -101,19 +102,15 @@ impl Sweep for Handle<Face> {
let top_face = Face::new(top_surface, top_region).insert(services);
faces.push(top_face);

Shell::new(faces).insert(services)
Shell::new(faces)
}
}

fn bottom_face(
face: Handle<Face>,
path: Vector<3>,
services: &mut Services,
) -> Handle<Face> {
fn bottom_face(face: &Face, path: Vector<3>, services: &mut Services) -> Face {
let is_negative_sweep = {
let u = match face.surface().geometry().u {
GlobalPath::Circle(_) => todo!(
"Sweeping from faces defined in round surfaces is not \
"Sweeping from faces defined in rounded surfaces is not \
supported"
),
GlobalPath::Line(line) => line.direction(),
Expand All @@ -126,8 +123,8 @@ fn bottom_face(
};

if is_negative_sweep {
face
face.clone()
} else {
face.reverse(services).insert(services)
face.reverse(services)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use fj_math::{Point, Scalar, Vector};
use crate::{
objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex},
operations::{
build::BuildHalfEdge,
build::{BuildCycle, BuildHalfEdge},
insert::Insert,
update::{UpdateCycle, UpdateHalfEdge},
},
Expand All @@ -14,28 +14,29 @@ use crate::{

use super::{Sweep, SweepCache};

impl Sweep for (&HalfEdge, &Handle<Vertex>, &Surface, Option<Color>) {
type Swept = (Handle<Face>, Handle<HalfEdge>);
impl Sweep for (&HalfEdge, Handle<Vertex>, &Surface, Option<Color>) {
type Swept = (Face, Handle<HalfEdge>);

fn sweep_with_cache(
self,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
services: &mut Services,
) -> Self::Swept {
let (edge, next_vertex, surface, color) = self;
let (edge, end_vertex, surface, color) = self;
let path = path.into();

let surface =
(edge.path(), surface).sweep_with_cache(path, cache, services);
let surface = (edge.path(), surface)
.sweep_with_cache(path, cache, services)
.insert(services);

// Next, we need to define the boundaries of the face. Let's start with
// the global vertices and edges.
let (vertices, curves) = {
let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone);
let (curve_up, [_, c]) =
let [a, b] = [edge.start_vertex().clone(), end_vertex];
let (curve_up, c) =
b.clone().sweep_with_cache(path, cache, services);
let (curve_down, [_, d]) =
let (curve_down, d) =
a.clone().sweep_with_cache(path, cache, services);

(
Expand Down Expand Up @@ -75,7 +76,7 @@ impl Sweep for (&HalfEdge, &Handle<Vertex>, &Surface, Option<Color>) {
[[a, b], [c, d], [b, a], [d, c]]
};

let mut exterior = Some(Cycle::new([]));
let mut exterior = Cycle::empty();

// Armed with all of that, we're ready to create the edges.
let [_edge_bottom, _edge_up, edge_top, _edge_down] = boundaries
Expand All @@ -101,21 +102,15 @@ impl Sweep for (&HalfEdge, &Handle<Vertex>, &Surface, Option<Color>) {
edge.insert(services)
};

exterior = Some(
exterior.take().unwrap().add_half_edges([edge.clone()]),
);
exterior = exterior.add_half_edges([edge.clone()]);

edge
});

let region = Region::new(exterior.unwrap().insert(services), [], color)
.insert(services);

let exterior = exterior.insert(services);
let region = Region::new(exterior, [], color).insert(services);
let face = Face::new(surface, region);

// And we're done creating the face! All that's left to do is build our
// return values.
let face = face.insert(services);
(face, edge_top)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Sweeping objects along a path to create new objects
mod edge;
mod face;
mod half_edge;
mod path;
mod sketch;
mod vertex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ use fj_math::{Circle, Line, Vector};
use crate::{
geometry::{GlobalPath, SurfaceGeometry, SurfacePath},
objects::Surface,
operations::insert::Insert,
services::Services,
storage::Handle,
};

use super::{Sweep, SweepCache};

impl Sweep for (SurfacePath, &Surface) {
type Swept = Handle<Surface>;
type Swept = Surface;

fn sweep_with_cache(
self,
path: impl Into<Vector<3>>,
_: &mut SweepCache,
services: &mut Services,
_: &mut Services,
) -> Self::Swept {
let (curve, surface) = self;

Expand Down Expand Up @@ -72,6 +70,6 @@ impl Sweep for (SurfacePath, &Surface) {
}
};

Surface::new(SurfaceGeometry { u, v: path.into() }).insert(services)
Surface::new(SurfaceGeometry { u, v: path.into() })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::{

use super::{Sweep, SweepCache};

impl Sweep for (Handle<Sketch>, Handle<Surface>) {
type Swept = Handle<Solid>;
impl Sweep for (&Sketch, Handle<Surface>) {
type Swept = Solid;

fn sweep_with_cache(
self,
Expand All @@ -25,10 +25,12 @@ impl Sweep for (Handle<Sketch>, Handle<Surface>) {
for region in sketch.regions() {
let face =
Face::new(surface.clone(), region.clone()).insert(services);
let shell = face.sweep_with_cache(path, cache, services);
let shell = face
.sweep_with_cache(path, cache, services)
.insert(services);
shells.push(shell);
}

Solid::new(shells).insert(services)
Solid::new(shells)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
use super::{Sweep, SweepCache};

impl Sweep for Handle<Vertex> {
type Swept = (Handle<Curve>, [Self; 2]);
type Swept = (Handle<Curve>, Self);

fn sweep_with_cache(
self,
Expand All @@ -24,14 +24,12 @@ impl Sweep for Handle<Vertex> {
.or_insert_with(|| Curve::new().insert(services))
.clone();

let a = self.clone();
let b = cache
let vertex = cache
.vertices
.entry(self.id())
.or_insert_with(|| Vertex::new().insert(services))
.clone();
let vertices = [a, b];

(curve, vertices)
(curve, vertex)
}
}
28 changes: 13 additions & 15 deletions models/cuboid/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use fj::{
core::{
algorithms::sweep::Sweep,
objects::{Region, Sketch, Solid},
operations::{
build::{BuildRegion, BuildSketch},
insert::Insert,
sweep::Sweep,
update::UpdateSketch,
},
services::Services,
Expand All @@ -14,22 +14,20 @@ use fj::{
};

pub fn model(x: f64, y: f64, z: f64, services: &mut Services) -> Handle<Solid> {
let sketch = Sketch::empty()
.add_region(
Region::polygon(
[
[-x / 2., -y / 2.],
[x / 2., -y / 2.],
[x / 2., y / 2.],
[-x / 2., y / 2.],
],
services,
)
.insert(services),
let sketch = Sketch::empty().add_region(
Region::polygon(
[
[-x / 2., -y / 2.],
[x / 2., -y / 2.],
[x / 2., y / 2.],
[-x / 2., y / 2.],
],
services,
)
.insert(services);
.insert(services),
);

let surface = services.objects.surfaces.xy_plane();
let path = Vector::from([0., 0., z]);
(sketch, surface).sweep(path, services)
(&sketch, surface).sweep(path, services).insert(services)
}
20 changes: 7 additions & 13 deletions models/spacer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use fj::{
core::{
algorithms::sweep::Sweep,
objects::{Cycle, Region, Sketch, Solid},
operations::{
build::{BuildCycle, BuildRegion, BuildSketch},
insert::Insert,
reverse::Reverse,
sweep::Sweep,
update::{UpdateRegion, UpdateSketch},
},
services::Services,
Expand All @@ -20,21 +20,15 @@ pub fn model(
height: f64,
services: &mut Services,
) -> Handle<Solid> {
let sketch = Sketch::empty()
.add_region(
Region::circle(Point::origin(), outer, services)
.add_interiors([Cycle::circle(
Point::origin(),
inner,
services,
)
let sketch = Sketch::empty().add_region(
Region::circle(Point::origin(), outer, services)
.add_interiors([Cycle::circle(Point::origin(), inner, services)
.reverse(services)
.insert(services)])
.insert(services),
)
.insert(services);
.insert(services),
);

let surface = services.objects.surfaces.xy_plane();
let path = Vector::from([0., 0., height]);
(sketch, surface).sweep(path, services)
(&sketch, surface).sweep(path, services).insert(services)
}
28 changes: 13 additions & 15 deletions models/split/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use fj::{
core::{
algorithms::sweep::Sweep,
objects::{Region, Sketch, Solid},
operations::{
build::{BuildRegion, BuildSketch},
insert::Insert,
split::SplitFace,
sweep::Sweep,
update::{UpdateSketch, UpdateSolid},
},
services::Services,
Expand All @@ -19,24 +19,22 @@ pub fn model(
split_pos: f64,
services: &mut Services,
) -> Handle<Solid> {
let sketch = Sketch::empty()
.add_region(
Region::polygon(
[
[-size / 2., -size / 2.],
[size / 2., -size / 2.],
[size / 2., size / 2.],
[-size / 2., size / 2.],
],
services,
)
.insert(services),
let sketch = Sketch::empty().add_region(
Region::polygon(
[
[-size / 2., -size / 2.],
[size / 2., -size / 2.],
[size / 2., size / 2.],
[-size / 2., size / 2.],
],
services,
)
.insert(services);
.insert(services),
);

let surface = services.objects.surfaces.xy_plane();
let path = Vector::from([0., 0., size]);
let solid = (sketch, surface).sweep(path, services);
let solid = (&sketch, surface).sweep(path, services);

solid
.update_shell(solid.shells().only(), |shell| {
Expand Down
Loading

0 comments on commit 9e9004c

Please sign in to comment.