mkocabas2206 commited on
Commit
76e0a5c
·
1 Parent(s): 35447e1

fix mcs to glb conversion

Browse files
pipeline/mcs_export_cam.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import json
2
  import base64
3
  from typing import List, Dict, Any, Union, Tuple
@@ -5,6 +6,15 @@ import numpy as np
5
  import scipy as sp
6
  from numpy.typing import NDArray
7
 
 
 
 
 
 
 
 
 
 
8
  def create_gltf_structure(num_frames: int) -> Dict[str, Any]:
9
  """Create the initial structure of the GLTF file.
10
 
@@ -79,6 +89,7 @@ def add_camera_intrinsics(
79
  "aspectRatio": float(aspect_ratio)
80
  }
81
 
 
82
  def add_smpl_buffers_to_gltf(
83
  gltf: Dict[str, Any],
84
  smpl_buffers: List[bytes],
@@ -238,6 +249,7 @@ def add_camera_animation(
238
  ]
239
  })
240
 
 
241
  def write_gltf_to_file(gltf: Dict[str, Any], output_path: str) -> None:
242
  """Write the GLTF structure to a file.
243
 
@@ -248,6 +260,48 @@ def write_gltf_to_file(gltf: Dict[str, Any], output_path: str) -> None:
248
  with open(output_path, 'w', encoding='utf-8') as f:
249
  json.dump(gltf, f, indent=2)
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  def export_scene_with_camera(
252
  smpl_buffers: List[bytes],
253
  frame_presences: List[List[int]],
@@ -257,7 +311,8 @@ def export_scene_with_camera(
257
  translations: NDArray[np.float32],
258
  focal_length: float,
259
  principal_point: Tuple[float, float],
260
- frame_rate: float
 
261
  ) -> None:
262
  """Export the GLTF file with SMPL bodies and animated camera.
263
 
@@ -277,27 +332,5 @@ def export_scene_with_camera(
277
  add_smpl_buffers_to_gltf(gltf, smpl_buffers, frame_presences)
278
  add_camera_animation(gltf, rotation_matrices, translations, num_frames, frame_rate)
279
  write_gltf_to_file(gltf, output_path)
280
- print(f"GLTF file exported to {output_path}")
281
-
282
- if __name__ == "__main__":
283
- # Example usage
284
- MFV_RUN_NAME = "dancing_on_beach"
285
- SMPL_PATHS = [f"../mfv_with_cameras/{MFV_RUN_NAME}/{MFV_RUN_NAME}_sub-1.smpl"]
286
- FRAME_RATE = np.load(SMPL_PATHS[0])["frameRate"]
287
- FRAME_PRESENCES = [[0, 511]]
288
- NUM_FRAMES = 511
289
- camera_data = np.load(f"../mfv_with_cameras/{MFV_RUN_NAME}/camera.npz")
290
-
291
- smpl_buffer_data = [open(path, 'rb').read() for path in SMPL_PATHS]
292
-
293
- export_scene_with_camera(
294
- smpl_buffer_data,
295
- FRAME_PRESENCES,
296
- NUM_FRAMES,
297
- f"./data/mcs_w_camera/{MFV_RUN_NAME}.mcs",
298
- camera_data["R"],
299
- camera_data["T"],
300
- camera_data["focal_length"],
301
- camera_data["principal_point"],
302
- FRAME_RATE
303
- )
 
1
+ import os
2
  import json
3
  import base64
4
  from typing import List, Dict, Any, Union, Tuple
 
6
  import scipy as sp
7
  from numpy.typing import NDArray
8
 
9
+ from gloss import ViewerDummy
10
+
11
+ from smpl_rs import SmplCache
12
+ from smpl_rs.codec import McsCodec, GltfCodec
13
+ from smpl_rs.plugins import SmplPlugin
14
+ from smpl_rs.types import SmplType, Gender, GltfCompatibilityMode
15
+ from smpl_rs.components import GlossInterop
16
+
17
+
18
  def create_gltf_structure(num_frames: int) -> Dict[str, Any]:
19
  """Create the initial structure of the GLTF file.
20
 
 
89
  "aspectRatio": float(aspect_ratio)
90
  }
91
 
92
+
93
  def add_smpl_buffers_to_gltf(
94
  gltf: Dict[str, Any],
95
  smpl_buffers: List[bytes],
 
249
  ]
250
  })
251
 
252
+
253
  def write_gltf_to_file(gltf: Dict[str, Any], output_path: str) -> None:
254
  """Write the GLTF structure to a file.
255
 
 
260
  with open(output_path, 'w', encoding='utf-8') as f:
261
  json.dump(gltf, f, indent=2)
262
 
263
+
264
+ def convert_mcs_to_gltf(mcs_path: str, gltf_path: str, smplx_path: str) -> None:
265
+ """Convert an MCS file to a GLTF file.
266
+
267
+ Args:
268
+ mcs_path: Path to the MCS file.
269
+ gltf_path: Path to write the GLTF file.
270
+ """
271
+ viewer = ViewerDummy()
272
+
273
+ mcs_codec = McsCodec.from_file(mcs_path)
274
+
275
+ print("\nInformation from the MCS file:")
276
+ print(f"Number of frames: {mcs_codec.num_frames}")
277
+ print(f"Number of bodies: {mcs_codec.num_bodies}")
278
+ print(f"Has camera: {mcs_codec.has_camera}")
279
+ print(f"Frame rate: {mcs_codec.frame_rate}")
280
+
281
+ entity_builders = mcs_codec.to_entity_builders()
282
+
283
+ for current_ent, builder in enumerate(entity_builders):
284
+ entity = viewer.get_or_create_entity(name=f"mcs_entity_{current_ent}")
285
+ entity.insert(builder)
286
+ interop = GlossInterop(with_uv=True)
287
+ entity.insert(interop)
288
+
289
+ smpl_models = SmplCache.default()
290
+ smpl_models.set_lazy_loading(SmplType.SmplX, Gender.Neutral, smplx_path)
291
+
292
+ viewer.add_resource(smpl_models)
293
+ viewer.insert_plugin(SmplPlugin(autorun=False))
294
+ viewer.run_manual_plugins()
295
+
296
+ # Create the writer and export as Glb
297
+ gltf_codec = GltfCodec.from_scene(viewer.get_scene().ptr_idx(), export_camera = True)
298
+ gltf_codec.save(gltf_path, GltfCompatibilityMode.Unreal)
299
+ print(f"glTF file exported to {os.path.abspath(gltf_path)}")
300
+
301
+ # here there is gltf and buffer0.bin data, how can I combine them into a single file?
302
+
303
+
304
+
305
  def export_scene_with_camera(
306
  smpl_buffers: List[bytes],
307
  frame_presences: List[List[int]],
 
311
  translations: NDArray[np.float32],
312
  focal_length: float,
313
  principal_point: Tuple[float, float],
314
+ frame_rate: float,
315
+ smplx_path: str
316
  ) -> None:
317
  """Export the GLTF file with SMPL bodies and animated camera.
318
 
 
332
  add_smpl_buffers_to_gltf(gltf, smpl_buffers, frame_presences)
333
  add_camera_animation(gltf, rotation_matrices, translations, num_frames, frame_rate)
334
  write_gltf_to_file(gltf, output_path)
335
+ print(f"MCS file exported to {os.path.abspath(output_path)}")
336
+ convert_mcs_to_gltf(output_path, output_path.replace(".mcs", ".glb"), smplx_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pipeline/pipeline.py CHANGED
@@ -395,13 +395,11 @@ class Pipeline:
395
  focal_length=self.results['camera_world']['img_focal'],
396
  principal_point=self.results['camera_world']['img_center'],
397
  frame_rate=float(self.cfg.fps),
 
398
  )
399
- print(f'MCS file saved to "{os.path.abspath(MCS_OUTPUT_PATH)}"')
400
- print(f'You can drag and drop the "world4d.mcs" file to https://me.meshcapade.com/editor to view the result')
401
-
402
-
403
- shutil.copy(MCS_OUTPUT_PATH, f'{seq_folder}/world4d.glb')
404
- print(f'GLB file saved to "{os.path.abspath(f"{seq_folder}/world4d.glb")}"')
405
- print(f'You can import the "world4d.glb" file on Blender to view the result')
406
 
407
  return self.results
 
395
  focal_length=self.results['camera_world']['img_focal'],
396
  principal_point=self.results['camera_world']['img_center'],
397
  frame_rate=float(self.cfg.fps),
398
+ smplx_path='data/body_models/smplx/SMPLX_neutral_array_f32_slim.npz',
399
  )
400
+
401
+ print("Usage:")
402
+ print(f'\tYou can drag and drop the "world4d.mcs" file to https://me.meshcapade.com/editor to view the result')
403
+ print(f'\tYou can import the "world4d.glb" file on Blender to view the result')
 
 
 
404
 
405
  return self.results
requirements.txt CHANGED
@@ -32,5 +32,7 @@ smplx==0.1.28
32
  fvcore
33
  pyliblzfse
34
  smplcodec
 
 
35
  git+https://github.com/mattloper/chumpy@9b045ff5d6588a24a0bab52c83f032e2ba433e17
36
  git+https://github.com/facebookresearch/pytorch3d.git@stable
 
32
  fvcore
33
  pyliblzfse
34
  smplcodec
35
+ smpl-rs==0.6.1
36
+ gloss-rs==0.6.0
37
  git+https://github.com/mattloper/chumpy@9b045ff5d6588a24a0bab52c83f032e2ba433e17
38
  git+https://github.com/facebookresearch/pytorch3d.git@stable
scripts/fetch_smplx.sh CHANGED
@@ -33,4 +33,5 @@ rm -rf data/body_models/smpl/smpl
33
  rm -rf data/body_models/smpl/smpl.zip
34
 
35
  # Supplementary files
36
- gdown --folder -O ./data/ https://drive.google.com/drive/folders/1JU7CuU2rKkwD7WWjvSZJKpQFFk_Z6NL7?usp=share_link
 
 
33
  rm -rf data/body_models/smpl/smpl.zip
34
 
35
  # Supplementary files
36
+ gdown --folder -O ./data/ https://drive.google.com/drive/folders/1JU7CuU2rKkwD7WWjvSZJKpQFFk_Z6NL7?usp=share_link
37
+ gdown -O ./data/body_models/smplx/ 1v9Qy7ZXWcTM8_a9K2nSLyyVrJMFYcUOk
scripts/install.sh CHANGED
@@ -128,7 +128,6 @@ if [ "$PT_VERSION" == "2.4" ]; then
128
  pip install data/wheels/droid_backends_intr-0.3-cp311-cp311-linux_x86_64.whl
129
  pip install data/wheels/lietorch-0.3-cp311-cp311-linux_x86_64.whl
130
  pip install data/wheels/sam2-1.5-cp311-cp311-linux_x86_64.whl
131
- pip install data/wheels/gloss-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
132
  fi
133
 
134
  elif [ "$PT_VERSION" == "2.6" ]; then
@@ -151,8 +150,6 @@ elif [ "$PT_VERSION" == "2.6" ]; then
151
  pip install data/wheels/sam2-1.6-cp312-cp312-linux_x86_64.whl
152
  pip install data/wheels/detectron2-0.9-cp312-cp312-linux_x86_64.whl
153
  pip install data/wheels/droid_backends_intr-0.4-cp312-cp312-linux_x86_64.whl
154
- # pip install data/wheels/gloss_rs-0.6.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
155
- pip install data/wheels/gloss-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
156
  pip install data/wheels/lietorch-0.4-cp312-cp312-linux_x86_64.whl
157
  fi
158
  fi
 
128
  pip install data/wheels/droid_backends_intr-0.3-cp311-cp311-linux_x86_64.whl
129
  pip install data/wheels/lietorch-0.3-cp311-cp311-linux_x86_64.whl
130
  pip install data/wheels/sam2-1.5-cp311-cp311-linux_x86_64.whl
 
131
  fi
132
 
133
  elif [ "$PT_VERSION" == "2.6" ]; then
 
150
  pip install data/wheels/sam2-1.6-cp312-cp312-linux_x86_64.whl
151
  pip install data/wheels/detectron2-0.9-cp312-cp312-linux_x86_64.whl
152
  pip install data/wheels/droid_backends_intr-0.4-cp312-cp312-linux_x86_64.whl
 
 
153
  pip install data/wheels/lietorch-0.4-cp312-cp312-linux_x86_64.whl
154
  fi
155
  fi