#pragma once #include "vde/core/point.h" #include #include #include namespace vde::mesh { struct MCMesh { std::vector vertices; std::vector> triangles; }; /// Marching Cubes for scalar field f(x,y,z) /// Extracts isosurface at value = iso_level within the bounding box MCMesh marching_cubes(const std::function& f, double iso_level, const Point3D& bmin, const Point3D& bmax, int resolution); /// SDF sphere inline double sdf_sphere(double x, double y, double z, double cx, double cy, double cz, double r) { return std::sqrt((x-cx)*(x-cx) + (y-cy)*(y-cy) + (z-cz)*(z-cz)) - r; } /// SDF box inline double sdf_box(double x, double y, double z, double hx, double hy, double hz) { double dx = std::abs(x) - hx, dy = std::abs(y) - hy, dz = std::abs(z) - hz; return std::sqrt(std::max(dx,0.0)*std::max(dx,0.0) + std::max(dy,0.0)*std::max(dy,0.0) + std::max(dz,0.0)*std::max(dz,0.0)) + std::min(std::max({dx,dy,dz}), 0.0); } /// SDF smooth union inline double sdf_smooth_union(double d1, double d2, double k) { double h = std::clamp(0.5 + 0.5*(d2-d1)/k, 0.0, 1.0); return std::lerp(d2, d1, h) - k*h*(1.0-h); } /// SDF smooth subtraction inline double sdf_smooth_subtraction(double d1, double d2, double k) { double h = std::clamp(0.5 - 0.5*(d2+d1)/k, 0.0, 1.0); return std::lerp(d2, -d1, h) + k*h*(1.0-h); } } // namespace vde::mesh