pbrt_r3/shapes/
loopsubdiv.rs

1use crate::core::prelude::*;
2
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::ops::Deref;
6use std::sync::Arc;
7use std::sync::Weak;
8
9use super::create_triangle_mesh;
10
11const TRI: [usize; 4] = [0, 1, 2, 0];
12const NEXT: [usize; 4] = [1, 2, 0, 1];
13const PREV: [usize; 4] = [2, 0, 1, 2];
14
15// LoopSubdiv Local Structures
16#[derive(Clone, Debug)]
17struct SDVertex {
18    p: Point3f,
19    start_face: Option<Weak<RefCell<SDFace>>>,
20    child: Option<Weak<RefCell<SDVertex>>>,
21    regular: bool,
22    boundary: bool,
23}
24
25#[derive(Clone, Debug)]
26struct SDFace {
27    v: [Option<Weak<RefCell<SDVertex>>>; 3],
28    f: [Option<Weak<RefCell<SDFace>>>; 3],
29    children: [Option<Weak<RefCell<SDFace>>>; 4],
30}
31
32#[derive(Clone, Debug)]
33struct SDEdge {
34    v: [Option<Weak<RefCell<SDVertex>>>; 2],
35    f: [Option<Weak<RefCell<SDFace>>>; 2],
36    f0edge_num: usize,
37}
38
39impl SDVertex {
40    pub fn new(p: &Point3f) -> Self {
41        SDVertex {
42            p: *p,
43            start_face: None,
44            child: None,
45            regular: false,
46            boundary: false,
47        }
48    }
49
50    pub fn get_start_face(&self) -> Option<Arc<RefCell<SDFace>>> {
51        if let Some(f) = self.start_face.as_ref() {
52            return f.upgrade();
53        }
54        return None;
55    }
56
57    pub fn valence(&self) -> u32 {
58        let start_face = self.get_start_face().unwrap();
59        if !self.boundary {
60            // Compute valence of interior vertex
61            let mut nf = 1;
62            let mut f = start_face.clone();
63            loop {
64                let f2 = f.as_ref().borrow().next_face(self).unwrap();
65                if f2.as_ptr() == start_face.as_ptr() {
66                    break;
67                }
68                f = f2;
69                nf += 1;
70            }
71            return nf;
72        } else {
73            // Compute valence of boundary vertex
74            let mut nf = 1;
75            let mut f = start_face.clone();
76            loop {
77                let f2 = f.as_ref().borrow().next_face(self);
78                if let Some(ff) = f2 {
79                    f = ff;
80                } else {
81                    break;
82                }
83                nf += 1;
84            }
85            let mut f = start_face.clone();
86            loop {
87                let f2 = f.as_ref().borrow().prev_face(self);
88                if let Some(ff) = f2 {
89                    f = ff;
90                } else {
91                    break;
92                }
93                nf += 1;
94            }
95            return nf + 1;
96        }
97    }
98
99    pub fn one_ring(&self) -> Vec<Point3f> {
100        let valence = self.valence();
101        let mut points = Vec::with_capacity(valence as usize);
102        let start_face = self.get_start_face().unwrap();
103
104        if !self.boundary {
105            // Get one-ring vertices for interior vertex
106            let mut face = start_face.clone();
107            loop {
108                let p = face
109                    .as_ref()
110                    .borrow()
111                    .next_vert(self)
112                    .unwrap()
113                    .as_ref()
114                    .borrow()
115                    .p;
116                points.push(p);
117                let f2 = face.as_ref().borrow().next_face(self).unwrap();
118                if f2.as_ptr() == start_face.as_ptr() {
119                    break;
120                }
121                face = f2;
122            }
123        } else {
124            // Get one-ring vertices for boundary vertex
125            let mut face = start_face.clone();
126            loop {
127                let f2 = face.as_ref().borrow().next_face(self);
128                if let Some(ff) = f2 {
129                    face = ff;
130                } else {
131                    break;
132                }
133            }
134            {
135                let p = face
136                    .as_ref()
137                    .borrow()
138                    .next_vert(self)
139                    .unwrap()
140                    .as_ref()
141                    .borrow()
142                    .p;
143                points.push(p);
144            }
145            loop {
146                let p = face
147                    .as_ref()
148                    .borrow()
149                    .prev_vert(self)
150                    .unwrap()
151                    .as_ref()
152                    .borrow()
153                    .p;
154                points.push(p);
155
156                let f2 = face.as_ref().borrow().prev_face(self);
157                if let Some(ff) = f2 {
158                    face = ff;
159                } else {
160                    break;
161                }
162            }
163        }
164        return points;
165    }
166}
167
168impl SDFace {
169    pub fn new() -> Self {
170        SDFace {
171            v: [None, None, None],
172            f: [None, None, None],
173            children: [None, None, None, None],
174        }
175    }
176
177    fn vnum(&self, v: &SDVertex) -> i32 {
178        let p_v = v as *const SDVertex;
179        for i in 0..3 {
180            let vi = self.v[i].as_ref().unwrap().upgrade().unwrap();
181            let p_vi: *const SDVertex = vi.as_ptr();
182            if p_v == p_vi {
183                return i as i32;
184            }
185        }
186        return -1;
187    }
188
189    pub fn next_face(&self, v: &SDVertex) -> Option<Arc<RefCell<SDFace>>> {
190        let i = self.vnum(v);
191        if i >= 0 {
192            if let Some(f) = self.f[i as usize].as_ref() {
193                return f.upgrade();
194            }
195        }
196        return None;
197    }
198
199    pub fn prev_face(&self, v: &SDVertex) -> Option<Arc<RefCell<SDFace>>> {
200        let i = self.vnum(v);
201        if i >= 0 {
202            if let Some(f) = self.f[PREV[i as usize]].as_ref() {
203                return f.upgrade();
204            }
205        }
206        return None;
207    }
208
209    pub fn next_vert(&self, v: &SDVertex) -> Option<Arc<RefCell<SDVertex>>> {
210        let i = self.vnum(v);
211        if i >= 0 {
212            if let Some(f) = self.v[NEXT[i as usize]].as_ref() {
213                return f.upgrade();
214            }
215        }
216        return None;
217    }
218
219    pub fn prev_vert(&self, v: &SDVertex) -> Option<Arc<RefCell<SDVertex>>> {
220        let i = self.vnum(v);
221        if i >= 0 {
222            if let Some(f) = self.v[PREV[i as usize]].as_ref() {
223                return f.upgrade();
224            }
225        }
226        return None;
227    }
228
229    pub fn other_vert(&self, v0: &SDVertex, v1: &SDVertex) -> Option<Arc<RefCell<SDVertex>>> {
230        let p_v0: *const SDVertex = v0 as *const SDVertex;
231        let p_v1: *const SDVertex = v1 as *const SDVertex;
232        for i in 0..3 {
233            let vi = self.v[i].as_ref().unwrap().upgrade().unwrap();
234            let p_vi: *const SDVertex = vi.as_ref().as_ptr();
235            if p_vi != p_v0 && p_vi != p_v1 {
236                return Some(vi);
237            }
238        }
239        return None;
240    }
241
242    pub fn get_child(&self, i: usize) -> Option<Arc<RefCell<SDFace>>> {
243        if let Some(child) = self.children[i].as_ref() {
244            return child.upgrade();
245        }
246        return None;
247    }
248}
249
250impl SDEdge {
251    pub fn new(v0: &Option<Weak<RefCell<SDVertex>>>, v1: &Option<Weak<RefCell<SDVertex>>>) -> Self {
252        let mut v = [None, None];
253        let p_v0 = v0.as_ref().unwrap().upgrade().unwrap().as_ptr();
254        let p_v1 = v1.as_ref().unwrap().upgrade().unwrap().as_ptr();
255        if p_v0 < p_v1 {
256            v[0] = v0.clone();
257            v[1] = v1.clone();
258        } else {
259            v[0] = v1.clone();
260            v[1] = v0.clone();
261        }
262
263        SDEdge {
264            v,
265            f: [None, None],
266            f0edge_num: 0,
267        }
268    }
269
270    pub fn get_key(&self) -> String {
271        let v0 = self.v[0].as_ref().unwrap();
272        let v0 = v0.upgrade().unwrap();
273        let v0 = v0.as_ptr();
274
275        let v1 = self.v[1].as_ref().unwrap();
276        let v1 = v1.upgrade().unwrap();
277        let v1 = v1.as_ptr();
278
279        //println!("{:?}_{:?}", v0, v1);
280        assert!(v0 < v1);
281
282        return format!("{:?}_{:?}", v0, v1);
283    }
284
285    pub fn get_position(&self, i: usize) -> Point3f {
286        let v = self.v[i].as_ref().unwrap().upgrade().unwrap();
287        let p = v.as_ref().borrow().p;
288        return p;
289    }
290}
291
292fn weight_one_ring(vert: &SDVertex, beta: Float) -> Point3f {
293    // Put _vert_ one-ring in _p_ring_
294    let p_ring = vert.one_ring();
295    let valence = p_ring.len() as Float;
296    let mut p = (1.0 - valence * beta) * vert.p;
297    for pp in p_ring.iter() {
298        p += beta * *pp;
299    }
300    return p;
301}
302
303fn weight_boundary(vert: &SDVertex, beta: Float) -> Point3f {
304    // Put _vert_ one-ring in _p_ring_
305    let p_ring = vert.one_ring();
306    let mut p = (1.0 - 2.0 * beta) * vert.p;
307    p += beta * p_ring[0];
308    p += beta * p_ring[p_ring.len() - 1];
309    return p;
310}
311
312fn beta(valence: u32) -> Float {
313    if valence == 3 {
314        return 3.0 / 16.0;
315    } else {
316        return 3.0 / (8.0 * valence as Float);
317    }
318}
319
320fn loop_gamma(valence: u32) -> Float {
321    return 1.0 / (valence as Float + 3.0 / (8.0 * beta(valence)));
322}
323
324fn loop_subdiv(
325    o2w: &Transform,
326    w2o: &Transform,
327    reverse_orientation: bool,
328    n_levels: i32,
329    vertex_indices: Vec<u32>,
330    p: Vec<Point3f>,
331    params: &ParamSet,
332) -> Result<Vec<Arc<dyn Shape>>, PbrtError> {
333    let mut vertices = Vec::new();
334    let mut faces = Vec::new();
335
336    let n_vertices = p.len();
337    for i in 0..n_vertices {
338        let v = Arc::new(RefCell::new(SDVertex::new(&p[i])));
339        vertices.push(v);
340    }
341    let n_indices = vertex_indices.len();
342    let n_faces = n_indices / 3;
343    for _ in 0..n_faces {
344        let f = Arc::new(RefCell::new(SDFace::new()));
345        faces.push(f);
346    }
347
348    // Set face to vertex pointers
349    for i in 0..n_faces {
350        for j in 0..3 {
351            let v = vertices[vertex_indices[3 * i + j] as usize].clone();
352            {
353                let mut f = faces[i].as_ref().borrow_mut();
354                let w = Arc::downgrade(&v);
355                f.v[j] = Some(w);
356            }
357            {
358                let mut v = v.as_ref().borrow_mut();
359                v.start_face = Some(Arc::downgrade(&faces[i]));
360            }
361        }
362    }
363
364    // Set neighbor pointers in _faces_
365    let mut edges = HashMap::new();
366    for i in 0..n_faces {
367        //let f = faces[i].borrow();
368        for en in 0..3 {
369            let v0 = TRI[en + 0];
370            let v1 = TRI[en + 1];
371
372            //let ff = faces[i].borrow();
373            let e = Arc::new(RefCell::new(SDEdge::new(
374                &faces[i].borrow().v[v0],
375                &faces[i].borrow().v[v1],
376            )));
377            let key = e.borrow().get_key();
378            if !edges.contains_key(&key) {
379                //if let std::collections::hash_map::Entry::Vacant(e) = edges.entry(key) {
380                // Handle new edge
381                {
382                    let mut e = e.as_ref().borrow_mut();
383                    e.f[0] = Some(Arc::downgrade(&faces[i]));
384                    e.f0edge_num = v0;
385                }
386                edges.insert(key, e);
387            } else {
388                // Handle previously seen edge
389                {
390                    let e = edges.get(&key).unwrap();
391                    let e = e.as_ref().borrow_mut();
392                    {
393                        let f0 = e.f[0].as_ref().unwrap().upgrade().unwrap();
394                        let mut f0 = f0.as_ref().borrow_mut();
395                        f0.f[e.f0edge_num] = Some(Arc::downgrade(&faces[i]));
396                    }
397                    {
398                        let mut f = faces[i].as_ref().borrow_mut();
399                        let ef = e.f[0].as_ref().unwrap().clone();
400                        f.f[en] = Some(ef);
401                    }
402                }
403                edges.remove(&key);
404            }
405        }
406    }
407
408    // Finish vertex initialization
409    for i in 0..n_vertices {
410        let mut v = vertices[i].as_ref().borrow_mut();
411        let start_face = v.get_start_face().unwrap();
412        let mut face = start_face.clone();
413        loop {
414            let f2 = face.borrow().next_face(v.deref());
415            if let Some(ff) = f2 {
416                if start_face.as_ptr() == ff.as_ptr() {
417                    break;
418                }
419                face = ff;
420            } else {
421                v.boundary = true;
422                break;
423            }
424        }
425        if !v.boundary && v.valence() == 6 {
426            v.regular = true;
427        } else if v.boundary && v.valence() == 4 {
428            v.regular = true;
429        } else {
430            v.regular = false;
431        }
432    }
433
434    // Refine _LoopSubdiv_ into triangles
435    let mut f = faces.clone();
436    let mut v = vertices.clone();
437    for _ in 0..n_levels {
438        // Update _f_ and _v_ for next level of subdivision
439        let mut new_faces = Vec::new();
440        let mut new_vertices = Vec::new();
441
442        // Allocate next level of children in mesh tree
443        for vertex in v.iter() {
444            let mut vv = vertex.as_ref().borrow_mut();
445            let new_vertex = Arc::new(RefCell::new(SDVertex::new(&vv.p)));
446            {
447                let mut nv = new_vertex.as_ref().borrow_mut();
448                nv.regular = vv.regular;
449                nv.boundary = vv.boundary;
450            }
451            vv.child = Some(Arc::downgrade(&new_vertex));
452
453            new_vertices.push(new_vertex);
454        }
455
456        for face in f.iter() {
457            let mut ff = face.as_ref().borrow_mut();
458            for k in 0..4 {
459                let new_face = Arc::new(RefCell::new(SDFace::new()));
460                ff.children[k] = Some(Arc::downgrade(&new_face));
461                new_faces.push(new_face);
462            }
463        }
464
465        // Update vertex positions and create new edge vertices
466
467        // Update vertex positions for even vertices
468        for vertex in v.iter() {
469            let vv = vertex.as_ref().borrow_mut();
470            if !vv.boundary {
471                // Apply one-ring rule for even vertex
472                if vv.regular {
473                    let child = vv.child.as_ref().unwrap().upgrade().unwrap();
474                    let mut child = child.as_ref().borrow_mut();
475                    child.p = weight_one_ring(vv.deref(), 1.0 / 16.0);
476                } else {
477                    let child = vv.child.as_ref().unwrap().upgrade().unwrap();
478                    let mut child = child.as_ref().borrow_mut();
479                    child.p = weight_one_ring(vv.deref(), beta(vv.valence()));
480                }
481            } else {
482                // Apply boundary rule for even vertex
483                let child = vv.child.as_ref().unwrap().upgrade().unwrap();
484                let mut child = child.as_ref().borrow_mut();
485                child.p = weight_boundary(vv.deref(), 1.0 / 8.0);
486            }
487        }
488
489        // Compute new odd edge vertices
490        let mut edge_verts: HashMap<String, Arc<RefCell<SDVertex>>> = HashMap::new();
491        for face in f.iter() {
492            let face = face.as_ref().borrow();
493            for k in 0..3 {
494                // Compute odd vertex on _k_th edge
495                let edge = SDEdge::new(&face.v[k], &face.v[NEXT[k]]);
496                let key = edge.get_key();
497                if !edge_verts.contains_key(&key) {
498                    let p = Vector3f::zero();
499                    let vert = Arc::new(RefCell::new(SDVertex::new(&p)));
500                    new_vertices.push(vert.clone());
501                    let boundary = face.f[k].is_none();
502                    let mut vv = vert.as_ref().borrow_mut();
503                    vv.regular = true;
504                    vv.boundary = boundary;
505                    vv.start_face = face.children[3].clone();
506                    if boundary {
507                        let p0 = edge.get_position(0);
508                        let p1 = edge.get_position(1);
509                        vv.p = 0.5 * p0 + 0.5 * p1;
510                    } else {
511                        let p0 = edge.get_position(0);
512                        let p1 = edge.get_position(1);
513                        let v0 = edge.v[0].as_ref().unwrap().upgrade().unwrap();
514                        let v1 = edge.v[1].as_ref().unwrap().upgrade().unwrap();
515                        let po0 = face
516                            .other_vert(v0.borrow().deref(), v1.borrow().deref())
517                            .unwrap()
518                            .borrow()
519                            .p;
520                        let po1 = face.f[k]
521                            .as_ref()
522                            .unwrap()
523                            .upgrade()
524                            .unwrap()
525                            .borrow()
526                            .other_vert(v0.borrow().deref(), v1.borrow().deref())
527                            .unwrap()
528                            .borrow()
529                            .p;
530                        vv.p = (3.0 / 8.0) * p0
531                            + (3.0 / 8.0) * p1
532                            + (1.0 / 8.0) * po0
533                            + (1.0 / 8.0) * po1;
534                    }
535                    edge_verts.insert(key.clone(), vert.clone());
536                }
537            }
538        }
539
540        // Update new mesh topology
541
542        // Update even vertex face pointers
543        for vertex in v.iter() {
544            let vv = vertex.as_ref().borrow();
545            let start_face = vv.get_start_face().unwrap();
546            let vert_num = start_face.as_ref().borrow().vnum(vv.deref());
547            let child = vv.child.as_ref().unwrap().upgrade().unwrap();
548            let mut child = child.as_ref().borrow_mut();
549            child.start_face = start_face.as_ref().borrow().children[vert_num as usize].clone();
550        }
551
552        // Update face neighbor pointers
553        for face in f.iter() {
554            let face = face.as_ref().borrow();
555            for j in 0..3 {
556                // Update children _f_ pointers for siblings
557                {
558                    let f3 = face.get_child(3).unwrap();
559                    let mut f3 = f3.as_ref().borrow_mut();
560                    f3.f[j] = face.children[NEXT[j]].clone();
561                }
562                {
563                    let fj = face.get_child(j).unwrap();
564                    let mut fj = fj.as_ref().borrow_mut();
565                    fj.f[NEXT[j]] = face.children[3].clone();
566                }
567                // Update children _f_ pointers for neighbor children
568                {
569                    if let Some(f2) = face.f[j].as_ref() {
570                        let fj = face.get_child(j).unwrap();
571                        let mut fj = fj.as_ref().borrow_mut();
572                        let f2 = f2.upgrade().unwrap();
573                        let f2 = f2.as_ref().borrow();
574                        let face_vj = face.v[j].as_ref().unwrap().upgrade().unwrap();
575                        let face_vj = face_vj.borrow(); //face->v[j]
576                        fj.f[j] = f2.children[f2.vnum(face_vj.deref()) as usize].clone();
577                    }
578                    if let Some(f2) = face.f[PREV[j]].as_ref() {
579                        let fj = face.get_child(j).unwrap();
580                        let mut fj = fj.as_ref().borrow_mut();
581                        let f2 = f2.upgrade().unwrap();
582                        let f2 = f2.as_ref().borrow();
583                        let face_vj = face.v[j].as_ref().unwrap().upgrade().unwrap();
584                        let face_vj = face_vj.borrow(); //face->v[j]
585                        fj.f[PREV[j]] = f2.children[f2.vnum(face_vj.deref()) as usize].clone();
586                    }
587                }
588            }
589        }
590
591        // Update face vertex pointers
592        for face in f.iter() {
593            let face = face.as_ref().borrow();
594            for j in 0..3 {
595                // Update child vertex pointer to new even vertex
596                {
597                    let fj = face.get_child(j).unwrap();
598                    let mut fj = fj.as_ref().borrow_mut();
599                    let face_vj = face.v[j].as_ref().unwrap().upgrade().unwrap();
600                    let face_vj = face_vj.borrow();
601                    fj.v[j] = face_vj.child.clone();
602                }
603
604                // Update child vertex pointer to new odd vertex
605                {
606                    let edge = SDEdge::new(&face.v[j], &face.v[NEXT[j]]);
607                    let key = edge.get_key();
608                    if let Some(vert) = edge_verts.get(&key) {
609                        {
610                            let f_child_j = face.get_child(j).unwrap();
611                            let mut f_child_j = f_child_j.as_ref().borrow_mut();
612                            f_child_j.v[NEXT[j]] = Some(Arc::downgrade(vert));
613                        }
614                        {
615                            let f_child_j = face.get_child(NEXT[j]).unwrap();
616                            let mut f_child_j = f_child_j.as_ref().borrow_mut();
617                            f_child_j.v[j] = Some(Arc::downgrade(vert));
618                        }
619                        {
620                            let f_child_j = face.get_child(3).unwrap();
621                            let mut f_child_j = f_child_j.as_ref().borrow_mut();
622                            f_child_j.v[j] = Some(Arc::downgrade(vert));
623                        }
624                    }
625                }
626            }
627        }
628        // Prepare for next level of subdivision
629        f = new_faces;
630        v = new_vertices;
631    }
632
633    // Push vertices to limit surface
634    let mut p_limit = Vec::with_capacity(v.len());
635    for vert in v.iter() {
636        let mut vert = vert.as_ref().borrow_mut();
637        if vert.boundary {
638            vert.p = weight_boundary(vert.deref(), 1.0 / 5.0);
639        } else {
640            vert.p = weight_one_ring(vert.deref(), loop_gamma(vert.valence()));
641        }
642        p_limit.push(vert.p);
643    }
644
645    // Compute vertex tangents on limit surface
646    let mut ns = Vec::with_capacity(v.len());
647    for vertex in v.iter() {
648        let vertex = vertex.as_ref().borrow();
649
650        let mut s = Vector3f::zero();
651        let mut t = Vector3f::zero();
652
653        let p_ring = vertex.one_ring();
654        let valence = p_ring.len();
655        if !vertex.boundary {
656            for j in 0..valence {
657                s += Float::cos(2.0 * PI * j as Float / valence as Float) * p_ring[j];
658                t += Float::sin(2.0 * PI * j as Float / valence as Float) * p_ring[j];
659            }
660        } else {
661            // Compute tangents of boundary face
662            s = p_ring[valence - 1] - p_ring[0];
663            if valence == 2 {
664                t = p_ring[0] + p_ring[1] - 2.0 * vertex.p;
665            } else if valence == 3 {
666                t = p_ring[1] - vertex.p;
667            } else if valence == 4 {
668                // regular
669                t = -1.0 * p_ring[0]
670                    + 2.0 * p_ring[1]
671                    + 2.0 * p_ring[2]
672                    + -1.0 * p_ring[3]
673                    + -2.0 * vertex.p;
674            } else {
675                let theta = PI / (valence - 1) as Float;
676                t = Float::sin(theta) * (p_ring[0] + p_ring[valence - 1]);
677                for k in 1..(valence - 1) {
678                    let wt = (2.0 * Float::cos(theta) - 2.0) * Float::sin(k as Float * theta);
679                    t += wt * p_ring[k];
680                }
681                t = -t;
682            }
683        }
684        let n = Vector3f::cross(&s, &t).normalize();
685        ns.push(n);
686    }
687
688    // Create triangle mesh from subdivision mesh
689    let ntris = f.len();
690    let mut verts: Vec<u32> = Vec::with_capacity(ntris * 3);
691    {
692        let mut used_verts = HashMap::new();
693        for i in 0..v.len() {
694            let p_vi = v[i].as_ref().as_ptr();
695            used_verts.insert(p_vi, i as u32);
696        }
697        for i in 0..ntris {
698            let face = f[i].as_ref().borrow();
699            for j in 0..3 {
700                let vj = face.v[j].as_ref().unwrap().upgrade().unwrap();
701                let p_vj = vj.as_ptr();
702                let index = *used_verts.get(&p_vj).unwrap();
703                verts.push(index);
704            }
705        }
706    }
707    let _uv = Vec::new();
708    let _s = Vec::new();
709    return Ok(create_triangle_mesh(
710        o2w,
711        w2o,
712        reverse_orientation,
713        verts,
714        p_limit,
715        _s,
716        ns,
717        _uv,
718        params,
719    ));
720}
721
722pub fn create_loop_subdiv(
723    o2w: &Transform,
724    w2o: &Transform,
725    reverse_orientation: bool,
726    params: &ParamSet,
727) -> Result<Vec<Arc<dyn Shape>>, PbrtError> {
728    let n_levels = params.find_one_int("levels", params.find_one_int("nlevels", 3));
729
730    let mut vertex_indices = Vec::new();
731    let mut p: Vec<Vector3f> = Vec::new();
732
733    if let Some(vi) = params.get_ints_ref("indices") {
734        vertex_indices.resize(vi.len(), 0);
735        for i in 0..vi.len() {
736            vertex_indices[i] = vi[i] as u32;
737        }
738    } else {
739        return Err(PbrtError::error(
740            "Vertex indices \"indices\" not provided for LoopSubdiv shape.",
741        ));
742    }
743
744    if let Some(ps) = params.get_points_ref("P") {
745        let sz = ps.len() / 3;
746        p.resize(sz, Point3f::zero());
747        for i in 0..sz {
748            p[i] = Point3f::new(ps[3 * i + 0], ps[3 * i + 1], ps[3 * i + 2]);
749        }
750    } else {
751        return Err(PbrtError::error(
752            "Vertex positions \"P\" not provided for LoopSubdiv shape.",
753        ));
754    }
755
756    // don't actually use this for now...
757    let _scheme = params.find_one_string("scheme", "loop");
758    return loop_subdiv(
759        o2w,
760        w2o,
761        reverse_orientation,
762        n_levels,
763        vertex_indices,
764        p,
765        params,
766    );
767}