pbrt_r3/shapes/
plymesh.rs1use super::alphamask::AlphaMaskShape;
2use super::triangle::*;
3use crate::core::prelude::*;
4
5use std::collections::HashMap;
6use std::io::BufRead;
7use std::sync::Arc;
8
9use ply_rs::parser;
10use ply_rs::ply;
11
12type FloatTextureMap = HashMap<String, Arc<dyn Texture<Float>>>;
13
14const VERTEX_P: u32 = 1;
15const VERTEX_N: u32 = 2;
16const VERTEX_UV: u32 = 8;
17
18#[derive(Debug)]
19struct Vertex {
20 x: f32,
21 y: f32,
22 z: f32,
23 nx: f32,
24 ny: f32,
25 nz: f32,
26 u: f32,
27 v: f32,
28 flags: u32,
29}
30
31#[derive(Debug)]
32struct Face {
33 vertex_index: Vec<i32>,
34 n: [f32; 3],
35}
36
37impl ply::PropertyAccess for Vertex {
38 fn new() -> Self {
39 Vertex {
40 x: 0.0,
41 y: 0.0,
42 z: 0.0,
43 nx: 0.0,
44 ny: 0.0,
45 nz: 0.0,
46 u: 0.0,
47 v: 0.0,
48 flags: 0,
49 }
50 }
51 fn set_property(&mut self, key: String, property: ply::Property) {
52 match property {
53 ply::Property::Float(v) => match key.as_str() {
54 "x" => {
55 self.x = v;
56 self.flags |= VERTEX_P;
57 }
58 "y" => {
59 self.y = v;
60 self.flags |= VERTEX_P;
61 }
62 "z" => {
63 self.z = v;
64 self.flags |= VERTEX_P;
65 }
66 "nx" => {
67 self.nx = v;
68 self.flags |= VERTEX_N;
69 }
70 "ny" => {
71 self.ny = v;
72 self.flags |= VERTEX_N;
73 }
74 "nz" => {
75 self.nz = v;
76 self.flags |= VERTEX_N;
77 }
78 "u" => {
79 self.u = v;
80 self.flags |= VERTEX_UV;
81 }
82 "v" => {
83 self.v = v;
84 self.flags |= VERTEX_UV;
85 }
86 "s" => {
87 self.u = v;
88 self.flags |= VERTEX_UV;
89 }
90 "t" => {
91 self.v = v;
92 self.flags |= VERTEX_UV;
93 }
94 "texture_u" => {
95 self.u = v;
96 self.flags |= VERTEX_UV;
97 }
98 "texture_v" => {
99 self.v = v;
100 self.flags |= VERTEX_UV;
101 }
102 "texture_s" => {
103 self.u = v;
104 self.flags |= VERTEX_UV;
105 }
106 "texture_t" => {
107 self.v = v;
108 self.flags |= VERTEX_UV;
109 }
110 k => panic!("Vertex: Unexpected key/value combination: key: {}", k),
111 },
112 _ => {
113 panic!(
114 "Vertex: Unexpected key/value combination: key: {}, type: {:?}",
115 &key, property
116 );
117 }
118 }
119 }
120}
121
122impl ply::PropertyAccess for Face {
124 fn new() -> Self {
125 Face {
126 vertex_index: Vec::new(),
127 n: [0.0; 3],
128 }
129 }
130 fn set_property(&mut self, key: String, property: ply::Property) {
131 if key == "vertex_indices" || key == "vertex_index" {
132 match property {
133 ply::Property::ListInt(vec) => {
134 for i in 0..vec.len() {
135 self.vertex_index.push(vec[i]);
136 }
137 }
138 ply::Property::ListUInt(vec) => {
139 for i in 0..vec.len() {
140 self.vertex_index.push(vec[i] as i32);
141 }
142 }
143 _ => {
144 panic!(
145 "Face: Unexpected key/value combination: key: {}, type: {:?}",
146 &key, property
147 );
148 }
149 }
150 } else if key == "nx" || key == "ny" || key == "nz" {
151 match property {
152 ply::Property::Float(v) => match key.as_str() {
153 "nx" => self.n[0] = v,
154 "ny" => self.n[1] = v,
155 "nz" => self.n[2] = v,
156 _ => {}
157 },
158 _ => {
159 panic!(
160 "Face: Unexpected key/value combination: key: {}, type: {:?}",
161 &key, property
162 );
163 }
164 }
165 }
166 }
167}
168
169fn create_reader(filanme: &str) -> Result<Box<dyn BufRead>, PbrtError> {
235 let filanme = std::path::PathBuf::from(filanme);
236 let extent = filanme
237 .extension()
238 .ok_or(PbrtError::error("No extension found"))?;
239 let extent = extent.to_string_lossy().into_owned();
240 if extent == "gz" {
241 let f = std::fs::File::open(filanme)?;
242 let reader = std::io::BufReader::new(f);
243 let reader = flate2::read::GzDecoder::new(reader);
244 let reader = std::io::BufReader::new(reader);
245 return Ok(Box::new(reader));
246 } else {
247 let f = std::fs::File::open(filanme)?;
248 let reader = std::io::BufReader::new(f);
249 return Ok(Box::new(reader));
250 }
251}
252
253pub fn create_ply_mesh(
254 o2w: &Transform,
255 w2o: &Transform,
256 reverse_orientation: bool,
257 params: &ParamSet,
258 float_textures: &FloatTextureMap,
259) -> Result<Vec<Arc<dyn Shape>>, PbrtError> {
260 let filename = params.find_one_string("filename", "");
261 let mut reader = create_reader(&filename)?;
262 let vertex_parser = parser::Parser::<Vertex>::new();
263 let face_parser = parser::Parser::<Face>::new();
264 let header = vertex_parser.read_header(&mut reader).unwrap();
265
266 let mut p = Vec::new();
267 let mut vertex_indices: Vec<u32> = Vec::new();
268 let mut n = Vec::new();
270 let s = Vec::new();
271 let mut uv = Vec::new();
272 for (_name, element) in header.elements.iter() {
273 match element.name.as_ref() {
276 "vertex" => {
277 let r = vertex_parser.read_payload_for_element(&mut reader, element, &header);
278 match r {
279 Ok(vertex_list) => {
280 if !vertex_list.is_empty() {
281 let flags = vertex_list[0].flags;
282 if (flags & VERTEX_P) != 0 {
283 p.reserve(vertex_list.len());
284 for v in vertex_list.iter() {
285 p.push(Vector3f::new(v.x as Float, v.y as Float, v.z as Float));
286 }
287 }
288 if (flags & VERTEX_N) != 0 {
289 n.reserve(vertex_list.len());
290 for v in vertex_list.iter() {
291 n.push(Normal3f::new(
292 v.nx as Float,
293 v.ny as Float,
294 v.nz as Float,
295 ));
296 }
297 }
298 if (flags & VERTEX_UV) != 0 {
299 uv.reserve(vertex_list.len());
300 for v in vertex_list.iter() {
301 uv.push(Vector2f::new(v.u as Float, v.v as Float));
302 }
303 }
304 }
305 }
306 Err(e) => {
307 return Err(PbrtError::from(e));
308 }
309 }
310 }
311 "face" => {
312 let r = face_parser.read_payload_for_element(&mut reader, element, &header);
313 match r {
314 Ok(face_list) => {
315 vertex_indices.reserve(face_list.len() * 3);
316 for face in face_list {
317 let n_vert = face.vertex_index.len();
318 match n_vert {
319 3 => {
320 for idx in face.vertex_index {
321 vertex_indices.push(idx as u32);
322 }
323 }
324 4 => {
325 let i0 = face.vertex_index[0] as u32;
326 let i1 = face.vertex_index[1] as u32;
327 let i2 = face.vertex_index[2] as u32;
328 let i3 = face.vertex_index[3] as u32;
329 vertex_indices.push(i0);
330 vertex_indices.push(i1);
331 vertex_indices.push(i2);
332 vertex_indices.push(i3);
333 vertex_indices.push(i0);
334 vertex_indices.push(i2);
335 }
336 _ => {
337 let msg = format!("plymesh: Ignoring face with {} vertices (only triangles and quads are supported!)", n_vert);
338 return Err(PbrtError::error(&msg));
339 }
340 }
341 }
342 }
343 Err(e) => {
344 return Err(PbrtError::from(e));
345 }
346 }
347 }
348 _ => {}
349 }
350 }
351
352 let mut mesh = create_triangle_mesh(
353 o2w,
354 w2o,
355 reverse_orientation,
356 vertex_indices,
357 p,
358 s,
359 n,
360 uv,
361 params,
362 );
363 let alpha_mask_info = get_alpha_texture(params, float_textures);
366 let shadow_alpha_mask_info = get_shadow_alpha_texture(params, float_textures);
367 if alpha_mask_info.is_some() || shadow_alpha_mask_info.is_some() {
368 for i in 0..mesh.len() {
369 mesh[i] = Arc::new(AlphaMaskShape::new(
370 &mesh[i],
371 &alpha_mask_info,
372 &shadow_alpha_mask_info,
373 ));
374 }
375 }
376
377 return Ok(mesh);
378}