vox_geometry_rust/
implicit_surface_set2.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::bvh2::Bvh2;
10use crate::implicit_surface2::*;
11use crate::surface2::*;
12use crate::vector2::Vector2D;
13use crate::transform2::Transform2;
14use crate::bounding_box2::BoundingBox2D;
15use crate::ray2::Ray2D;
16use crate::surface_to_implicit2::SurfaceToImplicit2;
17use crate::nearest_neighbor_query_engine2::NearestNeighborQueryEngine2;
18use crate::intersection_query_engine2::IntersectionQueryEngine2;
19use std::sync::{RwLock, Arc};
20
21///
22/// # 2-D implicit surface set.
23///
24/// This class represents 2-D implicit surface set which extends
25/// ImplicitSurface2 by overriding implicit surface-related quries. This is
26/// class can hold a collection of other implicit surface instances.
27///
28pub struct ImplicitSurfaceSet2 {
29    _surfaces: Vec<ImplicitSurface2Ptr>,
30    _unbounded_surfaces: Vec<ImplicitSurface2Ptr>,
31    _bvh: RwLock<Bvh2<ImplicitSurface2Ptr>>,
32    _bvh_invalidated: RwLock<bool>,
33
34    /// data from surface2
35    pub surface_data: Surface2Data,
36}
37
38impl ImplicitSurfaceSet2 {
39    /// Constructs an empty implicit surface set.
40    pub fn new_default() -> ImplicitSurfaceSet2 {
41        return ImplicitSurfaceSet2 {
42            _surfaces: vec![],
43            _unbounded_surfaces: vec![],
44            _bvh: RwLock::new(Bvh2::new()),
45            _bvh_invalidated: RwLock::new(true),
46            surface_data: Surface2Data::new(None, None),
47        };
48    }
49
50    /// Constructs an implicit surface set using list of other surfaces.
51    pub fn new(surfaces: Vec<ImplicitSurface2Ptr>,
52               transform: Option<Transform2>,
53               is_normal_flipped: Option<bool>) -> ImplicitSurfaceSet2 {
54        let mut unbounded_surfaces: Vec<ImplicitSurface2Ptr> = vec![];
55        for surface in &surfaces {
56            if !surface.read().unwrap().is_bounded() {
57                unbounded_surfaces.push(surface.clone());
58            }
59        }
60
61        return ImplicitSurfaceSet2 {
62            _surfaces: surfaces,
63            _unbounded_surfaces: unbounded_surfaces,
64            _bvh: RwLock::new(Bvh2::new()),
65            _bvh_invalidated: RwLock::new(true),
66            surface_data: Surface2Data::new(transform, is_normal_flipped),
67        };
68    }
69
70    /// Constructs an implicit surface set using list of other surfaces.
71    pub fn new_explicit(surfaces: Vec<Surface2Ptr>,
72                        transform: Option<Transform2>,
73                        is_normal_flipped: Option<bool>) -> ImplicitSurfaceSet2 {
74        let mut set = ImplicitSurfaceSet2::new_default();
75        set.surface_data.transform = transform.unwrap_or(Transform2::new_default());
76        set.surface_data.is_normal_flipped = is_normal_flipped.unwrap_or(false);
77        for surface in &surfaces {
78            set.add_explicit_surface(surface.clone());
79        }
80
81        return set;
82    }
83
84    /// Returns builder fox ImplicitSurfaceSet2.
85    pub fn builder() -> Builder {
86        return Builder::new();
87    }
88
89    /// Returns the number of implicit surfaces.
90    pub fn number_of_surfaces(&self) -> usize {
91        return self._surfaces.len();
92    }
93
94    /// Returns the i-th implicit surface.
95    pub fn surface_at(&self, i: usize) -> ImplicitSurface2Ptr {
96        return self._surfaces[i].clone();
97    }
98
99    /// Adds an explicit surface instance.
100    pub fn add_explicit_surface(&mut self, surface: Surface2Ptr) {
101        self.add_surface(Arc::new(RwLock::new(SurfaceToImplicit2::new(surface, None, None))));
102    }
103
104    /// Adds an implicit surface instance.
105    pub fn add_surface(&mut self, surface: ImplicitSurface2Ptr) {
106        self._surfaces.push(surface.clone());
107        if !surface.read().unwrap().is_bounded() {
108            self._unbounded_surfaces.push(surface);
109        }
110        self.invalidate_bvh();
111    }
112
113    fn invalidate_bvh(&self) {
114        *(self._bvh_invalidated.write().unwrap()) = true;
115    }
116
117    fn build_bvh(&self) {
118        if *self._bvh_invalidated.read().unwrap() {
119            let mut surfs: Vec<ImplicitSurface2Ptr> = Vec::new();
120            let mut bounds: Vec<BoundingBox2D> = Vec::new();
121            for i in 0..self._surfaces.len() {
122                if self._surfaces[i].read().unwrap().is_bounded() {
123                    surfs.push(self._surfaces[i].clone());
124                    bounds.push(self._surfaces[i].read().unwrap().bounding_box());
125                }
126            }
127            self._bvh.write().unwrap().build(&surfs, &bounds);
128            *(self._bvh_invalidated.write().unwrap()) = false;
129        }
130    }
131}
132
133impl Surface2 for ImplicitSurfaceSet2 {
134    fn closest_point_local(&self, other_point: &Vector2D) -> Vector2D {
135        self.build_bvh();
136
137        let mut distance_func = |surface: &ImplicitSurface2Ptr, pt: &Vector2D| {
138            return surface.read().unwrap().closest_distance(pt);
139        };
140
141        let mut result = Vector2D::new(f64::MAX, f64::MAX);
142        let query_result = self._bvh.read().unwrap().nearest(other_point, &mut distance_func);
143        if let Some(item) = query_result.item {
144            result = item.read().unwrap().closest_point(other_point);
145        }
146
147        let mut min_dist = query_result.distance;
148        for surface in &self._unbounded_surfaces {
149            let pt = surface.read().unwrap().closest_point(other_point);
150            let dist = pt.distance_to(*other_point);
151            if dist < min_dist {
152                min_dist = dist;
153                result = surface.read().unwrap().closest_point(other_point);
154            }
155        }
156
157        return result;
158    }
159
160    fn bounding_box_local(&self) -> BoundingBox2D {
161        self.build_bvh();
162
163        return self._bvh.read().unwrap().bounding_box();
164    }
165
166    fn closest_intersection_local(&self, ray: &Ray2D) -> SurfaceRayIntersection2 {
167        self.build_bvh();
168
169        let mut test_func = |surface: &ImplicitSurface2Ptr, ray: &Ray2D| {
170            let result = surface.read().unwrap().closest_intersection(ray);
171            return result.distance;
172        };
173
174        let query_result = self._bvh.read().unwrap().closest_intersection(ray, &mut test_func);
175        let mut result = SurfaceRayIntersection2::new();
176        result.distance = query_result.distance;
177        result.is_intersecting = match query_result.item {
178            None => false,
179            Some(_) => true
180        };
181        if let Some(item) = query_result.item {
182            result.point = ray.point_at(query_result.distance);
183            result.normal = item.read().unwrap().closest_normal(&result.point);
184        }
185
186        for surface in &self._unbounded_surfaces {
187            let local_result = surface.read().unwrap().closest_intersection(ray);
188            if local_result.distance < result.distance {
189                result = local_result;
190            }
191        }
192
193        return result;
194    }
195
196    fn closest_normal_local(&self, other_point: &Vector2D) -> Vector2D {
197        self.build_bvh();
198
199        let mut distance_func = |surface: &ImplicitSurface2Ptr, pt: &Vector2D| {
200            return surface.read().unwrap().closest_distance(pt);
201        };
202
203        let mut result = Vector2D::new(1.0, 0.0);
204        let query_result = self._bvh.read().unwrap().nearest(other_point, &mut distance_func);
205        if let Some(item) = query_result.item {
206            result = item.read().unwrap().closest_normal(other_point);
207        }
208
209        let mut min_dist = query_result.distance;
210        for surface in &self._unbounded_surfaces {
211            let pt = surface.read().unwrap().closest_point(other_point);
212            let dist = pt.distance_to(*other_point);
213            if dist < min_dist {
214                min_dist = dist;
215                result = surface.read().unwrap().closest_normal(other_point);
216            }
217        }
218
219        return result;
220    }
221
222    fn intersects_local(&self, ray: &Ray2D) -> bool {
223        self.build_bvh();
224
225        let mut test_func = |surface: &ImplicitSurface2Ptr, ray: &Ray2D| {
226            return surface.read().unwrap().intersects(ray);
227        };
228
229        let mut result = self._bvh.read().unwrap().intersects_ray(ray, &mut test_func);
230        for surface in &self._unbounded_surfaces {
231            result |= surface.read().unwrap().intersects(ray);
232        }
233
234        return result;
235    }
236
237    fn closest_distance_local(&self, other_point: &Vector2D) -> f64 {
238        self.build_bvh();
239
240        let mut distance_func = |surface: &ImplicitSurface2Ptr, pt: &Vector2D| {
241            return surface.read().unwrap().closest_distance(pt);
242        };
243
244        let query_result = self._bvh.read().unwrap().nearest(other_point, &mut distance_func);
245
246        let mut min_dist = query_result.distance;
247        for surface in &self._unbounded_surfaces {
248            let pt = surface.read().unwrap().closest_point(other_point);
249            let dist = pt.distance_to(*other_point);
250            if dist < min_dist {
251                min_dist = dist;
252            }
253        }
254
255        return min_dist;
256    }
257
258    fn update_query_engine(&self) {
259        self.invalidate_bvh();
260        self.build_bvh();
261    }
262
263    fn is_bounded(&self) -> bool {
264        // All surfaces should be bounded.
265        for surface in &self._surfaces {
266            if !surface.read().unwrap().is_bounded() {
267                return false;
268            }
269        }
270
271        // Empty set is not bounded.
272        return !self._surfaces.is_empty();
273    }
274
275    fn is_valid_geometry(&self) -> bool {
276        // All surfaces should be valid.
277        for surface in &self._surfaces {
278            if !surface.read().unwrap().is_valid_geometry() {
279                return false;
280            }
281        }
282
283        // Empty set is not valid.
284        return !self._surfaces.is_empty();
285    }
286
287    fn view(&self) -> &Surface2Data {
288        return &self.surface_data;
289    }
290}
291
292impl ImplicitSurface2 for ImplicitSurfaceSet2 {
293    fn signed_distance_local(&self, other_point: &Vector2D) -> f64 {
294        let mut sdf = f64::MAX;
295        for surface in &self._surfaces {
296            sdf = f64::min(sdf, surface.read().unwrap().signed_distance(other_point));
297        }
298
299        return sdf;
300    }
301
302    fn is_inside_local(&self, other_point: &Vector2D) -> bool {
303        for surface in &self._surfaces {
304            if surface.read().unwrap().is_inside(other_point) {
305                return true;
306            }
307        }
308
309        return false;
310    }
311}
312
313/// Shared pointer type for the ImplicitSurfaceSet2.
314pub type ImplicitSurfaceSet2Ptr = Arc<RwLock<ImplicitSurfaceSet2>>;
315
316///
317/// # Front-end to create ImplicitSurfaceSet2 objects step by step.
318///
319pub struct Builder {
320    _surfaces: Vec<ImplicitSurface2Ptr>,
321
322    _surface_data: Surface2Data,
323}
324
325impl Builder {
326    /// Returns builder with surfaces.
327    pub fn with_surfaces(&mut self, surfaces: Vec<ImplicitSurface2Ptr>) -> &mut Self {
328        self._surfaces = surfaces;
329        return self;
330    }
331
332    /// Returns builder with explicit surfaces.
333    pub fn with_explicit_surfaces(&mut self, surfaces: Vec<Surface2Ptr>) -> &mut Self {
334        self._surfaces.clear();
335        for surface in surfaces {
336            self._surfaces.push(Arc::new(RwLock::new(SurfaceToImplicit2::new(surface, None, None))));
337        }
338
339        return self;
340    }
341
342    /// Builds ImplicitSurfaceSet2.
343    pub fn build(&mut self) -> ImplicitSurfaceSet2 {
344        return ImplicitSurfaceSet2::new(self._surfaces.clone(),
345                                        Some(self._surface_data.transform.clone()),
346                                        Some(self._surface_data.is_normal_flipped));
347    }
348
349    /// Builds shared pointer of ImplicitSurfaceSet2 instance.
350    pub fn make_shared(&mut self) -> ImplicitSurfaceSet2Ptr {
351        return ImplicitSurfaceSet2Ptr::new(RwLock::new(self.build()));
352    }
353
354    /// constructor
355    pub fn new() -> Builder {
356        return Builder {
357            _surfaces: vec![],
358            _surface_data: Surface2Data::new(None, None),
359        };
360    }
361}
362
363impl SurfaceBuilderBase2 for Builder {
364    fn view(&mut self) -> &mut Surface2Data {
365        return &mut self._surface_data;
366    }
367}