use imlet::types::{
computation::{
data::sampler::{DenseSampler, Sampler},
model::ImplicitModel,
traits::{ImplicitComponent, ImplicitFunction, ModelFloat},
ModelError,
},
geometry::{BoundingBox, Vec3},
};
use imlet::utils;
pub struct HyperbolicParaboloid<T> {
a: T,
b: T,
}
impl<T: ModelFloat> ImplicitComponent<T> for HyperbolicParaboloid<T> {
fn name(&self) -> &'static str {
"HyperbolicParaboloid"
}
}
impl<T: ModelFloat> ImplicitFunction<T> for HyperbolicParaboloid<T> {
fn eval(&self, x: T, y: T, z: T) -> T {
(y.powi(2) / self.b.powi(2)) - (x.powi(2) / self.a.powi(2)) - z
}
}
fn create_hyperbolic_paraboliod(a: f32, b: f32) -> Result<ImplicitModel<f32>, ModelError> {
let mut model = ImplicitModel::new();
let func = HyperbolicParaboloid { a, b };
model.add_function("func", func)?;
Ok(model)
}
pub fn main() {
utils::logging::init_info();
let size: f32 = 5.0;
let cell_size = 0.1;
let bounds = BoundingBox::new(Vec3::new(-size, -size, -size), Vec3::new(size, size, size));
let a: f32 = 2.0;
let b: f32 = 3.0;
let model = create_hyperbolic_paraboliod(a, b).unwrap();
let mut sampler = DenseSampler::builder()
.with_bounds(bounds)
.with_cell_size(cell_size)
.build()
.unwrap();
sampler.sample_field(&model).expect("Sampling should work.");
let mesh = sampler
.iso_surface(0.0)
.expect("Extracting iso-surface should work.");
utils::io::write_obj_file(&mesh, "custom_function_example").unwrap();
#[cfg(feature = "viewer")]
{
imlet::viewer::show_mesh(&mesh, Some(bounds));
}
}