1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! tessellation is crate for creating polygons from implicit functions or volumes.
//! It uses
//! [Manifold Dual Contouring](http://faculty.cs.tamu.edu/schaefer/research/dualsimp_tvcg.pdf).
//!
//! # Examples
//!
//! Create a unit sphere and tessellate it:
//!
//! ```rust
//! use nalgebra as na;
//!
//! struct UnitSphere {
//!   bbox : tessellation::BoundingBox<f64>
//! }
//!
//! impl UnitSphere {
//!   fn new() -> UnitSphere {
//!     UnitSphere {
//!       bbox: tessellation::BoundingBox::new(&na::Point3::new(-1., -1., -1.),
//!                                            &na::Point3::new( 1.,  1.,  1.)) }
//!   }
//! }
//!
//! impl tessellation::ImplicitFunction<f64> for UnitSphere {
//!    fn bbox(&self) -> &tessellation::BoundingBox<f64> {
//!      &self.bbox
//!    }
//!   fn value(&self, p: &na::Point3<f64>) -> f64 {
//!     return na::Vector3::new(p.x, p.y, p.z).norm() - 1.0;
//!   }
//!   fn normal(&self, p: &na::Point3<f64>) -> na::Vector3<f64> {
//!     return na::Vector3::new(p.x, p.y, p.z).normalize();
//!   }
//! }
//!
//! let sphere = UnitSphere::new();
//! let mut mdc =  tessellation::ManifoldDualContouring::new(&sphere, 0.2, 0.1);
//! let triangles = mdc.tessellate().unwrap();
//! ```
#![warn(missing_docs)]

pub use bbox::BoundingBox;
use nalgebra as na;
use std::fmt::Debug;

mod bitset;
mod cell_configs;
mod manifold_dual_contouring;
mod mesh;
mod plane;
mod qef;
mod vertex_index;

pub use self::manifold_dual_contouring::ManifoldDualContouring;
pub use self::mesh::Mesh;

/// A Combination of alga::general::RealField and na::RealField.
pub trait RealField: alga::general::RealField + na::RealField {}
impl RealField for f64 {}
impl RealField for f32 {}

/// Trait to be implemented by functions that should be tessellated.
pub trait ImplicitFunction<S: Debug + RealField> {
    /// Return a Bounding Box, which is essential, so the algorithm knows where to search for
    /// surfaces.
    fn bbox(&self) -> &BoundingBox<S>;
    /// Evaluate the function on p and return the value. A value of zero signifies that p is on the
    /// surface to be tessellated. A negative value means p in inside the object. A positive value
    /// means p is outside the object.
    /// The magnitude of value must be continuous. Furthermore value has to be equal or greater
    /// than the euclidean distance between p and the surface.
    fn value(&self, p: &na::Point3<S>) -> S;
    /// Compute the normal of the function at p.
    fn normal(&self, p: &na::Point3<S>) -> na::Vector3<S>;
}

/// Trait which allows to convert Self to usize, since To<usize> is not implemented by f32 and f64.
pub trait AsUSize {
    /// Convert Self to usize.
    fn as_usize(self) -> usize;
}

impl AsUSize for f32 {
    fn as_usize(self) -> usize {
        self as usize
    }
}

impl AsUSize for f64 {
    fn as_usize(self) -> usize {
        self as usize
    }
}

#[cfg(test)]
#[macro_use]
extern crate approx;