Skip to main content

microcad_export/stl/
primitives.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Write primitives to STL ([`WriteSvg`] trait implementations).
5
6use microcad_core::{Geometry3D, Manifold, Transformed3D, TriangleMesh};
7use microcad_lang::model::{Element, Model};
8
9use crate::stl::{StlWriter, WriteStl};
10
11impl WriteStl for TriangleMesh {
12    fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
13        self.triangles()
14            .try_for_each(|tri| writer.write_triangle(&tri))
15    }
16}
17
18impl WriteStl for Manifold {
19    fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
20        let triangle_mesh: TriangleMesh = self.to_mesh().into();
21        triangle_mesh.write_stl(writer)
22    }
23}
24
25impl WriteStl for Geometry3D {
26    fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
27        match self {
28            Geometry3D::Mesh(triangle_mesh) => triangle_mesh.write_stl(writer),
29            Geometry3D::Manifold(manifold) => manifold.write_stl(writer),
30            _ => unreachable!("Can only write triangle geometries to STL"),
31        }
32    }
33}
34
35impl WriteStl for Model {
36    fn write_stl(&self, writer: &mut StlWriter) -> std::io::Result<()> {
37        let self_ = self.borrow();
38        // Recurse into groups.
39        if matches!(self_.element(), Element::Group | Element::Multiplicity) {
40            self_
41                .children()
42                .try_for_each(|model| model.write_stl(writer))?;
43            return Ok(());
44        }
45
46        let output = self_.output();
47        let geometry = &output.geometry;
48        let mat = output.world_matrix.expect("Some matrix");
49        match geometry {
50            Some(microcad_lang::render::GeometryOutput::Geometry3D(geometry)) => {
51                geometry.transformed_3d(&mat).write_stl(writer)
52            }
53            Some(_) => Ok(()),
54            None => self_
55                .children()
56                .try_for_each(|model| model.write_stl(writer)),
57        }
58    }
59}