use crate::error::Error;
use crate::shape::Shape;
use glam::DVec3;
fn extrude_faces(cut_faces: &Shape, delta: DVec3) -> Result<Shape, Error> {
let mut filler: Option<Shape> = None;
for face in cut_faces.faces() {
let extruded = Shape::from(face.extrude(delta)?);
filler = Some(match filler {
None => extruded,
Some(f) => Shape::from(f.union(&extruded)?),
});
}
Ok(filler.unwrap_or_else(Shape::empty))
}
pub fn revolve_section(
shape: &Shape,
origin: DVec3,
axis_dir: DVec3,
plane_normal: DVec3,
angle: f64,
) -> Result<Shape, Error> {
let half = Shape::half_space(origin, -plane_normal.normalize());
let cut_faces = shape.intersect(&half)?.new_faces;
let mut result: Option<Shape> = None;
for face in cut_faces.faces() {
let revolved = Shape::from(face.revolve(origin, axis_dir, angle)?);
result = Some(match result {
None => revolved,
Some(r) => Shape::from(r.union(&revolved)?),
});
}
Ok(result.unwrap_or_else(Shape::empty))
}
pub fn stretch_vector(shape: &Shape, origin: DVec3, delta: DVec3) -> Result<Shape, Error> {
let half = Shape::half_space(origin, -delta.normalize());
let intersect_result = shape.intersect(&half)?;
let part_neg = intersect_result.shape;
let cut_faces = intersect_result.new_faces;
let part_pos = Shape::from(shape.subtract(&half)?).translated(delta);
let filler = extrude_faces(&cut_faces, delta)?;
let combined = Shape::from(part_neg.union(&filler)?);
combined.union(&part_pos).map(Shape::from)
}