fidget_mesh/
output.rs

1//! Mesh output implementation
2use super::Mesh;
3use std::io::{BufWriter, Write};
4
5impl Mesh {
6    /// Writes a binary STL to the given output
7    pub fn write_stl<F: std::io::Write>(
8        &self,
9        out: &mut F,
10    ) -> std::io::Result<()> {
11        // We're going to do many small writes and will typically be writing to
12        // a file, so using a `BufWriter` saves excessive syscalls.
13        let mut out = BufWriter::new(out);
14        const HEADER: &[u8] = b"This is a binary STL file exported by Fidget";
15        static_assertions::const_assert!(HEADER.len() <= 80);
16        out.write_all(HEADER)?;
17        out.write_all(&[0u8; 80 - HEADER.len()])?;
18        out.write_all(&(self.triangles.len() as u32).to_le_bytes())?;
19        for t in &self.triangles {
20            // Not the _best_ way to calculate a normal, but good enough
21            let a = self.vertices[t.x];
22            let b = self.vertices[t.y];
23            let c = self.vertices[t.z];
24            let ab = b - a;
25            let ac = c - a;
26            let normal = ab.cross(&ac);
27            for p in &normal {
28                out.write_all(&p.to_le_bytes())?;
29            }
30            for v in t {
31                for p in &self.vertices[*v] {
32                    out.write_all(&p.to_le_bytes())?;
33                }
34            }
35            out.write_all(&[0u8; std::mem::size_of::<u16>()])?; // attributes
36        }
37        Ok(())
38    }
39}