1use 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
86pub 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 pub surface_data: Surface3Data,
111}
112
113impl TriangleMesh3 {
114 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 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 pub fn builder() -> Builder {
165 return Builder::new();
166 }
167
168 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 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 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 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 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 pub fn point(&self, i: usize) -> Vector3D {
224 return self._points[i];
225 }
226
227 pub fn point_mut(&mut self, i: usize) -> Vector3D {
229 self.invalidate_cache();
230 return self._points[i];
231 }
232
233 pub fn normal(&self, i: usize) -> Vector3D {
235 return self._normals[i];
236 }
237
238 pub fn normal_mut(&mut self, i: usize) -> Vector3D {
240 return self._normals[i];
241 }
242
243 pub fn uv(&self, i: usize) -> Vector2D {
245 return self._uvs[i];
246 }
247
248 pub fn uv_mut(&mut self, i: usize) -> Vector2D {
250 return self._uvs[i];
251 }
252
253 pub fn point_index(&self, i: usize) -> USize3 {
255 return self._point_indices[i];
256 }
257
258 pub fn point_index_mut(&mut self, i: usize) -> USize3 {
260 return self._point_indices[i];
261 }
262
263 pub fn normal_index(&self, i: usize) -> USize3 {
265 return self._normal_indices[i];
266 }
267
268 pub fn normal_index_mut(&mut self, i: usize) -> USize3 {
270 return self._normal_indices[i];
271 }
272
273 pub fn uv_index(&self, i: usize) -> USize3 {
275 return self._uv_indices[i];
276 }
277
278 pub fn uv_index_mut(&mut self, i: usize) -> USize3 {
280 return self._uv_indices[i];
281 }
282
283 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 pub fn number_of_points(&self) -> usize {
308 return self._points.len();
309 }
310
311 pub fn number_of_normals(&self) -> usize {
313 return self._normals.len();
314 }
315
316 pub fn number_of_uvs(&self) -> usize {
318 return self._uvs.len();
319 }
320
321 pub fn number_of_triangles(&self) -> usize {
323 return self._point_indices.len();
324 }
325
326 pub fn has_normals(&self) -> bool {
328 return self._normals.len() > 0;
329 }
330
331 pub fn has_uvs(&self) -> bool {
333 return self._uvs.len() > 0;
334 }
335
336 pub fn add_point(&mut self, pt: Vector3D) {
338 self._points.push(pt);
339 }
340
341 pub fn add_normal(&mut self, n: Vector3D) {
343 self._normals.push(n);
344 }
345
346 pub fn add_uv(&mut self, t: Vector2D) {
348 self._uvs.push(t);
349 }
350
351 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 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 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 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 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 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 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 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 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 for j in 0..3 {
464 idx[j] = self._point_indices[i][j];
465 pts[j] = self._points[idx[j]];
466 }
467
468 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 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 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 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 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 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 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 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 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 (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 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 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 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 for pt in &self._points {
680 write!(f, "v {}\n", pt)?;
681 }
682
683 for uv in &self._uvs {
685 write!(f, "vt {}\n", uv)?;
686 }
687
688 for n in &self._normals {
690 write!(f, "vn {}\n", n)?;
691 }
692
693 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 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 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 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 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 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 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 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 fn bounding_box_local(&self) -> BoundingBox3D {
885 self.build_bvh();
886
887 return self._bvh.read().unwrap().bounding_box();
888 }
889
890 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 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 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 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 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
1127pub type TriangleMesh3Ptr = Arc<RwLock<TriangleMesh3>>;
1129
1130pub 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 pub fn with_points(&mut self, points: Vec<Vector3D>) -> &mut Self {
1148 self._points = points;
1149 return self;
1150 }
1151
1152 pub fn with_normals(&mut self, normals: Vec<Vector3D>) -> &mut Self {
1154 self._normals = normals;
1155 return self;
1156 }
1157
1158 pub fn with_uvs(&mut self, uvs: Vec<Vector2D>) -> &mut Self {
1160 self._uvs = uvs;
1161 return self;
1162 }
1163
1164 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 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 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 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 pub fn make_shared(&mut self) -> TriangleMesh3Ptr {
1268 return TriangleMesh3Ptr::new(RwLock::new(self.build()));
1269 }
1270
1271 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}