rdz-falcon commited on
Commit
36c3965
·
verified ·
1 Parent(s): 587a7d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -33
app.py CHANGED
@@ -476,17 +476,10 @@ def render_single_frame(
476
  blank = np.ones((frame_height, frame_width, 3), dtype=np.uint8) * 200
477
  return blank
478
 
479
- # Use vertices as-is (rotation should be applied before calling this function)
480
- # But if fixed_center is None, we need to compute from unrotated vertices
481
- # If fixed_center is provided, it should be from rotated vertices
482
- verts_used = verts.copy()
483
-
484
- # Compute center for camera positioning
485
- mesh_center = verts_used.mean(axis=0)
486
- if fixed_center is not None:
487
- camera_target = fixed_center
488
- else:
489
- camera_target = mesh_center
490
 
491
  # Create scene
492
  scene = pyrender.Scene(bg_color=bg_color, ambient_light=[0.4, 0.4, 0.4])
@@ -499,10 +492,19 @@ def render_single_frame(
499
  baseColorFactor=color
500
  )
501
 
502
- # Create mesh (exactly like compare_vqvae.py)
503
- mesh = trimesh.Trimesh(vertices=verts_used, faces=faces)
 
 
 
 
 
504
  mesh_render = pyrender.Mesh.from_trimesh(mesh, material=material, smooth=True)
505
  scene.add(mesh_render)
 
 
 
 
506
 
507
  # Camera setup
508
  camera = pyrender.IntrinsicsCamera(
@@ -511,13 +513,22 @@ def render_single_frame(
511
  znear=0.1, zfar=20.0
512
  )
513
 
514
- # Camera pose: positioned BEHIND the subject (at +Z), looking at -Z (toward face)
515
- # This matches compare_vqvae.py exactly
 
 
516
  camera_pose = np.eye(4)
517
  camera_pose[0, 3] = camera_target[0] # Center X
518
- camera_pose[1, 3] = camera_target[1] # Center Y
519
- camera_pose[2, 3] = camera_target[2] + camera_distance # BEHIND (positive Z)
520
- camera_pose[:3, :3] = np.eye(3) # Identity = look at -Z
 
 
 
 
 
 
 
521
 
522
  scene.add(camera, pose=camera_pose)
523
 
@@ -619,17 +630,16 @@ def render_video(
619
  # Apply rotation to all frames
620
  # (T, V, 3) dot (3, 3) -> (T, V, 3)
621
  verts = np.matmul(verts, rot_matrix[:3, :3].T)
622
- # Apply orientation fix: rotate 180 degrees around X-axis (like compare_vqvae.py)
623
- verts = verts.copy()
624
- verts[..., 1:] *= -1
625
-
626
  # Trim last few frames to remove end-of-sequence artifacts
627
  T_total = verts.shape[0]
628
  trim_amount = min(8, int(T_total * 0.15))
629
  T = max(5, T_total - trim_amount)
630
 
631
- # Compute fixed camera target from first frame (using rotated vertices)
632
- fixed_center = verts[0].mean(axis=0)
 
 
 
633
 
634
  frames = []
635
  for t in range(T):
@@ -668,12 +678,6 @@ def render_comparison_video(
668
  if not ensure_pyrender():
669
  raise RuntimeError("PyRender not available")
670
 
671
- # Apply orientation fix: rotate 180 degrees around X-axis (like compare_vqvae.py)
672
- verts1 = verts1.copy()
673
- verts2 = verts2.copy()
674
- verts1[..., 1:] *= -1
675
- verts2[..., 1:] *= -1
676
-
677
  # Match lengths and trim
678
  T_total = min(verts1.shape[0], verts2.shape[0])
679
  trim_amount = min(8, int(T_total * 0.15))
@@ -682,9 +686,13 @@ def render_comparison_video(
682
  verts1 = verts1[:T]
683
  verts2 = verts2[:T]
684
 
685
- # Compute fixed camera targets
686
- fixed_center1 = verts1[0].mean(axis=0)
687
- fixed_center2 = verts2[0].mean(axis=0)
 
 
 
 
688
 
689
  labels = [label1, label2]
690
 
 
476
  blank = np.ones((frame_height, frame_width, 3), dtype=np.uint8) * 200
477
  return blank
478
 
479
+ # IMPORTANT: Rotate mesh 180 degrees around X-axis (like visualize.py)
480
+ # This fixes the coordinate system so we view from the front
481
+ rot_matrix = trimesh.transformations.rotation_matrix(np.radians(180), [1, 0, 0])
482
+ verts_rotated = np.dot(verts, rot_matrix[:3, :3].T)
 
 
 
 
 
 
 
483
 
484
  # Create scene
485
  scene = pyrender.Scene(bg_color=bg_color, ambient_light=[0.4, 0.4, 0.4])
 
492
  baseColorFactor=color
493
  )
494
 
495
+ # Create mesh with rotated vertices
496
+ mesh = trimesh.Trimesh(vertices=verts_rotated, faces=faces)
497
+ # Fix normals to ensure proper face rendering
498
+ # This is critical for proper face/lip visibility - ensures all faces point outward
499
+ mesh.fix_normals()
500
+ # Recompute vertex normals for smooth shading
501
+ mesh.vertex_normals
502
  mesh_render = pyrender.Mesh.from_trimesh(mesh, material=material, smooth=True)
503
  scene.add(mesh_render)
504
+
505
+ # Compute center for camera positioning (using rotated vertices)
506
+ mesh_center = verts_rotated.mean(axis=0)
507
+ camera_target = fixed_center if fixed_center is not None else mesh_center
508
 
509
  # Camera setup
510
  camera = pyrender.IntrinsicsCamera(
 
513
  znear=0.1, zfar=20.0
514
  )
515
 
516
+ # Camera pose: positioned in front of the subject, looking at them
517
+ # After 180-degree rotation, Z points down
518
+ # Camera should be at negative Z (in front) looking at positive Z
519
+ # This matches visualize.py exactly
520
  camera_pose = np.eye(4)
521
  camera_pose[0, 3] = camera_target[0] # Center X
522
+ camera_pose[1, 3] = camera_target[1] # Center Y (body center)
523
+ camera_pose[2, 3] = camera_target[2] - camera_distance # In front, distance controls zoom
524
+
525
+ # Camera orientation: flip to look at subject (SOKE-style)
526
+ # This rotation makes camera look toward +Z (at the subject)
527
+ camera_pose[:3, :3] = np.array([
528
+ [1, 0, 0],
529
+ [0, -1, 0],
530
+ [0, 0, -1]
531
+ ])
532
 
533
  scene.add(camera, pose=camera_pose)
534
 
 
630
  # Apply rotation to all frames
631
  # (T, V, 3) dot (3, 3) -> (T, V, 3)
632
  verts = np.matmul(verts, rot_matrix[:3, :3].T)
 
 
 
 
633
  # Trim last few frames to remove end-of-sequence artifacts
634
  T_total = verts.shape[0]
635
  trim_amount = min(8, int(T_total * 0.15))
636
  T = max(5, T_total - trim_amount)
637
 
638
+ # Compute fixed camera target from first frame (rotation happens inside render_single_frame)
639
+ # We need to compute it from rotated vertices for consistency
640
+ rot_matrix = trimesh.transformations.rotation_matrix(np.radians(180), [1, 0, 0])
641
+ verts_rotated_first = np.dot(verts[0], rot_matrix[:3, :3].T)
642
+ fixed_center = verts_rotated_first.mean(axis=0)
643
 
644
  frames = []
645
  for t in range(T):
 
678
  if not ensure_pyrender():
679
  raise RuntimeError("PyRender not available")
680
 
 
 
 
 
 
 
681
  # Match lengths and trim
682
  T_total = min(verts1.shape[0], verts2.shape[0])
683
  trim_amount = min(8, int(T_total * 0.15))
 
686
  verts1 = verts1[:T]
687
  verts2 = verts2[:T]
688
 
689
+ # Compute fixed camera targets (rotation happens inside render_single_frame)
690
+ # We need to compute from rotated vertices for consistency
691
+ rot_matrix = trimesh.transformations.rotation_matrix(np.radians(180), [1, 0, 0])
692
+ verts1_rotated_first = np.dot(verts1[0], rot_matrix[:3, :3].T)
693
+ verts2_rotated_first = np.dot(verts2[0], rot_matrix[:3, :3].T)
694
+ fixed_center1 = verts1_rotated_first.mean(axis=0)
695
+ fixed_center2 = verts2_rotated_first.mean(axis=0)
696
 
697
  labels = [label1, label2]
698