Spaces:
Sleeping
Sleeping
File size: 4,761 Bytes
31d16ca | 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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | import gradio as gr
import requests
import tempfile
import os
import trimesh
def download_model(url):
"""Download model from URL to temporary file."""
try:
response = requests.get(url, stream=True, timeout=10)
response.raise_for_status()
with tempfile.NamedTemporaryFile(suffix=".glb", delete=False) as tmp:
for chunk in response.iter_content(chunk_size=8192):
tmp.write(chunk)
return tmp.name
except Exception as e:
print(f"Download error: {e}")
return None
def load_and_convert_model(url, target_format):
"""Load model from URL and convert to target format."""
if not url:
return None
# Download the GLB file
glb_path = download_model(url)
if not glb_path:
return None
try:
# Load the model using trimesh
mesh = trimesh.load(glb_path)
# Save to temporary file in target format
output_ext = target_format.lower()
with tempfile.NamedTemporaryFile(suffix=f".{output_ext}", delete=False) as tmp:
output_path = tmp.name
# Export based on format
if output_ext == "obj":
mesh.export(output_path, file_type="obj")
elif output_ext == "stl":
mesh.export(output_path, file_type="stl")
elif output_ext == "ply":
mesh.export(output_path, file_type="ply")
elif output_ext == "glb":
mesh.export(output_path, file_type="glb")
elif output_ext == "gltf":
mesh.export(output_path, file_type="gltf")
else:
# For unsupported formats, return None
return None
return output_path
except Exception as e:
print(f"Conversion error: {e}")
return None
finally:
# Clean up original downloaded file
if os.path.exists(glb_path):
os.unlink(glb_path)
def cleanup(file_path):
if file_path and os.path.exists(file_path):
os.unlink(file_path)
# Gradio interface
with gr.Blocks(title="3D Model Converter") as demo:
gr.Markdown("## 🌐 3D Model Viewer & Converter")
gr.Markdown("Enter a URL to a GLB file to view and download in different formats.")
with gr.Row():
url_input = gr.Textbox(
label="GLB File URL",
placeholder="https://example.com/model.glb",
scale=4
)
submit_btn = gr.Button("Load Model", variant="primary", scale=1)
model_output = gr.Model3D(
label="3D Model Preview",
clear_color=[0.2, 0.2, 0.2, 0.8],
camera_position=(2, 2, 3),
scale=1.0
)
gr.Markdown("### 💾 Download Options")
with gr.Row():
obj_btn = gr.Button("Download as OBJ", variant="secondary")
stl_btn = gr.Button("Download as STL", variant="secondary")
ply_btn = gr.Button("Download as PLY", variant="secondary")
glb_btn = gr.Button("Download as GLB", variant="secondary")
obj_file = gr.File(label="Download OBJ", visible=False)
stl_file = gr.File(label="Download STL", visible=False)
ply_file = gr.File(label="Download PLY", visible=False)
glb_file = gr.File(label="Download GLB", visible=False)
# State to store the current URL
current_url = gr.State()
# When loading, store URL and display model
submit_btn.click(
fn=lambda url: (url, download_model(url)),
inputs=url_input,
outputs=[current_url, model_output]
)
# Conversion functions
def convert_and_download(url, format_type):
if not url:
return None
output_path = load_and_convert_model(url, format_type)
if output_path:
return output_path
return None
# Wire up download buttons
obj_btn.click(
fn=lambda url: convert_and_download(url, "obj"),
inputs=current_url,
outputs=obj_file
).then(
fn=lambda: gr.update(visible=True),
outputs=obj_file
)
stl_btn.click(
fn=lambda url: convert_and_download(url, "stl"),
inputs=current_url,
outputs=stl_file
).then(
fn=lambda: gr.update(visible=True),
outputs=stl_file
)
ply_btn.click(
fn=lambda url: convert_and_download(url, "ply"),
inputs=current_url,
outputs=ply_file
).then(
fn=lambda: gr.update(visible=True),
outputs=ply_file
)
glb_btn.click(
fn=lambda url: convert_and_download(url, "glb"),
inputs=current_url,
outputs=glb_file
).then(
fn=lambda: gr.update(visible=True),
outputs=glb_file
)
if __name__ == "__main__":
demo.launch() |