Skip to content

Improvements #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/linear_hashed_marching_cubes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::marching_cubes_impl::{get_offset, interpolate, march_cube};
use crate::marching_cubes_tables::EDGE_CONNECTION;
use crate::math::Vec3;
use crate::morton::Morton;
use crate::source::{HermiteSource, Source};
use crate::source::{HermiteSource, Norm, Source};
use std::collections::HashMap;

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

impl LinearHashedMarchingCubes {
/// Create a new LinearHashedMarchingCubes.
///
/// The depth of the internal octree will be at most `max_depth`, causing the tree to span the
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction.
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction. Distances
/// will be evaluated in Euclidean space.
pub fn new(max_depth: usize) -> Self {
Self { max_depth }
Self {
max_depth,
norm: Norm::Euclidean,
}
}

/// Create a new LinearHashedMarchingCubes.
///
/// The depth of the internal octree will be at most `max_depth`, causing the tree to span the
/// equivalent of a cubic grid at most `2.pow(max_depth)` in either direction. Distances will
/// be evaluated in accordance with the provided Norm.
pub fn with_norm(max_depth: usize, norm: Norm) -> Self {
Self { max_depth, norm }
}

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

fn diagonal(&self, distance: f32) -> f32 {
match self.norm {
Norm::Euclidean => distance * SQRT_OF_3,
Norm::Max => distance,
}
}

fn build_octree<S>(&mut self, source: &S) -> LinearHashedOctree<f32>
where
S: Source,
Expand All @@ -130,7 +151,7 @@ impl LinearHashedMarchingCubes {
|key: Morton, distance: &f32| {
let level = key.level();
let size = key.size();
level < 2 || (level < max_depth && distance.abs() <= size * SQRT_OF_3)
level < 2 || (level < max_depth && distance.abs() <= self.diagonal(size))
},
|key: Morton| {
let p = key.center();
Expand Down
47 changes: 47 additions & 0 deletions src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@ impl Vec3 {
z: 1.0,
}
}

/// Create a vector by taking the absolute value of each component in this vector
pub fn abs(&self) -> Self {
Self {
x: self.x.abs(),
y: self.y.abs(),
z: self.z.abs(),
}
}

/// Sum all of the components in this vector
pub fn component_sum(&self) -> f32 {
self.x + self.y + self.z
}

/// Find the maximum value out of all components in this vector
pub fn component_max(&self) -> f32 {
self.x.max(self.y.max(self.z))
}

/// Find the minimum value out of all components in this vector
pub fn component_min(&self) -> f32 {
self.x.min(self.y.min(self.z))
}
}

impl std::ops::Add for Vec3 {
Expand Down Expand Up @@ -81,6 +105,13 @@ impl std::ops::Mul<f32> for Vec3 {
Vec3::new(self.x * other, self.y * other, self.z * other)
}
}
impl std::ops::Mul<Vec3> for f32 {
type Output = Vec3;

fn mul(self, other: Vec3) -> Vec3 {
Vec3::new(self * other.x, self * other.y, self * other.z)
}
}

impl std::ops::Div for Vec3 {
type Output = Vec3;
Expand All @@ -89,3 +120,19 @@ impl std::ops::Div for Vec3 {
Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
}
}

impl std::ops::Div<f32> for Vec3 {
type Output = Vec3;

fn div(self, other: f32) -> Vec3 {
Vec3::new(self.x / other, self.y / other, self.z / other)
}
}

impl std::ops::Div<Vec3> for f32 {
type Output = Vec3;

fn div(self, other: Vec3) -> Vec3 {
Vec3::new(self / other.x, self / other.y, self / other.z)
}
}
12 changes: 10 additions & 2 deletions src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@

use crate::math::Vec3;

/// The context in which signed distance fields should be evaluated
pub enum Norm {
/// The L^2 or Euclidean norm is the one you are used to, i.e. where l = sqrt(x^2 + y^2 + z^2).
Euclidean,
/// The L^∞ or Max norm represents Manhattan/Taxicab distance, i.e. l = max(|x|, |y|, |z|).
Max,
}

/// A source capable of sampling a signed distance field at discrete coordinates.
pub trait Source {
/// Samples the distance field at the given (x, y, z) coordinates.
///
/// Must return the signed distance (i.e. negative for coodinates inside the surface),
/// Must return the signed distance (i.e. negative for coordinates inside the surface),
/// as our Marching Cubes implementation will evaluate the surface at the zero-crossing.
fn sample(&self, x: f32, y: f32, z: f32) -> f32;
}
Expand All @@ -33,7 +41,7 @@ pub trait HermiteSource: Source {

/// Adapts a `Source` to a `HermiteSource` by deriving normals from the surface via central differencing
pub struct CentralDifference<S: Source> {
source: S,
pub source: S,
epsilon: f32,
}

Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy