mirror of https://github.com/hannobraun/Fornjot
Merge pull request #734 from hannobraun/ops
Reduce `fj-operations`' reliance on `Shape`
This commit is contained in:
commit
c08da0d683
|
@ -15,31 +15,31 @@ impl ToShape for fj::Circle {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
_: Tolerance,
|
_: Tolerance,
|
||||||
_: &mut DebugInfo,
|
_: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError> {
|
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||||
let mut shape = Shape::new();
|
let mut tmp = Shape::new();
|
||||||
|
|
||||||
// Circles have just a single round edge with no vertices. So none need
|
// Circles have just a single round edge with no vertices. So none need
|
||||||
// to be added here.
|
// to be added here.
|
||||||
|
|
||||||
let edge = Edge::builder(&mut shape)
|
let edge = Edge::builder(&mut tmp)
|
||||||
.build_circle(Scalar::from_f64(self.radius()));
|
.build_circle(Scalar::from_f64(self.radius()));
|
||||||
|
|
||||||
let cycle_local = Cycle {
|
let cycle_local = Cycle {
|
||||||
edges: vec![edge.clone()],
|
edges: vec![edge.clone()],
|
||||||
};
|
};
|
||||||
let cycle_canonical = shape.insert(Cycle::new(vec![edge.canonical()]));
|
let cycle_canonical = tmp.insert(Cycle::new(vec![edge.canonical()]));
|
||||||
|
|
||||||
let surface = shape.insert(Surface::xy_plane());
|
let surface = tmp.insert(Surface::xy_plane());
|
||||||
shape.insert(Face::new(
|
let face = tmp
|
||||||
surface,
|
.insert(Face::new(
|
||||||
vec![LocalForm::new(cycle_local, cycle_canonical)],
|
surface,
|
||||||
Vec::new(),
|
vec![LocalForm::new(cycle_local, cycle_canonical)],
|
||||||
self.color(),
|
Vec::new(),
|
||||||
));
|
self.color(),
|
||||||
|
))
|
||||||
|
.get();
|
||||||
|
|
||||||
let shape = validate(shape, config)?;
|
validate(vec![face], config)
|
||||||
|
|
||||||
Ok(shape)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::debug::DebugInfo;
|
||||||
use fj_kernel::{
|
use fj_kernel::{
|
||||||
algorithms::Tolerance,
|
algorithms::Tolerance,
|
||||||
|
iter::ObjectIters,
|
||||||
objects::{Cycle, Edge, Face},
|
objects::{Cycle, Edge, Face},
|
||||||
shape::{LocalForm, Shape},
|
shape::{LocalForm, Shape},
|
||||||
validation::{validate, Validated, ValidationConfig, ValidationError},
|
validation::{validate, Validated, ValidationConfig, ValidationError},
|
||||||
|
@ -15,11 +16,11 @@ impl ToShape for fj::Difference2d {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError> {
|
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||||
// This method assumes that `b` is fully contained within `a`:
|
// This method assumes that `b` is fully contained within `a`:
|
||||||
// https://github.com/hannobraun/Fornjot/issues/92
|
// https://github.com/hannobraun/Fornjot/issues/92
|
||||||
|
|
||||||
let mut difference = Shape::new();
|
let mut difference = Vec::new();
|
||||||
|
|
||||||
let mut exteriors = Vec::new();
|
let mut exteriors = Vec::new();
|
||||||
let mut interiors = Vec::new();
|
let mut interiors = Vec::new();
|
||||||
|
@ -32,13 +33,12 @@ impl ToShape for fj::Difference2d {
|
||||||
[a, b].map(|shape| shape.to_shape(config, tolerance, debug_info));
|
[a, b].map(|shape| shape.to_shape(config, tolerance, debug_info));
|
||||||
let [a, b] = [a?, b?];
|
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.
|
// 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() {
|
for face in a.face_iter() {
|
||||||
let face = face.get();
|
|
||||||
let face = face.brep();
|
let face = face.brep();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -48,17 +48,16 @@ impl ToShape for fj::Difference2d {
|
||||||
);
|
);
|
||||||
|
|
||||||
for cycle in face.exteriors.as_local_form().cloned() {
|
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);
|
exteriors.push(cycle);
|
||||||
}
|
}
|
||||||
for cycle in face.interiors.as_local_form().cloned() {
|
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);
|
interiors.push(cycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for face in b.faces() {
|
for face in b.face_iter() {
|
||||||
let face = face.get();
|
|
||||||
let face = face.brep();
|
let face = face.brep();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -68,12 +67,12 @@ impl ToShape for fj::Difference2d {
|
||||||
);
|
);
|
||||||
|
|
||||||
for cycle in face.exteriors.as_local_form().cloned() {
|
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);
|
interiors.push(cycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
difference.merge(Face::new(
|
difference.push(Face::new(
|
||||||
surface,
|
surface,
|
||||||
exteriors,
|
exteriors,
|
||||||
interiors,
|
interiors,
|
||||||
|
@ -81,9 +80,7 @@ impl ToShape for fj::Difference2d {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let difference = validate(difference, config)?;
|
validate(difference, config)
|
||||||
|
|
||||||
Ok(difference)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
@ -96,9 +93,10 @@ impl ToShape for fj::Difference2d {
|
||||||
|
|
||||||
fn add_cycle(
|
fn add_cycle(
|
||||||
cycle: LocalForm<Cycle<2>, Cycle<3>>,
|
cycle: LocalForm<Cycle<2>, Cycle<3>>,
|
||||||
shape: &mut Shape,
|
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
) -> LocalForm<Cycle<2>, Cycle<3>> {
|
) -> LocalForm<Cycle<2>, Cycle<3>> {
|
||||||
|
let mut tmp = Shape::new();
|
||||||
|
|
||||||
let mut edges = Vec::new();
|
let mut edges = Vec::new();
|
||||||
for edge in cycle.local().edges.clone() {
|
for edge in cycle.local().edges.clone() {
|
||||||
let curve_local = *edge.local().curve.local();
|
let curve_local = *edge.local().curve.local();
|
||||||
|
@ -114,7 +112,7 @@ fn add_cycle(
|
||||||
} else {
|
} else {
|
||||||
curve_canonical
|
curve_canonical
|
||||||
};
|
};
|
||||||
let curve_canonical = shape.insert(curve_canonical);
|
let curve_canonical = tmp.insert(curve_canonical);
|
||||||
|
|
||||||
let vertices = if reverse {
|
let vertices = if reverse {
|
||||||
edge.local().vertices.clone().reverse()
|
edge.local().vertices.clone().reverse()
|
||||||
|
@ -126,7 +124,7 @@ fn add_cycle(
|
||||||
curve: LocalForm::new(curve_local, curve_canonical.clone()),
|
curve: LocalForm::new(curve_local, curve_canonical.clone()),
|
||||||
vertices: vertices.clone(),
|
vertices: vertices.clone(),
|
||||||
};
|
};
|
||||||
let edge_canonical = shape.merge(Edge {
|
let edge_canonical = tmp.merge(Edge {
|
||||||
curve: LocalForm::canonical_only(curve_canonical),
|
curve: LocalForm::canonical_only(curve_canonical),
|
||||||
vertices,
|
vertices,
|
||||||
});
|
});
|
||||||
|
@ -141,8 +139,8 @@ fn add_cycle(
|
||||||
let cycle_local = Cycle {
|
let cycle_local = Cycle {
|
||||||
edges: edges.clone(),
|
edges: edges.clone(),
|
||||||
};
|
};
|
||||||
let cycle_canonical = shape
|
let cycle_canonical =
|
||||||
.insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical())));
|
tmp.insert(Cycle::new(edges.into_iter().map(|edge| edge.canonical())));
|
||||||
|
|
||||||
LocalForm::new(cycle_local, cycle_canonical)
|
LocalForm::new(cycle_local, cycle_canonical)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::debug::DebugInfo;
|
||||||
use fj_kernel::{
|
use fj_kernel::{
|
||||||
algorithms::Tolerance,
|
algorithms::Tolerance,
|
||||||
shape::Shape,
|
objects::Face,
|
||||||
validation::{validate, Validated, ValidationConfig, ValidationError},
|
validation::{validate, Validated, ValidationConfig, ValidationError},
|
||||||
};
|
};
|
||||||
use fj_math::Aabb;
|
use fj_math::Aabb;
|
||||||
|
@ -14,18 +14,16 @@ impl ToShape for fj::Group {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError> {
|
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||||
let mut shape = Shape::new();
|
let mut shape = Vec::new();
|
||||||
|
|
||||||
let a = self.a.to_shape(config, tolerance, debug_info)?;
|
let a = self.a.to_shape(config, tolerance, debug_info)?;
|
||||||
let b = self.b.to_shape(config, tolerance, debug_info)?;
|
let b = self.b.to_shape(config, tolerance, debug_info)?;
|
||||||
|
|
||||||
shape.merge_shape(&a);
|
shape.extend(a.into_inner());
|
||||||
shape.merge_shape(&b);
|
shape.extend(b.into_inner());
|
||||||
|
|
||||||
let shape = validate(shape, config)?;
|
validate(shape, config)
|
||||||
|
|
||||||
Ok(shape)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
|
|
@ -28,7 +28,7 @@ mod transform;
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::debug::DebugInfo;
|
||||||
use fj_kernel::{
|
use fj_kernel::{
|
||||||
algorithms::Tolerance,
|
algorithms::Tolerance,
|
||||||
shape::Shape,
|
objects::Face,
|
||||||
validation::{Validated, ValidationConfig, ValidationError},
|
validation::{Validated, ValidationConfig, ValidationError},
|
||||||
};
|
};
|
||||||
use fj_math::Aabb;
|
use fj_math::Aabb;
|
||||||
|
@ -41,7 +41,7 @@ pub trait ToShape {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError>;
|
) -> Result<Validated<Vec<Face>>, ValidationError>;
|
||||||
|
|
||||||
/// Access the axis-aligned bounding box of a shape
|
/// Access the axis-aligned bounding box of a shape
|
||||||
///
|
///
|
||||||
|
@ -94,6 +94,6 @@ dispatch! {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError>;
|
) -> Result<Validated<Vec<Face>>, ValidationError>;
|
||||||
bounding_volume() -> Aabb<3>;
|
bounding_volume() -> Aabb<3>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,8 @@ impl ShapeProcessor {
|
||||||
|
|
||||||
let config = ValidationConfig::default();
|
let config = ValidationConfig::default();
|
||||||
let mut debug_info = DebugInfo::new();
|
let mut debug_info = DebugInfo::new();
|
||||||
let shape = shape
|
let shape = shape.to_shape(&config, tolerance, &mut debug_info)?;
|
||||||
.to_shape(&config, tolerance, &mut debug_info)?
|
let mesh = triangulate(shape.into_inner(), tolerance, &mut debug_info);
|
||||||
.faces()
|
|
||||||
.map(|handle| handle.get())
|
|
||||||
.collect();
|
|
||||||
let mesh = triangulate(shape, tolerance, &mut debug_info);
|
|
||||||
|
|
||||||
Ok(ProcessedShape {
|
Ok(ProcessedShape {
|
||||||
aabb,
|
aabb,
|
||||||
|
|
|
@ -15,20 +15,19 @@ impl ToShape for fj::Sketch {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
_: Tolerance,
|
_: Tolerance,
|
||||||
_: &mut DebugInfo,
|
_: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError> {
|
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||||
let mut shape = Shape::new();
|
let mut tmp = Shape::new();
|
||||||
|
|
||||||
let surface = Surface::xy_plane();
|
let surface = Surface::xy_plane();
|
||||||
let points = self.to_points().into_iter().map(Point::from);
|
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_exterior_polygon(points)
|
||||||
.with_color(self.color())
|
.with_color(self.color())
|
||||||
.build();
|
.build()
|
||||||
|
.get();
|
||||||
|
|
||||||
let shape = validate(shape, config)?;
|
validate(vec![sketch], config)
|
||||||
|
|
||||||
Ok(shape)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
|
|
@ -1,8 +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,
|
objects::Face,
|
||||||
shape::Shape,
|
|
||||||
validation::{validate, Validated, ValidationConfig, ValidationError},
|
validation::{validate, Validated, ValidationConfig, ValidationError},
|
||||||
};
|
};
|
||||||
use fj_math::{Aabb, Vector};
|
use fj_math::{Aabb, Vector};
|
||||||
|
@ -15,22 +14,14 @@ impl ToShape for fj::Sweep {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) -> Result<Validated<Shape>, ValidationError> {
|
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||||
let shape = self.shape().to_shape(config, tolerance, debug_info)?;
|
let sketch = self.shape().to_shape(config, tolerance, debug_info)?;
|
||||||
let path = Vector::from(self.path());
|
let path = Vector::from(self.path());
|
||||||
let color = self.shape().color();
|
let color = self.shape().color();
|
||||||
|
|
||||||
let shape = shape.face_iter().collect::<Vec<_>>();
|
let solid = sweep(sketch.into_inner(), path, tolerance, color);
|
||||||
let swept = sweep(shape, path, tolerance, color);
|
|
||||||
|
|
||||||
let mut shape = Shape::new();
|
validate(solid, config)
|
||||||
for face in swept {
|
|
||||||
shape.merge(face);
|
|
||||||
}
|
|
||||||
|
|
||||||
let swept = validate(shape, config)?;
|
|
||||||
|
|
||||||
Ok(swept)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::debug::DebugInfo;
|
||||||
use fj_kernel::{
|
use fj_kernel::{
|
||||||
algorithms::{transform, Tolerance},
|
algorithms::{transform, Tolerance},
|
||||||
iter::ObjectIters,
|
objects::Face,
|
||||||
shape::Shape,
|
|
||||||
validation::{validate, Validated, ValidationConfig, ValidationError},
|
validation::{validate, Validated, ValidationConfig, ValidationError},
|
||||||
};
|
};
|
||||||
use fj_math::{Aabb, Transform, Vector};
|
use fj_math::{Aabb, Transform, Vector};
|
||||||
|
@ -15,21 +14,10 @@ impl ToShape for fj::Transform {
|
||||||
config: &ValidationConfig,
|
config: &ValidationConfig,
|
||||||
tolerance: Tolerance,
|
tolerance: Tolerance,
|
||||||
debug_info: &mut DebugInfo,
|
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 = self.shape.to_shape(config, tolerance, debug_info)?;
|
||||||
let shape = shape.into_inner();
|
let faces = transform(&shape.into_inner(), &make_transform(self));
|
||||||
|
validate(faces, config)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
|
|
Loading…
Reference in New Issue