vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use crate::surface2::*;
use crate::transform2::Transform2;
use crate::implicit_surface2::ImplicitSurface2;
use crate::vector2::Vector2D;
use crate::bounding_box2::BoundingBox2D;
use crate::ray2::Ray2D;
use std::sync::{RwLock, Arc};

///
/// # 2-D implicit surface wrapper for generic Surface2 instance.
///
/// This class represents 2-D implicit surface that converts Surface2 instance
/// to an ImplicitSurface2 object. The conversion is made by evaluating closest
/// point and normal from a given point for the given (explicit) surface. Thus,
/// this conversion won't work for every single surfaces. Use this class only
/// for the basic primitives such as Sphere2 or Box2.
///
pub struct SurfaceToImplicit2 {
    _surface: Surface2Ptr,

    /// data from surface2
    pub surface_data: Surface2Data,
}

impl SurfaceToImplicit2 {
    /// Constructs an instance with generic Surface2 instance.
    pub fn new(
        surface: Surface2Ptr,
        transform: Option<Transform2>,
        is_normal_flipped: Option<bool>) -> SurfaceToImplicit2 {
        return SurfaceToImplicit2 {
            _surface: surface,
            surface_data: Surface2Data::new(transform, is_normal_flipped),
        };
    }

    /// Returns builder fox SurfaceToImplicit2.
    pub fn builder() -> Builder {
        return Builder::new();
    }

    /// Returns the raw surface instance.
    pub fn surface(&self) -> Surface2Ptr {
        return self._surface.clone();
    }
}

impl Surface2 for SurfaceToImplicit2 {
    fn closest_point_local(&self, other_point: &Vector2D) -> Vector2D {
        return self._surface.read().unwrap().closest_point(other_point);
    }

    fn bounding_box_local(&self) -> BoundingBox2D {
        return self._surface.read().unwrap().bounding_box();
    }

    fn closest_intersection_local(&self, ray: &Ray2D) -> SurfaceRayIntersection2 {
        return self._surface.read().unwrap().closest_intersection(ray);
    }

    fn closest_normal_local(&self, other_point: &Vector2D) -> Vector2D {
        return self._surface.read().unwrap().closest_normal(other_point);
    }

    fn intersects_local(&self, ray: &Ray2D) -> bool {
        return self._surface.read().unwrap().intersects(ray);
    }

    fn closest_distance_local(&self, other_point: &Vector2D) -> f64 {
        return self._surface.read().unwrap().closest_distance(other_point);
    }

    fn update_query_engine(&self) {
        self._surface.read().unwrap().update_query_engine();
    }

    fn is_bounded(&self) -> bool {
        return self._surface.read().unwrap().is_bounded();
    }

    fn is_valid_geometry(&self) -> bool {
        return self._surface.read().unwrap().is_valid_geometry();
    }

    fn view(&self) -> &Surface2Data {
        return &self.surface_data;
    }
}

impl ImplicitSurface2 for SurfaceToImplicit2 {
    fn signed_distance_local(&self, other_point: &Vector2D) -> f64 {
        let x = self._surface.read().unwrap().closest_point(other_point);
        let inside = self._surface.read().unwrap().is_inside(other_point);
        return match inside {
            true => -x.distance_to(*other_point),
            false => x.distance_to(*other_point)
        };
    }

    fn is_inside_local(&self, other_point: &Vector2D) -> bool {
        return self._surface.read().unwrap().is_inside(other_point);
    }
}

/// Shared pointer for the SurfaceToImplicit2 type.
pub type SurfaceToImplicit2Ptr = Arc<RwLock<SurfaceToImplicit2>>;

///
/// # Front-end to create SurfaceToImplicit2 objects step by step.
///
pub struct Builder {
    _surface: Option<Surface2Ptr>,

    _surface_data: Surface2Data,
}

impl Builder {
    /// Returns builder with surface.
    pub fn with_surface(&mut self, surface: Surface2Ptr) -> &mut Self {
        self._surface = Some(surface);
        return self;
    }

    /// Builds SurfaceToImplicit2.
    pub fn build(&mut self) -> SurfaceToImplicit2 {
        return SurfaceToImplicit2::new(self._surface.as_ref().unwrap().clone(),
                                       Some(self._surface_data.transform.clone()),
                                       Some(self._surface_data.is_normal_flipped));
    }

    /// Builds shared pointer of SurfaceToImplicit2 instance.
    pub fn make_shared(&mut self) -> SurfaceToImplicit2Ptr {
        return SurfaceToImplicit2Ptr::new(RwLock::new(self.build()));
    }

    /// constructor
    pub fn new() -> Builder {
        return Builder {
            _surface: None,
            _surface_data: Surface2Data::new(None, None),
        };
    }
}

impl SurfaceBuilderBase2 for Builder {
    fn view(&mut self) -> &mut Surface2Data {
        return &mut self._surface_data;
    }
}