#include #include "vde/sdf/sdf_primitives.h" #include "vde/sdf/sdf_operations.h" #include "vde/sdf/sdf_tree.h" #include #include using namespace vde::sdf; using namespace vde::core; // ── SDF fuzz: random sphere evaluation ── TEST(FuzzSdf, RandomSpheres) { std::mt19937 rng(42); std::uniform_real_distribution pos(-100, 100); std::uniform_real_distribution rad(0.1, 10.0); for (int i = 0; i < 100; ++i) { double r = rad(rng); double x = pos(rng), y = pos(rng), z = pos(rng); Point3D p(x, y, z); double d = sphere(p, r); // Basic sanity: SDF should be finite EXPECT_TRUE(std::isfinite(d)); // On surface, SDF should be 0 // Point on sphere in X direction Point3D on_surf(r, 0, 0); EXPECT_NEAR(sphere(on_surf, r), 0.0, 1e-6); } } // ── SDF fuzz: random CSG boolean combinations ── TEST(FuzzSdf, RandomCSG) { std::mt19937 rng(42); std::uniform_real_distribution pos(-10, 10); std::uniform_real_distribution rad(0.5, 5.0); for (int i = 0; i < 100; ++i) { double r1 = rad(rng), r2 = rad(rng); double x = pos(rng), y = pos(rng), z = pos(rng); Point3D p(x, y, z); double d1 = sphere(Point3D(x, y, z), r1); double d2 = box(Point3D(x, y, z), Point3D(r2, r2, r2)); double du = op_union(d1, d2); double di = op_intersection(d1, d2); double dd = op_difference(d1, d2); EXPECT_TRUE(std::isfinite(du)); EXPECT_TRUE(std::isfinite(di)); EXPECT_TRUE(std::isfinite(dd)); // Union of A and B should be <= max(A,B) at any point EXPECT_LE(du, std::max(d1, d2) + 1e-9); } } // ── SDF fuzz: random SDF tree construction and evaluation ── TEST(FuzzSdf, RandomTreeEvaluate) { std::mt19937 rng(42); for (int i = 0; i < 50; ++i) { auto tree = SdfNode::smooth_union( SdfNode::sphere(1.0 + (i % 5) * 0.5), SdfNode::box(Point3D(1, 1, 1)), 0.1 + (i % 3) * 0.2 ); for (int j = 0; j < 20; ++j) { double x = (j % 7 - 3) * 1.0; double y = (j % 5 - 2) * 1.0; double z = (j % 3 - 1) * 1.0; double v = evaluate(tree, Point3D(x, y, z)); EXPECT_TRUE(std::isfinite(v)); } } }