Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 82fed2e

Browse files
committed
Add support for evaluating max-norm distance fields
1 parent 6ca1055 commit 82fed2e

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/linear_hashed_marching_cubes.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::marching_cubes_impl::{get_offset, interpolate, march_cube};
1717
use crate::marching_cubes_tables::EDGE_CONNECTION;
1818
use crate::math::Vec3;
1919
use crate::morton::Morton;
20-
use crate::source::{HermiteSource, Source};
20+
use crate::source::{HermiteSource, Norm, Source};
2121
use std::collections::HashMap;
2222

2323
// Morton cube corners are ordered differently to the marching cubes tables, so remap them to match.
@@ -43,15 +43,29 @@ impl Edge {
4343
/// Extracts meshes from distance fields using marching cubes over a linear hashed octree.
4444
pub struct LinearHashedMarchingCubes {
4545
max_depth: usize,
46+
norm: Norm,
4647
}
4748

4849
impl LinearHashedMarchingCubes {
4950
/// Create a new LinearHashedMarchingCubes.
5051
///
5152
/// The depth of the internal octree will be at most `max_depth`, causing the tree to span the
52-
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction.
53+
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction. Distances
54+
/// will be evaluated in Euclidean space.
5355
pub fn new(max_depth: usize) -> Self {
54-
Self { max_depth }
56+
Self {
57+
max_depth,
58+
norm: Norm::Euclidean,
59+
}
60+
}
61+
62+
/// Create a new LinearHashedMarchingCubes.
63+
///
64+
/// The depth of the internal octree will be at most `max_depth`, causing the tree to span the
65+
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction. Distances will
66+
/// be evaluated in accordance with the provided Norm.
67+
pub fn with_norm(max_depth: usize, norm: Norm) -> Self {
68+
Self { max_depth, norm }
5569
}
5670

5771
/// Extracts a mesh from the given [`Source`](../source/trait.Source.html).
@@ -119,6 +133,13 @@ impl LinearHashedMarchingCubes {
119133
self.extract_surface(&octree, &primal_vertices, indices, &mut base_index, extract);
120134
}
121135

136+
fn diagonal(&self, distance: f32) -> f32 {
137+
match self.norm {
138+
Norm::Euclidean => distance * SQRT_OF_3,
139+
Norm::Max => distance,
140+
}
141+
}
142+
122143
fn build_octree<S>(&mut self, source: &S) -> LinearHashedOctree<f32>
123144
where
124145
S: Source,
@@ -130,7 +151,7 @@ impl LinearHashedMarchingCubes {
130151
|key: Morton, distance: &f32| {
131152
let level = key.level();
132153
let size = key.size();
133-
level < 2 || (level < max_depth && distance.abs() <= size * SQRT_OF_3)
154+
level < 2 || (level < max_depth && distance.abs() <= self.diagonal(size))
134155
},
135156
|key: Morton| {
136157
let p = key.center();

src/source.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,19 @@
1414

1515
use crate::math::Vec3;
1616

17+
/// The context in which signed distance fields should be evaluated
18+
pub enum Norm {
19+
/// The L^2 or Euclidean norm is the one you are used to, i.e. where l = sqrt(x^2 + y^2 + z^2).
20+
Euclidean,
21+
/// The L^∞ or Max norm represents Manhattan/Taxicab distance, i.e. l = max(|x|, |y|, |z|).
22+
Max,
23+
}
24+
1725
/// A source capable of sampling a signed distance field at discrete coordinates.
1826
pub trait Source {
1927
/// Samples the distance field at the given (x, y, z) coordinates.
2028
///
21-
/// Must return the signed distance (i.e. negative for coodinates inside the surface),
29+
/// Must return the signed distance (i.e. negative for coordinates inside the surface),
2230
/// as our Marching Cubes implementation will evaluate the surface at the zero-crossing.
2331
fn sample(&self, x: f32, y: f32, z: f32) -> f32;
2432
}

0 commit comments

Comments
 (0)