vox_geometry_rust/
triangle_mesh3.rs

1/*
2 * // Copyright (c) 2021 Feng Yang
3 * //
4 * // I am making my contributions/submissions to this project solely in my
5 * // personal capacity and am not conveying any rights to any intellectual
6 * // property of any third parties.
7 */
8
9use crate::vector3::Vector3D;
10use crate::vector2::Vector2D;
11use crate::usize3::USize3;
12use crate::transform3::Transform3;
13use crate::surface3::*;
14use crate::bvh3::Bvh3;
15use crate::triangle3::Triangle3;
16use crate::quaternion::QuaternionD;
17use crate::ray3::Ray3D;
18use crate::bounding_box3::BoundingBox3D;
19use crate::nearest_neighbor_query_engine3::NearestNeighborQueryEngine3;
20use crate::intersection_query_engine3::IntersectionQueryEngine3;
21use crate::matrix3x3::Matrix3x3D;
22use rayon::iter::ParallelIterator;
23use rayon::prelude::IntoParallelRefMutIterator;
24use std::mem::swap;
25use std::sync::{RwLock, Arc};
26use std::ops::Add;
27use std::io::{Cursor, BufWriter, Write, Result};
28use std::borrow::BorrowMut;
29use std::fs::OpenOptions;
30
31const K_DEFAULT_FAST_WINDING_NUMBER_ACCURACY: f64 = 2.0;
32
33#[derive(Clone)]
34struct WindingNumberGatherData {
35    area_sums: f64,
36    area_weighted_normal_sums: Vector3D,
37    area_weighted_position_sums: Vector3D,
38}
39
40impl WindingNumberGatherData {
41    pub fn new() -> WindingNumberGatherData {
42        return WindingNumberGatherData {
43            area_sums: 0.0,
44            area_weighted_normal_sums: Vector3D::new_default(),
45            area_weighted_position_sums: Vector3D::new_default(),
46        };
47    }
48}
49
50impl Add for WindingNumberGatherData {
51    type Output = WindingNumberGatherData;
52
53    fn add(self, rhs: Self) -> Self::Output {
54        let mut sum = WindingNumberGatherData::new();
55        sum.area_sums = self.area_sums + rhs.area_sums;
56        sum.area_weighted_normal_sums =
57            self.area_weighted_normal_sums + rhs.area_weighted_normal_sums;
58        sum.area_weighted_position_sums =
59            self.area_weighted_position_sums + rhs.area_weighted_position_sums;
60
61        return sum;
62    }
63}
64
65fn post_order_traversal<GatherFunc, LeafGatherFunc>(bvh: &Bvh3<usize>, node_index: usize, visitor_func: &mut GatherFunc,
66                                                    leaf_func: &mut LeafGatherFunc,
67                                                    init_gather_data: &WindingNumberGatherData) -> WindingNumberGatherData
68    where GatherFunc: FnMut(usize, &WindingNumberGatherData),
69          LeafGatherFunc: FnMut(usize) -> WindingNumberGatherData {
70    let mut data = init_gather_data.clone();
71
72    if bvh.is_leaf(node_index) {
73        data = leaf_func(node_index);
74    } else {
75        let children = bvh.children(node_index);
76        data = data + post_order_traversal(bvh, children.0, visitor_func,
77                                           leaf_func, init_gather_data);
78        data = data + post_order_traversal(bvh, children.1, visitor_func,
79                                           leaf_func, init_gather_data);
80    }
81    visitor_func(node_index, &data);
82
83    return data;
84}
85
86//--------------------------------------------------------------------------------------------------
87///
88/// # 3-D triangle mesh geometry.
89///
90/// This class represents 3-D triangle mesh geometry which extends Surface3 by
91/// overriding surface-related queries. The mesh structure stores point,
92/// normals, and UV coordinates.
93///
94pub struct TriangleMesh3 {
95    _points: Vec<Vector3D>,
96    _normals: Vec<Vector3D>,
97    _uvs: Vec<Vector2D>,
98    _point_indices: Vec<USize3>,
99    _normal_indices: Vec<USize3>,
100    _uv_indices: Vec<USize3>,
101
102    _bvh: RwLock<Bvh3<usize>>,
103    _bvh_invalidated: RwLock<bool>,
104
105    _wn_area_weighted_normal_sums: RwLock<Vec<Vector3D>>,
106    _wn_area_weighted_avg_positions: RwLock<Vec<Vector3D>>,
107    _wn_invalidated: RwLock<bool>,
108
109    /// data from surface3
110    pub surface_data: Surface3Data,
111}
112
113impl TriangleMesh3 {
114    /// Default constructor.
115    /// ```
116    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
117    /// let mesh1 = TriangleMesh3::new_default(None, None);
118    /// assert_eq!(0, mesh1.number_of_points());
119    /// assert_eq!(0, mesh1.number_of_normals());
120    /// assert_eq!(0, mesh1.number_of_uvs());
121    /// assert_eq!(0, mesh1.number_of_triangles());
122    /// ```
123    pub fn new_default(transform: Option<Transform3>,
124                       is_normal_flipped: Option<bool>) -> TriangleMesh3 {
125        return TriangleMesh3 {
126            _points: vec![],
127            _normals: vec![],
128            _uvs: vec![],
129            _point_indices: vec![],
130            _normal_indices: vec![],
131            _uv_indices: vec![],
132            _bvh: RwLock::new(Bvh3::new()),
133            _bvh_invalidated: RwLock::new(true),
134            _wn_area_weighted_normal_sums: RwLock::new(vec![]),
135            _wn_area_weighted_avg_positions: RwLock::new(vec![]),
136            _wn_invalidated: RwLock::new(true),
137            surface_data: Surface3Data::new(transform, is_normal_flipped),
138        };
139    }
140
141    /// Constructs mesh with points, normals, uvs, and their indices.
142    pub fn new(points: Vec<Vector3D>, normals: Vec<Vector3D>,
143               uvs: Vec<Vector2D>, point_indices: Vec<USize3>,
144               normal_indices: Vec<USize3>, uv_indices: Vec<USize3>,
145               transform: Option<Transform3>,
146               is_normal_flipped: Option<bool>) -> TriangleMesh3 {
147        return TriangleMesh3 {
148            _points: points,
149            _normals: normals,
150            _uvs: uvs,
151            _point_indices: point_indices,
152            _normal_indices: normal_indices,
153            _uv_indices: uv_indices,
154            _bvh: RwLock::new(Bvh3::new()),
155            _bvh_invalidated: RwLock::new(true),
156            _wn_area_weighted_normal_sums: RwLock::new(vec![]),
157            _wn_area_weighted_avg_positions: RwLock::new(vec![]),
158            _wn_invalidated: RwLock::new(true),
159            surface_data: Surface3Data::new(transform, is_normal_flipped),
160        };
161    }
162
163    /// Returns builder fox TriangleMesh3.
164    pub fn builder() -> Builder {
165        return Builder::new();
166    }
167
168    /// Clears all content.
169    pub fn clear(&mut self) {
170        self._points.clear();
171        self._normals.clear();
172        self._uvs.clear();
173        self._point_indices.clear();
174        self._normal_indices.clear();
175        self._uv_indices.clear();
176
177        self.invalidate_cache();
178    }
179
180    /// Copies the contents from \p other mesh.
181    pub fn set(&mut self, other: &TriangleMesh3) {
182        self._points = other._points.clone();
183        self._normals = other._normals.clone();
184        self._uvs = other._uvs.clone();
185        self._point_indices = other._point_indices.clone();
186        self._normal_indices = other._normal_indices.clone();
187        self._uv_indices = other._uv_indices.clone();
188
189        self.invalidate_cache();
190    }
191
192    /// Swaps the contents with \p other mesh.
193    pub fn swap(&mut self, other: &mut TriangleMesh3) {
194        swap(&mut self._points, &mut other._points);
195        swap(&mut self._normals, &mut other._normals);
196        swap(&mut self._uvs, &mut other._uvs);
197        swap(&mut self._point_indices, &mut other._point_indices);
198        swap(&mut self._normal_indices, &mut other._normal_indices);
199        swap(&mut self._uv_indices, &mut other._uv_indices);
200    }
201
202    /// Returns area of this mesh.
203    pub fn area(&self) -> f64 {
204        let mut a: f64 = 0.0;
205        for i in 0..self.number_of_triangles() {
206            let tri = self.triangle(i);
207            a += tri.area();
208        }
209        return a;
210    }
211
212    /// Returns volume of this mesh.
213    pub fn volume(&self) -> f64 {
214        let mut vol: f64 = 0.0;
215        for i in 0..self.number_of_triangles() {
216            let tri = self.triangle(i);
217            vol += tri.points[0].dot(&tri.points[1].cross(&tri.points[2])) / 6.0;
218        }
219        return vol;
220    }
221
222    /// Returns constant reference to the i-th point.
223    pub fn point(&self, i: usize) -> Vector3D {
224        return self._points[i];
225    }
226
227    /// Returns reference to the i-th point.
228    pub fn point_mut(&mut self, i: usize) -> Vector3D {
229        self.invalidate_cache();
230        return self._points[i];
231    }
232
233    /// Returns constant reference to the i-th normal.
234    pub fn normal(&self, i: usize) -> Vector3D {
235        return self._normals[i];
236    }
237
238    /// Returns reference to the i-th normal.
239    pub fn normal_mut(&mut self, i: usize) -> Vector3D {
240        return self._normals[i];
241    }
242
243    /// Returns constant reference to the i-th UV coordinates.
244    pub fn uv(&self, i: usize) -> Vector2D {
245        return self._uvs[i];
246    }
247
248    /// Returns reference to the i-th UV coordinates.
249    pub fn uv_mut(&mut self, i: usize) -> Vector2D {
250        return self._uvs[i];
251    }
252
253    /// Returns constant reference to the point indices of i-th triangle.
254    pub fn point_index(&self, i: usize) -> USize3 {
255        return self._point_indices[i];
256    }
257
258    /// Returns reference to the point indices of i-th triangle.
259    pub fn point_index_mut(&mut self, i: usize) -> USize3 {
260        return self._point_indices[i];
261    }
262
263    /// Returns constant reference to the normal indices of i-th triangle.
264    pub fn normal_index(&self, i: usize) -> USize3 {
265        return self._normal_indices[i];
266    }
267
268    /// Returns reference to the normal indices of i-th triangle.
269    pub fn normal_index_mut(&mut self, i: usize) -> USize3 {
270        return self._normal_indices[i];
271    }
272
273    /// Returns constant reference to the UV indices of i-th triangle.
274    pub fn uv_index(&self, i: usize) -> USize3 {
275        return self._uv_indices[i];
276    }
277
278    /// Returns reference to the UV indices of i-th triangle.
279    pub fn uv_index_mut(&mut self, i: usize) -> USize3 {
280        return self._uv_indices[i];
281    }
282
283    /// Returns i-th triangle.
284    pub fn triangle(&self, i: usize) -> Triangle3 {
285        let mut tri = Triangle3::new_default(None, None);
286        for j in 0..3 {
287            tri.points[j] = self._points[self._point_indices[i][j]];
288            if self.has_uvs() {
289                tri.uvs[j] = self._uvs[self._uv_indices[i][j]];
290            }
291        }
292
293        let n = tri.face_normal();
294
295        for j in 0..3 {
296            if self.has_normals() {
297                tri.normals[j] = self._normals[self._normal_indices[i][j]];
298            } else {
299                tri.normals[j] = n;
300            }
301        }
302
303        return tri;
304    }
305
306    /// Returns number of points.
307    pub fn number_of_points(&self) -> usize {
308        return self._points.len();
309    }
310
311    /// Returns number of normals.
312    pub fn number_of_normals(&self) -> usize {
313        return self._normals.len();
314    }
315
316    /// Returns number of UV coordinates.
317    pub fn number_of_uvs(&self) -> usize {
318        return self._uvs.len();
319    }
320
321    /// Returns number of triangles.
322    pub fn number_of_triangles(&self) -> usize {
323        return self._point_indices.len();
324    }
325
326    /// Returns true if the mesh has normals.
327    pub fn has_normals(&self) -> bool {
328        return self._normals.len() > 0;
329    }
330
331    /// Returns true if the mesh has UV coordinates.
332    pub fn has_uvs(&self) -> bool {
333        return self._uvs.len() > 0;
334    }
335
336    /// Adds a point.
337    pub fn add_point(&mut self, pt: Vector3D) {
338        self._points.push(pt);
339    }
340
341    /// Adds a normal.
342    pub fn add_normal(&mut self, n: Vector3D) {
343        self._normals.push(n);
344    }
345
346    /// Adds a UV.
347    pub fn add_uv(&mut self, t: Vector2D) {
348        self._uvs.push(t);
349    }
350
351    /// Adds a triangle with points.
352    pub fn add_point_triangle(&mut self, new_point_indices: USize3) {
353        self._point_indices.push(new_point_indices);
354        self.invalidate_cache();
355    }
356
357    /// Adds a triangle with normal.
358    pub fn add_normal_triangle(&mut self, new_normal_indices: USize3) {
359        self._normal_indices.push(new_normal_indices);
360
361        self.invalidate_cache();
362    }
363
364    /// Adds a triangle with UV.
365    pub fn add_uv_triangle(&mut self, new_uv_indices: USize3) {
366        self._uv_indices.push(new_uv_indices);
367
368        self.invalidate_cache();
369    }
370
371    /// Adds a triangle with point and normal.
372    pub fn add_point_normal_triangle(&mut self, new_point_indices: USize3,
373                                     new_normal_indices: USize3) {
374        self._point_indices.push(new_point_indices);
375        self._normal_indices.push(new_normal_indices);
376
377        self.invalidate_cache();
378    }
379
380    /// Adds a triangle with point, normal, and UV.
381    pub fn add_point_uv_normal_triangle(&mut self, new_point_indices: USize3,
382                                        new_uv_indices: USize3,
383                                        new_normal_indices: USize3) {
384        self._point_indices.push(new_point_indices);
385        self._normal_indices.push(new_normal_indices);
386        self._uv_indices.push(new_uv_indices);
387
388        self.invalidate_cache();
389    }
390
391    /// Adds a triangle with point and UV.
392    pub fn add_point_uv_triangle(&mut self, new_point_indices: USize3,
393                                 new_uv_indices: USize3) {
394        self._point_indices.push(new_point_indices);
395        self._uv_indices.push(new_uv_indices);
396
397        self.invalidate_cache();
398    }
399
400    /// Add a triangle.
401    pub fn add_triangle(&mut self, tri: Triangle3) {
402        let v_start = self._points.len();
403        let n_start = self._normals.len();
404        let t_start = self._uvs.len();
405        let mut new_point_indices = USize3::new_default();
406        let mut new_normal_indices = USize3::new_default();
407        let mut new_uv_indices = USize3::new_default();
408        for i in 0..3 {
409            self._points.push(tri.points[i]);
410            self._normals.push(tri.normals[i]);
411            self._uvs.push(tri.uvs[i]);
412            new_point_indices[i] = v_start + i;
413            new_normal_indices[i] = n_start + i;
414            new_uv_indices[i] = t_start + i;
415        }
416        self._point_indices.push(new_point_indices);
417        self._normal_indices.push(new_normal_indices);
418        self._uv_indices.push(new_uv_indices);
419
420        self.invalidate_cache();
421    }
422
423    /// Sets entire normals to the face normals.
424    pub fn set_face_normal(&mut self) {
425        self._normals.resize(self._points.len(), Vector3D::new_default());
426        self._normal_indices = self._point_indices.clone();
427
428        for i in 0..self.number_of_triangles() {
429            let tri = self.triangle(i);
430            let n = tri.face_normal();
431            let f = self._point_indices[i];
432            self._normals[f.x] = n;
433            self._normals[f.y] = n;
434            self._normals[f.z] = n;
435        }
436    }
437
438    /// Sets angle weighted vertex normal.
439    pub fn set_angle_weighted_vertex_normal(&mut self) {
440        self._normals.clear();
441        self._normal_indices.clear();
442
443        let mut angle_weights: Vec<f64> = Vec::new();
444        angle_weights.resize(self._points.len(), 0.0);
445        let mut pseudo_normals: Vec<Vector3D> = Vec::new();
446        pseudo_normals.resize(self._points.len(), Vector3D::new_default());
447
448        for i in 0..self._points.len() {
449            angle_weights[i] = 0.0;
450            pseudo_normals[i] = Vector3D::new_default();
451        }
452
453        for i in 0..self.number_of_triangles() {
454            let mut pts: [Vector3D; 3] = [Vector3D::new_default(); 3];
455            let mut normal: Vector3D;
456            let mut e0: Vector3D;
457            let mut e1: Vector3D;
458            let mut cosangle: f64;
459            let mut angle: f64;
460            let mut idx: [usize; 3] = [0; 3];
461
462            // Quick references
463            for j in 0..3 {
464                idx[j] = self._point_indices[i][j];
465                pts[j] = self._points[idx[j]];
466            }
467
468            // Angle for point 0
469            e0 = pts[1] - pts[0];
470            e1 = pts[2] - pts[0];
471            e0.normalize();
472            e1.normalize();
473            normal = e0.cross(&e1);
474            normal.normalize();
475            cosangle = crate::math_utils::clamp(e0.dot(&e1), -1.0, 1.0);
476            angle = f64::acos(cosangle);
477            angle_weights[idx[0]] += angle;
478            pseudo_normals[idx[0]] += normal * angle;
479
480            // Angle for point 1
481            e0 = pts[2] - pts[1];
482            e1 = pts[0] - pts[1];
483            e0.normalize();
484            e1.normalize();
485            normal = e0.cross(&e1);
486            normal.normalize();
487            cosangle = crate::math_utils::clamp(e0.dot(&e1), -1.0, 1.0);
488            angle = f64::acos(cosangle);
489            angle_weights[idx[1]] += angle;
490            pseudo_normals[idx[1]] += normal * angle;
491
492            // Angle for point 2
493            e0 = pts[0] - pts[2];
494            e1 = pts[1] - pts[2];
495            e0.normalize();
496            e1.normalize();
497            normal = e0.cross(&e1);
498            normal.normalize();
499            cosangle = crate::math_utils::clamp(e0.dot(&e1), -1.0, 1.0);
500            angle = f64::acos(cosangle);
501            angle_weights[idx[2]] += angle;
502            pseudo_normals[idx[2]] += normal * angle;
503        }
504
505        for i in 0..self._points.len() {
506            if angle_weights[i] > 0.0 {
507                pseudo_normals[i] /= angle_weights[i];
508            }
509        }
510
511        swap(&mut pseudo_normals, &mut self._normals);
512        self._normal_indices = self._point_indices.clone();
513    }
514
515    /// Scales the mesh by given factor.
516    pub fn scale(&mut self, factor: f64) {
517        self._points.par_iter_mut().for_each(|x| {
518            *x *= factor;
519        });
520
521        self.invalidate_cache();
522    }
523
524    /// Translates the mesh.
525    pub fn translate(&mut self, t: Vector3D) {
526        self._points.par_iter_mut().for_each(|x| {
527            *x += t;
528        });
529
530        self.invalidate_cache();
531    }
532
533    /// Rotates the mesh.
534    pub fn rotate(&mut self, q: QuaternionD) {
535        self._points.par_iter_mut().for_each(|x| {
536            *x = q * (*x);
537        });
538
539        self._normals.par_iter_mut().for_each(|x| {
540            *x = q * (*x);
541        });
542
543        self.invalidate_cache();
544    }
545}
546
547impl TriangleMesh3 {
548    fn invalidate_cache(&self) {
549        *(self._bvh_invalidated.write().unwrap()) = true;
550        *(self._wn_invalidated.write().unwrap()) = true;
551    }
552
553    fn build_bvh(&self) {
554        if *self._bvh_invalidated.read().unwrap() {
555            let n_tris = self.number_of_triangles();
556            let mut ids: Vec<usize> = Vec::new();
557            ids.resize(n_tris, 0);
558            let mut bounds: Vec<BoundingBox3D> = Vec::new();
559            bounds.resize(n_tris, BoundingBox3D::new_default());
560            for i in 0..n_tris {
561                ids[i] = i;
562                bounds[i] = self.triangle(i).bounding_box();
563            }
564            self._bvh.write().unwrap().build(&ids, &bounds);
565            *(self._bvh_invalidated.write().unwrap()) = false;
566        }
567    }
568
569    fn build_winding_numbers(&self) {
570        // Barill et al., Fast Winding Numbers for Soups and Clouds, ACM SIGGRAPH
571        // 2018
572        if *self._wn_invalidated.read().unwrap() {
573            self.build_bvh();
574
575            let n_nodes = self._bvh.read().unwrap().number_of_nodes();
576            self._wn_area_weighted_normal_sums.write().unwrap().resize(n_nodes, Vector3D::new_default());
577            self._wn_area_weighted_avg_positions.write().unwrap().resize(n_nodes, Vector3D::new_default());
578
579            let mut visitor_func = |node_index: usize, data: &WindingNumberGatherData| {
580                self._wn_area_weighted_normal_sums.write().unwrap()[node_index] = data.area_weighted_normal_sums;
581                self._wn_area_weighted_avg_positions.write().unwrap()[node_index] = data.area_weighted_position_sums / data.area_sums;
582            };
583            let mut leaf_func = |node_index: usize| -> WindingNumberGatherData {
584                let mut result = WindingNumberGatherData::new();
585
586                let iter = self._bvh.read().unwrap().item_of_node(node_index);
587
588                let tri = self.triangle(iter);
589                let area = tri.area();
590                result.area_sums = area;
591                result.area_weighted_normal_sums = tri.face_normal() * area;
592                result.area_weighted_position_sums =
593                    (tri.points[0] + tri.points[1] + tri.points[2]) * area / 3.0;
594
595                return result;
596            };
597
598            post_order_traversal(&*self._bvh.read().unwrap(), 0, &mut visitor_func, &mut leaf_func,
599                                 &WindingNumberGatherData::new());
600
601            *(self._wn_invalidated.write().unwrap()) = false;
602        }
603    }
604
605    fn winding_number(&self, query_point: &Vector3D, tri_index: usize) -> f64 {
606        // Jacobson et al., Robust Inside-Outside Segmentation using Generalized
607        // Winding Numbers, ACM SIGGRAPH 2013.
608        let vi = self._points[self._point_indices[tri_index][0]];
609        let vj = self._points[self._point_indices[tri_index][1]];
610        let vk = self._points[self._point_indices[tri_index][2]];
611        let va = vi - *query_point;
612        let vb = vj - *query_point;
613        let vc = vk - *query_point;
614        let a = va.length();
615        let b = vb.length();
616        let c = vc.length();
617
618        let mat = Matrix3x3D::new(va.x, vb.x, vc.x,
619                                  va.y, vb.y, vc.y,
620                                  va.z, vb.z, vc.z);
621        let det = mat.determinant();
622        let denom =
623            a * b * c + va.dot(&vb) * c + vb.dot(&vc) * a + vc.dot(&va) * b;
624
625        let solid_angle = 2.0 * f64::atan2(det, denom);
626
627        return solid_angle;
628    }
629
630    fn fast_winding_number(&self, query_point: &Vector3D, accuracy: f64) -> f64 {
631        self.build_winding_numbers();
632
633        return self.fast_winding_number_internal(query_point, 0, accuracy);
634    }
635
636    fn fast_winding_number_internal(&self, q: &Vector3D, root_node_index: usize,
637                                    accuracy: f64) -> f64 {
638        // Barill et al., Fast Winding Numbers for Soups and Clouds, ACM SIGGRAPH
639        // 2018.
640        let tree_p = self._wn_area_weighted_avg_positions.read().unwrap()[root_node_index];
641        let q_to_p2 = q.distance_squared_to(tree_p);
642
643        let tree_n = self._wn_area_weighted_normal_sums.read().unwrap()[root_node_index];
644        let tree_bound = self._bvh.read().unwrap().node_bound(root_node_index);
645        let tree_rvec =
646            crate::vector3::max(&(tree_p - tree_bound.lower_corner), &(tree_bound.lower_corner - tree_p));
647        let tree_r = tree_rvec.length();
648
649        return if q_to_p2 > crate::math_utils::square(accuracy * tree_r) {
650            // Case: q is sufficiently far from all elements in tree
651            // TODO: This is zero-th order approximation. Higher-order approximation
652            // from Section 3.2.1 could be implemented for better accuracy in the
653            // future.
654            (tree_p - *q).dot(&tree_n) / (crate::constants::K_FOUR_PI_D * crate::math_utils::cubic(f64::sqrt(q_to_p2)))
655        } else {
656            if self._bvh.read().unwrap().is_leaf(root_node_index) {
657                // Case: q is nearby; use direct sum for tree’s elements
658                let iter = self._bvh.read().unwrap().item_of_node(root_node_index);
659                self.winding_number(q, iter) * crate::constants::K_FOUR_PI_D
660            } else {
661                // Case: Recursive call
662                let children = self._bvh.read().unwrap().children(root_node_index);
663                let mut wn = 0.0;
664                wn += self.fast_winding_number_internal(q, children.0, accuracy);
665                wn += self.fast_winding_number_internal(q, children.1, accuracy);
666                wn
667            }
668        };
669    }
670}
671
672impl TriangleMesh3 {
673    /// Writes the mesh in obj format to the file.
674    pub fn write_obj(&self, filename: String) -> Result<()> {
675        let f = OpenOptions::new().write(true).create(true)
676            .open(filename).unwrap();
677        let mut f = BufWriter::new(f);
678        // vertex
679        for pt in &self._points {
680            write!(f, "v {}\n", pt)?;
681        }
682
683        // uv coords
684        for uv in &self._uvs {
685            write!(f, "vt {}\n", uv)?;
686        }
687
688        // normals
689        for n in &self._normals {
690            write!(f, "vn {}\n", n)?;
691        }
692
693        // faces
694        let has_uvs = self.has_uvs();
695        let has_normals = self.has_normals();
696        for i in 0..self.number_of_triangles() {
697            write!(f, "f ")?;
698            for j in 0..3 {
699                write!(f, "{}", self._point_indices[i][j] + 1)?;
700                if has_normals || has_uvs {
701                    write!(f, "/")?;
702                }
703                if has_uvs {
704                    write!(f, "{}", self._uv_indices[i][j] + 1)?;
705                }
706                if has_normals {
707                    write!(f, "/{}", self._normal_indices[i][j] + 1)?;
708                }
709                write!(f, " ")?;
710            }
711            write!(f, "\n")?;
712        }
713
714        f.flush()?;
715
716        return Ok(());
717    }
718
719
720    /// Reads the mesh in obj format from the buffer.
721    /// ```
722    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
723    /// use vox_geometry_rust::unit_tests_utils::get_cube_tri_mesh3x3x3obj;
724    /// use std::io::Cursor;
725    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
726    ///
727    /// let mut mesh = TriangleMesh3::new_default(None, None);
728    /// mesh.read_obj_buffer(&mut buffer);
729    ///
730    /// assert_eq!(56, mesh.number_of_points());
731    /// assert_eq!(96, mesh.number_of_normals());
732    /// assert_eq!(76, mesh.number_of_uvs());
733    /// assert_eq!(108, mesh.number_of_triangles());
734    /// ```
735    pub fn read_obj_buffer(&mut self, strm: &mut Cursor<&[u8]>) -> bool {
736        let (models, _) = tobj::load_obj_buf(
737            &mut strm.borrow_mut(),
738            &tobj::LoadOptions::default(),
739            |_| { unreachable!(); })
740            .expect("Failed to OBJ load buffer");
741
742        return self.read_model(models);
743    }
744
745    /// Reads the mesh in obj format from the file.
746    pub fn read_obj_file(&mut self, filename: String) -> bool {
747        let (models, _) =
748            tobj::load_obj(
749                &filename,
750                &tobj::LoadOptions::default(),
751            ).expect("Failed to OBJ load file");
752
753        return self.read_model(models);
754    }
755
756    fn read_model(&mut self, models: Vec<tobj::Model>) -> bool {
757        for (_, m) in models.iter().enumerate() {
758            let mesh = &m.mesh;
759            // Read vertices
760            for v in 0..mesh.positions.len() / 3 {
761                let vx = mesh.positions[3 * v] as f64;
762                let vy = mesh.positions[3 * v + 1] as f64;
763                let vz = mesh.positions[3 * v + 2] as f64;
764                self.add_point(Vector3D::new(vx, vy, vz));
765            }
766
767            // Read normals
768            for v in 0..mesh.normals.len() / 3 {
769                let vx = mesh.normals[3 * v] as f64;
770                let vy = mesh.normals[3 * v + 1] as f64;
771                let vz = mesh.normals[3 * v + 2] as f64;
772                self.add_normal(Vector3D::new(vx, vy, vz));
773            }
774
775            // Read UVs
776            for v in 0..mesh.texcoords.len() / 2 {
777                let tu = mesh.texcoords[2 * v] as f64;
778                let tv = mesh.texcoords[2 * v + 1] as f64;
779                self.add_uv(Vector2D::new(tu, tv));
780            }
781
782            // the mesh consists only of triangles.
783            let mut next_face = 0;
784            if mesh.face_arities.is_empty() {
785                let fv = 3;
786                for _ in 0..mesh.indices.len() / 3 {
787                    if !mesh.indices.is_empty() {
788                        self.add_point_triangle(USize3::new(mesh.indices[next_face] as usize,
789                                                            mesh.indices[next_face + 1] as usize,
790                                                            mesh.indices[next_face + 2] as usize));
791                    }
792
793                    if !mesh.normal_indices.is_empty() {
794                        self.add_normal_triangle(USize3::new(mesh.normal_indices[next_face] as usize,
795                                                             mesh.normal_indices[next_face + 1] as usize,
796                                                             mesh.normal_indices[next_face + 2] as usize));
797                    }
798
799                    if !mesh.texcoord_indices.is_empty() {
800                        self.add_uv_triangle(USize3::new(mesh.texcoord_indices[next_face] as usize,
801                                                         mesh.texcoord_indices[next_face + 1] as usize,
802                                                         mesh.texcoord_indices[next_face + 2] as usize));
803                    }
804                    next_face += fv;
805                }
806            }
807        }
808
809
810        self.invalidate_cache();
811        return true;
812    }
813}
814
815impl Surface3 for TriangleMesh3 {
816    /// ```
817    /// use vox_geometry_rust::vector3::Vector3D;
818    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
819    /// use vox_geometry_rust::unit_tests_utils::*;
820    /// use std::io::Cursor;
821    /// use vox_geometry_rust::surface3::Surface3;
822    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
823    ///
824    /// let mut mesh = TriangleMesh3::new_default(None, None);
825    /// mesh.read_obj_buffer(&mut buffer);
826    ///
827    /// let brute_force_search = |pt:&Vector3D| {
828    ///     let mut min_dist2 = f64::MAX;
829    ///     let mut result = Vector3D::new_default();
830    ///     for i in 0..mesh.number_of_triangles() {
831    ///         let tri = mesh.triangle(i);
832    ///         let local_result = tri.closest_point(pt);
833    ///         let local_dist2 = pt.distance_squared_to(local_result);
834    ///         if local_dist2 < min_dist2 {
835    ///             min_dist2 = local_dist2;
836    ///             result = local_result;
837    ///         }
838    ///     }
839    ///     return result;
840    /// };
841    ///
842    /// let num_samples = get_number_of_sample_points3();
843    /// for i in 0..num_samples {
844    ///     let actual = mesh.closest_point(&Vector3D::new_lst(get_sample_points3()[i]));
845    ///     let expected = brute_force_search(&Vector3D::new_lst(get_sample_points3()[i]));
846    ///     assert_eq!(expected, actual);
847    /// }
848    /// ```
849    fn closest_point_local(&self, other_point: &Vector3D) -> Vector3D {
850        self.build_bvh();
851
852        let mut distance_func = |tri_idx: &usize, pt: &Vector3D| {
853            let tri = self.triangle(*tri_idx);
854            return tri.closest_distance(pt);
855        };
856
857        let query_result = self._bvh.read().unwrap().nearest(other_point, &mut distance_func);
858        match query_result.item {
859            None => {
860                panic!("No item found!");
861            }
862            Some(item) => {
863                return self.triangle(item).closest_point(other_point);
864            }
865        }
866    }
867
868    /// ```
869    /// use vox_geometry_rust::vector3::Vector3D;
870    /// use vox_geometry_rust::bounding_box3::BoundingBox3D;
871    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
872    /// use vox_geometry_rust::unit_tests_utils::*;
873    /// use std::io::Cursor;
874    /// use vox_geometry_rust::surface3::Surface3;
875    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
876    ///
877    /// let mut mesh = TriangleMesh3::new_default(None, None);
878    /// mesh.read_obj_buffer(&mut buffer);
879    ///
880    /// let aabb = BoundingBox3D::new(Vector3D::new(-0.5, -0.5, -0.5), Vector3D::new(0.5, 0.5, 0.5));
881    /// assert_eq!(aabb.lower_corner, mesh.bounding_box().lower_corner);
882    /// assert_eq!(aabb.upper_corner, mesh.bounding_box().upper_corner);
883    /// ```
884    fn bounding_box_local(&self) -> BoundingBox3D {
885        self.build_bvh();
886
887        return self._bvh.read().unwrap().bounding_box();
888    }
889
890    /// ```
891    /// use vox_geometry_rust::vector3::Vector3D;
892    /// use vox_geometry_rust::ray3::Ray3D;
893    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
894    /// use vox_geometry_rust::unit_tests_utils::*;
895    /// use std::io::Cursor;
896    /// use vox_geometry_rust::surface3::*;
897    /// use vox_geometry_rust::assert_delta;
898    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
899    ///
900    /// let mut mesh = TriangleMesh3::new_default(None, None);
901    /// mesh.read_obj_buffer(&mut buffer);
902    ///
903    /// let num_samples = get_number_of_sample_points3();
904    ///
905    /// let brute_force_test = |ray:&Ray3D| {
906    ///     let mut result = SurfaceRayIntersection3::new();
907    ///     for i in 0..mesh.number_of_triangles() {
908    ///         let tri = mesh.triangle(i);
909    ///         let local_result = tri.closest_intersection(ray);
910    ///         if local_result.distance < result.distance {
911    ///             result = local_result;
912    ///         }
913    ///     }
914    ///     return result;
915    /// };
916    ///
917    /// for i in 0..num_samples {
918    ///     let ray = Ray3D::new(Vector3D::new_lst(get_sample_points3()[i]),
919    ///                          Vector3D::new_lst(get_sample_dirs3()[i]));
920    ///     let actual = mesh.closest_intersection(&ray);
921    ///     let expected = brute_force_test(&ray);
922    ///     assert_delta!(expected.distance, actual.distance, f64::EPSILON);
923    ///     assert_eq!(expected.point.is_similar(&actual.point, None), true);
924    ///     assert_eq!(expected.normal, actual.normal);
925    ///     assert_eq!(expected.is_intersecting, actual.is_intersecting);
926    /// }
927    /// ```
928    fn closest_intersection_local(&self, ray: &Ray3D) -> SurfaceRayIntersection3 {
929        self.build_bvh();
930
931        let mut test_func = |tri_idx: &usize, ray: &Ray3D| {
932            let tri = self.triangle(*tri_idx);
933            let result = tri.closest_intersection(ray);
934            return result.distance;
935        };
936
937        let query_result = self._bvh.read().unwrap().closest_intersection(ray, &mut test_func);
938        let mut result = SurfaceRayIntersection3::new();
939        result.distance = query_result.distance;
940        match query_result.item {
941            None => {
942                result.is_intersecting = false;
943            }
944            Some(item) => {
945                result.is_intersecting = true;
946                result.point = ray.point_at(query_result.distance);
947                result.normal = self.triangle(item).closest_normal(&result.point);
948            }
949        }
950        return result;
951    }
952
953    /// ```
954    /// use vox_geometry_rust::vector3::Vector3D;
955    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
956    /// use vox_geometry_rust::unit_tests_utils::*;
957    /// use std::io::Cursor;
958    /// use vox_geometry_rust::surface3::Surface3;
959    /// let mut buffer = Cursor::new(get_sphere_tri_mesh5x5obj());
960    ///
961    /// let mut mesh = TriangleMesh3::new_default(None, None);
962    /// mesh.read_obj_buffer(&mut buffer);
963    ///
964    /// let brute_force_search = |pt:&Vector3D| {
965    ///     let mut min_dist2 = f64::MAX;
966    ///     let mut result = Vector3D::new_default();
967    ///     for i in 0..mesh.number_of_triangles() {
968    ///         let tri = mesh.triangle(i);
969    ///         let local_result = tri.closest_normal(pt);
970    ///         let closest_pt = tri.closest_point(pt);
971    ///         let local_dist2 = pt.distance_squared_to(closest_pt);
972    ///         if local_dist2 < min_dist2 {
973    ///             min_dist2 = local_dist2;
974    ///             result = local_result;
975    ///         }
976    ///     }
977    ///     return result;
978    /// };
979    ///
980    /// let num_samples = get_number_of_sample_points3();
981    /// for i in 0..num_samples {
982    ///     let actual = mesh.closest_normal(&Vector3D::new_lst(get_sample_points3()[i]));
983    ///     let expected = brute_force_search(&Vector3D::new_lst(get_sample_points3()[i]));
984    ///     assert_eq!(expected.is_similar(&actual, Some(1.0e-9)), true);
985    /// }
986    /// ```
987    fn closest_normal_local(&self, other_point: &Vector3D) -> Vector3D {
988        self.build_bvh();
989
990        let mut distance_func = |tri_idx: &usize, pt: &Vector3D| {
991            let tri = self.triangle(*tri_idx);
992            return tri.closest_distance(pt);
993        };
994
995        let query_result = self._bvh.read().unwrap().nearest(other_point, &mut distance_func);
996        match query_result.item {
997            None => {
998                panic!("No item found!");
999            }
1000            Some(item) => {
1001                return self.triangle(item).closest_normal(other_point);
1002            }
1003        }
1004    }
1005
1006    /// ```
1007    /// use vox_geometry_rust::vector3::Vector3D;
1008    /// use vox_geometry_rust::ray3::Ray3D;
1009    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
1010    /// use vox_geometry_rust::unit_tests_utils::*;
1011    /// use std::io::Cursor;
1012    /// use vox_geometry_rust::surface3::Surface3;
1013    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
1014    ///
1015    /// let mut mesh = TriangleMesh3::new_default(None, None);
1016    /// mesh.read_obj_buffer(&mut buffer);
1017    ///
1018    /// let num_samples = get_number_of_sample_points3();
1019    ///
1020    /// let brute_force_test = |ray:&Ray3D| {
1021    ///     for i in 0..mesh.number_of_triangles() {
1022    ///         let tri = mesh.triangle(i);
1023    ///         if tri.intersects(ray) {
1024    ///             return true;
1025    ///         }
1026    ///     }
1027    ///     return false;
1028    /// };
1029    ///
1030    /// for i in 0..num_samples {
1031    ///     let ray = Ray3D::new(Vector3D::new_lst(get_sample_points3()[i]),
1032    ///                          Vector3D::new_lst(get_sample_dirs3()[i]));
1033    ///     let actual = mesh.intersects(&ray);
1034    ///     let expected = brute_force_test(&ray);
1035    ///     assert_eq!(expected, actual);
1036    /// }
1037    /// ```
1038    fn intersects_local(&self, ray_local: &Ray3D) -> bool {
1039        self.build_bvh();
1040
1041        let mut test_func = |tri_idx: &usize, ray: &Ray3D| {
1042            let tri = self.triangle(*tri_idx);
1043            return tri.intersects(ray);
1044        };
1045
1046        return self._bvh.read().unwrap().intersects_ray(ray_local, &mut test_func);
1047    }
1048
1049    /// ```
1050    /// use vox_geometry_rust::vector3::Vector3D;
1051    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
1052    /// use vox_geometry_rust::unit_tests_utils::*;
1053    /// use std::io::Cursor;
1054    /// use vox_geometry_rust::surface3::Surface3;
1055    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
1056    ///
1057    /// let mut mesh = TriangleMesh3::new_default(None, None);
1058    /// mesh.read_obj_buffer(&mut buffer);
1059    ///
1060    /// let brute_force_search = |pt:&Vector3D| {
1061    ///     let mut min_dist = f64::MAX;
1062    ///     for i in 0..mesh.number_of_triangles() {
1063    ///         let tri = mesh.triangle(i);
1064    ///         let local_result = tri.closest_distance(pt);
1065    ///         if local_result < min_dist {
1066    ///             min_dist = local_result;
1067    ///         }
1068    ///     }
1069    ///     return min_dist;
1070    /// };
1071    ///
1072    /// let num_samples = get_number_of_sample_points3();
1073    /// for i in 0..num_samples {
1074    ///     let actual = mesh.closest_distance(&Vector3D::new_lst(get_sample_points3()[i]));
1075    ///     let expected = brute_force_search(&Vector3D::new_lst(get_sample_points3()[i]));
1076    ///     assert_eq!(expected, actual);
1077    /// }
1078    /// ```
1079    fn closest_distance_local(&self, other_point_local: &Vector3D) -> f64 {
1080        self.build_bvh();
1081
1082        let mut distance_func = |tri_idx: &usize, pt: &Vector3D| {
1083            let tri = self.triangle(*tri_idx);
1084            return tri.closest_distance(pt);
1085        };
1086
1087        let query_result = self._bvh.read().unwrap().nearest(other_point_local, &mut distance_func);
1088        return query_result.distance;
1089    }
1090
1091    /// ```
1092    /// use vox_geometry_rust::vector3::Vector3D;
1093    /// use vox_geometry_rust::ray3::Ray3D;
1094    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
1095    /// use vox_geometry_rust::unit_tests_utils::*;
1096    /// use std::io::Cursor;
1097    /// use vox_geometry_rust::surface3::Surface3;
1098    /// let mut buffer = Cursor::new(get_cube_tri_mesh3x3x3obj());
1099    ///
1100    /// let mut mesh = TriangleMesh3::new_default(None, None);
1101    /// mesh.read_obj_buffer(&mut buffer);
1102    ///
1103    /// let num_samples = get_number_of_sample_points3();
1104    ///
1105    /// for i in 0..num_samples {
1106    ///     let p = Vector3D::new_lst(get_sample_points3()[i]);
1107    ///     let actual = mesh.is_inside(&p);
1108    ///     let expected = mesh.bounding_box().contains(&p);
1109    ///     assert_eq!(expected, actual);
1110    /// }
1111    /// ```
1112    fn is_inside_local(&self, other_point_local: &Vector3D) -> bool {
1113        return self.fast_winding_number(other_point_local, K_DEFAULT_FAST_WINDING_NUMBER_ACCURACY) >
1114            0.5;
1115    }
1116
1117    fn update_query_engine(&self) {
1118        self.build_bvh();
1119        self.build_winding_numbers();
1120    }
1121
1122    fn view(&self) -> &Surface3Data {
1123        return &self.surface_data;
1124    }
1125}
1126
1127/// Shared pointer for the TriangleMesh3 type.
1128pub type TriangleMesh3Ptr = Arc<RwLock<TriangleMesh3>>;
1129
1130//--------------------------------------------------------------------------------------------------
1131///
1132/// # Front-end to create TriangleMesh3 objects step by step.
1133///
1134pub struct Builder {
1135    _points: Vec<Vector3D>,
1136    _normals: Vec<Vector3D>,
1137    _uvs: Vec<Vector2D>,
1138    _point_indices: Vec<USize3>,
1139    _normal_indices: Vec<USize3>,
1140    _uv_indices: Vec<USize3>,
1141
1142    _surface_data: Surface3Data,
1143}
1144
1145impl Builder {
1146    /// Returns builder with points.
1147    pub fn with_points(&mut self, points: Vec<Vector3D>) -> &mut Self {
1148        self._points = points;
1149        return self;
1150    }
1151
1152    /// Returns builder with normals.
1153    pub fn with_normals(&mut self, normals: Vec<Vector3D>) -> &mut Self {
1154        self._normals = normals;
1155        return self;
1156    }
1157
1158    /// Returns builder with uvs.
1159    pub fn with_uvs(&mut self, uvs: Vec<Vector2D>) -> &mut Self {
1160        self._uvs = uvs;
1161        return self;
1162    }
1163
1164    /// Returns builder with point indices.
1165    pub fn with_point_indices(&mut self, point_indices: Vec<USize3>) -> &mut Self {
1166        self._point_indices = point_indices;
1167        return self;
1168    }
1169
1170    /// Returns builder with normal indices.
1171    pub fn with_normal_indices(&mut self, normal_indices: Vec<USize3>) -> &mut Self {
1172        self._normal_indices = normal_indices;
1173        return self;
1174    }
1175
1176    /// Returns builder with uv indices.
1177    pub fn with_uv_indices(&mut self, uv_indices: Vec<USize3>) -> &mut Self {
1178        self._uv_indices = uv_indices;
1179        return self;
1180    }
1181
1182    /// Builds TriangleMesh3.
1183    /// ```
1184    /// use vox_geometry_rust::vector3::Vector3D;
1185    /// use vox_geometry_rust::vector2::Vector2D;
1186    /// use vox_geometry_rust::triangle_mesh3::TriangleMesh3;
1187    /// use vox_geometry_rust::usize3::USize3;
1188    ///
1189    /// let points = vec![
1190    ///     Vector3D::new(1.0, 2.0, 3.0),
1191    ///     Vector3D::new(4.0, 5.0, 6.0),
1192    ///     Vector3D::new(7.0, 8.0, 9.0),
1193    ///     Vector3D::new(10.0, 11.0, 12.0)
1194    /// ];
1195    ///
1196    /// let normals = vec![
1197    ///     Vector3D::new(10.0, 11.0, 12.0),
1198    ///     Vector3D::new(7.0, 8.0, 9.0),
1199    ///     Vector3D::new(4.0, 5.0, 6.0),
1200    ///     Vector3D::new(1.0, 2.0, 3.0)
1201    /// ];
1202    ///
1203    /// let uvs = vec![
1204    ///     Vector2D::new(13.0, 14.0),
1205    ///     Vector2D::new(15.0, 16.0)
1206    /// ];
1207    ///
1208    /// let point_indices = vec![
1209    ///     USize3::new(0, 1, 2),
1210    ///     USize3::new(0, 1, 3)
1211    /// ];
1212    ///
1213    /// let normal_indices = vec![
1214    ///     USize3::new(1, 2, 3),
1215    ///     USize3::new(2, 1, 0)
1216    /// ];
1217    ///
1218    /// let uv_indices = vec![
1219    ///     USize3::new(1, 0, 2),
1220    ///     USize3::new(3, 1, 0)
1221    /// ];
1222    ///
1223    /// let mesh = TriangleMesh3::builder()
1224    ///     .with_points(points.clone())
1225    ///     .with_normals(normals.clone())
1226    ///     .with_uvs(uvs.clone())
1227    ///     .with_point_indices(point_indices.clone())
1228    ///     .with_normal_indices(normal_indices.clone())
1229    ///     .with_uv_indices(uv_indices.clone())
1230    ///     .build();
1231    ///
1232    /// assert_eq!(4, mesh.number_of_points());
1233    /// assert_eq!(4, mesh.number_of_normals());
1234    /// assert_eq!(2, mesh.number_of_uvs());
1235    /// assert_eq!(2, mesh.number_of_triangles());
1236    ///
1237    /// for i in 0..mesh.number_of_points() {
1238    ///     assert_eq!(points[i], mesh.point(i));
1239    /// }
1240    ///
1241    /// for i in 0..mesh.number_of_normals() {
1242    ///     assert_eq!(normals[i], mesh.normal(i));
1243    /// }
1244    ///
1245    /// for i in 0..mesh.number_of_uvs() {
1246    ///     assert_eq!(uvs[i], mesh.uv(i));
1247    /// }
1248    ///
1249    /// for i in 0..mesh.number_of_triangles() {
1250    ///     assert_eq!(point_indices[i], mesh.point_index(i));
1251    ///     assert_eq!(normal_indices[i], mesh.normal_index(i));
1252    ///     assert_eq!(uv_indices[i], mesh.uv_index(i));
1253    /// }
1254    /// ```
1255    pub fn build(&mut self) -> TriangleMesh3 {
1256        return TriangleMesh3::new(self._points.clone(),
1257                                  self._normals.clone(),
1258                                  self._uvs.clone(),
1259                                  self._point_indices.clone(),
1260                                  self._normal_indices.clone(),
1261                                  self._uv_indices.clone(),
1262                                  Some(self._surface_data.transform.clone()),
1263                                  Some(self._surface_data.is_normal_flipped));
1264    }
1265
1266    /// Builds shared pointer of TriangleMesh3 instance.
1267    pub fn make_shared(&mut self) -> TriangleMesh3Ptr {
1268        return TriangleMesh3Ptr::new(RwLock::new(self.build()));
1269    }
1270
1271    /// constructor
1272    pub fn new() -> Builder {
1273        return Builder {
1274            _points: vec![],
1275            _normals: vec![],
1276            _uvs: vec![],
1277            _point_indices: vec![],
1278            _normal_indices: vec![],
1279            _surface_data: Surface3Data::new(None, None),
1280            _uv_indices: vec![],
1281        };
1282    }
1283}
1284
1285impl SurfaceBuilderBase3 for Builder {
1286    fn view(&mut self) -> &mut Surface3Data {
1287        return &mut self._surface_data;
1288    }
1289}