//! Draw concentric spheres that are rendered together //! //! >>> cargo run --example concentric //! //! Writes to `target/test_renderings/concentric.*` use crater::{ bounding::BoundingBox, csg::{ algebra::CSGAlgebra, marching_cubes::{marching_cubes, MarchingCubesParams}, regions::Region, surfaces::{IntoSurface, Surface3D}, }, mesh::MeshCollection, serde::vtk::evaluations::{GeometryEvaluator, MeshCollectionEvaluator, MeshColoring}, utils::Parallel, }; fn make_concentric() -> Vec<Region<3>> { (0..10) .map(|i| { let r = 0.5 * (i as f64 + 1.0); -Surface3D::Sphere { r }.into_surface() }) .collect() } fn main() { // Generate the spheres let spheres = make_concentric(); // Marching Cubes over each of them let resolution = 30; let bound = 10.0; let meshes: MeshCollection = spheres .into_iter() .map(|region| { let params = MarchingCubesParams { region, bounds: BoundingBox { min: [-bound, -bound, -bound], max: [bound, bound, bound], }, resolution: (resolution, resolution, resolution), algebra: CSGAlgebra::default(), }; marching_cubes::<Parallel>(¶ms) }) .into(); let mut path_buf = std::path::PathBuf::from("./target/test_renderings/"); path_buf.push("concentric"); path_buf.set_extension("stl"); std::fs::create_dir_all(path_buf.parent().expect("Failed to get parent directory")) .expect("Failed to create directory"); // Write the mesh to VTK: // STL meshes .write_stl(path_buf.to_str().unwrap()) .expect("Failed to write csg.stl"); // VTK let algebra = CSGAlgebra::default(); let spheres = make_concentric(); let evaluators: Vec<Box<dyn MeshCollectionEvaluator>> = vec![ Box::new(GeometryEvaluator::Gradients(&spheres, &algebra)), Box::new(GeometryEvaluator::Normals(&spheres, &algebra)), Box::new(MeshColoring), ]; meshes .to_vtk(Some(evaluators.as_slice())) .export_be(path_buf.with_extension("vtk").to_str().unwrap()) .unwrap(); }