use crate::marching_cubes::{FaceAmbiguity, MarchingCubes};
use crate::mesh::MeshSink;
use crate::real::Real;
use crate::sdf::Sdf;
use crate::shape::Shape3;
pub trait Extractor<R: Real> {
fn extract_into<S, M>(
&mut self,
field: &S,
shape: &impl Shape3,
origin: [R; 3],
cell_size: R,
out: &mut M,
) -> crate::Result<()>
where
S: Sdf<Scalar = R>,
M: MeshSink<Scalar = R>;
}
macro_rules! forward_extractor {
($($ty:path),+ $(,)?) => {
$(
impl<R: Real> Extractor<R> for $ty {
fn extract_into<S, M>(
&mut self,
field: &S,
shape: &impl Shape3,
origin: [R; 3],
cell_size: R,
out: &mut M,
) -> crate::Result<()>
where
S: Sdf<Scalar = R>,
M: MeshSink<Scalar = R>,
{
self.extract(field, shape, origin, cell_size, out)
}
}
)+
};
}
forward_extractor!(
crate::marching_cubes::MarchingCubes<R>,
crate::marching_tetrahedra::MarchingTetrahedra<R>,
crate::surface_nets::SurfaceNets<R>,
crate::dual_contouring::DualContouring<R>,
crate::manifold_dual_contouring::ManifoldDualContouring<R>,
crate::greedy_quads::GreedyQuads<R>,
crate::subgrid::extract::SubgridMarchingTetrahedra<R>,
);
pub const SUBGRID_SAMPLES: u32 = 16;
#[macro_export]
macro_rules! for_each_extractor {
($scalar:ty, |$name:ident, $extractor:ident| $body:block) => {{
{
let $name = "marching_cubes";
#[allow(unused_mut)]
let mut $extractor = $crate::marching_cubes::MarchingCubes::<$scalar>::new();
$body
}
{
let $name = "marching_cubes+decider";
#[allow(unused_mut)]
let mut $extractor = {
let mut mesher = $crate::marching_cubes::MarchingCubes::<$scalar>::new();
mesher.set_face_ambiguity($crate::marching_cubes::FaceAmbiguity::AsymptoticDecider);
mesher
};
$body
}
{
let $name = "marching_tetrahedra";
#[allow(unused_mut)]
let mut $extractor = $crate::marching_tetrahedra::MarchingTetrahedra::<$scalar>::new();
$body
}
{
let $name = "surface_nets";
#[allow(unused_mut)]
let mut $extractor = $crate::surface_nets::SurfaceNets::<$scalar>::new();
$body
}
{
let $name = "dual_contouring";
#[allow(unused_mut)]
let mut $extractor = $crate::dual_contouring::DualContouring::<$scalar>::new();
$body
}
{
let $name = "manifold_dual_contouring";
#[allow(unused_mut)]
let mut $extractor =
$crate::manifold_dual_contouring::ManifoldDualContouring::<$scalar>::new();
$body
}
{
let $name = "subgrid_marching_tetrahedra";
#[allow(unused_mut)]
let mut $extractor =
$crate::subgrid::extract::SubgridMarchingTetrahedra::<$scalar>::new(
$crate::extractor::SUBGRID_SAMPLES,
)
.expect("SUBGRID_SAMPLES is a positive sampling resolution");
$body
}
}};
}
pub const ALL_EXTRACTORS: [&str; 7] = [
"marching_cubes",
"marching_cubes+decider",
"marching_tetrahedra",
"surface_nets",
"dual_contouring",
"manifold_dual_contouring",
"subgrid_marching_tetrahedra",
];
pub const UNREGISTERED: [&str; 1] = ["GreedyQuads"];
#[allow(dead_code)]
fn macro_paths_are_used(_: Option<FaceAmbiguity>, _: Option<MarchingCubes<f32>>) {}
#[cfg(test)]
mod tests;