use microcad_core::{Geometry3D, Manifold, Transformed3D, TriangleMesh};
use microcad_lang::model::{Element, Model};
use crate::stl::{StlWriter, WriteStl};
impl WriteStl for TriangleMesh {
fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
self.triangles()
.try_for_each(|tri| writer.write_triangle(&tri))
}
}
impl WriteStl for Manifold {
fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
let triangle_mesh: TriangleMesh = self.to_mesh().into();
triangle_mesh.write_stl(writer)
}
}
impl WriteStl for Geometry3D {
fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
match self {
Geometry3D::Mesh(triangle_mesh) => triangle_mesh.write_stl(writer),
Geometry3D::Manifold(manifold) => manifold.write_stl(writer),
_ => unreachable!("Can only write triangle geometries to STL"),
}
}
}
impl WriteStl for Model {
fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
let self_ = self.borrow();
if matches!(self_.element(), Element::Group | Element::Multiplicity) {
self_
.children()
.try_for_each(|model| model.write_stl(writer))?;
return Ok(());
}
let output = self_.output();
let geometry = &output.geometry;
let mat = output.world_matrix.expect("Some matrix");
match geometry {
Some(microcad_lang::render::GeometryOutput::Geometry3D(geometry)) => {
geometry.transformed_3d(&mat).write_stl(writer)
}
Some(_) => Ok(()),
None => self_
.children()
.try_for_each(|model| model.write_stl(writer)),
}
}
}