Spaces:
Build error
Build error
Commit ·
86ef168
1
Parent(s): d07a311
Update files
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitignore +5 -1
- README.md +176 -10
- TRELLIS/trellis/pipelines/trellis_image_to_3d.py +1 -4
- TRELLIS/trellis/utils/postprocessing_utils.py +15 -6
- add_disk.py +2 -2
- app.py +371 -357
- assets/disk.png +2 -2
- assets/teaser.png +2 -2
- configs/default.yaml +20 -3
- configs/partnet_target.json +1 -1
- datasets/PartNet/100214/02_pure.png +0 -3
- datasets/PartNet/100214/02_seg.png +0 -3
- datasets/PartNet/100214/03_pure.png +0 -3
- datasets/PartNet/100214/03_seg.png +0 -3
- datasets/PartNet/100214/04_pure.png +0 -3
- datasets/PartNet/100214/04_seg.png +0 -3
- datasets/PartNet/100214/05_pure.png +0 -3
- datasets/PartNet/100214/05_seg.png +0 -3
- datasets/PartNet/100214/gt_mesh/00.glb +0 -3
- datasets/PartNet/100214/gt_mesh/01.glb +0 -3
- datasets/PartNet/100214/gt_mesh/02.glb +0 -3
- datasets/PartNet/100214/gt_mesh/03.glb +0 -3
- datasets/PartNet/100214/gt_mesh/04.glb +0 -3
- datasets/PartNet/100214/gt_mesh/05.glb +0 -3
- datasets/PartNet/100214/joint_info.json +0 -21
- datasets/PartNet/100214/joints.json +0 -16
- datasets/PartNet/100214/mobility.urdf +0 -470
- datasets/PartNet/100350/00_pure.png +0 -3
- datasets/PartNet/100350/00_seg.png +0 -3
- datasets/PartNet/100350/01_pure.png +0 -3
- datasets/PartNet/100350/01_seg.png +0 -3
- datasets/PartNet/100350/02_pure.png +0 -3
- datasets/PartNet/100350/02_seg.png +0 -3
- datasets/PartNet/100350/03_pure.png +0 -3
- datasets/PartNet/100350/03_seg.png +0 -3
- datasets/PartNet/100350/04_pure.png +0 -3
- datasets/PartNet/100350/04_seg.png +0 -3
- datasets/PartNet/100350/05_pure.png +0 -3
- datasets/PartNet/100350/05_seg.png +0 -3
- datasets/PartNet/100350/gt_mesh/00.glb +0 -3
- datasets/PartNet/100350/gt_mesh/01.glb +0 -3
- datasets/PartNet/100350/gt_mesh/02.glb +0 -3
- datasets/PartNet/100350/gt_mesh/03.glb +0 -3
- datasets/PartNet/100350/gt_mesh/04.glb +0 -3
- datasets/PartNet/100350/gt_mesh/05.glb +0 -3
- datasets/PartNet/100350/joint_info.json +0 -21
- datasets/PartNet/100350/joints.json +0 -14
- datasets/PartNet/100350/mobility.urdf +0 -904
- datasets/PartNet/101363/00_pure.png +0 -3
- datasets/PartNet/101363/00_seg.png +0 -3
.gitignore
CHANGED
|
@@ -3,7 +3,11 @@
|
|
| 3 |
*.pth
|
| 4 |
*.ckpt
|
| 5 |
|
|
|
|
|
|
|
|
|
|
| 6 |
tmp/
|
| 7 |
-
debug/
|
|
|
|
| 8 |
outputs/
|
| 9 |
evaluations/
|
|
|
|
| 3 |
*.pth
|
| 4 |
*.ckpt
|
| 5 |
|
| 6 |
+
**/__pycache__/
|
| 7 |
+
.gradio/
|
| 8 |
+
|
| 9 |
tmp/
|
| 10 |
+
debug/
|
| 11 |
+
datasets/PartNet
|
| 12 |
outputs/
|
| 13 |
evaluations/
|
README.md
CHANGED
|
@@ -1,10 +1,176 @@
|
|
| 1 |
-
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<h1 align="center">FreeArt3D: Training-Free Articulated Object Generation using 3D Diffusion</h1>
|
| 2 |
+
<h3 align="center">SIGGRAPH Asia 2025</h3>
|
| 3 |
+
|
| 4 |
+
<p align="center"><a href="https://czzzzh.github.io/FreeArt3D/FreeArt3D.pdf"><img src='https://img.shields.io/badge/arXiv-Paper-red?logo=arxiv&logoColor=white' alt='arXiv'></a>
|
| 5 |
+
<a href="https://czzzzh.github.io/FreeArt3D"><img src='https://img.shields.io/badge/Project_Page-Website-green?logo=googlechrome&logoColor=white' alt='Project Page'></a>
|
| 6 |
+
<a href="https://huggingface.co/spaces/MorPhLingXD/FreeArt3D"><img src='https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Live_Demo-blue'></a>
|
| 7 |
+
</p>
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
Official Implementation for ***FreeArt3D: Training-Free Articulated Object Generation using 3D Diffusion***
|
| 11 |
+
|
| 12 |
+
<p align="center"><img src="assets/teaser.png" width="100%"></p>
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
## 🔔 Updates
|
| 17 |
+
[10/29/2025] We released our code, dataset and results!
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
## 🚧 TODO List
|
| 23 |
+
- [ ] Release test data on Objaverse dataset
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
## 🚀 Quick Start
|
| 28 |
+
1. Setup the environment
|
| 29 |
+
|
| 30 |
+
```bash
|
| 31 |
+
conda create -n fa3d python=3.10
|
| 32 |
+
conda activate fa3d
|
| 33 |
+
bash setup.sh
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
**Note:** If you need to use different torch or cudatoolkit version (for correctly building other libraries), please also install the compatible version of [kaolin](https://github.com/NVIDIAGameWorks/kaolin)
|
| 37 |
+
|
| 38 |
+
2. Download the checkpoint of [GIM-DKM](https://github.com/xuelunshen/gim) from [Google Drive](https://drive.google.com/file/d/1iYmEctoA-a3sds9VQPwVJIJbs0v6oztb/view?usp=sharing), and put it to `gim/weights`
|
| 39 |
+
|
| 40 |
+
3. Generate the articulated **cabinet** from the input images in `examples/cabinet`
|
| 41 |
+
|
| 42 |
+
```bash
|
| 43 |
+
python run_two_parts.py
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
Then check `outputs/cabinet/sds_output/part_meshes` and `outputs/cabinet/sds_output/states` for the articulated mesh results!
|
| 47 |
+
|
| 48 |
+
You can also check `outputs/cabinet/output.urdf` for the **URDF** format output, and we provide a script to parse it in `pipelines/urdf.py`
|
| 49 |
+
|
| 50 |
+
4. Try other examples by simply changing the input directory and the joint type.
|
| 51 |
+
|
| 52 |
+
```bash
|
| 53 |
+
python run_two_parts.py --input_dir examples/cabinet2 --joint_type revolute
|
| 54 |
+
python run_two_parts.py --input_dir examples/cabinet3
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
## 💻 PartNet-Mobility Articulation
|
| 62 |
+
|
| 63 |
+
1. Download the **preprocessed PartNet-Mobility dataset** from [Google Drive](https://drive.google.com/file/d/1MGvp_Sm7lkn87ZXH3I1uSGNTJ_-hD4eA/view?usp=drive_link) (including **144** objects in **12** categories, the objects have been rendered with disks) and put it to the `datasets` directory. The folder structure should be
|
| 64 |
+
|
| 65 |
+
```bash
|
| 66 |
+
FreeArt3D
|
| 67 |
+
|--datasets
|
| 68 |
+
|-- PartNet
|
| 69 |
+
|-- 100214
|
| 70 |
+
└-- ...
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
2. Then run the same script with specified input directory and the PartNet option
|
| 74 |
+
|
| 75 |
+
```bash
|
| 76 |
+
python run_two_parts.py --input_dir datasets/PartNet/100214 --partnet # You can use any other object id included in the dataset
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
3. *(Optional)* Evaluate the metric of results
|
| 80 |
+
|
| 81 |
+
We provide the script to evaluate different metrics for the PartNet-Mobility results. Note that this is a general evaluation script so you can use it to evaluate other objects if you have ground-truth for them (simply changing the **test_id**)
|
| 82 |
+
|
| 83 |
+
```bash
|
| 84 |
+
python evaluate_partnet.py --test_id 100214
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
4. *(Optional)* Preprocess the PartNet-Mobility dataset
|
| 88 |
+
|
| 89 |
+
If you want to test our method on the objects **not in** our processed dataset, you can use the following scripts the process meshes from the [original PartNet-Mobility dataset](https://sapien.ucsd.edu/downloads). Note that you need to manually filter out the joints you want to use. You can check `configs/partnet_target.json` and `partnet.json` for the format. Here we provide the steps to **preprocess** and **render** the objects according to the object ids in `partnet.json`
|
| 90 |
+
|
| 91 |
+
```bash
|
| 92 |
+
python preprocess_partnet_joint.py
|
| 93 |
+
blenderproc run preprocess_partnet_mesh.py
|
| 94 |
+
python render_partnet_mesh.py
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
The scripts will generate **.glb** meshes at different qpos in `datasets/PartNet/{$test_id}/gt_mesh` and the renderings **with** **disk** in `datasets/PartNet/{$test_id}`, which is the same as the ones in the downloaded preprocessed dataset.
|
| 98 |
+
|
| 99 |
+
5. *(Optional)* Download the PartNet-Mobility results
|
| 100 |
+
|
| 101 |
+
We provide the [PartNet-Mobility results](https://drive.google.com/drive/folders/1cthxRlejeTbU3AJC0OmRBeBx0pQr6gef?usp=sharing) run at our end with our latest version of the code for reference. The results are reproducible with the code, but you might get results with minor difference (we have fixed the random seed but some CUDA implementations (e.g. [tiny-cuda-nn](https://github.com/NVlabs/tiny-cuda-nn)) are non-deterministic)
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
## 🚪 Multi-joint Articulation
|
| 106 |
+
|
| 107 |
+
1. Download the **processed multi-joint dataset** from [Google Drive](https://drive.google.com/file/d/1-Bl5X5XahyMzY9NvrMqsVUzCYthzU11w/view?usp=drive_link) (the objects have been rendered with disks for **each joint**) and put it to the `datasets`directory. The folder structure should be
|
| 108 |
+
|
| 109 |
+
```bash
|
| 110 |
+
FreeArt3D
|
| 111 |
+
|--datasets
|
| 112 |
+
|-- multi-joint
|
| 113 |
+
|-- 46180
|
| 114 |
+
|-- ...
|
| 115 |
+
└-- meta.json
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
**Note:** This small dataset includes objects from both **PartNet-Mobility** and **Objaverse**. A meta file records the types of joints for each object.
|
| 119 |
+
|
| 120 |
+
2. Run the script for multi-joint articulation
|
| 121 |
+
|
| 122 |
+
```bash
|
| 123 |
+
python run_multi_parts.py --input_dir datasets/multi_joint/46180 # You can use any other object id included in the dataset
|
| 124 |
+
```
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
## 🌟 Use your own images
|
| 129 |
+
|
| 130 |
+
If you want to use your own images, you need to segment them first using tools such as SAM. Here is a [webtool](https://huggingface.co/spaces/Xenova/segment-anything-webgpu) you can refer to
|
| 131 |
+
|
| 132 |
+
<img src="assets\sam.png" alt="sam" style="zoom: 33%;" />
|
| 133 |
+
|
| 134 |
+
After segmentation, if your image wasn't segmented out with a **"carpet"**, you can manually add a **virtual disk** with a GUI tool we provided
|
| 135 |
+
|
| 136 |
+
```bash
|
| 137 |
+
python add_disk.py --input_dir examples/cabinet3_no_disk
|
| 138 |
+
```
|
| 139 |
+
|
| 140 |
+
This tool can help you add a virtual disk for every input image efficiently. It also supports rescaling the objects to a suitable size for better articulation.
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
## 🤗 Demo
|
| 146 |
+
We have deployed our live demo at [huggingface space](https://huggingface.co/spaces/MorPhLingXD/FreeArt3D). However, due to the long running time of our method, it's also recommended running the demo on your local machine:
|
| 147 |
+
|
| 148 |
+
```bash
|
| 149 |
+
python app.py
|
| 150 |
+
```
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
## 🍀 Acknowledgement
|
| 155 |
+
|
| 156 |
+
We acknowledge the following repositories for borrowing the codes:
|
| 157 |
+
|
| 158 |
+
**TRELLIS:** https://github.com/microsoft/TRELLIS
|
| 159 |
+
|
| 160 |
+
**GIM:** https://github.com/xuelunshen/gim
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
## 📜 Citation
|
| 165 |
+
|
| 166 |
+
If you find this repository useful in your project, welcome to cite our work :)
|
| 167 |
+
|
| 168 |
+
```
|
| 169 |
+
[BibTex]
|
| 170 |
+
@InProceedings{chen2025freeart3d,
|
| 171 |
+
title = {FreeArt3D: Training-Free Articulated Object Generation using 3D Diffusion},
|
| 172 |
+
author = {Chen, Chuhao and Liu, Isabella and Wei, Xinyue and Su, Hao and Liu, Minghua},
|
| 173 |
+
booktitle = {SIGGRAPH Asia 2025 Conference Papers},
|
| 174 |
+
year = {2025}
|
| 175 |
+
}
|
| 176 |
+
```
|
TRELLIS/trellis/pipelines/trellis_image_to_3d.py
CHANGED
|
@@ -346,10 +346,7 @@ class TrellisImageTo3DPipeline(Pipeline):
|
|
| 346 |
|
| 347 |
# Decode occupancy latent
|
| 348 |
decoder = self.models['sparse_structure_decoder']
|
| 349 |
-
decoded = decoder(z_s)
|
| 350 |
-
|
| 351 |
-
# visualize_dense_voxels(noise[0].permute(1, 2, 3, 0)[..., :3], 16, 'noise_low')
|
| 352 |
-
# visualize_dense_voxels(z_s[0].permute(1, 2, 3, 0)[..., :3], 16, 'denoised_low')
|
| 353 |
coords = torch.argwhere(decoded > 0)[:, [0, 2, 3, 4]].int()
|
| 354 |
return coords
|
| 355 |
|
|
|
|
| 346 |
|
| 347 |
# Decode occupancy latent
|
| 348 |
decoder = self.models['sparse_structure_decoder']
|
| 349 |
+
decoded = decoder(z_s)
|
|
|
|
|
|
|
|
|
|
| 350 |
coords = torch.argwhere(decoded > 0)[:, [0, 2, 3, 4]].int()
|
| 351 |
return coords
|
| 352 |
|
TRELLIS/trellis/utils/postprocessing_utils.py
CHANGED
|
@@ -318,22 +318,30 @@ def bake_texture(
|
|
| 318 |
texture = torch.zeros((texture_size * texture_size, 3), dtype=torch.float32).cuda()
|
| 319 |
texture_weights = torch.zeros((texture_size * texture_size), dtype=torch.float32).cuda()
|
| 320 |
rastctx = utils3d.torch.RastContext(backend='cuda')
|
|
|
|
|
|
|
| 321 |
for observation, view, projection in tqdm(zip(observations, views, projections), total=len(observations), disable=not verbose, desc='Texture baking (fast)'):
|
| 322 |
-
|
|
|
|
| 323 |
rast = utils3d.torch.rasterize_triangle_faces(
|
| 324 |
rastctx, vertices[None], faces, observation.shape[1], observation.shape[0], uv=uvs[None], view=view, projection=projection
|
| 325 |
)
|
| 326 |
uv_map = rast['uv'][0].detach().flip(0)
|
| 327 |
mask = rast['mask'][0].detach().bool() & masks[0]
|
| 328 |
|
| 329 |
-
# nearest neighbor interpolation
|
| 330 |
uv_map = (uv_map * texture_size).floor().long()
|
| 331 |
obs = observation[mask]
|
| 332 |
uv_map = uv_map[mask]
|
| 333 |
idx = uv_map[:, 0] + (texture_size - uv_map[:, 1] - 1) * texture_size
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
texture = texture.scatter_add(0, idx.view(-1, 1).expand(-1, 3), obs)
|
| 335 |
texture_weights = texture_weights.scatter_add(0, idx, torch.ones((obs.shape[0]), dtype=torch.float32, device=texture.device))
|
| 336 |
-
|
| 337 |
mask = texture_weights > 0
|
| 338 |
texture[mask] /= texture_weights[mask][:, None]
|
| 339 |
texture = np.clip(texture.reshape(texture_size, texture_size, 3).cpu().numpy() * 255, 0, 255).astype(np.uint8)
|
|
@@ -404,6 +412,7 @@ def to_glb(
|
|
| 404 |
fill_holes_max_size: float = 0.04,
|
| 405 |
texture_size: int = 1024,
|
| 406 |
debug: bool = False,
|
|
|
|
| 407 |
verbose: bool = True,
|
| 408 |
) -> trimesh.Trimesh:
|
| 409 |
"""
|
|
@@ -443,15 +452,15 @@ def to_glb(
|
|
| 443 |
observations, extrinsics, intrinsics = render_multiview(app_rep, resolution=1024, nviews=100)
|
| 444 |
masks = [np.any(observation > 0, axis=-1) for observation in observations]
|
| 445 |
extrinsics = [extrinsics[i].cpu().numpy() for i in range(len(extrinsics))]
|
| 446 |
-
intrinsics = [intrinsics[i].cpu().numpy() for i in range(len(intrinsics))]
|
| 447 |
texture = bake_texture(
|
| 448 |
vertices, faces, uvs,
|
| 449 |
observations, masks, extrinsics, intrinsics,
|
| 450 |
-
texture_size=texture_size, mode=
|
| 451 |
lambda_tv=0.01,
|
| 452 |
verbose=verbose
|
| 453 |
)
|
| 454 |
-
texture = Image.fromarray(texture)
|
| 455 |
|
| 456 |
# rotate mesh (from z-up to y-up)
|
| 457 |
vertices = vertices @ np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
|
|
|
|
| 318 |
texture = torch.zeros((texture_size * texture_size, 3), dtype=torch.float32).cuda()
|
| 319 |
texture_weights = torch.zeros((texture_size * texture_size), dtype=torch.float32).cuda()
|
| 320 |
rastctx = utils3d.torch.RastContext(backend='cuda')
|
| 321 |
+
|
| 322 |
+
i = 0
|
| 323 |
for observation, view, projection in tqdm(zip(observations, views, projections), total=len(observations), disable=not verbose, desc='Texture baking (fast)'):
|
| 324 |
+
|
| 325 |
+
with torch.no_grad():
|
| 326 |
rast = utils3d.torch.rasterize_triangle_faces(
|
| 327 |
rastctx, vertices[None], faces, observation.shape[1], observation.shape[0], uv=uvs[None], view=view, projection=projection
|
| 328 |
)
|
| 329 |
uv_map = rast['uv'][0].detach().flip(0)
|
| 330 |
mask = rast['mask'][0].detach().bool() & masks[0]
|
| 331 |
|
| 332 |
+
# nearest neighbor interpolation
|
| 333 |
uv_map = (uv_map * texture_size).floor().long()
|
| 334 |
obs = observation[mask]
|
| 335 |
uv_map = uv_map[mask]
|
| 336 |
idx = uv_map[:, 0] + (texture_size - uv_map[:, 1] - 1) * texture_size
|
| 337 |
+
|
| 338 |
+
# Fix a bug that some indices are out of range
|
| 339 |
+
idx_mask = idx < texture_size * texture_size
|
| 340 |
+
idx = idx[idx_mask]
|
| 341 |
+
obs = obs[idx_mask]
|
| 342 |
texture = texture.scatter_add(0, idx.view(-1, 1).expand(-1, 3), obs)
|
| 343 |
texture_weights = texture_weights.scatter_add(0, idx, torch.ones((obs.shape[0]), dtype=torch.float32, device=texture.device))
|
| 344 |
+
|
| 345 |
mask = texture_weights > 0
|
| 346 |
texture[mask] /= texture_weights[mask][:, None]
|
| 347 |
texture = np.clip(texture.reshape(texture_size, texture_size, 3).cpu().numpy() * 255, 0, 255).astype(np.uint8)
|
|
|
|
| 412 |
fill_holes_max_size: float = 0.04,
|
| 413 |
texture_size: int = 1024,
|
| 414 |
debug: bool = False,
|
| 415 |
+
baking_mode: Literal['fast', 'opt'] = 'opt',
|
| 416 |
verbose: bool = True,
|
| 417 |
) -> trimesh.Trimesh:
|
| 418 |
"""
|
|
|
|
| 452 |
observations, extrinsics, intrinsics = render_multiview(app_rep, resolution=1024, nviews=100)
|
| 453 |
masks = [np.any(observation > 0, axis=-1) for observation in observations]
|
| 454 |
extrinsics = [extrinsics[i].cpu().numpy() for i in range(len(extrinsics))]
|
| 455 |
+
intrinsics = [intrinsics[i].cpu().numpy() for i in range(len(intrinsics))]
|
| 456 |
texture = bake_texture(
|
| 457 |
vertices, faces, uvs,
|
| 458 |
observations, masks, extrinsics, intrinsics,
|
| 459 |
+
texture_size=texture_size, mode=baking_mode,
|
| 460 |
lambda_tv=0.01,
|
| 461 |
verbose=verbose
|
| 462 |
)
|
| 463 |
+
texture = Image.fromarray(texture)
|
| 464 |
|
| 465 |
# rotate mesh (from z-up to y-up)
|
| 466 |
vertices = vertices @ np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
|
add_disk.py
CHANGED
|
@@ -212,13 +212,13 @@ class EditorApp:
|
|
| 212 |
print(f"Failed: {fg_path} -> {e}", file=sys.stderr)
|
| 213 |
fail += 1
|
| 214 |
|
| 215 |
-
messagebox.showinfo("Batch Done", f"Saved {ok} image(s) to {output_dir}
|
| 216 |
|
| 217 |
def main():
|
| 218 |
|
| 219 |
parser = argparse.ArgumentParser()
|
| 220 |
parser.add_argument('--disk_path', type=str, default='assets/disk.png')
|
| 221 |
-
parser.add_argument('--input_dir', type=str, default='examples/
|
| 222 |
args = parser.parse_args()
|
| 223 |
|
| 224 |
bg_path = args.disk_path
|
|
|
|
| 212 |
print(f"Failed: {fg_path} -> {e}", file=sys.stderr)
|
| 213 |
fail += 1
|
| 214 |
|
| 215 |
+
messagebox.showinfo("Batch Done", f"Saved {ok} image(s) to {output_dir}")
|
| 216 |
|
| 217 |
def main():
|
| 218 |
|
| 219 |
parser = argparse.ArgumentParser()
|
| 220 |
parser.add_argument('--disk_path', type=str, default='assets/disk.png')
|
| 221 |
+
parser.add_argument('--input_dir', type=str, default='examples/cabinet3_no_disk')
|
| 222 |
args = parser.parse_args()
|
| 223 |
|
| 224 |
bg_path = args.disk_path
|
app.py
CHANGED
|
@@ -1,89 +1,65 @@
|
|
| 1 |
import os
|
| 2 |
import shutil
|
| 3 |
-
import json
|
| 4 |
-
import numpy as np
|
| 5 |
-
import subprocess
|
| 6 |
import gradio as gr
|
| 7 |
import spaces
|
| 8 |
-
|
| 9 |
-
|
| 10 |
from gradio_litmodel3d import LitModel3D
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
from typing import *
|
| 12 |
from omegaconf import OmegaConf
|
| 13 |
|
| 14 |
-
LOCAL_RUN = True
|
| 15 |
-
if not LOCAL_RUN:
|
| 16 |
-
subprocess.run(["bash", "setup.sh"], check=True)
|
| 17 |
-
|
| 18 |
partnet_dir = f'datasets/PartNet'
|
| 19 |
real_world_dir = f'examples'
|
| 20 |
multi_joint_dir = f'datasets/multi_joint'
|
| 21 |
-
|
| 22 |
with open(f"configs/partnet.json") as f:
|
| 23 |
data_info = json.load(f)
|
| 24 |
-
cfg = OmegaConf.load('configs/default.yaml')
|
| 25 |
-
|
| 26 |
-
# Ensure datasets/PartNet is available when running on Spaces (or locally if missing)
|
| 27 |
-
def _ensure_partnet_dataset():
|
| 28 |
-
|
| 29 |
-
if os.path.isdir(partnet_dir) and len(os.listdir(partnet_dir)) > 0:
|
| 30 |
-
return
|
| 31 |
-
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 32 |
-
snapshot_download(
|
| 33 |
-
repo_id="MorPhLingXD/FreeArt3D",
|
| 34 |
-
repo_type="dataset",
|
| 35 |
-
local_dir="datasets",
|
| 36 |
-
token=HF_TOKEN,
|
| 37 |
-
)
|
| 38 |
-
|
| 39 |
-
_ensure_partnet_dataset()
|
| 40 |
|
| 41 |
labels = {
|
| 42 |
'Cabinet (real-world)': 'cabinet',
|
| 43 |
'Cabinet2 (real-world)': 'cabinet2',
|
| 44 |
-
'Box (
|
| 45 |
'Dishwasher (12614)': '12614',
|
| 46 |
-
'Laptop (
|
| 47 |
-
'Lighter (
|
| 48 |
-
'Microwave (
|
| 49 |
-
'Oven (
|
| 50 |
-
'Refrigerator (
|
| 51 |
-
'Safe (
|
| 52 |
-
'Stapler (
|
| 53 |
'StorageFurniture (47183)': '47183',
|
| 54 |
-
'Table (
|
| 55 |
-
'WashingMachine (
|
| 56 |
}
|
| 57 |
-
|
| 58 |
-
MAX_SEED = np.iinfo(np.int32).max
|
| 59 |
TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
|
| 60 |
os.makedirs(TMP_DIR, exist_ok=True)
|
| 61 |
-
|
| 62 |
-
def
|
| 63 |
-
return
|
| 64 |
-
|
| 65 |
-
def start_session(req: gr.Request):
|
| 66 |
-
user_dir = os.path.join(TMP_DIR, str(req.session_hash))
|
| 67 |
-
os.makedirs(user_dir, exist_ok=True)
|
| 68 |
|
| 69 |
def end_session(req: gr.Request):
|
| 70 |
-
|
| 71 |
-
shutil.rmtree(user_dir, ignore_errors=True)
|
| 72 |
|
| 73 |
def get_available_ids():
|
| 74 |
"""Get list of available object IDs for the dropdown"""
|
| 75 |
-
#
|
| 76 |
-
# # multi_joint_ids = [filename for filename in os.listdir(multi_joint_dir) if \
|
| 77 |
-
# # os.path.isdir(os.path.join(multi_joint_dir, filename))]
|
| 78 |
-
# partnet_mobility_ids = list(data_info['total_obj_ids'])
|
| 79 |
-
# # total_list = real_world_ids + multi_joint_ids + partnet_mobility_ids
|
| 80 |
-
# total_list = real_world_ids + partnet_mobility_ids # TODO: Support multi-joints
|
| 81 |
total_list = list(labels.keys())
|
| 82 |
return total_list
|
| 83 |
|
| 84 |
-
def load_renderings_with_id(id_input: str) -> Tuple[List[str], str]:
|
| 85 |
|
| 86 |
selected_id = labels[id_input]
|
|
|
|
|
|
|
|
|
|
| 87 |
rendering_paths = []
|
| 88 |
if 'cabinet' in selected_id:
|
| 89 |
base_dir = real_world_dir
|
|
@@ -91,6 +67,7 @@ def load_renderings_with_id(id_input: str) -> Tuple[List[str], str]:
|
|
| 91 |
base_dir = partnet_dir
|
| 92 |
else:
|
| 93 |
base_dir = multi_joint_dir
|
|
|
|
| 94 |
for i in range(cfg.train_num_state):
|
| 95 |
rendering_paths.append(f'{base_dir}/{selected_id}/{i:02d}_seg.png')
|
| 96 |
return rendering_paths, selected_id
|
|
@@ -100,6 +77,7 @@ def handle_mesh_upload(files):
|
|
| 100 |
if not files or len(files) == 0:
|
| 101 |
return gr.Dropdown(choices=[], value=None), None
|
| 102 |
choices = [f"Mesh State {i:02d} - {os.path.basename(file.name)}" for i, file in enumerate(files)]
|
|
|
|
| 103 |
return gr.Dropdown(choices=choices, value=choices[0] if choices else None), files[0].name
|
| 104 |
|
| 105 |
def switch_mesh_view(selected_file, files):
|
|
@@ -124,66 +102,118 @@ def switch_mesh_view(selected_file, files):
|
|
| 124 |
|
| 125 |
return None
|
| 126 |
|
| 127 |
-
def process_and_update_gallery(mesh_files,
|
| 128 |
mesh_paths = [f.name for f in mesh_files] if mesh_files else []
|
| 129 |
cfg.train_num_state = len(mesh_paths)
|
| 130 |
-
|
| 131 |
-
rendering_paths = run_rendering(mesh_paths, output_dir=TMP_DIR)
|
| 132 |
-
# rendering_paths is assumed to be a list of image file paths
|
| 133 |
-
if not rendering_paths:
|
| 134 |
-
return current_gallery or []
|
| 135 |
-
if current_gallery:
|
| 136 |
-
return current_gallery + rendering_paths
|
| 137 |
return rendering_paths
|
| 138 |
|
| 139 |
-
def
|
| 140 |
-
"""
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
except Exception:
|
| 146 |
-
session_dir = os.path.join(TMP_DIR, 'uploaded_images')
|
| 147 |
-
os.makedirs(session_dir, exist_ok=True)
|
| 148 |
-
|
| 149 |
-
normalized_items = []
|
| 150 |
-
if not gallery_value:
|
| 151 |
-
return []
|
| 152 |
-
|
| 153 |
-
for idx, item in enumerate(gallery_value):
|
| 154 |
-
candidate = item
|
| 155 |
-
if isinstance(item, (list, tuple)) and len(item) > 0:
|
| 156 |
-
candidate = item[0]
|
| 157 |
-
|
| 158 |
-
saved_path = None
|
| 159 |
-
if isinstance(candidate, str) and os.path.exists(candidate):
|
| 160 |
-
# Copy to per-session folder for stability and cache isolation
|
| 161 |
-
base = os.path.basename(candidate)
|
| 162 |
-
stem, ext = os.path.splitext(base)
|
| 163 |
-
dest = os.path.join(session_dir, f"{stem}_{idx:02d}{ext or '.png'}")
|
| 164 |
try:
|
| 165 |
-
|
| 166 |
-
shutil.copy(candidate, dest)
|
| 167 |
-
else:
|
| 168 |
-
dest = candidate
|
| 169 |
-
saved_path = dest
|
| 170 |
except Exception:
|
| 171 |
-
|
| 172 |
-
else
|
| 173 |
-
# Unrecognized type; keep as-is
|
| 174 |
-
saved_path = None
|
| 175 |
-
|
| 176 |
-
if saved_path is not None:
|
| 177 |
-
normalized_items.append([saved_path, None])
|
| 178 |
-
else:
|
| 179 |
-
normalized_items.append(item)
|
| 180 |
|
| 181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
|
| 183 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
"""Persist gallery images into outputs/<selected_id>/renderings with SDS-expected names.
|
| 185 |
Ensures there are cfg.train_num_state frames by padding with the last image if needed.
|
| 186 |
-
Also writes the required '
|
| 187 |
"""
|
| 188 |
try:
|
| 189 |
image_paths = []
|
|
@@ -196,160 +226,50 @@ def save_gallery_to_renderings(gallery_value, selected_id):
|
|
| 196 |
return
|
| 197 |
|
| 198 |
cfg.train_num_state = len(image_paths)
|
| 199 |
-
base_dir = f'outputs/{selected_id}'
|
| 200 |
if "uploaded" in base_dir:
|
| 201 |
os.system(f"rm -rf {base_dir}/*")
|
|
|
|
| 202 |
rendering_dir = f'{base_dir}/renderings'
|
| 203 |
os.makedirs(rendering_dir, exist_ok=True)
|
| 204 |
|
| 205 |
# Normalize count to T frames
|
| 206 |
for i in range(cfg.train_num_state):
|
| 207 |
src = image_paths[i] if i < len(image_paths) else image_paths[-1]
|
| 208 |
-
dst = f'{rendering_dir}/
|
| 209 |
shutil.copy(src, dst)
|
| 210 |
|
| 211 |
# Write the 'pure' image as the last uploaded (or last padded) frame
|
| 212 |
-
|
| 213 |
-
|
|
|
|
|
|
|
|
|
|
| 214 |
shutil.copy(pure_src, pure_dst)
|
| 215 |
except Exception as e:
|
| 216 |
print(f"[Gallery->Renderings] Failed to persist images: {e}")
|
| 217 |
return
|
| 218 |
|
| 219 |
-
@spaces.GPU(duration=
|
| 220 |
-
def
|
|
|
|
|
|
|
|
|
|
| 221 |
# Carefully extract file paths from Gradio Gallery elements, which may be dicts, file objects, or strings.
|
| 222 |
image_paths = [img[0] for img in input_image_gallery]
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
return recon_voxel_paths, recon_mesh_paths
|
| 226 |
-
|
| 227 |
-
@spaces.GPU(duration=
|
| 228 |
-
def estimate_initial_joints(input_image_gallery,
|
| 229 |
-
image_paths = [img[0] for img in input_image_gallery]
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
else:
|
| 233 |
-
joint_type = 'prismatic' if (selected_id in data_info['prismatic']['obj_ids']) else 'revolute'
|
| 234 |
-
from pipelines.estimate import run_estimate
|
| 235 |
-
matching_examples, info_dict = run_estimate(image_paths, output_dir=f"outputs/{selected_id}",
|
| 236 |
-
joint_type=joint_type)
|
| 237 |
return matching_examples, info_dict
|
| 238 |
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
def to_str(v):
|
| 242 |
-
if isinstance(v, np.ndarray):
|
| 243 |
-
v = v.tolist()
|
| 244 |
-
if isinstance(v, (list, dict, tuple)):
|
| 245 |
-
try:
|
| 246 |
-
return json.dumps(v)
|
| 247 |
-
except Exception:
|
| 248 |
-
return str(v)
|
| 249 |
-
return "" if v is None else str(v)
|
| 250 |
-
|
| 251 |
-
# Extract axis components
|
| 252 |
-
axis_val = info_dict.get("joint_axis", "")
|
| 253 |
-
if isinstance(axis_val, np.ndarray):
|
| 254 |
-
axis_val = axis_val.tolist()
|
| 255 |
-
if isinstance(axis_val, (list, tuple)) and len(axis_val) >= 3:
|
| 256 |
-
ax_x, ax_y, ax_z = axis_val[0], axis_val[1], axis_val[2]
|
| 257 |
-
else:
|
| 258 |
-
ax_x = ax_y = ax_z = ""
|
| 259 |
-
ax_x_str = to_str(ax_x)
|
| 260 |
-
ax_y_str = to_str(ax_y)
|
| 261 |
-
ax_z_str = to_str(ax_z)
|
| 262 |
-
|
| 263 |
-
# Extract position components
|
| 264 |
-
pos_val = info_dict.get("joint_position", "")
|
| 265 |
-
if isinstance(pos_val, np.ndarray):
|
| 266 |
-
pos_val = pos_val.tolist()
|
| 267 |
-
if isinstance(pos_val, (list, tuple)) and len(pos_val) >= 3:
|
| 268 |
-
px, py, pz = pos_val[0], pos_val[1], pos_val[2]
|
| 269 |
-
else:
|
| 270 |
-
px = py = pz = ""
|
| 271 |
-
px_str = to_str(px)
|
| 272 |
-
py_str = to_str(py)
|
| 273 |
-
pz_str = to_str(pz)
|
| 274 |
-
|
| 275 |
-
# Extract scalar scale value for slider
|
| 276 |
-
scale_val = -info_dict.get("joint_scale", 1.0)
|
| 277 |
-
qpos_str = to_str(info_dict.get("joint_qpos", ""))
|
| 278 |
-
|
| 279 |
-
return (
|
| 280 |
-
ax_x_str,
|
| 281 |
-
ax_y_str,
|
| 282 |
-
ax_z_str,
|
| 283 |
-
px_str,
|
| 284 |
-
py_str,
|
| 285 |
-
pz_str,
|
| 286 |
-
scale_val,
|
| 287 |
-
qpos_str,
|
| 288 |
-
)
|
| 289 |
-
|
| 290 |
-
def fields_to_meta_ui(
|
| 291 |
-
axis_x: str,
|
| 292 |
-
axis_y: str,
|
| 293 |
-
axis_z: str,
|
| 294 |
-
pos_x: str,
|
| 295 |
-
pos_y: str,
|
| 296 |
-
pos_z: str,
|
| 297 |
-
scale_value: float,
|
| 298 |
-
joint_qpos: str,
|
| 299 |
-
):
|
| 300 |
-
"""Convert new UI fields (x/y/z textboxes, slider) to meta info dict."""
|
| 301 |
-
def parse_float(text: Any):
|
| 302 |
-
try:
|
| 303 |
-
return float(text)
|
| 304 |
-
except Exception:
|
| 305 |
-
return None
|
| 306 |
-
|
| 307 |
-
def parse_val(text: str):
|
| 308 |
-
if text is None:
|
| 309 |
-
return ""
|
| 310 |
-
t = str(text).strip()
|
| 311 |
-
if t == "":
|
| 312 |
-
return ""
|
| 313 |
-
try:
|
| 314 |
-
return json.loads(t)
|
| 315 |
-
except Exception:
|
| 316 |
-
if "," in t:
|
| 317 |
-
parts = [p.strip() for p in t.split(",")]
|
| 318 |
-
try:
|
| 319 |
-
return [float(p) for p in parts]
|
| 320 |
-
except Exception:
|
| 321 |
-
return parts
|
| 322 |
-
try:
|
| 323 |
-
return float(t)
|
| 324 |
-
except Exception:
|
| 325 |
-
return t
|
| 326 |
-
|
| 327 |
-
axis_vals = [parse_float(axis_x), parse_float(axis_y), parse_float(axis_z)]
|
| 328 |
-
if all(v is not None for v in axis_vals):
|
| 329 |
-
joint_axis = axis_vals
|
| 330 |
-
else:
|
| 331 |
-
joint_axis = ""
|
| 332 |
-
|
| 333 |
-
pos_vals = [parse_float(pos_x), parse_float(pos_y), parse_float(pos_z)]
|
| 334 |
-
if all(v is not None for v in pos_vals):
|
| 335 |
-
joint_position = pos_vals
|
| 336 |
-
else:
|
| 337 |
-
joint_position = ""
|
| 338 |
-
|
| 339 |
-
try:
|
| 340 |
-
joint_scale = -float(scale_value)
|
| 341 |
-
except Exception:
|
| 342 |
-
joint_scale = -1.0
|
| 343 |
-
|
| 344 |
-
return {
|
| 345 |
-
"joint_axis": joint_axis,
|
| 346 |
-
"joint_position": joint_position,
|
| 347 |
-
"joint_scale": joint_scale,
|
| 348 |
-
"joint_qpos": parse_val(joint_qpos),
|
| 349 |
-
}
|
| 350 |
-
|
| 351 |
-
@spaces.GPU(duration=600)
|
| 352 |
-
def articulated_generation_sds(selected_id):
|
| 353 |
|
| 354 |
if 'cabinet' in selected_id:
|
| 355 |
input_dir = real_world_dir
|
|
@@ -358,19 +278,122 @@ def articulated_generation_sds(selected_id):
|
|
| 358 |
else:
|
| 359 |
input_dir = multi_joint_dir
|
| 360 |
|
| 361 |
-
base_dir = f'outputs/{selected_id}'
|
| 362 |
rendering_dir = f'{base_dir}/renderings'
|
| 363 |
|
| 364 |
os.makedirs(rendering_dir, exist_ok=True)
|
| 365 |
if os.path.exists(f'{input_dir}/{selected_id}/05_seg.png'):
|
| 366 |
for i in range(6):
|
| 367 |
-
shutil.copy(f'{input_dir}/{selected_id}/{i:02d}_seg.png', f'{rendering_dir}/
|
| 368 |
-
shutil.copy(f'{input_dir}/{selected_id}/05_pure.png', f'{rendering_dir}/
|
| 369 |
-
|
| 370 |
-
from pipelines.sds import run_sds
|
| 371 |
full_mesh, fixed_part, articulated_part = run_sds(base_dir, 1, cfg)
|
| 372 |
return full_mesh, fixed_part, articulated_part
|
| 373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
with gr.Blocks(delete_cache=(600, 600), css="""
|
| 375 |
.gallery-container {
|
| 376 |
overflow-x: auto !important;
|
|
@@ -416,22 +439,25 @@ with gr.Blocks(delete_cache=(600, 600), css="""
|
|
| 416 |
gr.Markdown("""
|
| 417 |
## FreeArt3D Demo
|
| 418 |
### You can use the following three methods to generate articulated 3D models.
|
| 419 |
-
1. Choose
|
| 420 |
-
2. Upload multiple mesh files (e.g., .obj, .ply, .stl, .glb, .gltf)
|
| 421 |
-
3. Upload multiple input images
|
|
|
|
|
|
|
|
|
|
| 422 |
""")
|
| 423 |
|
| 424 |
with gr.Row(equal_height=True):
|
| 425 |
-
with gr.Tab("Load by
|
| 426 |
with gr.Row():
|
| 427 |
id_input = gr.Dropdown(
|
| 428 |
choices=get_available_ids(),
|
| 429 |
-
value='
|
| 430 |
-
label="
|
| 431 |
-
info='Select a real-world object
|
| 432 |
)
|
| 433 |
with gr.Row():
|
| 434 |
-
id_input_btn = gr.Button("
|
| 435 |
with gr.Tab("Upload Mesh Files"):
|
| 436 |
with gr.Row(equal_height=True):
|
| 437 |
with gr.Column():
|
|
@@ -440,25 +466,32 @@ with gr.Blocks(delete_cache=(600, 600), css="""
|
|
| 440 |
with gr.Column():
|
| 441 |
mesh_viewer = LitModel3D(label="Selected Mesh", exposure=10.0, height=300)
|
| 442 |
with gr.Row():
|
| 443 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
|
| 445 |
with gr.Row(equal_height=True):
|
| 446 |
with gr.Column():
|
| 447 |
-
input_image_gallery = gr.Gallery(label="Input Images", show_label=True, elem_id="gallery", height=300, columns=3, allow_preview=True, elem_classes=["gallery-container"])
|
| 448 |
-
input_image_confirm_btn = gr.Button("Confirm Images", variant="secondary")
|
| 449 |
with gr.Column():
|
| 450 |
-
voxel_gallery = gr.Gallery(label="Reconstructed Voxels", show_label=True, elem_id="gallery", height=360,
|
| 451 |
with gr.Column():
|
| 452 |
-
recon_mesh_gallery = gr.Gallery(label="Reconstructed Meshes", show_label=True, elem_id="gallery", height=360,
|
| 453 |
-
|
| 454 |
-
with gr.Row():
|
| 455 |
-
joint_type_in = gr.Dropdown(label="joint_type", choices=["revolute", "prismatic"], value=None)
|
| 456 |
-
|
| 457 |
-
with gr.Row():
|
| 458 |
-
estimate_btn = gr.Button("Estimate Initial Joints", variant="secondary")
|
| 459 |
-
|
| 460 |
with gr.Row():
|
| 461 |
-
matching_examples = gr.Gallery(label="
|
| 462 |
|
| 463 |
with gr.Row():
|
| 464 |
meta_info = gr.State(
|
|
@@ -470,54 +503,98 @@ with gr.Blocks(delete_cache=(600, 600), css="""
|
|
| 470 |
}
|
| 471 |
)
|
| 472 |
with gr.Accordion("Joint Information", open=True):
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
axis_z_in = gr.Textbox(label="Joint Axis Z", placeholder="", interactive=False)
|
| 477 |
-
with gr.Row():
|
| 478 |
-
pos_x_in = gr.Textbox(label="Joint Pivot X", placeholder="", interactive=False)
|
| 479 |
-
pos_y_in = gr.Textbox(label="Joint Pivot Y", placeholder="", interactive=False)
|
| 480 |
-
pos_z_in = gr.Textbox(label="Joint Pivot Z", placeholder="", interactive=False)
|
| 481 |
-
joint_scale_in = gr.Slider(label="Max Scale", minimum=0.0, maximum=5.0, step=0.01, value=1.0, interactive=False)
|
| 482 |
-
joint_qpos_in = gr.Textbox(label="qpos", placeholder="", interactive=False)
|
| 483 |
-
|
| 484 |
-
with gr.Row():
|
| 485 |
-
sds_btn = gr.Button("Generate Articulated Object", variant="primary")
|
| 486 |
-
|
| 487 |
-
with gr.Row():
|
| 488 |
with gr.Column():
|
| 489 |
full_mesh = LitModel3D(label="Full Mesh", exposure=10.0, height=300)
|
| 490 |
with gr.Column():
|
| 491 |
fixed_part = LitModel3D(label="Fixed Part", exposure=10.0, height=300)
|
| 492 |
with gr.Column():
|
| 493 |
articulated_part = LitModel3D(label="Articulated Part", exposure=10.0, height=300)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 494 |
|
| 495 |
-
|
| 496 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
|
| 498 |
# Handlers
|
| 499 |
-
demo.load(start_session)
|
| 500 |
demo.unload(end_session)
|
| 501 |
-
|
| 502 |
id_input_btn.click(
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 506 |
)
|
| 507 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
# Handle mesh file uploads
|
| 509 |
mesh_files.change(
|
| 510 |
handle_mesh_upload,
|
| 511 |
inputs=mesh_files,
|
| 512 |
outputs=[mesh_selector, mesh_viewer]
|
| 513 |
)
|
| 514 |
-
|
| 515 |
-
# Set flag to 'uploaded' when uploading files
|
| 516 |
-
mesh_files.change(
|
| 517 |
-
lambda *_: "uploaded",
|
| 518 |
-
inputs=None,
|
| 519 |
-
outputs=mesh_source_flag
|
| 520 |
-
)
|
| 521 |
|
| 522 |
# Handle dropdown selection for mesh view
|
| 523 |
mesh_selector.change(
|
|
@@ -526,75 +603,12 @@ with gr.Blocks(delete_cache=(600, 600), css="""
|
|
| 526 |
outputs=mesh_viewer
|
| 527 |
)
|
| 528 |
|
| 529 |
-
# Handle Process button click
|
| 530 |
-
mesh_processing_btn.click(
|
| 531 |
-
process_and_update_gallery,
|
| 532 |
-
inputs=[mesh_files, mesh_source_flag, input_image_gallery],
|
| 533 |
-
outputs=input_image_gallery
|
| 534 |
-
)
|
| 535 |
-
|
| 536 |
# Ensure downstream uses the generic 'uploaded' namespace for output paths
|
| 537 |
-
|
| 538 |
lambda *_: "uploaded",
|
| 539 |
inputs=None,
|
| 540 |
outputs=selected_id_state
|
| 541 |
)
|
| 542 |
-
|
| 543 |
-
input_image_confirm_btn.click(
|
| 544 |
-
save_gallery_to_renderings,
|
| 545 |
-
inputs=[input_image_gallery, selected_id_state],
|
| 546 |
-
outputs=None
|
| 547 |
-
).then(
|
| 548 |
-
recon_trellis_meshes,
|
| 549 |
-
inputs=[input_image_gallery, selected_id_state],
|
| 550 |
-
outputs=[voxel_gallery, recon_mesh_gallery]
|
| 551 |
-
)
|
| 552 |
-
|
| 553 |
-
estimate_btn.click(
|
| 554 |
-
estimate_initial_joints,
|
| 555 |
-
inputs=[input_image_gallery, selected_id_state, joint_type_in],
|
| 556 |
-
outputs=[matching_examples, meta_info]
|
| 557 |
-
).then(
|
| 558 |
-
meta_to_fields_ui,
|
| 559 |
-
inputs=meta_info,
|
| 560 |
-
outputs=[
|
| 561 |
-
axis_x_in,
|
| 562 |
-
axis_y_in,
|
| 563 |
-
axis_z_in,
|
| 564 |
-
pos_x_in,
|
| 565 |
-
pos_y_in,
|
| 566 |
-
pos_z_in,
|
| 567 |
-
joint_scale_in,
|
| 568 |
-
joint_qpos_in
|
| 569 |
-
]
|
| 570 |
-
).then(
|
| 571 |
-
lambda x: x,
|
| 572 |
-
inputs=meta_info,
|
| 573 |
-
outputs=meta_info
|
| 574 |
-
)
|
| 575 |
-
|
| 576 |
-
sds_btn.click(
|
| 577 |
-
fields_to_meta_ui,
|
| 578 |
-
inputs=[
|
| 579 |
-
axis_x_in,
|
| 580 |
-
axis_y_in,
|
| 581 |
-
axis_z_in,
|
| 582 |
-
pos_x_in,
|
| 583 |
-
pos_y_in,
|
| 584 |
-
pos_z_in,
|
| 585 |
-
joint_scale_in,
|
| 586 |
-
joint_qpos_in,
|
| 587 |
-
],
|
| 588 |
-
outputs=meta_info
|
| 589 |
-
).then(
|
| 590 |
-
_clear_3d,
|
| 591 |
-
inputs=None,
|
| 592 |
-
outputs=[full_mesh, fixed_part, articulated_part]
|
| 593 |
-
).then(
|
| 594 |
-
articulated_generation_sds,
|
| 595 |
-
inputs=selected_id_state,
|
| 596 |
-
outputs=[full_mesh, fixed_part, articulated_part]
|
| 597 |
-
)
|
| 598 |
|
| 599 |
# Launch the Gradio app
|
| 600 |
if __name__ == "__main__":
|
|
|
|
| 1 |
import os
|
| 2 |
import shutil
|
| 3 |
+
import json
|
| 4 |
+
import numpy as np
|
|
|
|
| 5 |
import gradio as gr
|
| 6 |
import spaces
|
| 7 |
+
import time
|
| 8 |
+
|
| 9 |
from gradio_litmodel3d import LitModel3D
|
| 10 |
+
from pipelines.render import run_rendering
|
| 11 |
+
from pipelines.recon import run_recon
|
| 12 |
+
from pipelines.estimate import run_estimate
|
| 13 |
+
from pipelines.sds import run_sds
|
| 14 |
from typing import *
|
| 15 |
from omegaconf import OmegaConf
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
partnet_dir = f'datasets/PartNet'
|
| 18 |
real_world_dir = f'examples'
|
| 19 |
multi_joint_dir = f'datasets/multi_joint'
|
| 20 |
+
|
| 21 |
with open(f"configs/partnet.json") as f:
|
| 22 |
data_info = json.load(f)
|
| 23 |
+
cfg = OmegaConf.load('configs/default.yaml')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
labels = {
|
| 26 |
'Cabinet (real-world)': 'cabinet',
|
| 27 |
'Cabinet2 (real-world)': 'cabinet2',
|
| 28 |
+
'Box (100247)': '100247',
|
| 29 |
'Dishwasher (12614)': '12614',
|
| 30 |
+
'Laptop (10270)': '10270',
|
| 31 |
+
'Lighter (100309)': '100309',
|
| 32 |
+
'Microwave (7320)': '7320',
|
| 33 |
+
'Oven (102001)': '102001',
|
| 34 |
+
'Refrigerator (11231)': '11231',
|
| 35 |
+
'Safe (102301)': '102301',
|
| 36 |
+
'Stapler (103111)': '103111',
|
| 37 |
'StorageFurniture (47183)': '47183',
|
| 38 |
+
'Table (20411)': '20411',
|
| 39 |
+
'WashingMachine (100283)': '100283',
|
| 40 |
}
|
| 41 |
+
|
|
|
|
| 42 |
TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
|
| 43 |
os.makedirs(TMP_DIR, exist_ok=True)
|
| 44 |
+
|
| 45 |
+
def start_session(req: gr.Request):
|
| 46 |
+
return req.session_hash
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
def end_session(req: gr.Request):
|
| 49 |
+
pass
|
|
|
|
| 50 |
|
| 51 |
def get_available_ids():
|
| 52 |
"""Get list of available object IDs for the dropdown"""
|
| 53 |
+
# TODO: Support multi-joints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
total_list = list(labels.keys())
|
| 55 |
return total_list
|
| 56 |
|
| 57 |
+
def load_renderings_with_id(id_input: str, session_hash: str) -> Tuple[List[str], str]:
|
| 58 |
|
| 59 |
selected_id = labels[id_input]
|
| 60 |
+
print(f'[Selected Object] {selected_id}')
|
| 61 |
+
cfg.train_num_state = 6
|
| 62 |
+
|
| 63 |
rendering_paths = []
|
| 64 |
if 'cabinet' in selected_id:
|
| 65 |
base_dir = real_world_dir
|
|
|
|
| 67 |
base_dir = partnet_dir
|
| 68 |
else:
|
| 69 |
base_dir = multi_joint_dir
|
| 70 |
+
|
| 71 |
for i in range(cfg.train_num_state):
|
| 72 |
rendering_paths.append(f'{base_dir}/{selected_id}/{i:02d}_seg.png')
|
| 73 |
return rendering_paths, selected_id
|
|
|
|
| 77 |
if not files or len(files) == 0:
|
| 78 |
return gr.Dropdown(choices=[], value=None), None
|
| 79 |
choices = [f"Mesh State {i:02d} - {os.path.basename(file.name)}" for i, file in enumerate(files)]
|
| 80 |
+
# yield gr.update(), gr.update(None)
|
| 81 |
return gr.Dropdown(choices=choices, value=choices[0] if choices else None), files[0].name
|
| 82 |
|
| 83 |
def switch_mesh_view(selected_file, files):
|
|
|
|
| 102 |
|
| 103 |
return None
|
| 104 |
|
| 105 |
+
def process_and_update_gallery(mesh_files, session_hash):
|
| 106 |
mesh_paths = [f.name for f in mesh_files] if mesh_files else []
|
| 107 |
cfg.train_num_state = len(mesh_paths)
|
| 108 |
+
rendering_paths = run_rendering(mesh_paths, output_dir=f'{TMP_DIR}/{session_hash}')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
return rendering_paths
|
| 110 |
|
| 111 |
+
def format_meta_info_text(info_dict):
|
| 112 |
+
"""Format joint meta info into 4 rich-text lines (larger font; bold title for Joint Axis)."""
|
| 113 |
+
def to_str(v):
|
| 114 |
+
if isinstance(v, np.ndarray):
|
| 115 |
+
v = v.tolist()
|
| 116 |
+
if isinstance(v, (list, dict, tuple)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
try:
|
| 118 |
+
return json.dumps(v)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
except Exception:
|
| 120 |
+
return str(v)
|
| 121 |
+
return "" if v is None else str(v)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
|
| 123 |
+
axis_val = info_dict.get("joint_axis", "")
|
| 124 |
+
pos_val = info_dict.get("joint_position", "")
|
| 125 |
+
scale_val = info_dict.get("joint_scale", "")
|
| 126 |
+
qpos_val = info_dict.get("joint_qpos", "")
|
| 127 |
+
|
| 128 |
+
axis_str = to_str(axis_val)
|
| 129 |
+
pos_str = to_str(pos_val)
|
| 130 |
+
scale_str = to_str(-scale_val)
|
| 131 |
+
qpos_str = to_str(qpos_val)
|
| 132 |
+
|
| 133 |
+
# Use inline HTML for size and emphasis; rendered by gr.Markdown
|
| 134 |
+
return (
|
| 135 |
+
"<div style=\"font-size: 18px; line-height: 1.5;\">"
|
| 136 |
+
f"<div><strong>Joint Axis:</strong> {axis_str}</div>"
|
| 137 |
+
f"<div><strong>Joint Pivot:</strong> {pos_str}</div>"
|
| 138 |
+
f"<div><strong>Max Scale:</strong> {scale_str}</div>"
|
| 139 |
+
f"<div><strong>qpos:</strong> {qpos_str}</div>"
|
| 140 |
+
"</div>"
|
| 141 |
+
)
|
| 142 |
|
| 143 |
+
def image_gallery_state_change(p_state):
|
| 144 |
+
base_dir = f'outputs/{p_state.get("sel_id")}_{p_state.get("session_hash")}'
|
| 145 |
+
if p_state.get("step") == "running":
|
| 146 |
+
while True:
|
| 147 |
+
with open(f'{base_dir}/state_list.json', 'r') as f:
|
| 148 |
+
state_list = json.load(f)
|
| 149 |
+
if state_list[0] == "done":
|
| 150 |
+
break
|
| 151 |
+
time.sleep(0.5)
|
| 152 |
+
return gr.update(), gr.update(), \
|
| 153 |
+
gr.update(), gr.update(), \
|
| 154 |
+
gr.update(), gr.update(), \
|
| 155 |
+
gr.update(), gr.update(), gr.update(), \
|
| 156 |
+
gr.update(), gr.update(), gr.update()
|
| 157 |
+
if p_state.get("step") == "done":
|
| 158 |
+
return p_state.get("gallery", gr.update()), p_state.get("sel_id", gr.update()), \
|
| 159 |
+
p_state.get("cached_path", gr.update())[0], \
|
| 160 |
+
p_state.get("cached_path", gr.update())[1], \
|
| 161 |
+
p_state.get("cached_path", gr.update())[2], \
|
| 162 |
+
gr.update(value=None), gr.update(value=None), \
|
| 163 |
+
gr.update(value=None), gr.update(value=None), \
|
| 164 |
+
gr.update(value=None), gr.update(value=None), gr.update(value=None)
|
| 165 |
+
return gr.update(), gr.update(), \
|
| 166 |
+
gr.update(), gr.update(), \
|
| 167 |
+
gr.update(), gr.update(), \
|
| 168 |
+
gr.update(), gr.update(), gr.update(), \
|
| 169 |
+
gr.update(), gr.update(), gr.update()
|
| 170 |
+
|
| 171 |
+
def recon_state_change(p_state):
|
| 172 |
+
base_dir = f'outputs/{p_state.get("sel_id")}_{p_state.get("session_hash")}'
|
| 173 |
+
if p_state.get("step") == "running":
|
| 174 |
+
while True:
|
| 175 |
+
with open(f'{base_dir}/state_list.json', 'r') as f:
|
| 176 |
+
state_list = json.load(f)
|
| 177 |
+
if state_list[1] == "done":
|
| 178 |
+
break
|
| 179 |
+
time.sleep(0.5)
|
| 180 |
+
return gr.update(), gr.update()
|
| 181 |
+
if p_state.get("step") == "done":
|
| 182 |
+
return p_state.get("vox", gr.update()), p_state.get("recon", gr.update())
|
| 183 |
+
return gr.update(), gr.update()
|
| 184 |
+
|
| 185 |
+
def estimate_state_change(p_state):
|
| 186 |
+
base_dir = f'outputs/{p_state.get("sel_id")}_{p_state.get("session_hash")}'
|
| 187 |
+
if p_state.get("step") == "running":
|
| 188 |
+
while True:
|
| 189 |
+
with open(f'{base_dir}/state_list.json', 'r') as f:
|
| 190 |
+
state_list = json.load(f)
|
| 191 |
+
if state_list[2] == "done":
|
| 192 |
+
break
|
| 193 |
+
time.sleep(0.5)
|
| 194 |
+
return gr.update(), gr.update()
|
| 195 |
+
if p_state.get("step") == "done":
|
| 196 |
+
return p_state.get("match", gr.update()), p_state.get("html", gr.update())
|
| 197 |
+
return gr.update(), gr.update()
|
| 198 |
+
|
| 199 |
+
def sds_state_change(p_state):
|
| 200 |
+
base_dir = f'outputs/{p_state.get("sel_id")}_{p_state.get("session_hash")}'
|
| 201 |
+
if p_state.get("step") == "running":
|
| 202 |
+
while True:
|
| 203 |
+
with open(f'{base_dir}/state_list.json', 'r') as f:
|
| 204 |
+
state_list = json.load(f)
|
| 205 |
+
if state_list[3] == "done":
|
| 206 |
+
break
|
| 207 |
+
time.sleep(0.5)
|
| 208 |
+
return gr.update(), gr.update(), gr.update()
|
| 209 |
+
if p_state.get("step") == "done":
|
| 210 |
+
return p_state.get("full", gr.update()), p_state.get("fixed", gr.update()), p_state.get("art", gr.update())
|
| 211 |
+
return gr.update(), gr.update(), gr.update()
|
| 212 |
+
|
| 213 |
+
def save_gallery_to_renderings(gallery_value, selected_id, session_hash):
|
| 214 |
"""Persist gallery images into outputs/<selected_id>/renderings with SDS-expected names.
|
| 215 |
Ensures there are cfg.train_num_state frames by padding with the last image if needed.
|
| 216 |
+
Also writes the required 'rendering_pure_joint_00_state_{T-1}.png' using the last frame.
|
| 217 |
"""
|
| 218 |
try:
|
| 219 |
image_paths = []
|
|
|
|
| 226 |
return
|
| 227 |
|
| 228 |
cfg.train_num_state = len(image_paths)
|
| 229 |
+
base_dir = f'outputs/{selected_id}_{session_hash}'
|
| 230 |
if "uploaded" in base_dir:
|
| 231 |
os.system(f"rm -rf {base_dir}/*")
|
| 232 |
+
|
| 233 |
rendering_dir = f'{base_dir}/renderings'
|
| 234 |
os.makedirs(rendering_dir, exist_ok=True)
|
| 235 |
|
| 236 |
# Normalize count to T frames
|
| 237 |
for i in range(cfg.train_num_state):
|
| 238 |
src = image_paths[i] if i < len(image_paths) else image_paths[-1]
|
| 239 |
+
dst = f'{rendering_dir}/rendering_joint_00_state_{i:02d}.png'
|
| 240 |
shutil.copy(src, dst)
|
| 241 |
|
| 242 |
# Write the 'pure' image as the last uploaded (or last padded) frame
|
| 243 |
+
if os.path.exists(image_paths[-1].replace('_seg.png', '_pure.png')):
|
| 244 |
+
pure_src = image_paths[-1].replace('_seg.png', '_pure.png')
|
| 245 |
+
else:
|
| 246 |
+
pure_src = image_paths[-1]
|
| 247 |
+
pure_dst = f'{rendering_dir}/rendering_pure_joint_00_state_{(cfg.train_num_state - 1):02d}.png'
|
| 248 |
shutil.copy(pure_src, pure_dst)
|
| 249 |
except Exception as e:
|
| 250 |
print(f"[Gallery->Renderings] Failed to persist images: {e}")
|
| 251 |
return
|
| 252 |
|
| 253 |
+
@spaces.GPU(duration=200)
|
| 254 |
+
def run_recon_trellis(image_paths, output_dir):
|
| 255 |
+
return run_recon(image_paths, output_dir=output_dir, app=True)
|
| 256 |
+
|
| 257 |
+
def recon_trellis_meshes(input_image_gallery, output_dir):
|
| 258 |
# Carefully extract file paths from Gradio Gallery elements, which may be dicts, file objects, or strings.
|
| 259 |
image_paths = [img[0] for img in input_image_gallery]
|
| 260 |
+
glb_paths, rendering_dir, recon_voxel_paths = run_recon_trellis(image_paths, output_dir=output_dir)
|
| 261 |
+
recon_mesh_paths = run_rendering(glb_paths, rendering_dir, recon=True)
|
| 262 |
+
return recon_voxel_paths, recon_mesh_paths
|
| 263 |
+
|
| 264 |
+
@spaces.GPU(duration=120)
|
| 265 |
+
def estimate_initial_joints(input_image_gallery, joint_type, output_dir):
|
| 266 |
+
image_paths = [img[0] for img in input_image_gallery]
|
| 267 |
+
print(image_paths)
|
| 268 |
+
matching_examples, info_dict = run_estimate(image_paths, output_dir=output_dir, cfg=cfg, joint_type=joint_type)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
return matching_examples, info_dict
|
| 270 |
|
| 271 |
+
@spaces.GPU(duration=800)
|
| 272 |
+
def articulated_generation_sds(selected_id, session_hash):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
|
| 274 |
if 'cabinet' in selected_id:
|
| 275 |
input_dir = real_world_dir
|
|
|
|
| 278 |
else:
|
| 279 |
input_dir = multi_joint_dir
|
| 280 |
|
| 281 |
+
base_dir = f'outputs/{selected_id}_{session_hash}'
|
| 282 |
rendering_dir = f'{base_dir}/renderings'
|
| 283 |
|
| 284 |
os.makedirs(rendering_dir, exist_ok=True)
|
| 285 |
if os.path.exists(f'{input_dir}/{selected_id}/05_seg.png'):
|
| 286 |
for i in range(6):
|
| 287 |
+
shutil.copy(f'{input_dir}/{selected_id}/{i:02d}_seg.png', f'{rendering_dir}/rendering_joint_00_state_{i:02d}.png')
|
| 288 |
+
shutil.copy(f'{input_dir}/{selected_id}/05_pure.png', f'{rendering_dir}/rendering_pure_joint_00_state_05.png')
|
| 289 |
+
|
|
|
|
| 290 |
full_mesh, fixed_part, articulated_part = run_sds(base_dir, 1, cfg)
|
| 291 |
return full_mesh, fixed_part, articulated_part
|
| 292 |
|
| 293 |
+
def pipeline(id_value, mesh_files, uploaded_image_gallery, joint_type_in, session_hash, run_idx):
|
| 294 |
+
"""Server-side pipeline that yields state only; UI updates are applied via a mapper."""
|
| 295 |
+
|
| 296 |
+
# 1) Prepare inputs
|
| 297 |
+
if id_value is not None:
|
| 298 |
+
sel_id = f"{labels[id_value]}_{run_idx:02d}"
|
| 299 |
+
elif mesh_files is not None:
|
| 300 |
+
sel_id = f"mesh_uploading_{run_idx:02d}"
|
| 301 |
+
elif uploaded_image_gallery is not None:
|
| 302 |
+
sel_id = f"image_uploading_{run_idx:02d}"
|
| 303 |
+
|
| 304 |
+
base_dir = f'outputs/{sel_id}_{session_hash}'
|
| 305 |
+
os.makedirs(base_dir, exist_ok=True)
|
| 306 |
+
state_list_output_path = f'{base_dir}/state_list.json'
|
| 307 |
+
|
| 308 |
+
state_list = ["running", "prepare", "prepare", "prepare"]
|
| 309 |
+
with open(state_list_output_path, 'w') as f:
|
| 310 |
+
json.dump(state_list, f)
|
| 311 |
+
yield (
|
| 312 |
+
{"step": state_list[0], "sel_id": sel_id, "session_hash": session_hash},
|
| 313 |
+
{"step": state_list[1], "sel_id": sel_id, "session_hash": session_hash},
|
| 314 |
+
{"step": state_list[2], "sel_id": sel_id, "session_hash": session_hash},
|
| 315 |
+
{"step": state_list[3], "sel_id": sel_id, "session_hash": session_hash}, run_idx, \
|
| 316 |
+
f"<h3>Preparing input images...<p style=\"color:red\">(<u>~3 min</u>)</p></h3>"
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
if id_value is not None:
|
| 320 |
+
rendering_paths, _ = load_renderings_with_id(id_value, session_hash)
|
| 321 |
+
elif mesh_files is not None:
|
| 322 |
+
rendering_paths = process_and_update_gallery(mesh_files, session_hash)
|
| 323 |
+
elif uploaded_image_gallery is not None:
|
| 324 |
+
rendering_paths = [img[0] for img in uploaded_image_gallery]
|
| 325 |
+
|
| 326 |
+
gallery = [[p, None] for p in rendering_paths]
|
| 327 |
+
cached_path = [f'datasets/cached_results/{labels[id_value]}/full.glb',
|
| 328 |
+
f'datasets/cached_results/{labels[id_value]}/fixed.glb',
|
| 329 |
+
f'datasets/cached_results/{labels[id_value]}/art.glb']
|
| 330 |
+
save_gallery_to_renderings(gallery, sel_id, session_hash)
|
| 331 |
+
|
| 332 |
+
state_list = ["done", "running", "prepare", "prepare"]
|
| 333 |
+
with open(state_list_output_path, 'w') as f:
|
| 334 |
+
json.dump(state_list, f)
|
| 335 |
+
yield (
|
| 336 |
+
{"step": state_list[0], "gallery": gallery, "sel_id": sel_id, "cached_path": cached_path, "session_hash": session_hash},
|
| 337 |
+
{"step": state_list[1], "sel_id": sel_id, "session_hash": session_hash},
|
| 338 |
+
{"step": state_list[2], "sel_id": sel_id, "session_hash": session_hash},
|
| 339 |
+
{"step": state_list[3], "sel_id": sel_id, "session_hash": session_hash}, run_idx, \
|
| 340 |
+
f"<h3>Stage 1: Initial reconstruction... <span style=\"color:red\">(<u style=\"color:red\">~3 min</u>)</span></h3>"
|
| 341 |
+
)
|
| 342 |
+
|
| 343 |
+
# 3) Reconstruction
|
| 344 |
+
vox, recon = recon_trellis_meshes(gallery, f"{base_dir}/recon")
|
| 345 |
+
|
| 346 |
+
state_list = ["done", "done", "running", "running"]
|
| 347 |
+
with open(state_list_output_path, 'w') as f:
|
| 348 |
+
json.dump(state_list, f)
|
| 349 |
+
yield (
|
| 350 |
+
{"step": state_list[0], "gallery": gallery, "sel_id": sel_id, "cached_path": cached_path, "session_hash": session_hash},
|
| 351 |
+
{"step": state_list[1], "vox": vox, "recon": recon, "sel_id": sel_id, "session_hash": session_hash},
|
| 352 |
+
{"step": state_list[2], "sel_id": sel_id, "session_hash": session_hash},
|
| 353 |
+
{"step": state_list[3], "sel_id": sel_id, "session_hash": session_hash}, run_idx, \
|
| 354 |
+
f"<h3>Stage 2: Joint initialization... <span style=\"color:red\">(<u style=\"color:red\">~1 min</u>)</span></h3>"
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
# 4) Joint estimation
|
| 358 |
+
if joint_type_in is not None:
|
| 359 |
+
joint_type = joint_type_in
|
| 360 |
+
else:
|
| 361 |
+
if 'cabinet' in sel_id:
|
| 362 |
+
joint_type = 'revolute' if 'cabinet2' in sel_id else 'prismatic'
|
| 363 |
+
else:
|
| 364 |
+
joint_type = 'prismatic' if (sel_id in data_info['prismatic']['obj_ids']) else 'revolute'
|
| 365 |
+
print(f"[Joint Type] {joint_type}")
|
| 366 |
+
match, meta = estimate_initial_joints(gallery, joint_type, base_dir)
|
| 367 |
+
|
| 368 |
+
# 5) Format meta info
|
| 369 |
+
html = format_meta_info_text(meta)
|
| 370 |
+
|
| 371 |
+
state_list = ["done", "done", "done", "running"]
|
| 372 |
+
with open(state_list_output_path, 'w') as f:
|
| 373 |
+
json.dump(state_list, f)
|
| 374 |
+
yield (
|
| 375 |
+
{"step": state_list[0], "gallery": gallery, "sel_id": sel_id, "cached_path": cached_path, "session_hash": session_hash},
|
| 376 |
+
{"step": state_list[1], "vox": vox, "recon": recon, "sel_id": sel_id, "session_hash": session_hash},
|
| 377 |
+
{"step": state_list[2], "match": match, "html": html, "sel_id": sel_id, "session_hash": session_hash},
|
| 378 |
+
{"step": state_list[3], "sel_id": sel_id, "session_hash": session_hash}, run_idx, \
|
| 379 |
+
f"<h3>Stage 3: SDS optimization... <span style=\"color:red\">(<u style=\"color:red\">~10 min</u>)</span></h3>"
|
| 380 |
+
)
|
| 381 |
+
|
| 382 |
+
# 6) SDS refinement
|
| 383 |
+
full, fixed, art = articulated_generation_sds(sel_id, session_hash)
|
| 384 |
+
|
| 385 |
+
state_list = ["done", "done", "done", "done"]
|
| 386 |
+
with open(state_list_output_path, 'w') as f:
|
| 387 |
+
json.dump(state_list, f)
|
| 388 |
+
yield (
|
| 389 |
+
{"step": state_list[0], "gallery": gallery, "sel_id": sel_id, "cached_path": cached_path,"session_hash": session_hash},
|
| 390 |
+
{"step": state_list[1], "vox": vox, "recon": recon, "sel_id": sel_id, "session_hash": session_hash},
|
| 391 |
+
{"step": state_list[2], "match": match, "html": html, "sel_id": sel_id, "session_hash": session_hash},
|
| 392 |
+
{"step": state_list[3], "full": full, "fixed": fixed, "art": art, "sel_id": sel_id, "session_hash": session_hash},
|
| 393 |
+
run_idx+1, \
|
| 394 |
+
f"<h3>Done!</h3>"
|
| 395 |
+
)
|
| 396 |
+
|
| 397 |
with gr.Blocks(delete_cache=(600, 600), css="""
|
| 398 |
.gallery-container {
|
| 399 |
overflow-x: auto !important;
|
|
|
|
| 439 |
gr.Markdown("""
|
| 440 |
## FreeArt3D Demo
|
| 441 |
### You can use the following three methods to generate articulated 3D models.
|
| 442 |
+
1. Choose an example object (from PartNet-Mobility or real-world).
|
| 443 |
+
2. Upload multiple mesh files (e.g., .obj, .ply, .stl, .glb, .gltf) at different articulation states (images will be rendered automatically).
|
| 444 |
+
3. Upload multiple input images with **a segmented object on the disk** at **different articulation states** (you can use a fixed view but have to contain ** at least 2 states**).
|
| 445 |
+
|
| 446 |
+
### The total generation time is *~10 min*. Be patient :)
|
| 447 |
+
### Currently it's difficult to run the full pipeline with ZeroGPU due to the long running time. We are applying for an exclusive GPU. Stay Tuned! (We add the cached results now for example objects for you to have a quick check)
|
| 448 |
""")
|
| 449 |
|
| 450 |
with gr.Row(equal_height=True):
|
| 451 |
+
with gr.Tab("Load by Example Object"):
|
| 452 |
with gr.Row():
|
| 453 |
id_input = gr.Dropdown(
|
| 454 |
choices=get_available_ids(),
|
| 455 |
+
value='Cabinet (real-world)',
|
| 456 |
+
label="Example Object",
|
| 457 |
+
info='Select a real-world object or an object from the PartNet-Mobility dataset. (e.g., Box (100214))',
|
| 458 |
)
|
| 459 |
with gr.Row():
|
| 460 |
+
id_input_btn = gr.Button("Generate Articulated Object", variant="primary")
|
| 461 |
with gr.Tab("Upload Mesh Files"):
|
| 462 |
with gr.Row(equal_height=True):
|
| 463 |
with gr.Column():
|
|
|
|
| 466 |
with gr.Column():
|
| 467 |
mesh_viewer = LitModel3D(label="Selected Mesh", exposure=10.0, height=300)
|
| 468 |
with gr.Row():
|
| 469 |
+
joint_type_in_mesh = gr.Dropdown(label="joint_type", choices=["revolute", "prismatic"], value=None)
|
| 470 |
+
with gr.Row():
|
| 471 |
+
mesh_input_btn = gr.Button("Generate Articulated Object", variant="primary")
|
| 472 |
+
with gr.Tab("Upload Image Files"):
|
| 473 |
+
with gr.Row(equal_height=True):
|
| 474 |
+
uploaded_image_gallery = gr.Gallery(label="Input Images", show_label=True, elem_id="gallery", height=300, columns=10, allow_preview=True, elem_classes=["gallery-container"])
|
| 475 |
+
with gr.Row():
|
| 476 |
+
joint_type_in_image = gr.Dropdown(label="joint_type", choices=["revolute", "prismatic"], value=None)
|
| 477 |
+
with gr.Row():
|
| 478 |
+
image_input_btn = gr.Button("Generate Articulated Object", variant="primary")
|
| 479 |
+
|
| 480 |
+
with gr.Row():
|
| 481 |
+
with gr.Accordion("Current Stage", open=True):
|
| 482 |
+
current_stage = gr.HTML(value="<h3>Waiting for input...</h3>")
|
| 483 |
+
|
| 484 |
|
| 485 |
with gr.Row(equal_height=True):
|
| 486 |
with gr.Column():
|
| 487 |
+
input_image_gallery = gr.Gallery(label="Input Images", show_label=True, elem_id="gallery", height=300, columns=3, allow_preview=True, interactive=False, elem_classes=["gallery-container"])
|
|
|
|
| 488 |
with gr.Column():
|
| 489 |
+
voxel_gallery = gr.Gallery(label="Reconstructed Voxels", show_label=True, elem_id="gallery", height=360, columns=3, allow_preview=True, interactive=False, elem_classes=["gallery-container"])
|
| 490 |
with gr.Column():
|
| 491 |
+
recon_mesh_gallery = gr.Gallery(label="Reconstructed Meshes", show_label=True, elem_id="gallery", height=360, columns=3, allow_preview=True, interactive=False, elem_classes=["gallery-container"])
|
| 492 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
with gr.Row():
|
| 494 |
+
matching_examples = gr.Gallery(label="Correspondences", show_label=True, elem_id="gallery", height=400, interactive=False, columns=5, allow_preview=True, elem_classes=["gallery-container"])
|
| 495 |
|
| 496 |
with gr.Row():
|
| 497 |
meta_info = gr.State(
|
|
|
|
| 503 |
}
|
| 504 |
)
|
| 505 |
with gr.Accordion("Joint Information", open=True):
|
| 506 |
+
joint_info_html = gr.HTML(value="")
|
| 507 |
+
|
| 508 |
+
with gr.Row():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 509 |
with gr.Column():
|
| 510 |
full_mesh = LitModel3D(label="Full Mesh", exposure=10.0, height=300)
|
| 511 |
with gr.Column():
|
| 512 |
fixed_part = LitModel3D(label="Fixed Part", exposure=10.0, height=300)
|
| 513 |
with gr.Column():
|
| 514 |
articulated_part = LitModel3D(label="Articulated Part", exposure=10.0, height=300)
|
| 515 |
+
with gr.Row():
|
| 516 |
+
with gr.Column():
|
| 517 |
+
full_mesh_cached = LitModel3D(label="Full Mesh (Cached)", exposure=10.0, height=300)
|
| 518 |
+
with gr.Column():
|
| 519 |
+
fixed_part_cached = LitModel3D(label="Fixed Part (Cached)", exposure=10.0, height=300)
|
| 520 |
+
with gr.Column():
|
| 521 |
+
articulated_part_cached = LitModel3D(label="Articulated Part (Cached)", exposure=10.0, height=300)
|
| 522 |
|
| 523 |
+
selected_id_state = gr.State(value="")
|
| 524 |
+
session_hash_state = gr.State(value="")
|
| 525 |
+
run_idx_state = gr.State(value=0)
|
| 526 |
+
|
| 527 |
+
image_gallery_state = gr.State(value="prepare")
|
| 528 |
+
recon_state = gr.State(value="prepare")
|
| 529 |
+
estimate_state = gr.State(value="prepare")
|
| 530 |
+
sds_state = gr.State(value="prepare")
|
| 531 |
+
none_val = gr.State(value=None)
|
| 532 |
|
| 533 |
# Handlers
|
| 534 |
+
demo.load(start_session, outputs=session_hash_state)
|
| 535 |
demo.unload(end_session)
|
| 536 |
+
|
| 537 |
id_input_btn.click(
|
| 538 |
+
start_session,
|
| 539 |
+
outputs=session_hash_state,
|
| 540 |
+
).then(
|
| 541 |
+
pipeline,
|
| 542 |
+
inputs=[id_input, none_val, none_val, none_val, session_hash_state, run_idx_state],
|
| 543 |
+
outputs=[image_gallery_state, recon_state, estimate_state, sds_state, run_idx_state, current_stage],
|
| 544 |
+
)
|
| 545 |
+
|
| 546 |
+
mesh_input_btn.click(
|
| 547 |
+
start_session,
|
| 548 |
+
outputs=session_hash_state,
|
| 549 |
+
).then(
|
| 550 |
+
pipeline,
|
| 551 |
+
inputs=[none_val, mesh_files, none_val, joint_type_in_mesh, session_hash_state, run_idx_state],
|
| 552 |
+
outputs=[image_gallery_state, recon_state, estimate_state, sds_state, run_idx_state, current_stage],
|
| 553 |
+
)
|
| 554 |
+
|
| 555 |
+
image_input_btn.click(
|
| 556 |
+
start_session,
|
| 557 |
+
outputs=session_hash_state,
|
| 558 |
+
).then(
|
| 559 |
+
pipeline,
|
| 560 |
+
inputs=[none_val, none_val, uploaded_image_gallery, joint_type_in_image, session_hash_state, run_idx_state],
|
| 561 |
+
outputs=[image_gallery_state, recon_state, estimate_state, sds_state, run_idx_state, current_stage],
|
| 562 |
+
)
|
| 563 |
+
|
| 564 |
+
# Watch state and update only relevant components per step
|
| 565 |
+
image_gallery_state.change(
|
| 566 |
+
image_gallery_state_change,
|
| 567 |
+
inputs=image_gallery_state,
|
| 568 |
+
outputs=[input_image_gallery, selected_id_state, full_mesh_cached, fixed_part_cached, articulated_part_cached,
|
| 569 |
+
voxel_gallery, recon_mesh_gallery,
|
| 570 |
+
matching_examples, joint_info_html,
|
| 571 |
+
full_mesh, fixed_part, articulated_part],
|
| 572 |
+
)
|
| 573 |
+
|
| 574 |
+
recon_state.change(
|
| 575 |
+
recon_state_change,
|
| 576 |
+
inputs=recon_state,
|
| 577 |
+
outputs=[voxel_gallery, recon_mesh_gallery],
|
| 578 |
+
)
|
| 579 |
+
|
| 580 |
+
estimate_state.change(
|
| 581 |
+
estimate_state_change,
|
| 582 |
+
inputs=estimate_state,
|
| 583 |
+
outputs=[matching_examples, joint_info_html],
|
| 584 |
)
|
| 585 |
|
| 586 |
+
sds_state.change(
|
| 587 |
+
sds_state_change,
|
| 588 |
+
inputs=sds_state,
|
| 589 |
+
outputs=[full_mesh, fixed_part, articulated_part],
|
| 590 |
+
)
|
| 591 |
+
|
| 592 |
# Handle mesh file uploads
|
| 593 |
mesh_files.change(
|
| 594 |
handle_mesh_upload,
|
| 595 |
inputs=mesh_files,
|
| 596 |
outputs=[mesh_selector, mesh_viewer]
|
| 597 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 598 |
|
| 599 |
# Handle dropdown selection for mesh view
|
| 600 |
mesh_selector.change(
|
|
|
|
| 603 |
outputs=mesh_viewer
|
| 604 |
)
|
| 605 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 606 |
# Ensure downstream uses the generic 'uploaded' namespace for output paths
|
| 607 |
+
uploaded_image_gallery.change(
|
| 608 |
lambda *_: "uploaded",
|
| 609 |
inputs=None,
|
| 610 |
outputs=selected_id_state
|
| 611 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 612 |
|
| 613 |
# Launch the Gradio app
|
| 614 |
if __name__ == "__main__":
|
assets/disk.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
assets/teaser.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
configs/default.yaml
CHANGED
|
@@ -1,16 +1,33 @@
|
|
| 1 |
-
total_iters:
|
| 2 |
print_interval: 10
|
| 3 |
save_interval: 500
|
| 4 |
vis_interval: 500
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
noise_start: 0.5
|
| 7 |
noise_end: 0.8
|
| 8 |
refine_noise: 0.5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
batch_size: 1
|
| 11 |
base_lr: 0.01
|
| 12 |
art_lr: 0.01
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
sds_weight: 0.1
|
| 16 |
voxel_weight: 1
|
|
@@ -20,4 +37,4 @@ sample_interval: 0.5
|
|
| 20 |
sample_coeff: 2.0
|
| 21 |
|
| 22 |
train_num_state: 6
|
| 23 |
-
inference_num_state: 6
|
|
|
|
| 1 |
+
total_iters: 1500
|
| 2 |
print_interval: 10
|
| 3 |
save_interval: 500
|
| 4 |
vis_interval: 500
|
| 5 |
|
| 6 |
+
min_azi: 0.39269908169872414
|
| 7 |
+
max_azi: 1.1780972450961724
|
| 8 |
+
|
| 9 |
+
ransac_iteration: 1000
|
| 10 |
+
ransac_threshold: 0.1
|
| 11 |
+
ransac_sample: 3
|
| 12 |
+
|
| 13 |
noise_start: 0.5
|
| 14 |
noise_end: 0.8
|
| 15 |
refine_noise: 0.5
|
| 16 |
+
expand_iteration: 100
|
| 17 |
+
expand_threshold_base: 0.5
|
| 18 |
+
expand_threshold_prismatic: 0.45
|
| 19 |
+
expand_threshold_revolute: 0.45
|
| 20 |
+
large_iteration_base: 50
|
| 21 |
+
large_iteration_prismatic: 30
|
| 22 |
+
large_iteration_revolute: 30
|
| 23 |
|
| 24 |
batch_size: 1
|
| 25 |
base_lr: 0.01
|
| 26 |
art_lr: 0.01
|
| 27 |
+
pivot_lr: 0.1
|
| 28 |
+
scale_lr_prismatic: 0.005
|
| 29 |
+
scale_lr_revolute: 0.01
|
| 30 |
+
qpos_lr: 0.01
|
| 31 |
|
| 32 |
sds_weight: 0.1
|
| 33 |
voxel_weight: 1
|
|
|
|
| 37 |
sample_coeff: 2.0
|
| 38 |
|
| 39 |
train_num_state: 6
|
| 40 |
+
inference_num_state: 6
|
configs/partnet_target.json
CHANGED
|
@@ -64,7 +64,7 @@
|
|
| 64 |
"joint_type": "revolute"
|
| 65 |
},
|
| 66 |
"Refrigerator": {
|
| 67 |
-
"joint_tags": ["door"],
|
| 68 |
"joint_type": "revolute"
|
| 69 |
},
|
| 70 |
"WashingMachine": {
|
|
|
|
| 64 |
"joint_type": "revolute"
|
| 65 |
},
|
| 66 |
"Refrigerator": {
|
| 67 |
+
"joint_tags": ["door", "door_frame"],
|
| 68 |
"joint_type": "revolute"
|
| 69 |
},
|
| 70 |
"WashingMachine": {
|
datasets/PartNet/100214/02_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/02_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/03_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/03_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/04_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/04_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/05_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/05_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100214/gt_mesh/00.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:aa33bf488300581d45bedaa1d1286e0a240068d1433b33d4b3625b95ff8b5e20
|
| 3 |
-
size 3908732
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/gt_mesh/01.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:9ba38020066067c5c9948892387d2cde48dec9c3d9aeaa4fe489b1851b6aad5c
|
| 3 |
-
size 3908756
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/gt_mesh/02.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:3adecc17b8dfe4f5fbd1da9695b9d634fa8c85f01ad472f56774224a63e74387
|
| 3 |
-
size 3908756
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/gt_mesh/03.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:716fb1a554ca852c3e850fffe2f43db1fe908a152140c8409937bdb6b419a19a
|
| 3 |
-
size 3908756
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/gt_mesh/04.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:0039fc82c8b7904f30e77cbcef101d31555960fc0eed0955fa625b7842000995
|
| 3 |
-
size 3908840
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/gt_mesh/05.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:8a6976d0390034206ebe897bb682140556f1e83712540c714f01e20a9c74c875
|
| 3 |
-
size 3908728
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/joint_info.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
| 1 |
-
[
|
| 2 |
-
{
|
| 3 |
-
"type": "revolute",
|
| 4 |
-
"range": [
|
| 5 |
-
-1.6755160819145563,
|
| 6 |
-
0.3490658503988659
|
| 7 |
-
],
|
| 8 |
-
"axis": {
|
| 9 |
-
"origin": [
|
| 10 |
-
0.4566900000000005,
|
| 11 |
-
0.19353231481404498,
|
| 12 |
-
-0.22
|
| 13 |
-
],
|
| 14 |
-
"direction": [
|
| 15 |
-
-1.0,
|
| 16 |
-
0.0,
|
| 17 |
-
0.0
|
| 18 |
-
]
|
| 19 |
-
}
|
| 20 |
-
}
|
| 21 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/joints.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"category": "Box",
|
| 3 |
-
"joints": [
|
| 4 |
-
"joint_0"
|
| 5 |
-
],
|
| 6 |
-
"descendants": {
|
| 7 |
-
"joint_0": [],
|
| 8 |
-
"joint_1": [],
|
| 9 |
-
"joint_2": [],
|
| 10 |
-
"joint_3": [
|
| 11 |
-
"joint_0",
|
| 12 |
-
"joint_1",
|
| 13 |
-
"joint_2"
|
| 14 |
-
]
|
| 15 |
-
}
|
| 16 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100214/mobility.urdf
DELETED
|
@@ -1,470 +0,0 @@
|
|
| 1 |
-
<?xml version="1.0" ?>
|
| 2 |
-
<robot name="partnet_802f6cfeb6f41f16a59ff8378a27445f">
|
| 3 |
-
<link name="base"/>
|
| 4 |
-
<link name="link_0">
|
| 5 |
-
<visual name="rotation_lid-1">
|
| 6 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 7 |
-
<geometry>
|
| 8 |
-
<mesh filename="textured_objs/original-4.obj"/>
|
| 9 |
-
</geometry>
|
| 10 |
-
</visual>
|
| 11 |
-
<visual name="rotation_lid-1">
|
| 12 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 13 |
-
<geometry>
|
| 14 |
-
<mesh filename="textured_objs/original-9.obj"/>
|
| 15 |
-
</geometry>
|
| 16 |
-
</visual>
|
| 17 |
-
<visual name="rotation_lid-1">
|
| 18 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 19 |
-
<geometry>
|
| 20 |
-
<mesh filename="textured_objs/original-37.obj"/>
|
| 21 |
-
</geometry>
|
| 22 |
-
</visual>
|
| 23 |
-
<visual name="rotation_lid-1">
|
| 24 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 25 |
-
<geometry>
|
| 26 |
-
<mesh filename="textured_objs/original-36.obj"/>
|
| 27 |
-
</geometry>
|
| 28 |
-
</visual>
|
| 29 |
-
<visual name="rotation_lid-1">
|
| 30 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 31 |
-
<geometry>
|
| 32 |
-
<mesh filename="textured_objs/original-34.obj"/>
|
| 33 |
-
</geometry>
|
| 34 |
-
</visual>
|
| 35 |
-
<visual name="rotation_lid-1">
|
| 36 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 37 |
-
<geometry>
|
| 38 |
-
<mesh filename="textured_objs/original-35.obj"/>
|
| 39 |
-
</geometry>
|
| 40 |
-
</visual>
|
| 41 |
-
<visual name="rotation_lid-1">
|
| 42 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 43 |
-
<geometry>
|
| 44 |
-
<mesh filename="textured_objs/original-38.obj"/>
|
| 45 |
-
</geometry>
|
| 46 |
-
</visual>
|
| 47 |
-
<visual name="rotation_lid-1">
|
| 48 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 49 |
-
<geometry>
|
| 50 |
-
<mesh filename="textured_objs/original-12.obj"/>
|
| 51 |
-
</geometry>
|
| 52 |
-
</visual>
|
| 53 |
-
<visual name="rotation_lid-1">
|
| 54 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 55 |
-
<geometry>
|
| 56 |
-
<mesh filename="textured_objs/original-13.obj"/>
|
| 57 |
-
</geometry>
|
| 58 |
-
</visual>
|
| 59 |
-
<visual name="rotation_lid-1">
|
| 60 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 61 |
-
<geometry>
|
| 62 |
-
<mesh filename="textured_objs/original-15.obj"/>
|
| 63 |
-
</geometry>
|
| 64 |
-
</visual>
|
| 65 |
-
<visual name="rotation_lid-1">
|
| 66 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 67 |
-
<geometry>
|
| 68 |
-
<mesh filename="textured_objs/original-16.obj"/>
|
| 69 |
-
</geometry>
|
| 70 |
-
</visual>
|
| 71 |
-
<visual name="rotation_lid-1">
|
| 72 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 73 |
-
<geometry>
|
| 74 |
-
<mesh filename="textured_objs/original-18.obj"/>
|
| 75 |
-
</geometry>
|
| 76 |
-
</visual>
|
| 77 |
-
<visual name="rotation_lid-1">
|
| 78 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 79 |
-
<geometry>
|
| 80 |
-
<mesh filename="textured_objs/original-19.obj"/>
|
| 81 |
-
</geometry>
|
| 82 |
-
</visual>
|
| 83 |
-
<visual name="rotation_lid-1">
|
| 84 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 85 |
-
<geometry>
|
| 86 |
-
<mesh filename="textured_objs/original-21.obj"/>
|
| 87 |
-
</geometry>
|
| 88 |
-
</visual>
|
| 89 |
-
<visual name="rotation_lid-1">
|
| 90 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 91 |
-
<geometry>
|
| 92 |
-
<mesh filename="textured_objs/original-20.obj"/>
|
| 93 |
-
</geometry>
|
| 94 |
-
</visual>
|
| 95 |
-
<visual name="rotation_lid-1">
|
| 96 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 97 |
-
<geometry>
|
| 98 |
-
<mesh filename="textured_objs/original-17.obj"/>
|
| 99 |
-
</geometry>
|
| 100 |
-
</visual>
|
| 101 |
-
<visual name="rotation_lid-1">
|
| 102 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 103 |
-
<geometry>
|
| 104 |
-
<mesh filename="textured_objs/original-14.obj"/>
|
| 105 |
-
</geometry>
|
| 106 |
-
</visual>
|
| 107 |
-
<visual name="rotation_lid-1">
|
| 108 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 109 |
-
<geometry>
|
| 110 |
-
<mesh filename="textured_objs/original-32.obj"/>
|
| 111 |
-
</geometry>
|
| 112 |
-
</visual>
|
| 113 |
-
<visual name="rotation_lid-1">
|
| 114 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 115 |
-
<geometry>
|
| 116 |
-
<mesh filename="textured_objs/original-31.obj"/>
|
| 117 |
-
</geometry>
|
| 118 |
-
</visual>
|
| 119 |
-
<visual name="rotation_lid-1">
|
| 120 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 121 |
-
<geometry>
|
| 122 |
-
<mesh filename="textured_objs/original-30.obj"/>
|
| 123 |
-
</geometry>
|
| 124 |
-
</visual>
|
| 125 |
-
<visual name="rotation_lid-1">
|
| 126 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 127 |
-
<geometry>
|
| 128 |
-
<mesh filename="textured_objs/original-29.obj"/>
|
| 129 |
-
</geometry>
|
| 130 |
-
</visual>
|
| 131 |
-
<visual name="rotation_lid-1">
|
| 132 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 133 |
-
<geometry>
|
| 134 |
-
<mesh filename="textured_objs/original-26.obj"/>
|
| 135 |
-
</geometry>
|
| 136 |
-
</visual>
|
| 137 |
-
<visual name="rotation_lid-1">
|
| 138 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 139 |
-
<geometry>
|
| 140 |
-
<mesh filename="textured_objs/original-27.obj"/>
|
| 141 |
-
</geometry>
|
| 142 |
-
</visual>
|
| 143 |
-
<visual name="rotation_lid-1">
|
| 144 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 145 |
-
<geometry>
|
| 146 |
-
<mesh filename="textured_objs/original-25.obj"/>
|
| 147 |
-
</geometry>
|
| 148 |
-
</visual>
|
| 149 |
-
<visual name="rotation_lid-1">
|
| 150 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 151 |
-
<geometry>
|
| 152 |
-
<mesh filename="textured_objs/original-24.obj"/>
|
| 153 |
-
</geometry>
|
| 154 |
-
</visual>
|
| 155 |
-
<visual name="rotation_lid-1">
|
| 156 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 157 |
-
<geometry>
|
| 158 |
-
<mesh filename="textured_objs/original-23.obj"/>
|
| 159 |
-
</geometry>
|
| 160 |
-
</visual>
|
| 161 |
-
<visual name="rotation_lid-1">
|
| 162 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 163 |
-
<geometry>
|
| 164 |
-
<mesh filename="textured_objs/original-33.obj"/>
|
| 165 |
-
</geometry>
|
| 166 |
-
</visual>
|
| 167 |
-
<visual name="rotation_lid-1">
|
| 168 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 169 |
-
<geometry>
|
| 170 |
-
<mesh filename="textured_objs/original-28.obj"/>
|
| 171 |
-
</geometry>
|
| 172 |
-
</visual>
|
| 173 |
-
<collision>
|
| 174 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 175 |
-
<geometry>
|
| 176 |
-
<mesh filename="textured_objs/original-4.obj"/>
|
| 177 |
-
</geometry>
|
| 178 |
-
</collision>
|
| 179 |
-
<collision>
|
| 180 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 181 |
-
<geometry>
|
| 182 |
-
<mesh filename="textured_objs/original-9.obj"/>
|
| 183 |
-
</geometry>
|
| 184 |
-
</collision>
|
| 185 |
-
<collision>
|
| 186 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 187 |
-
<geometry>
|
| 188 |
-
<mesh filename="textured_objs/original-37.obj"/>
|
| 189 |
-
</geometry>
|
| 190 |
-
</collision>
|
| 191 |
-
<collision>
|
| 192 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 193 |
-
<geometry>
|
| 194 |
-
<mesh filename="textured_objs/original-36.obj"/>
|
| 195 |
-
</geometry>
|
| 196 |
-
</collision>
|
| 197 |
-
<collision>
|
| 198 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 199 |
-
<geometry>
|
| 200 |
-
<mesh filename="textured_objs/original-34.obj"/>
|
| 201 |
-
</geometry>
|
| 202 |
-
</collision>
|
| 203 |
-
<collision>
|
| 204 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 205 |
-
<geometry>
|
| 206 |
-
<mesh filename="textured_objs/original-35.obj"/>
|
| 207 |
-
</geometry>
|
| 208 |
-
</collision>
|
| 209 |
-
<collision>
|
| 210 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 211 |
-
<geometry>
|
| 212 |
-
<mesh filename="textured_objs/original-38.obj"/>
|
| 213 |
-
</geometry>
|
| 214 |
-
</collision>
|
| 215 |
-
<collision>
|
| 216 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 217 |
-
<geometry>
|
| 218 |
-
<mesh filename="textured_objs/original-12.obj"/>
|
| 219 |
-
</geometry>
|
| 220 |
-
</collision>
|
| 221 |
-
<collision>
|
| 222 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 223 |
-
<geometry>
|
| 224 |
-
<mesh filename="textured_objs/original-13.obj"/>
|
| 225 |
-
</geometry>
|
| 226 |
-
</collision>
|
| 227 |
-
<collision>
|
| 228 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 229 |
-
<geometry>
|
| 230 |
-
<mesh filename="textured_objs/original-15.obj"/>
|
| 231 |
-
</geometry>
|
| 232 |
-
</collision>
|
| 233 |
-
<collision>
|
| 234 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 235 |
-
<geometry>
|
| 236 |
-
<mesh filename="textured_objs/original-16.obj"/>
|
| 237 |
-
</geometry>
|
| 238 |
-
</collision>
|
| 239 |
-
<collision>
|
| 240 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 241 |
-
<geometry>
|
| 242 |
-
<mesh filename="textured_objs/original-18.obj"/>
|
| 243 |
-
</geometry>
|
| 244 |
-
</collision>
|
| 245 |
-
<collision>
|
| 246 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 247 |
-
<geometry>
|
| 248 |
-
<mesh filename="textured_objs/original-19.obj"/>
|
| 249 |
-
</geometry>
|
| 250 |
-
</collision>
|
| 251 |
-
<collision>
|
| 252 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 253 |
-
<geometry>
|
| 254 |
-
<mesh filename="textured_objs/original-21.obj"/>
|
| 255 |
-
</geometry>
|
| 256 |
-
</collision>
|
| 257 |
-
<collision>
|
| 258 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 259 |
-
<geometry>
|
| 260 |
-
<mesh filename="textured_objs/original-20.obj"/>
|
| 261 |
-
</geometry>
|
| 262 |
-
</collision>
|
| 263 |
-
<collision>
|
| 264 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 265 |
-
<geometry>
|
| 266 |
-
<mesh filename="textured_objs/original-17.obj"/>
|
| 267 |
-
</geometry>
|
| 268 |
-
</collision>
|
| 269 |
-
<collision>
|
| 270 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 271 |
-
<geometry>
|
| 272 |
-
<mesh filename="textured_objs/original-14.obj"/>
|
| 273 |
-
</geometry>
|
| 274 |
-
</collision>
|
| 275 |
-
<collision>
|
| 276 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 277 |
-
<geometry>
|
| 278 |
-
<mesh filename="textured_objs/original-32.obj"/>
|
| 279 |
-
</geometry>
|
| 280 |
-
</collision>
|
| 281 |
-
<collision>
|
| 282 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 283 |
-
<geometry>
|
| 284 |
-
<mesh filename="textured_objs/original-31.obj"/>
|
| 285 |
-
</geometry>
|
| 286 |
-
</collision>
|
| 287 |
-
<collision>
|
| 288 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 289 |
-
<geometry>
|
| 290 |
-
<mesh filename="textured_objs/original-30.obj"/>
|
| 291 |
-
</geometry>
|
| 292 |
-
</collision>
|
| 293 |
-
<collision>
|
| 294 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 295 |
-
<geometry>
|
| 296 |
-
<mesh filename="textured_objs/original-29.obj"/>
|
| 297 |
-
</geometry>
|
| 298 |
-
</collision>
|
| 299 |
-
<collision>
|
| 300 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 301 |
-
<geometry>
|
| 302 |
-
<mesh filename="textured_objs/original-26.obj"/>
|
| 303 |
-
</geometry>
|
| 304 |
-
</collision>
|
| 305 |
-
<collision>
|
| 306 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 307 |
-
<geometry>
|
| 308 |
-
<mesh filename="textured_objs/original-27.obj"/>
|
| 309 |
-
</geometry>
|
| 310 |
-
</collision>
|
| 311 |
-
<collision>
|
| 312 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 313 |
-
<geometry>
|
| 314 |
-
<mesh filename="textured_objs/original-25.obj"/>
|
| 315 |
-
</geometry>
|
| 316 |
-
</collision>
|
| 317 |
-
<collision>
|
| 318 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 319 |
-
<geometry>
|
| 320 |
-
<mesh filename="textured_objs/original-24.obj"/>
|
| 321 |
-
</geometry>
|
| 322 |
-
</collision>
|
| 323 |
-
<collision>
|
| 324 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 325 |
-
<geometry>
|
| 326 |
-
<mesh filename="textured_objs/original-23.obj"/>
|
| 327 |
-
</geometry>
|
| 328 |
-
</collision>
|
| 329 |
-
<collision>
|
| 330 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 331 |
-
<geometry>
|
| 332 |
-
<mesh filename="textured_objs/original-33.obj"/>
|
| 333 |
-
</geometry>
|
| 334 |
-
</collision>
|
| 335 |
-
<collision>
|
| 336 |
-
<origin xyz="-0.4566900000000005 -0.19353231481404498 0.22"/>
|
| 337 |
-
<geometry>
|
| 338 |
-
<mesh filename="textured_objs/original-28.obj"/>
|
| 339 |
-
</geometry>
|
| 340 |
-
</collision>
|
| 341 |
-
</link>
|
| 342 |
-
<joint name="joint_0" type="revolute">
|
| 343 |
-
<origin xyz="0.4566900000000005 0.19353231481404498 -0.22"/>
|
| 344 |
-
<axis xyz="-1 0 0"/>
|
| 345 |
-
<child link="link_0"/>
|
| 346 |
-
<parent link="link_3"/>
|
| 347 |
-
<limit lower="-1.6755160819145563" upper="0.3490658503988659"/>
|
| 348 |
-
</joint>
|
| 349 |
-
<link name="link_1">
|
| 350 |
-
<visual name="lock-2">
|
| 351 |
-
<origin xyz="0.31702800000000186 -0.12031968844452468 -0.42424240488341747"/>
|
| 352 |
-
<geometry>
|
| 353 |
-
<mesh filename="textured_objs/original-3.obj"/>
|
| 354 |
-
</geometry>
|
| 355 |
-
</visual>
|
| 356 |
-
<collision>
|
| 357 |
-
<origin xyz="0.31702800000000186 -0.12031968844452468 -0.42424240488341747"/>
|
| 358 |
-
<geometry>
|
| 359 |
-
<mesh filename="textured_objs/original-3.obj"/>
|
| 360 |
-
</geometry>
|
| 361 |
-
</collision>
|
| 362 |
-
</link>
|
| 363 |
-
<joint name="joint_1" type="revolute">
|
| 364 |
-
<origin xyz="-0.31702800000000186 0.12031968844452468 0.42424240488341747"/>
|
| 365 |
-
<axis xyz="-1 0 0"/>
|
| 366 |
-
<child link="link_1"/>
|
| 367 |
-
<parent link="link_3"/>
|
| 368 |
-
<limit lower="-0.0" upper="0.4363323129985824"/>
|
| 369 |
-
</joint>
|
| 370 |
-
<link name="link_2">
|
| 371 |
-
<visual name="lock-3">
|
| 372 |
-
<origin xyz="0.31702800000000186 -0.12031968844452468 -0.42424240488341747"/>
|
| 373 |
-
<geometry>
|
| 374 |
-
<mesh filename="textured_objs/original-7.obj"/>
|
| 375 |
-
</geometry>
|
| 376 |
-
</visual>
|
| 377 |
-
<collision>
|
| 378 |
-
<origin xyz="0.31702800000000186 -0.12031968844452468 -0.42424240488341747"/>
|
| 379 |
-
<geometry>
|
| 380 |
-
<mesh filename="textured_objs/original-7.obj"/>
|
| 381 |
-
</geometry>
|
| 382 |
-
</collision>
|
| 383 |
-
</link>
|
| 384 |
-
<joint name="joint_2" type="revolute">
|
| 385 |
-
<origin xyz="-0.31702800000000186 0.12031968844452468 0.42424240488341747"/>
|
| 386 |
-
<axis xyz="-1 0 0"/>
|
| 387 |
-
<child link="link_2"/>
|
| 388 |
-
<parent link="link_3"/>
|
| 389 |
-
<limit lower="-0.0" upper="0.4363323129985824"/>
|
| 390 |
-
</joint>
|
| 391 |
-
<link name="link_3">
|
| 392 |
-
<visual name="base_body-4">
|
| 393 |
-
<origin xyz="0 0 0"/>
|
| 394 |
-
<geometry>
|
| 395 |
-
<mesh filename="textured_objs/original-2.obj"/>
|
| 396 |
-
</geometry>
|
| 397 |
-
</visual>
|
| 398 |
-
<visual name="base_body-4">
|
| 399 |
-
<origin xyz="0 0 0"/>
|
| 400 |
-
<geometry>
|
| 401 |
-
<mesh filename="textured_objs/original-39.obj"/>
|
| 402 |
-
</geometry>
|
| 403 |
-
</visual>
|
| 404 |
-
<visual name="base_body-4">
|
| 405 |
-
<origin xyz="0 0 0"/>
|
| 406 |
-
<geometry>
|
| 407 |
-
<mesh filename="textured_objs/original-5.obj"/>
|
| 408 |
-
</geometry>
|
| 409 |
-
</visual>
|
| 410 |
-
<visual name="base_body-4">
|
| 411 |
-
<origin xyz="0 0 0"/>
|
| 412 |
-
<geometry>
|
| 413 |
-
<mesh filename="textured_objs/original-6.obj"/>
|
| 414 |
-
</geometry>
|
| 415 |
-
</visual>
|
| 416 |
-
<visual name="base_body-4">
|
| 417 |
-
<origin xyz="0 0 0"/>
|
| 418 |
-
<geometry>
|
| 419 |
-
<mesh filename="textured_objs/original-1.obj"/>
|
| 420 |
-
</geometry>
|
| 421 |
-
</visual>
|
| 422 |
-
<visual name="base_body-4">
|
| 423 |
-
<origin xyz="0 0 0"/>
|
| 424 |
-
<geometry>
|
| 425 |
-
<mesh filename="textured_objs/original-40.obj"/>
|
| 426 |
-
</geometry>
|
| 427 |
-
</visual>
|
| 428 |
-
<collision>
|
| 429 |
-
<origin xyz="0 0 0"/>
|
| 430 |
-
<geometry>
|
| 431 |
-
<mesh filename="textured_objs/original-2.obj"/>
|
| 432 |
-
</geometry>
|
| 433 |
-
</collision>
|
| 434 |
-
<collision>
|
| 435 |
-
<origin xyz="0 0 0"/>
|
| 436 |
-
<geometry>
|
| 437 |
-
<mesh filename="textured_objs/original-39.obj"/>
|
| 438 |
-
</geometry>
|
| 439 |
-
</collision>
|
| 440 |
-
<collision>
|
| 441 |
-
<origin xyz="0 0 0"/>
|
| 442 |
-
<geometry>
|
| 443 |
-
<mesh filename="textured_objs/original-5.obj"/>
|
| 444 |
-
</geometry>
|
| 445 |
-
</collision>
|
| 446 |
-
<collision>
|
| 447 |
-
<origin xyz="0 0 0"/>
|
| 448 |
-
<geometry>
|
| 449 |
-
<mesh filename="textured_objs/original-6.obj"/>
|
| 450 |
-
</geometry>
|
| 451 |
-
</collision>
|
| 452 |
-
<collision>
|
| 453 |
-
<origin xyz="0 0 0"/>
|
| 454 |
-
<geometry>
|
| 455 |
-
<mesh filename="textured_objs/original-1.obj"/>
|
| 456 |
-
</geometry>
|
| 457 |
-
</collision>
|
| 458 |
-
<collision>
|
| 459 |
-
<origin xyz="0 0 0"/>
|
| 460 |
-
<geometry>
|
| 461 |
-
<mesh filename="textured_objs/original-40.obj"/>
|
| 462 |
-
</geometry>
|
| 463 |
-
</collision>
|
| 464 |
-
</link>
|
| 465 |
-
<joint name="joint_3" type="fixed">
|
| 466 |
-
<origin rpy="1.570796326794897 0 -1.570796326794897" xyz="0 0 0"/>
|
| 467 |
-
<child link="link_3"/>
|
| 468 |
-
<parent link="base"/>
|
| 469 |
-
</joint>
|
| 470 |
-
</robot>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/00_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/00_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/01_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/01_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/02_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/02_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/03_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/03_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/04_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/04_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/05_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/05_seg.png
DELETED
Git LFS Details
|
datasets/PartNet/100350/gt_mesh/00.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:bf6091c51252d287b15c8593ae1ea6c5597ae18bc83ba4b8c1de34b50a8ba5e3
|
| 3 |
-
size 786128
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/gt_mesh/01.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:4d0cb35167941fea77e80bd5e7d0e74dc206399d6037cf3d4a17af7e2f0004d6
|
| 3 |
-
size 787016
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/gt_mesh/02.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:223f20abebd138a4144131cbe03e7f731f1a5ad6e6077539697443d915419130
|
| 3 |
-
size 786996
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/gt_mesh/03.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:992c725b6d5a5e46a5e81820dea75bb97feb2fef055f9df078aee469000cc766
|
| 3 |
-
size 786976
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/gt_mesh/04.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:2362483d8bc9aca709293d03f4eb49dc1062e4c6dbf213687e896945d85e8b0c
|
| 3 |
-
size 787068
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/gt_mesh/05.glb
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:f0b351e9a97d47a1234ddb875dc74bf0fc292a4b2480041920c59de222272941
|
| 3 |
-
size 787080
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/joint_info.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
| 1 |
-
[
|
| 2 |
-
{
|
| 3 |
-
"type": "revolute",
|
| 4 |
-
"range": [
|
| 5 |
-
-0.0,
|
| 6 |
-
2.9216811678385075
|
| 7 |
-
],
|
| 8 |
-
"axis": {
|
| 9 |
-
"origin": [
|
| 10 |
-
0.0,
|
| 11 |
-
0.07382043606209616,
|
| 12 |
-
0.5268791881000544
|
| 13 |
-
],
|
| 14 |
-
"direction": [
|
| 15 |
-
1.0,
|
| 16 |
-
0.0,
|
| 17 |
-
0.0
|
| 18 |
-
]
|
| 19 |
-
}
|
| 20 |
-
}
|
| 21 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/joints.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"category": "Lighter",
|
| 3 |
-
"joints": [
|
| 4 |
-
"joint_0"
|
| 5 |
-
],
|
| 6 |
-
"descendants": {
|
| 7 |
-
"joint_0": [],
|
| 8 |
-
"joint_1": [],
|
| 9 |
-
"joint_2": [
|
| 10 |
-
"joint_0",
|
| 11 |
-
"joint_1"
|
| 12 |
-
]
|
| 13 |
-
}
|
| 14 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/100350/mobility.urdf
DELETED
|
@@ -1,904 +0,0 @@
|
|
| 1 |
-
<?xml version="1.0" ?>
|
| 2 |
-
<robot name="partnet_u7a32a94d-41d2-4f02-b21c-489a6646b9a5">
|
| 3 |
-
<link name="base"/>
|
| 4 |
-
<link name="link_0">
|
| 5 |
-
<visual name="lid-1">
|
| 6 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 7 |
-
<geometry>
|
| 8 |
-
<mesh filename="textured_objs/original-50.obj"/>
|
| 9 |
-
</geometry>
|
| 10 |
-
</visual>
|
| 11 |
-
<visual name="lid-1">
|
| 12 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 13 |
-
<geometry>
|
| 14 |
-
<mesh filename="textured_objs/original-46.obj"/>
|
| 15 |
-
</geometry>
|
| 16 |
-
</visual>
|
| 17 |
-
<visual name="lid-1">
|
| 18 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 19 |
-
<geometry>
|
| 20 |
-
<mesh filename="textured_objs/original-49.obj"/>
|
| 21 |
-
</geometry>
|
| 22 |
-
</visual>
|
| 23 |
-
<visual name="lid-1">
|
| 24 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 25 |
-
<geometry>
|
| 26 |
-
<mesh filename="textured_objs/original-54.obj"/>
|
| 27 |
-
</geometry>
|
| 28 |
-
</visual>
|
| 29 |
-
<visual name="lid-1">
|
| 30 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 31 |
-
<geometry>
|
| 32 |
-
<mesh filename="textured_objs/original-53.obj"/>
|
| 33 |
-
</geometry>
|
| 34 |
-
</visual>
|
| 35 |
-
<visual name="lid-1">
|
| 36 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 37 |
-
<geometry>
|
| 38 |
-
<mesh filename="textured_objs/original-52.obj"/>
|
| 39 |
-
</geometry>
|
| 40 |
-
</visual>
|
| 41 |
-
<visual name="lid-1">
|
| 42 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 43 |
-
<geometry>
|
| 44 |
-
<mesh filename="textured_objs/original-51.obj"/>
|
| 45 |
-
</geometry>
|
| 46 |
-
</visual>
|
| 47 |
-
<visual name="lid-1">
|
| 48 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 49 |
-
<geometry>
|
| 50 |
-
<mesh filename="textured_objs/original-56.obj"/>
|
| 51 |
-
</geometry>
|
| 52 |
-
</visual>
|
| 53 |
-
<visual name="lid-1">
|
| 54 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 55 |
-
<geometry>
|
| 56 |
-
<mesh filename="textured_objs/original-55.obj"/>
|
| 57 |
-
</geometry>
|
| 58 |
-
</visual>
|
| 59 |
-
<visual name="lid-1">
|
| 60 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 61 |
-
<geometry>
|
| 62 |
-
<mesh filename="textured_objs/original-47.obj"/>
|
| 63 |
-
</geometry>
|
| 64 |
-
</visual>
|
| 65 |
-
<collision>
|
| 66 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 67 |
-
<geometry>
|
| 68 |
-
<mesh filename="textured_objs/original-50.obj"/>
|
| 69 |
-
</geometry>
|
| 70 |
-
</collision>
|
| 71 |
-
<collision>
|
| 72 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 73 |
-
<geometry>
|
| 74 |
-
<mesh filename="textured_objs/original-46.obj"/>
|
| 75 |
-
</geometry>
|
| 76 |
-
</collision>
|
| 77 |
-
<collision>
|
| 78 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 79 |
-
<geometry>
|
| 80 |
-
<mesh filename="textured_objs/original-49.obj"/>
|
| 81 |
-
</geometry>
|
| 82 |
-
</collision>
|
| 83 |
-
<collision>
|
| 84 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 85 |
-
<geometry>
|
| 86 |
-
<mesh filename="textured_objs/original-54.obj"/>
|
| 87 |
-
</geometry>
|
| 88 |
-
</collision>
|
| 89 |
-
<collision>
|
| 90 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 91 |
-
<geometry>
|
| 92 |
-
<mesh filename="textured_objs/original-53.obj"/>
|
| 93 |
-
</geometry>
|
| 94 |
-
</collision>
|
| 95 |
-
<collision>
|
| 96 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 97 |
-
<geometry>
|
| 98 |
-
<mesh filename="textured_objs/original-52.obj"/>
|
| 99 |
-
</geometry>
|
| 100 |
-
</collision>
|
| 101 |
-
<collision>
|
| 102 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 103 |
-
<geometry>
|
| 104 |
-
<mesh filename="textured_objs/original-51.obj"/>
|
| 105 |
-
</geometry>
|
| 106 |
-
</collision>
|
| 107 |
-
<collision>
|
| 108 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 109 |
-
<geometry>
|
| 110 |
-
<mesh filename="textured_objs/original-56.obj"/>
|
| 111 |
-
</geometry>
|
| 112 |
-
</collision>
|
| 113 |
-
<collision>
|
| 114 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 115 |
-
<geometry>
|
| 116 |
-
<mesh filename="textured_objs/original-55.obj"/>
|
| 117 |
-
</geometry>
|
| 118 |
-
</collision>
|
| 119 |
-
<collision>
|
| 120 |
-
<origin xyz="0 -0.07382043606209616 -0.5268791881000544"/>
|
| 121 |
-
<geometry>
|
| 122 |
-
<mesh filename="textured_objs/original-47.obj"/>
|
| 123 |
-
</geometry>
|
| 124 |
-
</collision>
|
| 125 |
-
</link>
|
| 126 |
-
<joint name="joint_0" type="revolute">
|
| 127 |
-
<origin xyz="0 0.07382043606209616 0.5268791881000544"/>
|
| 128 |
-
<axis xyz="1 0 0"/>
|
| 129 |
-
<child link="link_0"/>
|
| 130 |
-
<parent link="link_2"/>
|
| 131 |
-
<limit lower="-0.0" upper="2.9216811678385075"/>
|
| 132 |
-
</joint>
|
| 133 |
-
<link name="link_1">
|
| 134 |
-
<visual name="wheel-2">
|
| 135 |
-
<origin xyz="-0.17066000000000003 -0.37948606312151356 0.2798602405394533"/>
|
| 136 |
-
<geometry>
|
| 137 |
-
<mesh filename="textured_objs/original-21.obj"/>
|
| 138 |
-
</geometry>
|
| 139 |
-
</visual>
|
| 140 |
-
<collision>
|
| 141 |
-
<origin xyz="-0.17066000000000003 -0.37948606312151356 0.2798602405394533"/>
|
| 142 |
-
<geometry>
|
| 143 |
-
<mesh filename="textured_objs/original-21.obj"/>
|
| 144 |
-
</geometry>
|
| 145 |
-
</collision>
|
| 146 |
-
</link>
|
| 147 |
-
<joint name="joint_1" type="continuous">
|
| 148 |
-
<origin xyz="0.17066000000000003 0.37948606312151356 -0.2798602405394533"/>
|
| 149 |
-
<axis xyz="-1 0 0"/>
|
| 150 |
-
<child link="link_1"/>
|
| 151 |
-
<parent link="link_2"/>
|
| 152 |
-
</joint>
|
| 153 |
-
<link name="link_2">
|
| 154 |
-
<visual name="base_body-3">
|
| 155 |
-
<origin xyz="0 0 0"/>
|
| 156 |
-
<geometry>
|
| 157 |
-
<mesh filename="textured_objs/original-29.obj"/>
|
| 158 |
-
</geometry>
|
| 159 |
-
</visual>
|
| 160 |
-
<visual name="base_body-3">
|
| 161 |
-
<origin xyz="0 0 0"/>
|
| 162 |
-
<geometry>
|
| 163 |
-
<mesh filename="textured_objs/original-30.obj"/>
|
| 164 |
-
</geometry>
|
| 165 |
-
</visual>
|
| 166 |
-
<visual name="base_body-3">
|
| 167 |
-
<origin xyz="0 0 0"/>
|
| 168 |
-
<geometry>
|
| 169 |
-
<mesh filename="textured_objs/original-36.obj"/>
|
| 170 |
-
</geometry>
|
| 171 |
-
</visual>
|
| 172 |
-
<visual name="base_body-3">
|
| 173 |
-
<origin xyz="0 0 0"/>
|
| 174 |
-
<geometry>
|
| 175 |
-
<mesh filename="textured_objs/original-41.obj"/>
|
| 176 |
-
</geometry>
|
| 177 |
-
</visual>
|
| 178 |
-
<visual name="base_body-3">
|
| 179 |
-
<origin xyz="0 0 0"/>
|
| 180 |
-
<geometry>
|
| 181 |
-
<mesh filename="textured_objs/original-28.obj"/>
|
| 182 |
-
</geometry>
|
| 183 |
-
</visual>
|
| 184 |
-
<visual name="base_body-3">
|
| 185 |
-
<origin xyz="0 0 0"/>
|
| 186 |
-
<geometry>
|
| 187 |
-
<mesh filename="textured_objs/original-64.obj"/>
|
| 188 |
-
</geometry>
|
| 189 |
-
</visual>
|
| 190 |
-
<visual name="base_body-3">
|
| 191 |
-
<origin xyz="0 0 0"/>
|
| 192 |
-
<geometry>
|
| 193 |
-
<mesh filename="textured_objs/original-71.obj"/>
|
| 194 |
-
</geometry>
|
| 195 |
-
</visual>
|
| 196 |
-
<visual name="base_body-3">
|
| 197 |
-
<origin xyz="0 0 0"/>
|
| 198 |
-
<geometry>
|
| 199 |
-
<mesh filename="textured_objs/original-83.obj"/>
|
| 200 |
-
</geometry>
|
| 201 |
-
</visual>
|
| 202 |
-
<visual name="base_body-3">
|
| 203 |
-
<origin xyz="0 0 0"/>
|
| 204 |
-
<geometry>
|
| 205 |
-
<mesh filename="textured_objs/original-22.obj"/>
|
| 206 |
-
</geometry>
|
| 207 |
-
</visual>
|
| 208 |
-
<visual name="base_body-3">
|
| 209 |
-
<origin xyz="0 0 0"/>
|
| 210 |
-
<geometry>
|
| 211 |
-
<mesh filename="textured_objs/original-26.obj"/>
|
| 212 |
-
</geometry>
|
| 213 |
-
</visual>
|
| 214 |
-
<visual name="base_body-3">
|
| 215 |
-
<origin xyz="0 0 0"/>
|
| 216 |
-
<geometry>
|
| 217 |
-
<mesh filename="textured_objs/original-4.obj"/>
|
| 218 |
-
</geometry>
|
| 219 |
-
</visual>
|
| 220 |
-
<visual name="base_body-3">
|
| 221 |
-
<origin xyz="0 0 0"/>
|
| 222 |
-
<geometry>
|
| 223 |
-
<mesh filename="textured_objs/original-3.obj"/>
|
| 224 |
-
</geometry>
|
| 225 |
-
</visual>
|
| 226 |
-
<visual name="base_body-3">
|
| 227 |
-
<origin xyz="0 0 0"/>
|
| 228 |
-
<geometry>
|
| 229 |
-
<mesh filename="textured_objs/original-65.obj"/>
|
| 230 |
-
</geometry>
|
| 231 |
-
</visual>
|
| 232 |
-
<visual name="base_body-3">
|
| 233 |
-
<origin xyz="0 0 0"/>
|
| 234 |
-
<geometry>
|
| 235 |
-
<mesh filename="textured_objs/original-33.obj"/>
|
| 236 |
-
</geometry>
|
| 237 |
-
</visual>
|
| 238 |
-
<visual name="base_body-3">
|
| 239 |
-
<origin xyz="0 0 0"/>
|
| 240 |
-
<geometry>
|
| 241 |
-
<mesh filename="textured_objs/original-2.obj"/>
|
| 242 |
-
</geometry>
|
| 243 |
-
</visual>
|
| 244 |
-
<visual name="base_body-3">
|
| 245 |
-
<origin xyz="0 0 0"/>
|
| 246 |
-
<geometry>
|
| 247 |
-
<mesh filename="textured_objs/original-44.obj"/>
|
| 248 |
-
</geometry>
|
| 249 |
-
</visual>
|
| 250 |
-
<visual name="base_body-3">
|
| 251 |
-
<origin xyz="0 0 0"/>
|
| 252 |
-
<geometry>
|
| 253 |
-
<mesh filename="textured_objs/original-8.obj"/>
|
| 254 |
-
</geometry>
|
| 255 |
-
</visual>
|
| 256 |
-
<visual name="base_body-3">
|
| 257 |
-
<origin xyz="0 0 0"/>
|
| 258 |
-
<geometry>
|
| 259 |
-
<mesh filename="textured_objs/original-9.obj"/>
|
| 260 |
-
</geometry>
|
| 261 |
-
</visual>
|
| 262 |
-
<visual name="base_body-3">
|
| 263 |
-
<origin xyz="0 0 0"/>
|
| 264 |
-
<geometry>
|
| 265 |
-
<mesh filename="textured_objs/original-45.obj"/>
|
| 266 |
-
</geometry>
|
| 267 |
-
</visual>
|
| 268 |
-
<visual name="base_body-3">
|
| 269 |
-
<origin xyz="0 0 0"/>
|
| 270 |
-
<geometry>
|
| 271 |
-
<mesh filename="textured_objs/original-35.obj"/>
|
| 272 |
-
</geometry>
|
| 273 |
-
</visual>
|
| 274 |
-
<visual name="base_body-3">
|
| 275 |
-
<origin xyz="0 0 0"/>
|
| 276 |
-
<geometry>
|
| 277 |
-
<mesh filename="textured_objs/original-61.obj"/>
|
| 278 |
-
</geometry>
|
| 279 |
-
</visual>
|
| 280 |
-
<visual name="base_body-3">
|
| 281 |
-
<origin xyz="0 0 0"/>
|
| 282 |
-
<geometry>
|
| 283 |
-
<mesh filename="textured_objs/original-59.obj"/>
|
| 284 |
-
</geometry>
|
| 285 |
-
</visual>
|
| 286 |
-
<visual name="base_body-3">
|
| 287 |
-
<origin xyz="0 0 0"/>
|
| 288 |
-
<geometry>
|
| 289 |
-
<mesh filename="textured_objs/original-5.obj"/>
|
| 290 |
-
</geometry>
|
| 291 |
-
</visual>
|
| 292 |
-
<visual name="base_body-3">
|
| 293 |
-
<origin xyz="0 0 0"/>
|
| 294 |
-
<geometry>
|
| 295 |
-
<mesh filename="textured_objs/original-77.obj"/>
|
| 296 |
-
</geometry>
|
| 297 |
-
</visual>
|
| 298 |
-
<visual name="base_body-3">
|
| 299 |
-
<origin xyz="0 0 0"/>
|
| 300 |
-
<geometry>
|
| 301 |
-
<mesh filename="textured_objs/original-63.obj"/>
|
| 302 |
-
</geometry>
|
| 303 |
-
</visual>
|
| 304 |
-
<visual name="base_body-3">
|
| 305 |
-
<origin xyz="0 0 0"/>
|
| 306 |
-
<geometry>
|
| 307 |
-
<mesh filename="textured_objs/original-27.obj"/>
|
| 308 |
-
</geometry>
|
| 309 |
-
</visual>
|
| 310 |
-
<visual name="base_body-3">
|
| 311 |
-
<origin xyz="0 0 0"/>
|
| 312 |
-
<geometry>
|
| 313 |
-
<mesh filename="textured_objs/original-6.obj"/>
|
| 314 |
-
</geometry>
|
| 315 |
-
</visual>
|
| 316 |
-
<visual name="base_body-3">
|
| 317 |
-
<origin xyz="0 0 0"/>
|
| 318 |
-
<geometry>
|
| 319 |
-
<mesh filename="textured_objs/original-31.obj"/>
|
| 320 |
-
</geometry>
|
| 321 |
-
</visual>
|
| 322 |
-
<visual name="base_body-3">
|
| 323 |
-
<origin xyz="0 0 0"/>
|
| 324 |
-
<geometry>
|
| 325 |
-
<mesh filename="textured_objs/original-37.obj"/>
|
| 326 |
-
</geometry>
|
| 327 |
-
</visual>
|
| 328 |
-
<visual name="base_body-3">
|
| 329 |
-
<origin xyz="0 0 0"/>
|
| 330 |
-
<geometry>
|
| 331 |
-
<mesh filename="textured_objs/original-15.obj"/>
|
| 332 |
-
</geometry>
|
| 333 |
-
</visual>
|
| 334 |
-
<visual name="base_body-3">
|
| 335 |
-
<origin xyz="0 0 0"/>
|
| 336 |
-
<geometry>
|
| 337 |
-
<mesh filename="textured_objs/original-76.obj"/>
|
| 338 |
-
</geometry>
|
| 339 |
-
</visual>
|
| 340 |
-
<visual name="base_body-3">
|
| 341 |
-
<origin xyz="0 0 0"/>
|
| 342 |
-
<geometry>
|
| 343 |
-
<mesh filename="textured_objs/original-72.obj"/>
|
| 344 |
-
</geometry>
|
| 345 |
-
</visual>
|
| 346 |
-
<visual name="base_body-3">
|
| 347 |
-
<origin xyz="0 0 0"/>
|
| 348 |
-
<geometry>
|
| 349 |
-
<mesh filename="textured_objs/original-62.obj"/>
|
| 350 |
-
</geometry>
|
| 351 |
-
</visual>
|
| 352 |
-
<visual name="base_body-3">
|
| 353 |
-
<origin xyz="0 0 0"/>
|
| 354 |
-
<geometry>
|
| 355 |
-
<mesh filename="textured_objs/original-75.obj"/>
|
| 356 |
-
</geometry>
|
| 357 |
-
</visual>
|
| 358 |
-
<visual name="base_body-3">
|
| 359 |
-
<origin xyz="0 0 0"/>
|
| 360 |
-
<geometry>
|
| 361 |
-
<mesh filename="textured_objs/original-66.obj"/>
|
| 362 |
-
</geometry>
|
| 363 |
-
</visual>
|
| 364 |
-
<visual name="base_body-3">
|
| 365 |
-
<origin xyz="0 0 0"/>
|
| 366 |
-
<geometry>
|
| 367 |
-
<mesh filename="textured_objs/original-58.obj"/>
|
| 368 |
-
</geometry>
|
| 369 |
-
</visual>
|
| 370 |
-
<visual name="base_body-3">
|
| 371 |
-
<origin xyz="0 0 0"/>
|
| 372 |
-
<geometry>
|
| 373 |
-
<mesh filename="textured_objs/original-67.obj"/>
|
| 374 |
-
</geometry>
|
| 375 |
-
</visual>
|
| 376 |
-
<visual name="base_body-3">
|
| 377 |
-
<origin xyz="0 0 0"/>
|
| 378 |
-
<geometry>
|
| 379 |
-
<mesh filename="textured_objs/original-69.obj"/>
|
| 380 |
-
</geometry>
|
| 381 |
-
</visual>
|
| 382 |
-
<visual name="base_body-3">
|
| 383 |
-
<origin xyz="0 0 0"/>
|
| 384 |
-
<geometry>
|
| 385 |
-
<mesh filename="textured_objs/original-11.obj"/>
|
| 386 |
-
</geometry>
|
| 387 |
-
</visual>
|
| 388 |
-
<visual name="base_body-3">
|
| 389 |
-
<origin xyz="0 0 0"/>
|
| 390 |
-
<geometry>
|
| 391 |
-
<mesh filename="textured_objs/original-38.obj"/>
|
| 392 |
-
</geometry>
|
| 393 |
-
</visual>
|
| 394 |
-
<visual name="base_body-3">
|
| 395 |
-
<origin xyz="0 0 0"/>
|
| 396 |
-
<geometry>
|
| 397 |
-
<mesh filename="textured_objs/original-68.obj"/>
|
| 398 |
-
</geometry>
|
| 399 |
-
</visual>
|
| 400 |
-
<visual name="base_body-3">
|
| 401 |
-
<origin xyz="0 0 0"/>
|
| 402 |
-
<geometry>
|
| 403 |
-
<mesh filename="textured_objs/original-80.obj"/>
|
| 404 |
-
</geometry>
|
| 405 |
-
</visual>
|
| 406 |
-
<visual name="base_body-3">
|
| 407 |
-
<origin xyz="0 0 0"/>
|
| 408 |
-
<geometry>
|
| 409 |
-
<mesh filename="textured_objs/original-18.obj"/>
|
| 410 |
-
</geometry>
|
| 411 |
-
</visual>
|
| 412 |
-
<visual name="base_body-3">
|
| 413 |
-
<origin xyz="0 0 0"/>
|
| 414 |
-
<geometry>
|
| 415 |
-
<mesh filename="textured_objs/original-70.obj"/>
|
| 416 |
-
</geometry>
|
| 417 |
-
</visual>
|
| 418 |
-
<visual name="base_body-3">
|
| 419 |
-
<origin xyz="0 0 0"/>
|
| 420 |
-
<geometry>
|
| 421 |
-
<mesh filename="textured_objs/original-74.obj"/>
|
| 422 |
-
</geometry>
|
| 423 |
-
</visual>
|
| 424 |
-
<visual name="base_body-3">
|
| 425 |
-
<origin xyz="0 0 0"/>
|
| 426 |
-
<geometry>
|
| 427 |
-
<mesh filename="textured_objs/original-25.obj"/>
|
| 428 |
-
</geometry>
|
| 429 |
-
</visual>
|
| 430 |
-
<visual name="base_body-3">
|
| 431 |
-
<origin xyz="0 0 0"/>
|
| 432 |
-
<geometry>
|
| 433 |
-
<mesh filename="textured_objs/original-17.obj"/>
|
| 434 |
-
</geometry>
|
| 435 |
-
</visual>
|
| 436 |
-
<visual name="base_body-3">
|
| 437 |
-
<origin xyz="0 0 0"/>
|
| 438 |
-
<geometry>
|
| 439 |
-
<mesh filename="textured_objs/original-73.obj"/>
|
| 440 |
-
</geometry>
|
| 441 |
-
</visual>
|
| 442 |
-
<visual name="base_body-3">
|
| 443 |
-
<origin xyz="0 0 0"/>
|
| 444 |
-
<geometry>
|
| 445 |
-
<mesh filename="textured_objs/original-42.obj"/>
|
| 446 |
-
</geometry>
|
| 447 |
-
</visual>
|
| 448 |
-
<visual name="base_body-3">
|
| 449 |
-
<origin xyz="0 0 0"/>
|
| 450 |
-
<geometry>
|
| 451 |
-
<mesh filename="textured_objs/original-79.obj"/>
|
| 452 |
-
</geometry>
|
| 453 |
-
</visual>
|
| 454 |
-
<visual name="base_body-3">
|
| 455 |
-
<origin xyz="0 0 0"/>
|
| 456 |
-
<geometry>
|
| 457 |
-
<mesh filename="textured_objs/original-24.obj"/>
|
| 458 |
-
</geometry>
|
| 459 |
-
</visual>
|
| 460 |
-
<visual name="base_body-3">
|
| 461 |
-
<origin xyz="0 0 0"/>
|
| 462 |
-
<geometry>
|
| 463 |
-
<mesh filename="textured_objs/original-20.obj"/>
|
| 464 |
-
</geometry>
|
| 465 |
-
</visual>
|
| 466 |
-
<visual name="base_body-3">
|
| 467 |
-
<origin xyz="0 0 0"/>
|
| 468 |
-
<geometry>
|
| 469 |
-
<mesh filename="textured_objs/original-32.obj"/>
|
| 470 |
-
</geometry>
|
| 471 |
-
</visual>
|
| 472 |
-
<visual name="base_body-3">
|
| 473 |
-
<origin xyz="0 0 0"/>
|
| 474 |
-
<geometry>
|
| 475 |
-
<mesh filename="textured_objs/original-7.obj"/>
|
| 476 |
-
</geometry>
|
| 477 |
-
</visual>
|
| 478 |
-
<visual name="base_body-3">
|
| 479 |
-
<origin xyz="0 0 0"/>
|
| 480 |
-
<geometry>
|
| 481 |
-
<mesh filename="textured_objs/original-81.obj"/>
|
| 482 |
-
</geometry>
|
| 483 |
-
</visual>
|
| 484 |
-
<visual name="base_body-3">
|
| 485 |
-
<origin xyz="0 0 0"/>
|
| 486 |
-
<geometry>
|
| 487 |
-
<mesh filename="textured_objs/original-84.obj"/>
|
| 488 |
-
</geometry>
|
| 489 |
-
</visual>
|
| 490 |
-
<visual name="base_body-3">
|
| 491 |
-
<origin xyz="0 0 0"/>
|
| 492 |
-
<geometry>
|
| 493 |
-
<mesh filename="textured_objs/original-78.obj"/>
|
| 494 |
-
</geometry>
|
| 495 |
-
</visual>
|
| 496 |
-
<visual name="base_body-3">
|
| 497 |
-
<origin xyz="0 0 0"/>
|
| 498 |
-
<geometry>
|
| 499 |
-
<mesh filename="textured_objs/original-10.obj"/>
|
| 500 |
-
</geometry>
|
| 501 |
-
</visual>
|
| 502 |
-
<visual name="base_body-3">
|
| 503 |
-
<origin xyz="0 0 0"/>
|
| 504 |
-
<geometry>
|
| 505 |
-
<mesh filename="textured_objs/original-14.obj"/>
|
| 506 |
-
</geometry>
|
| 507 |
-
</visual>
|
| 508 |
-
<visual name="base_body-3">
|
| 509 |
-
<origin xyz="0 0 0"/>
|
| 510 |
-
<geometry>
|
| 511 |
-
<mesh filename="textured_objs/original-82.obj"/>
|
| 512 |
-
</geometry>
|
| 513 |
-
</visual>
|
| 514 |
-
<visual name="base_body-3">
|
| 515 |
-
<origin xyz="0 0 0"/>
|
| 516 |
-
<geometry>
|
| 517 |
-
<mesh filename="textured_objs/original-60.obj"/>
|
| 518 |
-
</geometry>
|
| 519 |
-
</visual>
|
| 520 |
-
<visual name="base_body-3">
|
| 521 |
-
<origin xyz="0 0 0"/>
|
| 522 |
-
<geometry>
|
| 523 |
-
<mesh filename="textured_objs/original-40.obj"/>
|
| 524 |
-
</geometry>
|
| 525 |
-
</visual>
|
| 526 |
-
<collision>
|
| 527 |
-
<origin xyz="0 0 0"/>
|
| 528 |
-
<geometry>
|
| 529 |
-
<mesh filename="textured_objs/original-29.obj"/>
|
| 530 |
-
</geometry>
|
| 531 |
-
</collision>
|
| 532 |
-
<collision>
|
| 533 |
-
<origin xyz="0 0 0"/>
|
| 534 |
-
<geometry>
|
| 535 |
-
<mesh filename="textured_objs/original-30.obj"/>
|
| 536 |
-
</geometry>
|
| 537 |
-
</collision>
|
| 538 |
-
<collision>
|
| 539 |
-
<origin xyz="0 0 0"/>
|
| 540 |
-
<geometry>
|
| 541 |
-
<mesh filename="textured_objs/original-36.obj"/>
|
| 542 |
-
</geometry>
|
| 543 |
-
</collision>
|
| 544 |
-
<collision>
|
| 545 |
-
<origin xyz="0 0 0"/>
|
| 546 |
-
<geometry>
|
| 547 |
-
<mesh filename="textured_objs/original-41.obj"/>
|
| 548 |
-
</geometry>
|
| 549 |
-
</collision>
|
| 550 |
-
<collision>
|
| 551 |
-
<origin xyz="0 0 0"/>
|
| 552 |
-
<geometry>
|
| 553 |
-
<mesh filename="textured_objs/original-28.obj"/>
|
| 554 |
-
</geometry>
|
| 555 |
-
</collision>
|
| 556 |
-
<collision>
|
| 557 |
-
<origin xyz="0 0 0"/>
|
| 558 |
-
<geometry>
|
| 559 |
-
<mesh filename="textured_objs/original-64.obj"/>
|
| 560 |
-
</geometry>
|
| 561 |
-
</collision>
|
| 562 |
-
<collision>
|
| 563 |
-
<origin xyz="0 0 0"/>
|
| 564 |
-
<geometry>
|
| 565 |
-
<mesh filename="textured_objs/original-71.obj"/>
|
| 566 |
-
</geometry>
|
| 567 |
-
</collision>
|
| 568 |
-
<collision>
|
| 569 |
-
<origin xyz="0 0 0"/>
|
| 570 |
-
<geometry>
|
| 571 |
-
<mesh filename="textured_objs/original-83.obj"/>
|
| 572 |
-
</geometry>
|
| 573 |
-
</collision>
|
| 574 |
-
<collision>
|
| 575 |
-
<origin xyz="0 0 0"/>
|
| 576 |
-
<geometry>
|
| 577 |
-
<mesh filename="textured_objs/original-22.obj"/>
|
| 578 |
-
</geometry>
|
| 579 |
-
</collision>
|
| 580 |
-
<collision>
|
| 581 |
-
<origin xyz="0 0 0"/>
|
| 582 |
-
<geometry>
|
| 583 |
-
<mesh filename="textured_objs/original-26.obj"/>
|
| 584 |
-
</geometry>
|
| 585 |
-
</collision>
|
| 586 |
-
<collision>
|
| 587 |
-
<origin xyz="0 0 0"/>
|
| 588 |
-
<geometry>
|
| 589 |
-
<mesh filename="textured_objs/original-4.obj"/>
|
| 590 |
-
</geometry>
|
| 591 |
-
</collision>
|
| 592 |
-
<collision>
|
| 593 |
-
<origin xyz="0 0 0"/>
|
| 594 |
-
<geometry>
|
| 595 |
-
<mesh filename="textured_objs/original-3.obj"/>
|
| 596 |
-
</geometry>
|
| 597 |
-
</collision>
|
| 598 |
-
<collision>
|
| 599 |
-
<origin xyz="0 0 0"/>
|
| 600 |
-
<geometry>
|
| 601 |
-
<mesh filename="textured_objs/original-65.obj"/>
|
| 602 |
-
</geometry>
|
| 603 |
-
</collision>
|
| 604 |
-
<collision>
|
| 605 |
-
<origin xyz="0 0 0"/>
|
| 606 |
-
<geometry>
|
| 607 |
-
<mesh filename="textured_objs/original-33.obj"/>
|
| 608 |
-
</geometry>
|
| 609 |
-
</collision>
|
| 610 |
-
<collision>
|
| 611 |
-
<origin xyz="0 0 0"/>
|
| 612 |
-
<geometry>
|
| 613 |
-
<mesh filename="textured_objs/original-2.obj"/>
|
| 614 |
-
</geometry>
|
| 615 |
-
</collision>
|
| 616 |
-
<collision>
|
| 617 |
-
<origin xyz="0 0 0"/>
|
| 618 |
-
<geometry>
|
| 619 |
-
<mesh filename="textured_objs/original-44.obj"/>
|
| 620 |
-
</geometry>
|
| 621 |
-
</collision>
|
| 622 |
-
<collision>
|
| 623 |
-
<origin xyz="0 0 0"/>
|
| 624 |
-
<geometry>
|
| 625 |
-
<mesh filename="textured_objs/original-8.obj"/>
|
| 626 |
-
</geometry>
|
| 627 |
-
</collision>
|
| 628 |
-
<collision>
|
| 629 |
-
<origin xyz="0 0 0"/>
|
| 630 |
-
<geometry>
|
| 631 |
-
<mesh filename="textured_objs/original-9.obj"/>
|
| 632 |
-
</geometry>
|
| 633 |
-
</collision>
|
| 634 |
-
<collision>
|
| 635 |
-
<origin xyz="0 0 0"/>
|
| 636 |
-
<geometry>
|
| 637 |
-
<mesh filename="textured_objs/original-45.obj"/>
|
| 638 |
-
</geometry>
|
| 639 |
-
</collision>
|
| 640 |
-
<collision>
|
| 641 |
-
<origin xyz="0 0 0"/>
|
| 642 |
-
<geometry>
|
| 643 |
-
<mesh filename="textured_objs/original-35.obj"/>
|
| 644 |
-
</geometry>
|
| 645 |
-
</collision>
|
| 646 |
-
<collision>
|
| 647 |
-
<origin xyz="0 0 0"/>
|
| 648 |
-
<geometry>
|
| 649 |
-
<mesh filename="textured_objs/original-61.obj"/>
|
| 650 |
-
</geometry>
|
| 651 |
-
</collision>
|
| 652 |
-
<collision>
|
| 653 |
-
<origin xyz="0 0 0"/>
|
| 654 |
-
<geometry>
|
| 655 |
-
<mesh filename="textured_objs/original-59.obj"/>
|
| 656 |
-
</geometry>
|
| 657 |
-
</collision>
|
| 658 |
-
<collision>
|
| 659 |
-
<origin xyz="0 0 0"/>
|
| 660 |
-
<geometry>
|
| 661 |
-
<mesh filename="textured_objs/original-5.obj"/>
|
| 662 |
-
</geometry>
|
| 663 |
-
</collision>
|
| 664 |
-
<collision>
|
| 665 |
-
<origin xyz="0 0 0"/>
|
| 666 |
-
<geometry>
|
| 667 |
-
<mesh filename="textured_objs/original-77.obj"/>
|
| 668 |
-
</geometry>
|
| 669 |
-
</collision>
|
| 670 |
-
<collision>
|
| 671 |
-
<origin xyz="0 0 0"/>
|
| 672 |
-
<geometry>
|
| 673 |
-
<mesh filename="textured_objs/original-63.obj"/>
|
| 674 |
-
</geometry>
|
| 675 |
-
</collision>
|
| 676 |
-
<collision>
|
| 677 |
-
<origin xyz="0 0 0"/>
|
| 678 |
-
<geometry>
|
| 679 |
-
<mesh filename="textured_objs/original-27.obj"/>
|
| 680 |
-
</geometry>
|
| 681 |
-
</collision>
|
| 682 |
-
<collision>
|
| 683 |
-
<origin xyz="0 0 0"/>
|
| 684 |
-
<geometry>
|
| 685 |
-
<mesh filename="textured_objs/original-6.obj"/>
|
| 686 |
-
</geometry>
|
| 687 |
-
</collision>
|
| 688 |
-
<collision>
|
| 689 |
-
<origin xyz="0 0 0"/>
|
| 690 |
-
<geometry>
|
| 691 |
-
<mesh filename="textured_objs/original-31.obj"/>
|
| 692 |
-
</geometry>
|
| 693 |
-
</collision>
|
| 694 |
-
<collision>
|
| 695 |
-
<origin xyz="0 0 0"/>
|
| 696 |
-
<geometry>
|
| 697 |
-
<mesh filename="textured_objs/original-37.obj"/>
|
| 698 |
-
</geometry>
|
| 699 |
-
</collision>
|
| 700 |
-
<collision>
|
| 701 |
-
<origin xyz="0 0 0"/>
|
| 702 |
-
<geometry>
|
| 703 |
-
<mesh filename="textured_objs/original-15.obj"/>
|
| 704 |
-
</geometry>
|
| 705 |
-
</collision>
|
| 706 |
-
<collision>
|
| 707 |
-
<origin xyz="0 0 0"/>
|
| 708 |
-
<geometry>
|
| 709 |
-
<mesh filename="textured_objs/original-76.obj"/>
|
| 710 |
-
</geometry>
|
| 711 |
-
</collision>
|
| 712 |
-
<collision>
|
| 713 |
-
<origin xyz="0 0 0"/>
|
| 714 |
-
<geometry>
|
| 715 |
-
<mesh filename="textured_objs/original-72.obj"/>
|
| 716 |
-
</geometry>
|
| 717 |
-
</collision>
|
| 718 |
-
<collision>
|
| 719 |
-
<origin xyz="0 0 0"/>
|
| 720 |
-
<geometry>
|
| 721 |
-
<mesh filename="textured_objs/original-62.obj"/>
|
| 722 |
-
</geometry>
|
| 723 |
-
</collision>
|
| 724 |
-
<collision>
|
| 725 |
-
<origin xyz="0 0 0"/>
|
| 726 |
-
<geometry>
|
| 727 |
-
<mesh filename="textured_objs/original-75.obj"/>
|
| 728 |
-
</geometry>
|
| 729 |
-
</collision>
|
| 730 |
-
<collision>
|
| 731 |
-
<origin xyz="0 0 0"/>
|
| 732 |
-
<geometry>
|
| 733 |
-
<mesh filename="textured_objs/original-66.obj"/>
|
| 734 |
-
</geometry>
|
| 735 |
-
</collision>
|
| 736 |
-
<collision>
|
| 737 |
-
<origin xyz="0 0 0"/>
|
| 738 |
-
<geometry>
|
| 739 |
-
<mesh filename="textured_objs/original-58.obj"/>
|
| 740 |
-
</geometry>
|
| 741 |
-
</collision>
|
| 742 |
-
<collision>
|
| 743 |
-
<origin xyz="0 0 0"/>
|
| 744 |
-
<geometry>
|
| 745 |
-
<mesh filename="textured_objs/original-67.obj"/>
|
| 746 |
-
</geometry>
|
| 747 |
-
</collision>
|
| 748 |
-
<collision>
|
| 749 |
-
<origin xyz="0 0 0"/>
|
| 750 |
-
<geometry>
|
| 751 |
-
<mesh filename="textured_objs/original-69.obj"/>
|
| 752 |
-
</geometry>
|
| 753 |
-
</collision>
|
| 754 |
-
<collision>
|
| 755 |
-
<origin xyz="0 0 0"/>
|
| 756 |
-
<geometry>
|
| 757 |
-
<mesh filename="textured_objs/original-11.obj"/>
|
| 758 |
-
</geometry>
|
| 759 |
-
</collision>
|
| 760 |
-
<collision>
|
| 761 |
-
<origin xyz="0 0 0"/>
|
| 762 |
-
<geometry>
|
| 763 |
-
<mesh filename="textured_objs/original-38.obj"/>
|
| 764 |
-
</geometry>
|
| 765 |
-
</collision>
|
| 766 |
-
<collision>
|
| 767 |
-
<origin xyz="0 0 0"/>
|
| 768 |
-
<geometry>
|
| 769 |
-
<mesh filename="textured_objs/original-68.obj"/>
|
| 770 |
-
</geometry>
|
| 771 |
-
</collision>
|
| 772 |
-
<collision>
|
| 773 |
-
<origin xyz="0 0 0"/>
|
| 774 |
-
<geometry>
|
| 775 |
-
<mesh filename="textured_objs/original-80.obj"/>
|
| 776 |
-
</geometry>
|
| 777 |
-
</collision>
|
| 778 |
-
<collision>
|
| 779 |
-
<origin xyz="0 0 0"/>
|
| 780 |
-
<geometry>
|
| 781 |
-
<mesh filename="textured_objs/original-18.obj"/>
|
| 782 |
-
</geometry>
|
| 783 |
-
</collision>
|
| 784 |
-
<collision>
|
| 785 |
-
<origin xyz="0 0 0"/>
|
| 786 |
-
<geometry>
|
| 787 |
-
<mesh filename="textured_objs/original-70.obj"/>
|
| 788 |
-
</geometry>
|
| 789 |
-
</collision>
|
| 790 |
-
<collision>
|
| 791 |
-
<origin xyz="0 0 0"/>
|
| 792 |
-
<geometry>
|
| 793 |
-
<mesh filename="textured_objs/original-74.obj"/>
|
| 794 |
-
</geometry>
|
| 795 |
-
</collision>
|
| 796 |
-
<collision>
|
| 797 |
-
<origin xyz="0 0 0"/>
|
| 798 |
-
<geometry>
|
| 799 |
-
<mesh filename="textured_objs/original-25.obj"/>
|
| 800 |
-
</geometry>
|
| 801 |
-
</collision>
|
| 802 |
-
<collision>
|
| 803 |
-
<origin xyz="0 0 0"/>
|
| 804 |
-
<geometry>
|
| 805 |
-
<mesh filename="textured_objs/original-17.obj"/>
|
| 806 |
-
</geometry>
|
| 807 |
-
</collision>
|
| 808 |
-
<collision>
|
| 809 |
-
<origin xyz="0 0 0"/>
|
| 810 |
-
<geometry>
|
| 811 |
-
<mesh filename="textured_objs/original-73.obj"/>
|
| 812 |
-
</geometry>
|
| 813 |
-
</collision>
|
| 814 |
-
<collision>
|
| 815 |
-
<origin xyz="0 0 0"/>
|
| 816 |
-
<geometry>
|
| 817 |
-
<mesh filename="textured_objs/original-42.obj"/>
|
| 818 |
-
</geometry>
|
| 819 |
-
</collision>
|
| 820 |
-
<collision>
|
| 821 |
-
<origin xyz="0 0 0"/>
|
| 822 |
-
<geometry>
|
| 823 |
-
<mesh filename="textured_objs/original-79.obj"/>
|
| 824 |
-
</geometry>
|
| 825 |
-
</collision>
|
| 826 |
-
<collision>
|
| 827 |
-
<origin xyz="0 0 0"/>
|
| 828 |
-
<geometry>
|
| 829 |
-
<mesh filename="textured_objs/original-24.obj"/>
|
| 830 |
-
</geometry>
|
| 831 |
-
</collision>
|
| 832 |
-
<collision>
|
| 833 |
-
<origin xyz="0 0 0"/>
|
| 834 |
-
<geometry>
|
| 835 |
-
<mesh filename="textured_objs/original-20.obj"/>
|
| 836 |
-
</geometry>
|
| 837 |
-
</collision>
|
| 838 |
-
<collision>
|
| 839 |
-
<origin xyz="0 0 0"/>
|
| 840 |
-
<geometry>
|
| 841 |
-
<mesh filename="textured_objs/original-32.obj"/>
|
| 842 |
-
</geometry>
|
| 843 |
-
</collision>
|
| 844 |
-
<collision>
|
| 845 |
-
<origin xyz="0 0 0"/>
|
| 846 |
-
<geometry>
|
| 847 |
-
<mesh filename="textured_objs/original-7.obj"/>
|
| 848 |
-
</geometry>
|
| 849 |
-
</collision>
|
| 850 |
-
<collision>
|
| 851 |
-
<origin xyz="0 0 0"/>
|
| 852 |
-
<geometry>
|
| 853 |
-
<mesh filename="textured_objs/original-81.obj"/>
|
| 854 |
-
</geometry>
|
| 855 |
-
</collision>
|
| 856 |
-
<collision>
|
| 857 |
-
<origin xyz="0 0 0"/>
|
| 858 |
-
<geometry>
|
| 859 |
-
<mesh filename="textured_objs/original-84.obj"/>
|
| 860 |
-
</geometry>
|
| 861 |
-
</collision>
|
| 862 |
-
<collision>
|
| 863 |
-
<origin xyz="0 0 0"/>
|
| 864 |
-
<geometry>
|
| 865 |
-
<mesh filename="textured_objs/original-78.obj"/>
|
| 866 |
-
</geometry>
|
| 867 |
-
</collision>
|
| 868 |
-
<collision>
|
| 869 |
-
<origin xyz="0 0 0"/>
|
| 870 |
-
<geometry>
|
| 871 |
-
<mesh filename="textured_objs/original-10.obj"/>
|
| 872 |
-
</geometry>
|
| 873 |
-
</collision>
|
| 874 |
-
<collision>
|
| 875 |
-
<origin xyz="0 0 0"/>
|
| 876 |
-
<geometry>
|
| 877 |
-
<mesh filename="textured_objs/original-14.obj"/>
|
| 878 |
-
</geometry>
|
| 879 |
-
</collision>
|
| 880 |
-
<collision>
|
| 881 |
-
<origin xyz="0 0 0"/>
|
| 882 |
-
<geometry>
|
| 883 |
-
<mesh filename="textured_objs/original-82.obj"/>
|
| 884 |
-
</geometry>
|
| 885 |
-
</collision>
|
| 886 |
-
<collision>
|
| 887 |
-
<origin xyz="0 0 0"/>
|
| 888 |
-
<geometry>
|
| 889 |
-
<mesh filename="textured_objs/original-60.obj"/>
|
| 890 |
-
</geometry>
|
| 891 |
-
</collision>
|
| 892 |
-
<collision>
|
| 893 |
-
<origin xyz="0 0 0"/>
|
| 894 |
-
<geometry>
|
| 895 |
-
<mesh filename="textured_objs/original-40.obj"/>
|
| 896 |
-
</geometry>
|
| 897 |
-
</collision>
|
| 898 |
-
</link>
|
| 899 |
-
<joint name="joint_2" type="fixed">
|
| 900 |
-
<origin rpy="1.570796326794897 0 -1.570796326794897" xyz="0 0 0"/>
|
| 901 |
-
<child link="link_2"/>
|
| 902 |
-
<parent link="base"/>
|
| 903 |
-
</joint>
|
| 904 |
-
</robot>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/PartNet/101363/00_pure.png
DELETED
Git LFS Details
|
datasets/PartNet/101363/00_seg.png
DELETED
Git LFS Details
|