microcad_export/ply/
writer.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! PLY Export
5
6use microcad_core::*;
7
8/// PLY writer
9pub struct PlyWriter<'a> {
10    writer: &'a mut dyn std::io::Write,
11}
12
13impl<'a> PlyWriter<'a> {
14    /// Create new PLY writer
15    pub fn new(mut w: &'a mut dyn std::io::Write) -> std::io::Result<Self> {
16        writeln!(&mut w, "ply")?;
17        writeln!(&mut w, "format ascii 1.0")?;
18        writeln!(&mut w, "comment written by rust-sdf")?;
19
20        Ok(Self { writer: w })
21    }
22
23    /// Generate header for vertex 3D
24    pub fn header_element_vertex3d(&mut self, len: usize) -> std::io::Result<()> {
25        writeln!(&mut self.writer, "element vertex {len}")?;
26        writeln!(&mut self.writer, "property float x")?;
27        writeln!(&mut self.writer, "property float y")?;
28        writeln!(&mut self.writer, "property float z")?;
29        writeln!(&mut self.writer, "property float nx")?;
30        writeln!(&mut self.writer, "property float ny")?;
31        writeln!(&mut self.writer, "property float nz")?;
32        Ok(())
33    }
34
35    /// Generate header of vertex 3D with colors
36    pub fn header_element_vertex3d_with_colors(&mut self, len: usize) -> std::io::Result<()> {
37        self.header_element_vertex3d(len)?;
38        writeln!(&mut self.writer, "property uchar red")?;
39        writeln!(&mut self.writer, "property uchar green")?;
40        writeln!(&mut self.writer, "property uchar blue")?;
41        Ok(())
42    }
43
44    /// Generate face header
45    pub fn header_element_face(&mut self, len: usize) -> std::io::Result<()> {
46        writeln!(&mut self.writer, "element face {len}")?;
47        writeln!(&mut self.writer, "property list uchar int vertex_index")?;
48        Ok(())
49    }
50
51    /// End header
52    pub fn header_end(&mut self) -> std::io::Result<()> {
53        writeln!(&mut self.writer, "end_header")?;
54        Ok(())
55    }
56
57    /// Generate vertex
58    pub fn vertex(&mut self, v: &Vertex) -> std::io::Result<()> {
59        writeln!(
60            &mut self.writer,
61            "{} {} {} {} {} {}",
62            v.pos.x, v.pos.y, v.pos.z, v.normal.x, v.normal.y, v.normal.z
63        )?;
64        Ok(())
65    }
66
67    /// Generate multiple vertices
68    pub fn vertices(&mut self, v: &[Vertex]) -> std::io::Result<()> {
69        v.iter().try_for_each(|v| self.vertex(v))
70    }
71
72    /// Generate vertex with color
73    pub fn vertex_color<T: std::fmt::Display>(
74        &mut self,
75        v: &Vertex,
76        color: &(T, T, T),
77    ) -> std::io::Result<()> {
78        writeln!(
79            &mut self.writer,
80            "{} {} {} {} {} {} {} {} {}",
81            v.pos.x,
82            v.pos.y,
83            v.pos.z,
84            v.normal.x,
85            v.normal.y,
86            v.normal.z,
87            color.0,
88            color.1,
89            color.2
90        )?;
91        Ok(())
92    }
93
94    /// Generate tri-face
95    pub fn tri_face(&mut self, tri: &Triangle<u32>) -> std::io::Result<()> {
96        writeln!(&mut self.writer, "3 {} {} {}", tri.0, tri.1, tri.2)?;
97        Ok(())
98    }
99
100    /// Generate multiple tri-faces
101    pub fn tri_faces(&mut self, tri_faces: &[Triangle<u32>]) -> std::io::Result<()> {
102        tri_faces.iter().try_for_each(|f| self.tri_face(f))
103    }
104}