pbrt_r3/shapes/
plymesh.rs

1use 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
122// same thing for Face
123impl 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
169/*
170fn create_bound_mesh(
171    o2w: &Transform,
172    w2o: &Transform,
173    reverse_orientation: bool,
174    _: Vec<u32>,
175    p: Vec<Point3f>,
176    _s: Vec<Vector3f>,
177    _n: Vec<Vector3f>,
178    _uv: Vec<Point2f>,
179    params: &ParamSet,
180) -> Vec<Arc<dyn Shape>> {
181    //return create_triangle_mesh(o2w, w2o, reverse_orientation, vertex_indices, p, s, n, uv);
182    let min = p[0]; //o2w.transform_point(&p[0]);
183    let min = p.iter().fold(min, |acc, e| -> Vector3f {
184        return Vector3f::new(
185            Float::min(acc.x, e.x),
186            Float::min(acc.y, e.y),
187            Float::min(acc.z, e.z),
188        );
189    });
190    let max = p[0]; //2w.transform_point(&p[0]);
191    let max = p.iter().fold(max, |acc, e| -> Vector3f {
192        return Vector3f::new(
193            Float::max(acc.x, e.x),
194            Float::max(acc.y, e.y),
195            Float::max(acc.z, e.z),
196        );
197    });
198
199    let bp = vec![
200        Vector3f::new(min.x, min.y, min.z), //0
201        Vector3f::new(min.x, min.y, max.z), //1
202        Vector3f::new(min.x, max.y, min.z), //2
203        Vector3f::new(min.x, max.y, max.z), //3
204        Vector3f::new(max.x, min.y, min.z), //4
205        Vector3f::new(max.x, min.y, max.z), //5
206        Vector3f::new(max.x, max.y, min.z), //6
207        Vector3f::new(max.x, max.y, max.z), //7
208    ];
209
210    #[rustfmt::skip]
211    let bi = vec![
212        0, 1, 2,
213        1, 3, 2,
214        4, 5, 0,
215        5, 1, 0,
216        6, 7, 4,
217        7, 5, 4,
218        2, 3, 6,
219        3, 7, 6,
220        1, 5, 3,
221        5, 7, 3,
222        4, 0, 6,
223        0, 2, 6
224    ];
225
226    let bs = Vec::new();
227    let bn = Vec::new();
228    let buv = Vec::new();
229
230    return create_triangle_mesh(o2w, w2o, reverse_orientation, bi, bp, bs, bn, buv, params);
231}
232*/
233
234fn 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 face_list = Vec::new();
269    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        //println!("{:?}", name);
274        // we could also just parse them in sequence, but the file format might change
275        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 mesh =
364    //    create_bound_mesh(o2w, w2o, reverse_orientation, vertex_indices, p, s, n, uv);
365    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}