| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import json |
| import os |
| import shutil |
| from dataclasses import dataclass |
|
|
| import tyro |
| from embodied_gen.scripts.simulate_sapien import entrypoint as sim_cli |
| from embodied_gen.utils.enum import LayoutInfo |
| from embodied_gen.utils.geometry import bfs_placement, compose_mesh_scene |
| from embodied_gen.utils.log import logger |
|
|
|
|
| @dataclass |
| class LayoutPlacementConfig: |
| layout_path: str |
| output_dir: str | None = None |
| seed: int | None = None |
| max_attempts: int = 1000 |
| output_iscene: bool = False |
| insert_robot: bool = False |
|
|
|
|
| def entrypoint(**kwargs): |
| if kwargs is None or len(kwargs) == 0: |
| args = tyro.cli(LayoutPlacementConfig) |
| else: |
| args = LayoutPlacementConfig(**kwargs) |
|
|
| output_dir = ( |
| args.output_dir |
| if args.output_dir is not None |
| else os.path.dirname(args.layout_path) |
| ) |
| os.makedirs(output_dir, exist_ok=True) |
| out_scene_path = f"{output_dir}/Iscene.glb" |
| out_layout_path = f"{output_dir}/layout.json" |
|
|
| layout_info = bfs_placement(args.layout_path, seed=args.seed) |
| origin_dir = os.path.dirname(args.layout_path) |
| for key in layout_info.assets: |
| src = f"{origin_dir}/{layout_info.assets[key]}" |
| dst = f"{output_dir}/{layout_info.assets[key]}" |
| if src == dst: |
| continue |
| shutil.copytree(src, dst, dirs_exist_ok=True) |
|
|
| with open(out_layout_path, "w") as f: |
| json.dump(layout_info.to_dict(), f, indent=4) |
|
|
| if args.output_iscene: |
| compose_mesh_scene(layout_info, out_scene_path) |
|
|
| sim_cli( |
| layout_path=out_layout_path, |
| output_dir=output_dir, |
| insert_robot=args.insert_robot, |
| ) |
|
|
| logger.info(f"Layout placement completed in {output_dir}") |
|
|
|
|
| if __name__ == "__main__": |
| entrypoint() |
|
|