""" vde.sdf — Implicit Modeling & Differentiable Geometry Usage: from vde.sdf import Sphere, Box, Union, evaluate, to_mesh s = Sphere(1.0) b = Box([0.5, 0.5, 0.5]) u = Union(s, b) d = evaluate(u, [0.5, 0, 0]) mesh = to_mesh(u, resolution=64) """ import numpy as np # Re-export C++ bindings from vde._vde import ( SdfNode, SdfOp, SdfParams, MCMesh, SdfBBox, evaluate, sdf_to_mesh, sdf_to_mesh_lambda, estimate_bounds, estimate_bbox, ) # ── Convenience constructors ────────────────────── def sphere(radius=1.0): """Create a sphere SDF node.""" return SdfNode.sphere(radius) def box(half_extents): """Create a box SDF node. Args: half_extents: [hx, hy, hz] half-size in each dimension """ return SdfNode.box(half_extents) def cylinder(radius=1.0, height=2.0): """Create a cylinder SDF node.""" return SdfNode.cylinder(radius, height) def torus(major_radius=1.0, minor_radius=0.3): """Create a torus SDF node.""" return SdfNode.torus(major_radius, minor_radius) def capsule(a, b, radius=0.5): """Create a capsule SDF node between points a and b.""" return SdfNode.capsule(a, b, radius) def cone(angle=0.5, height=2.0): """Create a cone SDF node.""" return SdfNode.cone(angle, height) def plane(normal, offset=0.0): """Create a plane SDF node.""" return SdfNode.plane(normal, offset) def ellipsoid(radii): """Create an ellipsoid SDF node.""" return SdfNode.ellipsoid(radii) # ── CSG Operations ──────────────────────────────── def union(a, b): """Union of two SDF nodes (min).""" return SdfNode.op_union(a, b) def intersection(a, b): """Intersection of two SDF nodes (max).""" return SdfNode.op_intersection(a, b) def difference(a, b): """Difference: subtract b from a.""" return SdfNode.op_difference(a, b) def smooth_union(a, b, k=0.1): """Smooth union with blend radius k.""" return SdfNode.smooth_union(a, b, k) def smooth_intersection(a, b, k=0.1): """Smooth intersection with blend radius k.""" return SdfNode.smooth_intersection(a, b, k) def smooth_difference(a, b, k=0.1): """Smooth difference with blend radius k.""" return SdfNode.smooth_difference(a, b, k) # ── Modifiers ───────────────────────────────────── def round_shape(node, r=0.1): """Round (fatten) a shape.""" return SdfNode.round(node, r) def onion(node, thickness=0.1): """Create a thin shell.""" return SdfNode.onion(node, thickness) # ── Domain Transforms ───────────────────────────── def translate(node, offset): """Translate a shape.""" return SdfNode.translate(node, offset) def rotate(node, angle): """Rotate around Y axis (radians).""" return SdfNode.rotate(node, angle) def scale(node, factors): """Non-uniform scale.""" return SdfNode.scale(node, factors) def repeat(node, cell): """Infinite repeat.""" return SdfNode.repeat(node, cell) def twist(node, amount): """Twist around Y axis.""" return SdfNode.twist(node, amount) def bend(node, amount): """Bend deformation.""" return SdfNode.bend(node, amount) # ── Mesh Conversion ─────────────────────────────── def to_mesh(node, resolution=64, level=0.0): """Convert SDF tree to triangle mesh. Returns: MCMesh with .vertices and .triangles (both numpy arrays) """ return sdf_to_mesh(node, resolution, level) def to_mesh_lambda(fn, bmin, bmax, resolution=64, level=0.0): """Convert lambda SDF to mesh.""" return sdf_to_mesh_lambda(fn, bmin, bmax, resolution, level)