//! Draw a 3 dimensional shape using solid //! This draws the classic csg example in the wiki on Constructive Solid Geometry //! (https://en.wikipedia.org/wiki/Constructive_solid_geometry) //! //! >>> cargo run --example csg //! //! Writes an .stl file to target/stl/csg.stl use crater::{ csg::{ algebra::CSGAlgebra, marching_cubes::{marching_cubes, MarchingCubesParams}, surfaces::{IntoSurface, Surface3D}, transformations::{RotateAbout, Translate}, }, utils::Parallel, }; fn main() { let c_r = 1.0; let s_r = 2.0 * c_r; let b_r = 0.7 * s_r; let c1 = -Surface3D::Cylinder { r: c_r }.into_surface(); let c2 = -Surface3D::Cylinder { r: c_r } .into_surface() .transform(RotateAbout(2, 0, std::f64::consts::FRAC_PI_2)); let c3 = -Surface3D::Cylinder { r: c_r } .into_surface() .transform(RotateAbout(2, 1, std::f64::consts::FRAC_PI_2)); let sphere = -Surface3D::Sphere { r: s_r }.into_surface(); let box_sides = ( Surface3D::Plane { normal: [1.0, 0.0, 0.0], } .into_surface() .transform(Translate([b_r, 0.0, 0.0])), Surface3D::Plane { normal: [1.0, 0.0, 0.0], } .into_surface() .transform(Translate([-b_r, 0.0, 0.0])), Surface3D::Plane { normal: [0.0, 1.0, 0.0], } .into_surface() .transform(Translate([0.0, b_r, 0.0])), Surface3D::Plane { normal: [0.0, 1.0, 0.0], } .into_surface() .transform(Translate([0.0, -b_r, 0.0])), Surface3D::Plane { normal: [0.0, 0.0, 1.0], } .into_surface() .transform(Translate([0.0, 0.0, b_r])), Surface3D::Plane { normal: [0.0, 0.0, 1.0], } .into_surface() .transform(Translate([0.0, 0.0, -b_r])), ); let box_region = -box_sides.0 & --box_sides.1 & -box_sides.2 & --box_sides.3 & -box_sides.4 & --box_sides.5; let csg = (sphere & box_region) & -(c1 | c2 | c3); // Run marching cubes to render this shape let resolution = 100; let params = MarchingCubesParams { region: csg, bounds: ( [-3.0 * c_r, -3.0 * c_r, -3.0 * c_r], [3.0 * c_r, 3.0 * c_r, 3.0 * c_r], ), resolution: (resolution, resolution, resolution), algebra: CSGAlgebra::default(), }; let mesh = marching_cubes::(params); let mut path_buf = std::path::PathBuf::from("./target/stl/"); path_buf.push("csg"); path_buf.set_extension("stl"); std::fs::create_dir_all(&path_buf.parent().expect("Failed to get parent directory")) .expect("Failed to create directory"); mesh.write_stl(path_buf.to_str().unwrap()) .expect("Failed to write csg.stl"); }