1use crate::*;
2use std::io::{BufRead, BufReader, BufWriter, Read, Write};
3type Vertex = StandardVertex;
4type Result<T> = std::result::Result<T, errors::Error>;
5
6pub fn write<W: Write>(mesh: &PolygonMesh, writer: W) -> Result<()> {
53 sub_write(mesh, &mut BufWriter::new(writer))
54}
55
56pub fn write_vec<W: Write>(mesh: &[PolygonMesh], writer: W) -> Result<()> {
58 let mut writer = BufWriter::new(writer);
59 for (i, mesh) in mesh.iter().enumerate() {
60 writer.write_fmt(format_args!("g {i}\n"))?;
61 sub_write(mesh, &mut writer)?;
62 }
63 Ok(())
64}
65
66fn write2vec<V: std::ops::Index<usize, Output = f64>, W: Write>(
67 writer: &mut BufWriter<W>,
68 vecs: &[V],
69 prefix: &str,
70) -> Result<()> {
71 for vec in vecs {
72 writer.write_fmt(format_args!("{} {:.10e} {:.10e}\n", prefix, vec[0], vec[1]))?;
73 }
74 Ok(())
75}
76
77fn write3vec<V: std::ops::Index<usize, Output = f64>, W: Write>(
78 writer: &mut BufWriter<W>,
79 vecs: &[V],
80 prefix: &str,
81) -> Result<()> {
82 for vec in vecs {
83 writer.write_fmt(format_args!(
84 "{} {:.10e} {:.10e} {:.10e}\n",
85 prefix, vec[0], vec[1], vec[2]
86 ))?;
87 }
88 Ok(())
89}
90
91impl Vertex {
92 fn write<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
93 match (self.uv, self.nor) {
94 (None, None) => writer.write_fmt(format_args!("{}", self.pos + 1)),
95 (Some(uv), None) => writer.write_fmt(format_args!("{}/{}", self.pos + 1, uv + 1)),
96 (None, Some(nor)) => writer.write_fmt(format_args!("{}//{}", self.pos + 1, nor + 1)),
97 (Some(uv), Some(nor)) => {
98 writer.write_fmt(format_args!("{}/{}/{}", self.pos + 1, uv + 1, nor + 1))
99 }
100 }
101 }
102}
103
104impl Faces {
105 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
106 for face in self.face_iter() {
107 writer.write_all(b"f")?;
108 for v in face {
109 writer.write_all(b" ")?;
110 v.write(writer)?;
111 }
112 writer.write_all(b"\n")?;
113 }
114 Ok(())
115 }
116}
117
118fn sub_write<W: Write>(mesh: &PolygonMesh, writer: &mut BufWriter<W>) -> Result<()> {
119 write3vec(writer, mesh.positions(), "v")?;
120 write2vec(writer, mesh.uv_coords(), "vt")?;
121 write3vec(writer, mesh.normals(), "vn")?;
122 mesh.faces.write(writer)
123}
124
125pub fn read<R: Read>(reader: R) -> Result<PolygonMesh> {
127 let mut positions = Vec::new();
128 let mut uv_coords = Vec::new();
129 let mut normals = Vec::new();
130 let mut faces = Faces::default();
131 let reader = BufReader::new(reader);
132 for line in reader.lines().map(|s| s.unwrap()) {
133 let mut args = line.split_whitespace();
134 if let Some(first_str) = args.next() {
135 if first_str == "v" {
136 let x = args.next().unwrap().parse::<f64>()?;
137 let y = args.next().unwrap().parse::<f64>()?;
138 let z = args.next().unwrap().parse::<f64>()?;
139 positions.push(Point3::new(x, y, z));
140 } else if first_str == "vt" {
141 let u = args.next().unwrap().parse::<f64>()?;
142 let v = args.next().unwrap().parse::<f64>()?;
143 uv_coords.push(Vector2::new(u, v));
144 } else if first_str == "vn" {
145 let x = args.next().unwrap().parse::<f64>()?;
146 let y = args.next().unwrap().parse::<f64>()?;
147 let z = args.next().unwrap().parse::<f64>()?;
148 normals.push(Vector3::new(x, y, z));
149 } else if first_str == "f" {
150 let mut face = Vec::new();
151 for vert_str in args {
152 if &vert_str[0..1] == "#" {
153 break;
154 }
155 let mut iter = vert_str.split('/');
156 let pos = iter
157 .next()
158 .map(|val| val.parse::<usize>().map(|i| i - 1).ok())
159 .unwrap_or(None);
160 let uv = iter
161 .next()
162 .map(|val| val.parse::<usize>().map(|i| i - 1).ok())
163 .unwrap_or(None);
164 let nor = iter
165 .next()
166 .map(|val| val.parse::<usize>().map(|i| i - 1).ok())
167 .unwrap_or(None);
168 let vert = match (pos, uv, nor) {
169 (None, _, _) => continue,
170 (Some(pos), uv, nor) => Vertex { pos, uv, nor },
171 };
172 face.push(vert);
173 }
174 faces.push(face);
175 }
176 }
177 }
178 PolygonMesh::try_new(
179 StandardAttributes {
180 positions,
181 uv_coords,
182 normals,
183 },
184 faces,
185 )
186}