B-rep Helper Functions
Centralize exports and reusable OBJ/STEP helpers in your truck_brep crate so shape files only worry about geometry.
src/lib.rs
Imports and module wiring
#![allow(unused)] fn main() { use std::{fs, io, path::Path}; use truck_meshalgo::prelude::*; use truck_modeling::*; use truck_stepio::out::{CompleteStepDisplay, StepModel}; use truck_topology::compress::{CompressedShell, CompressedSolid}; }
What this does
Brings in filesystem/IO utilities plus the Truck modeling, meshing, STEP output, and compression helpers that the rest of the files use.StepCompress trait
#![allow(unused)] fn main() { /// Helper to compress modeling shapes into STEP-compatible data. pub trait StepCompress { type Compressed; fn compress_for_step(&self) -> Self::Compressed; } }
What this does
Defines a small adapter trait so both `Shell` and `Solid` expose a common `compress_for_step` method, hiding their different compressed types.StepCompress for Shell
#![allow(unused)] fn main() { impl StepCompress for Shell { type Compressed = CompressedShell<Point3, Curve, Surface>; fn compress_for_step(&self) -> Self::Compressed { self.compress() } } }
What this does
Implements `StepCompress` for shells by delegating to the kernel’s built-in `compress`, returning the STEP-ready shell representation.StepCompress for Solid
#![allow(unused)] fn main() { impl StepCompress for Solid { type Compressed = CompressedSolid<Point3, Curve, Surface>; fn compress_for_step(&self) -> Self::Compressed { self.compress() } } }
What this does
Implements `StepCompress` for solids, again forwarding to `compress` so solids can be exported with the same helper API.save_step helper
#![allow(unused)] fn main() { /// Export any B-rep (Solid or Shell) to STEP. pub fn save_step<T, P>(brep: &T, path: P) -> io::Result<()> where T: StepCompress, for<'a> StepModel<'a, Point3, Curve, Surface>: From<&'a T::Compressed>, P: AsRef<Path>, { let path = path.as_ref(); if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } let compressed = brep.compress_for_step(); let display = CompleteStepDisplay::new(StepModel::from(&compressed), Default::default()); fs::write(path, display.to_string()) } }
What this does
Creates parent folders if needed, compresses the shape, wraps it in a STEP display with defaults, and writes the STEP text to disk.save_obj helper
#![allow(unused)] fn main() { /// Triangulate any B-rep (Solid or Shell) and write an OBJ mesh. pub fn save_obj(shape: &impl MeshableShape, path: impl AsRef<Path>) -> io::Result<()> { let mesh = shape.triangulation(0.01).to_polygon(); let path = path.as_ref(); if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } let mut obj = fs::File::create(path)?; obj::write(&mesh, &mut obj).map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } }
What this does
Tessellates the shape with a 0.01 chord tolerance, ensures the output folder exists, then writes the resulting polygon mesh as an OBJ file.Target directory tree
truck_brep/
├─ Cargo.toml # add truck-modeling, truck-meshalgo, truck-stepio deps
├─ src/
│ ├─ lib.rs # helpers + re-exports
│ ├─ ... # shape modules (add torus.rs, cylinder.rs, bottle.rs, etc.)
├─ examples/
│ └─ ... # one small example per shape
└─ output/ # generated OBJ/STEP files (created at runtime)
Complete src/lib.rs
#![allow(unused)] fn main() { use std::{fs, io, path::Path}; use truck_meshalgo::prelude::*; use truck_modeling::*; use truck_stepio::out::{CompleteStepDisplay, StepModel}; use truck_topology::compress::{CompressedShell, CompressedSolid}; /// Helper to compress modeling shapes into STEP-compatible data. pub trait StepCompress { type Compressed; fn compress_for_step(&self) -> Self::Compressed; } impl StepCompress for Shell { type Compressed = CompressedShell<Point3, Curve, Surface>; fn compress_for_step(&self) -> Self::Compressed { self.compress() } } impl StepCompress for Solid { type Compressed = CompressedSolid<Point3, Curve, Surface>; fn compress_for_step(&self) -> Self::Compressed { self.compress() } } /// Export any B-rep (Solid or Shell) to STEP. pub fn save_step<T, P>(brep: &T, path: P) -> io::Result<()> where T: StepCompress, for<'a> StepModel<'a, Point3, Curve, Surface>: From<&'a T::Compressed>, P: AsRef<Path>, { let path = path.as_ref(); if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } let compressed = brep.compress_for_step(); let display = CompleteStepDisplay::new( StepModel::from(&compressed), Default::default(), ); fs::write(path, display.to_string()) } /// Triangulate any B-rep (Solid or Shell) and write an OBJ mesh. pub fn save_obj(shape: &impl MeshableShape, path: impl AsRef<Path>) -> io::Result<()> { let mesh = shape.triangulation(0.01).to_polygon(); let path = path.as_ref(); if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } let mut obj = fs::File::create(path)?; obj::write(&mesh, &mut obj).map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } }