weijielyu commited on
Commit
e40964f
Β·
1 Parent(s): 0704fd9
Files changed (1) hide show
  1. app.py +86 -57
app.py CHANGED
@@ -333,71 +333,99 @@ def create_splat_viewer_html(ply_url: str) -> str:
333
  viewer_js_content = viewer_js_path.read_text() if viewer_js_path.exists() else ""
334
 
335
  return f"""
336
- <div id="splat-viewer-container" style="width:100%; height:600px; position:relative; background:#000; border:1px solid #333; border-radius:8px;">
337
  <canvas id="canvas" style="width:100%; height:100%; display:block;"></canvas>
338
- <div id="controls" style="position:absolute; top:10px; left:10px; color:white; font-family:Arial; font-size:12px; background:rgba(0,0,0,0.8); padding:10px; border-radius:4px;">
339
- <strong>Controls:</strong><br>
340
- Drag: Rotate | Scroll: Zoom<br>
341
- Right-drag: Pan
 
 
 
 
 
342
  </div>
343
- <div id="loading" style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:white; font-family:Arial; font-size:14px; background:rgba(0,0,0,0.8); padding:20px; border-radius:8px;">
344
- Loading 3D model...
 
 
 
 
 
 
 
345
  </div>
346
  </div>
 
347
  <script>
348
- {viewer_js_content}
 
 
 
349
  </script>
 
350
  <script>
351
- // Auto-load the PLY file when viewer is ready
352
- setTimeout(function() {{
353
- const plyUrl = '{ply_url}';
354
- const loadingDiv = document.getElementById('loading');
355
-
356
- console.log('=== PLY Loading Debug ===');
357
- console.log('PLY URL:', plyUrl);
358
- console.log('Current location:', window.location.href);
359
- console.log('Worker exists:', !!window.worker);
360
-
361
- loadingDiv.textContent = 'Fetching PLY from: ' + plyUrl;
 
362
 
363
- fetch(plyUrl)
364
- .then(response => {{
365
- console.log('Fetch response status:', response.status, response.statusText);
366
- console.log('Response headers:', Array.from(response.headers.entries()));
367
- console.log('Response OK:', response.ok);
368
-
369
- if (!response.ok) {{
370
- throw new Error(`HTTP ${{response.status}}: ${{response.statusText}}`);
371
- }}
372
- return response.arrayBuffer();
373
- }})
374
- .then(buffer => {{
375
- console.log('βœ“ PLY loaded successfully!');
376
- console.log('Buffer size:', buffer.byteLength, 'bytes');
377
- loadingDiv.textContent = 'Processing ' + (buffer.byteLength / 1024).toFixed(1) + ' KB...';
378
-
379
- // Trigger the viewer to process the PLY
380
- if (window.worker) {{
381
- console.log('Dispatching to worker...');
382
- const event = new MessageEvent('message', {{ data: {{ ply: buffer }} }});
383
- window.worker.dispatchEvent(event);
384
- setTimeout(() => {{
385
- if (loadingDiv) loadingDiv.style.display = 'none';
386
- }}, 2000);
387
- }} else {{
388
- console.error('βœ— Worker not initialized!');
389
- console.log('Window keys:', Object.keys(window).filter(k => k.includes('work')));
390
- loadingDiv.textContent = 'Error: Viewer worker not ready';
391
- loadingDiv.style.color = '#ff4444';
392
- }}
393
- }})
394
- .catch(error => {{
395
- console.error('βœ— Error loading PLY:', error);
396
- console.error('Error stack:', error.stack);
397
- loadingDiv.textContent = 'Error: ' + error.message;
398
- loadingDiv.style.color = '#ff4444';
399
- }});
400
- }}, 1000);
 
 
 
 
 
 
 
 
 
 
401
  </script>
402
  """
403
 
@@ -433,6 +461,7 @@ def main():
433
  ### πŸ’‘ Tips for Best Results
434
  - Works best with near-frontal portrait images
435
  - The provided checkpoints were not trained with accessories (glasses, hats, etc.). Portraits containing accessories may produce suboptimal results.
 
436
  """)
437
 
438
  with gr.Row():
 
333
  viewer_js_content = viewer_js_path.read_text() if viewer_js_path.exists() else ""
334
 
335
  return f"""
336
+ <div id="splat-viewer-container" style="width:100%; height:600px; position:relative; background:#000; border:1px solid #333; border-radius:8px; overflow:hidden;">
337
  <canvas id="canvas" style="width:100%; height:100%; display:block;"></canvas>
338
+
339
+ <!-- Required elements for viewer.js -->
340
+ <div id="spinner" style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:white; font-family:Arial; z-index:10;">
341
+ <div style="text-align:center; background:rgba(0,0,0,0.8); padding:20px; border-radius:8px;">
342
+ <div style="font-size:14px; margin-bottom:10px;">Loading 3D Viewer...</div>
343
+ <div style="background:#333; height:4px; width:200px; border-radius:2px; overflow:hidden;">
344
+ <div id="progress" style="background:#4CAF50; height:100%; width:0%; transition:width 0.3s;"></div>
345
+ </div>
346
+ </div>
347
  </div>
348
+
349
+ <div id="message" style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:#ff4444; font-family:Arial; font-size:14px; background:rgba(0,0,0,0.9); padding:20px; border-radius:8px; display:none; z-index:11;"></div>
350
+
351
+ <div id="fps" style="position:absolute; top:10px; right:10px; color:white; font-family:monospace; font-size:11px; background:rgba(0,0,0,0.7); padding:6px 10px; border-radius:4px; display:none;"></div>
352
+
353
+ <div id="camid" style="position:absolute; top:40px; right:10px; color:white; font-family:monospace; font-size:11px; background:rgba(0,0,0,0.7); padding:6px 10px; border-radius:4px; display:none;"></div>
354
+
355
+ <div id="controls-info" style="position:absolute; bottom:10px; left:10px; color:white; font-family:Arial; font-size:11px; background:rgba(0,0,0,0.7); padding:8px 12px; border-radius:4px;">
356
+ <strong>Controls:</strong> Drag: Rotate | Scroll: Zoom | Right-drag: Pan
357
  </div>
358
  </div>
359
+
360
  <script>
361
+ // Inject viewer.js
362
+ (function() {{
363
+ {viewer_js_content}
364
+ }})();
365
  </script>
366
+
367
  <script>
368
+ // Auto-load the PLY file after viewer initializes
369
+ (function() {{
370
+ const plyUrl = '{ply_url}';
371
+ console.log('=== Splat Viewer Init ===');
372
+ console.log('PLY URL:', plyUrl);
373
+
374
+ // Wait for viewer to initialize
375
+ let attempts = 0;
376
+ const maxAttempts = 50;
377
+
378
+ const checkAndLoad = setInterval(function() {{
379
+ attempts++;
380
 
381
+ if (window.worker) {{
382
+ console.log('βœ“ Worker initialized after', attempts * 100, 'ms');
383
+ clearInterval(checkAndLoad);
384
+
385
+ // Load the PLY file
386
+ fetch(plyUrl)
387
+ .then(response => {{
388
+ console.log('Fetch status:', response.status);
389
+ if (!response.ok) throw new Error(`HTTP ${{response.status}}`);
390
+ return response.arrayBuffer();
391
+ }})
392
+ .then(buffer => {{
393
+ console.log('βœ“ PLY loaded:', buffer.byteLength, 'bytes');
394
+
395
+ // Send to worker (viewer.js will handle it)
396
+ const file = new File([buffer], "model.ply");
397
+ const reader = new FileReader();
398
+ reader.onload = function() {{
399
+ window.worker.postMessage({{ ply: reader.result }});
400
+ console.log('βœ“ PLY sent to worker');
401
+ }};
402
+ reader.readAsArrayBuffer(file);
403
+ }})
404
+ .catch(error => {{
405
+ console.error('βœ— Error:', error);
406
+ const spinner = document.getElementById('spinner');
407
+ const message = document.getElementById('message');
408
+ if (spinner) spinner.style.display = 'none';
409
+ if (message) {{
410
+ message.textContent = 'Error loading model: ' + error.message;
411
+ message.style.display = 'block';
412
+ }}
413
+ }});
414
+ }} else if (attempts >= maxAttempts) {{
415
+ console.error('βœ— Worker failed to initialize');
416
+ clearInterval(checkAndLoad);
417
+ const spinner = document.getElementById('spinner');
418
+ const message = document.getElementById('message');
419
+ if (spinner) spinner.style.display = 'none';
420
+ if (message) {{
421
+ message.textContent = 'Viewer failed to initialize. Please refresh the page.';
422
+ message.style.display = 'block';
423
+ }}
424
+ }} else {{
425
+ console.log('Waiting for worker...', attempts);
426
+ }}
427
+ }}, 100);
428
+ }})();
429
  </script>
430
  """
431
 
 
461
  ### πŸ’‘ Tips for Best Results
462
  - Works best with near-frontal portrait images
463
  - The provided checkpoints were not trained with accessories (glasses, hats, etc.). Portraits containing accessories may produce suboptimal results.
464
+ - If face detection fails, try disabling auto-cropping and manually crop to square
465
  """)
466
 
467
  with gr.Row():