Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce fj-operations' reliance on Shape #734

Merged
merged 10 commits into from
Jun 28, 2022
32 changes: 16 additions & 16 deletions crates/fj-operations/src/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ impl ToShape for fj::Circle {
config: &ValidationConfig,
_: Tolerance,
_: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
let mut shape = Shape::new();
) -> Result<Validated<Vec<Face>>, ValidationError> {
let mut tmp = Shape::new();

// Circles have just a single round edge with no vertices. So none need
// to be added here.

let edge = Edge::builder(&mut shape)
let edge = Edge::builder(&mut tmp)
.build_circle(Scalar::from_f64(self.radius()));

let cycle_local = Cycle {
edges: vec![edge.clone()],
};
let cycle_canonical = shape.insert(Cycle::new(vec![edge.canonical()]));

let surface = shape.insert(Surface::xy_plane());
shape.insert(Face::new(
surface,
vec![LocalForm::new(cycle_local, cycle_canonical)],
Vec::new(),
self.color(),
));

let shape = validate(shape, config)?;

Ok(shape)
let cycle_canonical = tmp.insert(Cycle::new(vec![edge.canonical()]));

let surface = tmp.insert(Surface::xy_plane());
let face = tmp
.insert(Face::new(
surface,
vec![LocalForm::new(cycle_local, cycle_canonical)],
Vec::new(),
self.color(),
))
.get();

validate(vec![face], config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
38 changes: 18 additions & 20 deletions crates/fj-operations/src/difference_2d.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
iter::ObjectIters,
objects::{Cycle, Edge, Face},
shape::{LocalForm, Shape},
validation::{validate, Validated, ValidationConfig, ValidationError},
Expand All @@ -15,11 +16,11 @@ impl ToShape for fj::Difference2d {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
) -> Result<Validated<Vec<Face>>, ValidationError> {
// This method assumes that `b` is fully contained within `a`:
// https://github.com/hannobraun/Fornjot/issues/92

let mut difference = Shape::new();
let mut difference = Vec::new();

let mut exteriors = Vec::new();
let mut interiors = Vec::new();
Expand All @@ -32,13 +33,12 @@ impl ToShape for fj::Difference2d {
[a, b].map(|shape| shape.to_shape(config, tolerance, debug_info));
let [a, b] = [a?, b?];

if let Some(face) = a.faces().next() {
if let Some(face) = a.face_iter().next() {
// If there's at least one face to subtract from, we can proceed.

let surface = face.get().brep().surface.clone();
let surface = face.brep().surface.clone();

for face in a.faces() {
let face = face.get();
for face in a.face_iter() {
let face = face.brep();

assert_eq!(
Expand All @@ -48,17 +48,16 @@ impl ToShape for fj::Difference2d {
);

for cycle in face.exteriors.as_local_form().cloned() {
let cycle = add_cycle(cycle, &mut difference, false);
let cycle = add_cycle(cycle, false);
exteriors.push(cycle);
}
for cycle in face.interiors.as_local_form().cloned() {
let cycle = add_cycle(cycle, &mut difference, true);
let cycle = add_cycle(cycle, true);
interiors.push(cycle);
}
}

for face in b.faces() {
let face = face.get();
for face in b.face_iter() {
let face = face.brep();

assert_eq!(
Expand All @@ -68,22 +67,20 @@ impl ToShape for fj::Difference2d {
);

for cycle in face.exteriors.as_local_form().cloned() {
let cycle = add_cycle(cycle, &mut difference, true);
let cycle = add_cycle(cycle, true);
interiors.push(cycle);
}
}

difference.merge(Face::new(
difference.push(Face::new(
surface,
exteriors,
interiors,
self.color(),
));
}

let difference = validate(difference, config)?;

Ok(difference)
validate(difference, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand All @@ -96,9 +93,10 @@ impl ToShape for fj::Difference2d {

fn add_cycle(
cycle: LocalForm<Cycle<2>, Cycle<3>>,
shape: &mut Shape,
reverse: bool,
) -> LocalForm<Cycle<2>, Cycle<3>> {
let mut tmp = Shape::new();

let mut edges = Vec::new();
for edge in cycle.local().edges.clone() {
let curve_local = *edge.local().curve.local();
Expand All @@ -114,7 +112,7 @@ fn add_cycle(
} else {
curve_canonical
};
let curve_canonical = shape.insert(curve_canonical);
let curve_canonical = tmp.insert(curve_canonical);

let vertices = if reverse {
edge.local().vertices.clone().reverse()
Expand All @@ -126,7 +124,7 @@ fn add_cycle(
curve: LocalForm::new(curve_local, curve_canonical.clone()),
vertices: vertices.clone(),
};
let edge_canonical = shape.merge(Edge {
let edge_canonical = tmp.merge(Edge {
curve: LocalForm::canonical_only(curve_canonical),
vertices,
});
Expand All @@ -141,8 +139,8 @@ fn add_cycle(
let cycle_local = Cycle {
edges: edges.clone(),
};
let cycle_canonical = shape
.insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical())));
let cycle_canonical =
tmp.insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical())));

LocalForm::new(cycle_local, cycle_canonical)
}
14 changes: 6 additions & 8 deletions crates/fj-operations/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
shape::Shape,
objects::Face,
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::Aabb;
Expand All @@ -14,18 +14,16 @@ impl ToShape for fj::Group {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
let mut shape = Shape::new();
) -> Result<Validated<Vec<Face>>, ValidationError> {
let mut shape = Vec::new();

let a = self.a.to_shape(config, tolerance, debug_info)?;
let b = self.b.to_shape(config, tolerance, debug_info)?;

shape.merge_shape(&a);
shape.merge_shape(&b);
shape.extend(a.into_inner());
shape.extend(b.into_inner());

let shape = validate(shape, config)?;

Ok(shape)
validate(shape, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
6 changes: 3 additions & 3 deletions crates/fj-operations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mod transform;
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::Tolerance,
shape::Shape,
objects::Face,
validation::{Validated, ValidationConfig, ValidationError},
};
use fj_math::Aabb;
Expand All @@ -41,7 +41,7 @@ pub trait ToShape {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError>;
) -> Result<Validated<Vec<Face>>, ValidationError>;

/// Access the axis-aligned bounding box of a shape
///
Expand Down Expand Up @@ -94,6 +94,6 @@ dispatch! {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError>;
) -> Result<Validated<Vec<Face>>, ValidationError>;
bounding_volume() -> Aabb<3>;
}
8 changes: 2 additions & 6 deletions crates/fj-operations/src/shape_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ impl ShapeProcessor {

let config = ValidationConfig::default();
let mut debug_info = DebugInfo::new();
let shape = shape
.to_shape(&config, tolerance, &mut debug_info)?
.faces()
.map(|handle| handle.get())
.collect();
let mesh = triangulate(shape, tolerance, &mut debug_info);
let shape = shape.to_shape(&config, tolerance, &mut debug_info)?;
let mesh = triangulate(shape.into_inner(), tolerance, &mut debug_info);

Ok(ProcessedShape {
aabb,
Expand Down
13 changes: 6 additions & 7 deletions crates/fj-operations/src/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,19 @@ impl ToShape for fj::Sketch {
config: &ValidationConfig,
_: Tolerance,
_: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
let mut shape = Shape::new();
) -> Result<Validated<Vec<Face>>, ValidationError> {
let mut tmp = Shape::new();

let surface = Surface::xy_plane();
let points = self.to_points().into_iter().map(Point::from);

Face::builder(surface, &mut shape)
let sketch = Face::builder(surface, &mut tmp)
.with_exterior_polygon(points)
.with_color(self.color())
.build();
.build()
.get();

let shape = validate(shape, config)?;

Ok(shape)
validate(vec![sketch], config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
19 changes: 5 additions & 14 deletions crates/fj-operations/src/sweep.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::{sweep, Tolerance},
iter::ObjectIters,
shape::Shape,
objects::Face,
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::{Aabb, Vector};
Expand All @@ -15,22 +14,14 @@ impl ToShape for fj::Sweep {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
let shape = self.shape().to_shape(config, tolerance, debug_info)?;
) -> Result<Validated<Vec<Face>>, ValidationError> {
let sketch = self.shape().to_shape(config, tolerance, debug_info)?;
let path = Vector::from(self.path());
let color = self.shape().color();

let shape = shape.face_iter().collect::<Vec<_>>();
let swept = sweep(shape, path, tolerance, color);
let solid = sweep(sketch.into_inner(), path, tolerance, color);

let mut shape = Shape::new();
for face in swept {
shape.merge(face);
}

let swept = validate(shape, config)?;

Ok(swept)
validate(solid, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down
20 changes: 4 additions & 16 deletions crates/fj-operations/src/transform.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use fj_interop::debug::DebugInfo;
use fj_kernel::{
algorithms::{transform, Tolerance},
iter::ObjectIters,
shape::Shape,
objects::Face,
validation::{validate, Validated, ValidationConfig, ValidationError},
};
use fj_math::{Aabb, Transform, Vector};
Expand All @@ -15,21 +14,10 @@ impl ToShape for fj::Transform {
config: &ValidationConfig,
tolerance: Tolerance,
debug_info: &mut DebugInfo,
) -> Result<Validated<Shape>, ValidationError> {
) -> Result<Validated<Vec<Face>>, ValidationError> {
let shape = self.shape.to_shape(config, tolerance, debug_info)?;
let shape = shape.into_inner();

let shape = shape.face_iter().collect::<Vec<_>>();
let faces = transform(&shape, &make_transform(self));

let mut target = Shape::new();
for face in faces {
target.merge(face);
}

let shape = validate(target, config)?;

Ok(shape)
let faces = transform(&shape.into_inner(), &make_transform(self));
validate(faces, config)
}

fn bounding_volume(&self) -> Aabb<3> {
Expand Down