Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -192,126 +192,6 @@ def process_vox_file(vox_file) -> Tuple[str, str]:
|
|
| 192 |
except Exception as e:
|
| 193 |
return "", f"Error: {str(e)}"
|
| 194 |
|
| 195 |
-
def create_glb_preview(glb_file):
|
| 196 |
-
"""Create HTML preview for GLB file - FIXED SYNTAX ERROR"""
|
| 197 |
-
if glb_file is None:
|
| 198 |
-
return "<p>No GLB file to preview</p>"
|
| 199 |
-
|
| 200 |
-
if hasattr(glb_file, 'name'):
|
| 201 |
-
glb_path = glb_file.name
|
| 202 |
-
else:
|
| 203 |
-
glb_path = str(glb_file)
|
| 204 |
-
|
| 205 |
-
if not os.path.exists(glb_path):
|
| 206 |
-
return "<p>GLB file not found</p>"
|
| 207 |
-
|
| 208 |
-
# Create HTML with Three.js viewer - FIXED THE SYNTAX ERROR
|
| 209 |
-
html_content = f"""
|
| 210 |
-
<div style="width: 100%; height: 400px; position: relative; background: #1a1a1a; border-radius: 8px; overflow: hidden;">
|
| 211 |
-
<div id="preview-container" style="width: 100%; height: 100%;"></div>
|
| 212 |
-
<div style="position: absolute; top: 10px; left: 10px; color: white; font-size: 12px; background: rgba(0,0,0,0.7); padding: 5px 10px; border-radius: 4px;">
|
| 213 |
-
🎮 Drag to rotate • Scroll to zoom • Right-click to pan
|
| 214 |
-
</div>
|
| 215 |
-
</div>
|
| 216 |
-
|
| 217 |
-
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
|
| 218 |
-
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
|
| 219 |
-
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
|
| 220 |
-
|
| 221 |
-
<script>
|
| 222 |
-
// Initialize Three.js scene
|
| 223 |
-
const container = document.getElementById('preview-container');
|
| 224 |
-
const scene = new THREE.Scene();
|
| 225 |
-
scene.background = new THREE.Color(0x2a2a2a);
|
| 226 |
-
|
| 227 |
-
const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
|
| 228 |
-
camera.position.set(5, 5, 5);
|
| 229 |
-
|
| 230 |
-
const renderer = new THREE.WebGLRenderer({{ antialias: true }});
|
| 231 |
-
renderer.setSize(container.clientWidth, container.clientHeight);
|
| 232 |
-
renderer.setPixelRatio(window.devicePixelRatio);
|
| 233 |
-
renderer.shadowMap.enabled = true;
|
| 234 |
-
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
| 235 |
-
container.appendChild(renderer.domElement);
|
| 236 |
-
|
| 237 |
-
// Controls
|
| 238 |
-
const controls = new THREE.OrbitControls(camera, renderer.domElement);
|
| 239 |
-
controls.enableDamping = true;
|
| 240 |
-
controls.dampingFactor = 0.05;
|
| 241 |
-
controls.target.set(0, 0, 0);
|
| 242 |
-
|
| 243 |
-
// Lights
|
| 244 |
-
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
| 245 |
-
scene.add(ambientLight);
|
| 246 |
-
|
| 247 |
-
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
| 248 |
-
directionalLight.position.set(10, 10, 10);
|
| 249 |
-
directionalLight.castShadow = true;
|
| 250 |
-
scene.add(directionalLight);
|
| 251 |
-
|
| 252 |
-
// Grid helper
|
| 253 |
-
const gridHelper = new THREE.GridHelper(20, 20, 0x444444, 0x333333);
|
| 254 |
-
scene.add(gridHelper);
|
| 255 |
-
|
| 256 |
-
// Load GLB file
|
| 257 |
-
const loader = new THREE.GLTFLoader();
|
| 258 |
-
const glbPath = '{glb_path}';
|
| 259 |
-
|
| 260 |
-
loader.load(
|
| 261 |
-
glbPath,
|
| 262 |
-
function (gltf) {{
|
| 263 |
-
const model = gltf.scene;
|
| 264 |
-
|
| 265 |
-
// Center and scale the model
|
| 266 |
-
const box = new THREE.Box3().setFromObject(model);
|
| 267 |
-
const center = box.getCenter(new THREE.Vector3());
|
| 268 |
-
const size = box.getSize(new THREE.Vector3());
|
| 269 |
-
|
| 270 |
-
// Center the model
|
| 271 |
-
model.position.sub(center);
|
| 272 |
-
|
| 273 |
-
// Auto-scale to fit view
|
| 274 |
-
const maxDim = Math.max(size.x, size.y, size.z);
|
| 275 |
-
const scale = 10 / maxDim;
|
| 276 |
-
model.scale.multiplyScalar(scale);
|
| 277 |
-
|
| 278 |
-
scene.add(model);
|
| 279 |
-
|
| 280 |
-
// Auto-rotate camera
|
| 281 |
-
function animate() {{
|
| 282 |
-
requestAnimationFrame(animate);
|
| 283 |
-
controls.update();
|
| 284 |
-
|
| 285 |
-
// Gentle auto-rotation
|
| 286 |
-
const time = Date.now() * 0.001;
|
| 287 |
-
camera.position.x = Math.cos(time * 0.1) * 8;
|
| 288 |
-
camera.position.z = Math.sin(time * 0.1) * 8;
|
| 289 |
-
camera.lookAt(0, 0, 0);
|
| 290 |
-
|
| 291 |
-
renderer.render(scene, camera);
|
| 292 |
-
}}
|
| 293 |
-
animate();
|
| 294 |
-
}},
|
| 295 |
-
function (progress) {{
|
| 296 |
-
console.log('Loading:', progress);
|
| 297 |
-
}},
|
| 298 |
-
function (error) {{
|
| 299 |
-
console.error('Error loading GLB:', error);
|
| 300 |
-
container.innerHTML = '<p style="color: white; text-align: center; padding: 20px;">Error loading GLB file</p>';
|
| 301 |
-
}}
|
| 302 |
-
);
|
| 303 |
-
|
| 304 |
-
// Handle resize
|
| 305 |
-
window.addEventListener('resize', function() {{
|
| 306 |
-
camera.aspect = container.clientWidth / container.clientHeight;
|
| 307 |
-
camera.updateProjectionMatrix();
|
| 308 |
-
renderer.setSize(container.clientWidth, container.clientHeight);
|
| 309 |
-
}});
|
| 310 |
-
</script>
|
| 311 |
-
"""
|
| 312 |
-
|
| 313 |
-
return html_content
|
| 314 |
-
|
| 315 |
def create_gradio_interface():
|
| 316 |
with gr.Blocks(title="VOX to GLB Converter with Preview", theme=gr.themes.Soft()) as app:
|
| 317 |
gr.Markdown("""
|
|
@@ -328,23 +208,33 @@ def create_gradio_interface():
|
|
| 328 |
with gr.Column():
|
| 329 |
glb_output = gr.File(label="Download GLB File", file_types=[".glb"], interactive=False)
|
| 330 |
|
| 331 |
-
# 3D Preview Section
|
| 332 |
gr.Markdown("### 🎮 3D Preview")
|
| 333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
|
| 335 |
# Connect conversion to preview
|
| 336 |
def convert_with_preview(vox_file):
|
| 337 |
glb_path, message = process_vox_file(vox_file)
|
| 338 |
-
if glb_path:
|
| 339 |
-
|
| 340 |
-
return glb_path, message, preview
|
| 341 |
else:
|
| 342 |
-
return None, message,
|
| 343 |
|
| 344 |
convert_btn.click(
|
| 345 |
fn=convert_with_preview,
|
| 346 |
inputs=[vox_input],
|
| 347 |
-
outputs=[glb_output, status_output,
|
| 348 |
)
|
| 349 |
|
| 350 |
gr.Markdown("""
|
|
|
|
| 192 |
except Exception as e:
|
| 193 |
return "", f"Error: {str(e)}"
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
def create_gradio_interface():
|
| 196 |
with gr.Blocks(title="VOX to GLB Converter with Preview", theme=gr.themes.Soft()) as app:
|
| 197 |
gr.Markdown("""
|
|
|
|
| 208 |
with gr.Column():
|
| 209 |
glb_output = gr.File(label="Download GLB File", file_types=[".glb"], interactive=False)
|
| 210 |
|
| 211 |
+
# 3D Preview Section - Using Gradio's built-in 3D viewer
|
| 212 |
gr.Markdown("### 🎮 3D Preview")
|
| 213 |
+
|
| 214 |
+
# Use Gradio's native Model3D component for GLB files
|
| 215 |
+
model_3d = gr.Model3D(
|
| 216 |
+
label="GLB Preview",
|
| 217 |
+
height=400,
|
| 218 |
+
camera_radius=10.0,
|
| 219 |
+
camera_center=(0, 0, 0),
|
| 220 |
+
zoom_speed=1.0,
|
| 221 |
+
pan_speed=2.0,
|
| 222 |
+
rotate_speed=0.8,
|
| 223 |
+
interactive=True
|
| 224 |
+
)
|
| 225 |
|
| 226 |
# Connect conversion to preview
|
| 227 |
def convert_with_preview(vox_file):
|
| 228 |
glb_path, message = process_vox_file(vox_file)
|
| 229 |
+
if glb_path and os.path.exists(glb_path):
|
| 230 |
+
return glb_path, message, glb_path # Return path for both file and 3D viewer
|
|
|
|
| 231 |
else:
|
| 232 |
+
return None, message, None
|
| 233 |
|
| 234 |
convert_btn.click(
|
| 235 |
fn=convert_with_preview,
|
| 236 |
inputs=[vox_input],
|
| 237 |
+
outputs=[glb_output, status_output, model_3d]
|
| 238 |
)
|
| 239 |
|
| 240 |
gr.Markdown("""
|