sdf-glsl-generator / sdf_export.py
Stephen
try use mesh2sdf instead
4b51b31
raw
history blame
1.43 kB
import trimesh
import numpy as np
import mesh2sdf
def mesh_to_sdf_glsl(path, resolution=64):
# Load mesh
mesh = trimesh.load(path)
# Center and scale the mesh to fit in [-1, 1] cube
mesh.vertices -= mesh.centroid
# Calculate the maximum extent of the mesh
max_extent = np.max(np.abs(mesh.vertices))
scale = 1.0 / max_extent
mesh.vertices *= scale
# Create a grid of points
x = np.linspace(-1.0, 1.0, resolution)
y = np.linspace(-1.0, 1.0, resolution)
z = np.linspace(-1.0, 1.0, resolution)
X, Y, Z = np.meshgrid(x, y, z)
# Flatten the grid and reshape to (n,3)
query_points = np.column_stack((X.ravel(), Y.ravel(), Z.ravel()))
# Calculate signed distances using mesh2sdf
distances = mesh2sdf.compute(
mesh.vertices, mesh.faces, query_points, return_gradients=False
)
# Normalize distances to [-1, 1]
distances = np.clip(distances, -1.0, 1.0)
# Convert to GLSL array
glsl_array = ", ".join(f"{v:.6f}" for v in distances)
glsl_code = f"""// Auto-generated SDF GLSL from mesh
float sdfData[{resolution**3}] = float[](
{glsl_array}
);
float SDF(vec3 p) {{
vec3 dim = vec3({resolution}.0);
vec3 uv = (p + 1.0) * 0.5 * dim;
ivec3 idx = ivec3(clamp(floor(uv), vec3(0.0), dim - 1.0));
int i = idx.x + idx.y * {resolution} + idx.z * {resolution * resolution};
return sdfData[i];
}}
"""
return glsl_code