namespace VdeSharp; /// /// Managed wrapper for VDE SDF (Signed Distance Function) modeling. /// Provides an expression-tree based CSG modeling approach. /// public class SdfEngine : IDisposable { private readonly nint _ctx; internal nint _handle; private bool _disposed; internal SdfEngine(nint ctx, nint handle) { _ctx = ctx; _handle = handle; } /// Create a sphere SDF node. public static SdfEngine Sphere(nint ctx, double radius) { nint hdl = NativeMethods.vde_sdf_sphere(ctx, radius); return new SdfEngine(ctx, hdl); } /// Create a box SDF node with half-extents (hx, hy, hz). public static SdfEngine Box(nint ctx, double hx, double hy, double hz) { nint hdl = NativeMethods.vde_sdf_box(ctx, hx, hy, hz); return new SdfEngine(ctx, hdl); } /// Create a cylinder SDF node. public static SdfEngine Cylinder(nint ctx, double radius, double height) { nint hdl = NativeMethods.vde_sdf_cylinder(ctx, radius, height); return new SdfEngine(ctx, hdl); } /// CSG union: this ∪ other public SdfEngine Union(SdfEngine other) { nint hdl = NativeMethods.vde_sdf_union(_ctx, _handle, other._handle); return new SdfEngine(_ctx, hdl); } /// CSG intersection: this ∩ other public SdfEngine Intersection(SdfEngine other) { nint hdl = NativeMethods.vde_sdf_intersection(_ctx, _handle, other._handle); return new SdfEngine(_ctx, hdl); } /// CSG difference: this \ other public SdfEngine Difference(SdfEngine other) { nint hdl = NativeMethods.vde_sdf_difference(_ctx, _handle, other._handle); return new SdfEngine(_ctx, hdl); } /// /// Convert the SDF tree to a triangle mesh using Marching Cubes. /// /// Grid resolution per axis (e.g., 64 for 64³ voxels) public MeshData ToMesh(int resolution = 64) { nint mh = NativeMethods.vde_sdf_to_mesh(_ctx, _handle, resolution); var mesh = new MeshData(mh, ownsHandle: true); mesh.ExtractFromNative(); return mesh; } public void Dispose() { if (!_disposed && _handle != nint.Zero) { NativeMethods.vde_sdf_free(_handle); _handle = nint.Zero; _disposed = true; } } }