Spaces:
Sleeping
Sleeping
File size: 2,065 Bytes
e937288 e5b87f1 e937288 4cf835c f4b5e4a 4cf835c e937288 4cf835c e937288 4cf835c e5b87f1 e937288 f4b5e4a e5b87f1 f4b5e4a e5b87f1 f4b5e4a e5b87f1 e937288 e5b87f1 4cf835c e937288 4cf835c e937288 4cf835c e937288 f4b5e4a 4cf835c e937288 4cf835c e937288 4cf835c e937288 4cf835c e937288 f4b5e4a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
"""
Gradio app: robust .vox → .glb conversion + built-in Model3D viewer.
Handles small and large voxel files, centers and colors mesh to avoid 'paper icon'.
"""
import gradio as gr
import tempfile
import trimesh
import numpy as np
from pathlib import Path
from pyvox.parser import VoxParser
def vox_to_glb(file_path):
vox = VoxParser(file_path).parse()
model = vox.models[0]
voxels = model.voxels
size_x, size_y, size_z = model.size.x, model.size.y, model.size.z
if not voxels:
raise ValueError("No voxels found")
# Small grid: cube per voxel, Large grid: marching cubes
if max(size_x, size_y, size_z) <= 16:
cubes = []
for v in voxels:
cube = trimesh.creation.box(extents=(1,1,1))
cube.apply_translation([v.x, v.y, v.z])
cubes.append(cube)
mesh = trimesh.util.concatenate(cubes)
else:
grid = np.zeros((size_x, size_y, size_z), dtype=bool)
for v in voxels:
grid[v.x, v.y, v.z] = True
mesh = trimesh.voxel.ops.matrix_to_marching_cubes(grid)
# Center mesh, scale, add color
mesh.apply_translation(-mesh.centroid)
mesh.apply_scale(1.0)
mesh.visual.vertex_colors = [200, 100, 50, 255]
tmp = tempfile.NamedTemporaryFile(suffix=".glb", delete=False)
mesh.export(tmp.name)
return tmp.name
def handle_upload(file):
if file is None:
return None
ext = Path(file.name).suffix.lower()
if ext == '.vox':
try:
return vox_to_glb(file.name)
except Exception as e:
print(f"Failed to convert vox: {e}")
return None
elif ext in ['.glb', '.gltf']:
return file.name
else:
return None
with gr.Blocks() as demo:
gr.Markdown("# VOX / GLB Viewer\nUpload a `.vox` or `.glb/.gltf` file to preview.")
upload = gr.File(file_types=['.vox','.glb','.gltf'], label="Upload File")
viewer = gr.Model3D(label="Preview")
upload.change(handle_upload, upload, viewer)
if __name__ == '__main__':
demo.launch() |