diff --git a/.gitattributes b/.gitattributes
index 39d5ad6d0b23a59328e18723e04f051485fb9b7c..9b11c0a01f45c20cc352a2761705cbd7e666361d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -32,6 +32,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
+*.so filter=lfs diff=lfs merge=lfs -text
+*.o filter=lfs diff=lfs merge=lfs -text
+*.obj filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
checkpoints/face_0929/gaussianhead_latest filter=lfs diff=lfs merge=lfs -text
checkpoints/face_0929/supres_latest filter=lfs diff=lfs merge=lfs -text
@@ -40,3 +43,20 @@ checkpoints/pos_map_ys/body_mix/smpl_pos_map/cano_smpl_nml_map.exr filter=lfs di
checkpoints/pos_map_ys/body_mix/smpl_pos_map/cano_smpl_pos_map.exr filter=lfs diff=lfs merge=lfs -text
checkpoints/ref_gaussian/head/000000.ply filter=lfs diff=lfs merge=lfs -text
checkpoints/ filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/lib.linux-x86_64-cpython-310/fused.cpython-310-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/lib.linux-x86_64-cpython-310/upfirdn2d.cpython-310-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.linux-x86_64-cpython-310/fused_bias_act.o filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.linux-x86_64-cpython-310/upfirdn2d.o filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.win-amd64-cpython-38/Release/fused_bias_act.obj filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.win-amd64-cpython-38/Release/upfirdn2d.obj filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/posevocab_custom_ops/build/lib.linux-x86_64-cpython-38/posevocab_custom_ops.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/posevocab_custom_ops/build/temp.linux-x86_64-cpython-38/bind.o filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/root_finding/build/lib.linux-x86_64-cpython-38/root_finding.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/root_finding/build/temp.linux-x86_64-cpython-38/bind.o filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/assets/avatarrex_dataset_demo.gif filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.win-amd64-cpython-38/Release/fused_bias_act_kernel.obj filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/build/temp.win-amd64-cpython-38/Release/upfirdn2d_kernel.obj filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/dist/fused-0.0.0-py3.10-linux-x86_64.egg filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/network/styleunet/dist/upfirdn2d-0.0.0-py3.10-linux-x86_64.egg filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/posevocab_custom_ops/dist/posevocab_custom_ops-0.0.0-py3.8-linux-x86_64.egg filter=lfs diff=lfs merge=lfs -text
+AnimatableGaussians/utils/root_finding/dist/root_finding-0.0.0-py3.8-linux-x86_64.egg filter=lfs diff=lfs merge=lfs -text
diff --git a/AnimatableGaussians b/AnimatableGaussians
deleted file mode 160000
index f92794c6aaaf7ee69de63afce579b5fddc9e5467..0000000000000000000000000000000000000000
--- a/AnimatableGaussians
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f92794c6aaaf7ee69de63afce579b5fddc9e5467
diff --git a/AnimatableGaussians/.DS_Store b/AnimatableGaussians/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..7fc578bafb24761c77841c5e35005f1f60519992
Binary files /dev/null and b/AnimatableGaussians/.DS_Store differ
diff --git a/AnimatableGaussians/AVATARREX_DATASET.md b/AnimatableGaussians/AVATARREX_DATASET.md
new file mode 100644
index 0000000000000000000000000000000000000000..79e3ad7f4f60de0ab5e2179bf89d849f23bd31a1
--- /dev/null
+++ b/AnimatableGaussians/AVATARREX_DATASET.md
@@ -0,0 +1,168 @@
+# AvatarReX Dataset
+
+### AvatarReX: Real-time Expressive Full-body Avatars
+Zerong Zheng, Xiaochen Zhao, Hongwen Zhang, Boning Liu, Yebin Liu. SIGGRAPH 2023
+
+[[Project Page]](https://liuyebin.com/AvatarRex/)
+
+![teaser](./assets/avatarrex.jpg)
+
+This dataset contains four multi-view image sequences used in our paper "AvatarReX: Real-time Expressive Full-body Avatars". They are captured with 16 well-calibrated RGB cameras in 30 fps, with a resolution of 1500×2048 and lengths ranging from 1800 to 2000 frames. We use the data to evaluate our method for building animatable human body avatars.
+
+We also provide the SMPL-X fitting in the dataset.
+
+
+## Agreement
+1. The AvatarReX dataset (the "Dataset") is available for **non-commercial** research purposes only. Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The dataset may not be used for pornographic purposes or to generate pornographic material whether commercial or not. The Dataset may not be reproduced, modified and/or made available in any form to any third party without Tsinghua University’s prior written permission.
+
+2. You agree **not to** reproduce, modified, duplicate, copy, sell, trade, resell or exploit any portion of the images and any portion of derived data in any form to any third party without Tsinghua University’s prior written permission.
+
+3. You agree **not to** further copy, publish or distribute any portion of the Dataset. Except, for internal use at a single site within the same organization it is allowed to make copies of the dataset.
+
+4. Tsinghua University reserves the right to terminate your access to the Dataset at any time.
+
+
+## Download Instructions
+The dataset can be directly downloaded from the following links.
+
+* avatarrex_zzr: [this link](https://drive.google.com/file/d/1sCQJ3YU-F3lY9p_HYNIQbT7QyfVKy0HT/view?usp=sharing), 2001 frames in total, ~21 GB
+* avatarrex_zxc: [this link](https://drive.google.com/file/d/1pY1qRj2n6b2YOCmZRVM1D--CXKR02qXU/view?usp=sharing), 1801 frames in total, ~12 GB
+* avatarrex_lbn1: [this link](https://drive.google.com/file/d/1DuESdA5YwvJKapyo7i_KoQxKHHFWzi-w/view?usp=sharing), 1901 frames in total, ~11 GB
+* avatarrex_lbn2: [this link](https://drive.google.com/file/d/1J7ITsYhuWlqhoIkmYni8dL2KJw-wmcy_/view?usp=sharing), 1871 frames in total, ~16 GB
+
+Note again that by downloading the dataset you acknowledge that you have read the agreement, understand it, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Dataset.
+
+
+## Data Explanation
+For each subject, we provide the multi-view images (```./avatarrex_zzr/********/```) as well as the foreground segmentation (```./avatarrex_zzr/********/mask/pha```), which are obtained using [BackgroundMattingV2](https://github.com/PeterL1n/BackgroundMattingV2). The calibration data is provided in ```calibration_full.json```, and the SMPL fitting in ```smpl_params.npz```. Some frames are losed during the capture process, and we provide their filename in ```missing_img_files.txt```.
+
+Here we provide a code snip to show how to parse and visualize the data:
+```python
+import os
+import json
+import numpy as np
+import cv2 as cv
+import torch
+import smplx # (please setup the official SMPL-X model according to: https://pypi.org/project/smplx/)
+
+subject = './avatarrex_zzr'
+# subject = './avatarrex_zxc'
+# subject = './avatarrex_lbn1'
+# subject = './avatarrex_lbn2'
+
+# initialize smpl model
+smpl = smplx.SMPLX(model_path = './smplx', gender = 'neutral', use_pca = False, num_pca_comps = 45, flat_hand_mean = True, batch_size = 1)
+
+# load camera data
+with open(os.path.join(subject, 'calibration_full.json'), 'r') as fp:
+ cam_data = json.load(fp)
+
+# load smpl data
+smpl_data = np.load(os.path.join(subject, 'smpl_params.npz'), allow_pickle = True)
+smpl_data = dict(smpl_data)
+smpl_data = {k: torch.from_numpy(v.astype(np.float32)) for k, v in smpl_data.items()}
+
+frame_num = smpl_data['body_pose'].shape[0]
+for frame_id in range(0, frame_num, 30):
+ smpl_out = smpl.forward(
+ global_orient = smpl_data['global_orient'][frame_id].unsqueeze(0),
+ transl = smpl_data['transl'][frame_id].unsqueeze(0),
+ body_pose = smpl_data['body_pose'][frame_id].unsqueeze(0),
+ jaw_pose = smpl_data['jaw_pose'][frame_id].unsqueeze(0),
+ betas = smpl_data['betas'][0].unsqueeze(0),
+ expression = smpl_data['expression'][frame_id].unsqueeze(0),
+ left_hand_pose = smpl_data['left_hand_pose'][frame_id].unsqueeze(0),
+ right_hand_pose = smpl_data['right_hand_pose'][frame_id].unsqueeze(0),
+ )
+ smpl_verts = smpl_out.vertices # smpl vertices in live poses
+ smpl_verts = smpl_verts.detach().cpu().numpy().squeeze(0)
+
+ smpl_proj_vis = []
+ for cam_id in range(0, len(cam_data), 3):
+ cam_sn = list(cam_data.keys())[cam_id]
+
+ img_fpath = os.path.join(subject, '%s/%08d.jpg' % (cam_sn, frame_id))
+ msk_fpath = os.path.join(subject, '%s/mask/pha/%08d.jpg' % (cam_sn, frame_id))
+
+ if (not os.path.isfile(img_fpath)) or (not os.path.isfile(msk_fpath)):
+ break
+
+ img = cv.imread(img_fpath, cv.IMREAD_UNCHANGED)
+ msk = cv.imread(msk_fpath, cv.IMREAD_GRAYSCALE)
+ img = img * np.uint8(msk > 128)[:, :, np.newaxis] # remove background
+ img_ = cv.resize(img, (img.shape[1] // 2, img.shape[0] // 2))
+
+ # transform smpl from world to camera
+ cam_R = np.array(cam_data[cam_sn]['R']).astype(np.float32).reshape((3, 3))
+ cam_t = np.array(cam_data[cam_sn]['T']).astype(np.float32).reshape((3,))
+ smpl_verts_cam = np.matmul(smpl_verts, cam_R.transpose()) + cam_t.reshape(1, 3)
+
+ # project smpl vertices to the image
+ cam_K = np.array(cam_data[cam_sn]['K']).astype(np.float32).reshape((3, 3))
+ cam_K *= np.array([img_.shape[1] / img.shape[1], img_.shape[0] / img.shape[0], 1.0], dtype = np.float32).reshape(3, 1)
+ smpl_verts_proj = np.matmul(smpl_verts_cam / smpl_verts_cam[:, 2:], cam_K.transpose())
+
+ # visualize the projection
+ smpl_verts_proj = np.round(smpl_verts_proj).astype(np.int32)
+ smpl_verts_proj[:, 0] = np.clip(smpl_verts_proj[:, 0], 0, img_.shape[1] - 1)
+ smpl_verts_proj[:, 1] = np.clip(smpl_verts_proj[:, 1], 0, img_.shape[0] - 1)
+
+ for v in smpl_verts_proj:
+ img_[v[1], v[0], :] = np.array([255, 255, 255], dtype = np.uint8)
+ smpl_proj_vis.append(img_)
+
+ if len(smpl_proj_vis) != 6:
+ continue
+
+ vis = np.concatenate([
+ np.concatenate(smpl_proj_vis[:3], axis = 1),
+ np.concatenate(smpl_proj_vis[3:], axis = 1),
+ ], axis = 0)
+ vis = cv.resize(vis, (0, 0), fx = 0.5, fy = 0.5)
+ cv.imshow('vis', vis)
+ cv.waitKey(1)
+```
+If everything is setup properly, you can see an animation like this:
+
+
+
+
+
+## Related Datasets from THU3DV Lab [[Link]](https://liuyebin.com/dataset.html)
+[[THuman4.0 Dataset]](https://github.com/ZhengZerong/THUman4.0-Dataset/) Containing 3 multi-view RGB sequences captured with 24 well-calibrated cameras as well as corresponding SMPL-X registration.
+
+[[THuman3.0 Dataset]](https://github.com/fwbx529/THuman3.0-Dataset) Containing 20 human-garment combinations, where each combination has 15 to 35 high-quality human scans captured by a dense DLSR rig.
+
+[[MultiHuman Dataset]](https://github.com/y-zheng18/MultiHuman-Dataset/) Containing 453 high-quality scans, each contains 1-3 persons. The dataset can be used to train and evaluate multi-person reconstruction algorithms.
+
+[[THuman2.0 Dataset]](https://github.com/ytrock/THuman2.0-Dataset) Containing 500 high-quality human scans captured by a dense DLSR rig, with SMPL annotations.
+
+
+
+
+## Citation
+If you use this dataset for your research, please consider citing:
+```bibtex
+@article{zheng2023avatarrex,
+ title={AvatarRex: Real-time Expressive Full-body Avatars},
+ author={Zheng, Zerong and Zhao, Xiaochen and Zhang, Hongwen and Liu, Boning and Liu, Yebin},
+ journal={ACM Transactions on Graphics (TOG)},
+ volume={42},
+ number={4},
+ articleno={},
+ year={2023},
+ publisher={ACM New York, NY, USA}
+}
+
+@inproceedings{li2023animatablegaussians,
+ title={Animatable Gaussians: Learning Pose-dependent Gaussian Maps for High-fidelity Human Avatar Modeling},
+ author={Li, Zhe and Zheng, Zerong and Wang, Lizhen and Liu, Yebin},
+ booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
+ year={2024}
+}
+```
+
+## Contact
+- Zerong Zheng [(zrzheng1995@foxmail.com)](mailto:zrzheng1995@foxmail.com)
+- Zhe Li [(lizhe_thu@126.com)](mailto:lizhe_thu@126.com)
+- Yebin Liu [(liuyebin@mail.tsinghua.edu.cn)](mailto:liuyebin@mail.tsinghua.edu.cn)
\ No newline at end of file
diff --git a/AnimatableGaussians/LICENSE b/AnimatableGaussians/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4a77ba443d30bd54f1f5feb57bdf9b0e0efeba49
--- /dev/null
+++ b/AnimatableGaussians/LICENSE
@@ -0,0 +1,39 @@
+Please read carefully the following terms and conditions and any accompanying documentation before you download and/or use Animatable Gaussians Software/Code/Data (the "Software"). By downloading and/or using the Software, you acknowledge that you have read these terms and conditions, understand them, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Software.
+
+Ownership
+
+The Software has been developed at the Tsinghua University and is owned by and proprietary material of the Tsinghua University.
+
+License Grant
+
+Tsinghua University grants you a non-exclusive, non-transferable, free of charge right:
+
+To download the Software and use it on computers owned, leased or otherwise controlled by you and/or your organisation;
+
+To use the Software for the sole purpose of performing non-commercial scientific research, non-commercial education, or non-commercial artistic projects.
+
+Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The Software may not be used for pornographic purposes or to generate pornographic material whether commercial or not. This license also prohibits the use of the Software to train methods/algorithms/neural networks/etc. for commercial use of any kind. The Software may not be reproduced, modified and/or made available in any form to any third party without Tsinghua University’s prior written permission. By downloading the Software, you agree not to reverse engineer it.
+
+Disclaimer of Representations and Warranties
+
+You expressly acknowledge and agree that the Software results from basic research, is provided “AS IS”, may contain errors, and that any use of the Software is at your sole risk. TSINGHUA UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE SOFTWARE, NEITHER EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Tsinghua University makes no representations or warranties (i) regarding the merchantability or fitness for a particular purpose of the Software, (ii) that the use of the Software will not infringe any patents, copyrights or other intellectual property rights of a third party, and (iii) that the use of the Software will not cause any damage of any kind to you or a third party.
+
+Limitation of Liability
+
+Under no circumstances shall Tsinghua University be liable for any incidental, special, indirect or consequential damages arising out of or relating to this license, including but not limited to, any lost profits, business interruption, loss of programs or other data, or all other commercial damages or losses, even if advised of the possibility thereof.
+
+No Maintenance Services
+
+You understand and agree that Tsinghua University is under no obligation to provide either maintenance services, update services, notices of latent defects, or corrections of defects with regard to the Software. Tsinghua University nevertheless reserves the right to update, modify, or discontinue the Software at any time.
+
+Publication with the Software
+
+You agree to cite the paper describing the software and algorithm as specified on the download website.
+
+Media Projects with the Software
+
+When using the Software in a media project please give credit to Tsinghua University. For example: the Software was used for performance capture courtesy of the Tsinghua University.
+
+Commercial Licensing Opportunities
+
+For commercial use and commercial license please contact: liuyebin@mail.tsinghua.edu.cn.
\ No newline at end of file
diff --git a/AnimatableGaussians/PREPROCESSED_DATASET.md b/AnimatableGaussians/PREPROCESSED_DATASET.md
new file mode 100644
index 0000000000000000000000000000000000000000..a11063af982d38d96ce7c6b824a302737fdcb164
--- /dev/null
+++ b/AnimatableGaussians/PREPROCESSED_DATASET.md
@@ -0,0 +1,48 @@
+
+
+# Preprocessed Dataset
+
+
+
+## AvatarReX Dataset
+
+
+
+## ActorsHQ Dataset
+
+Stay tuned.
+
+## THuman4.0 Dataset
+
+Stay tuned.
\ No newline at end of file
diff --git a/AnimatableGaussians/PRETRAINED_MODEL.md b/AnimatableGaussians/PRETRAINED_MODEL.md
new file mode 100644
index 0000000000000000000000000000000000000000..9c549b370277ef5f9be1a75a12c56b6584d58a5b
--- /dev/null
+++ b/AnimatableGaussians/PRETRAINED_MODEL.md
@@ -0,0 +1,48 @@
+
+
+# Pretrained Model
+
+
+
+## AvatarReX Dataset
+
+
+
+## ActorsHQ Dataset
+
+Stay tuned.
+
+## THuman4.0 Dataset
+
+Stay tuned.
\ No newline at end of file
diff --git a/AnimatableGaussians/README.md b/AnimatableGaussians/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a4e36c39594a907b556fc1d5e07a4f882040b182
--- /dev/null
+++ b/AnimatableGaussians/README.md
@@ -0,0 +1,117 @@
+News
+- `05/22/2024` :loudspeaker: An extension work of Animatable Gaussians for human avatar relighting is available at [here](https://animatable-gaussians.github.io/relight). Welcome to check it!
+- `03/11/2024` The code has been released. Welcome to have a try!
+- `03/11/2024` [AvatarReX](AVATARREX_DATASET.md) dataset, a high-resolution multi-view video dataset for avatar modeling, has been released.
+- `02/27/2024` Animatable Gaussians is accepted by CVPR 2024!
+
+Todo
+- [x] Release the code.
+- [x] Release AvatarReX dataset.
+- [ ] Release all the checkpoints and preprocessed dataset.
+
+
+
+# Animatable Gaussians: Learning Pose-dependent Gaussian Maps for High-fidelity Human Avatar Modeling
+
+
CVPR 2024
+
+[Zhe Li](https://lizhe00.github.io/) 1, [Zerong Zheng](https://zhengzerong.github.io/) 2, [Lizhen Wang](https://lizhenwangt.github.io/) 1, [Yebin Liu](https://www.liuyebin.com) 1
+
+1Tsinghua Univserity 2NNKosmos Technology
+
+### [Projectpage](https://animatable-gaussians.github.io/) · [Paper](https://arxiv.org/pdf/2311.16096.pdf) · [Video](https://www.youtube.com/watch?v=kOmZxD0HxZI)
+
+
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/484e1263-06ed-409b-b9a1-790f5b514832
+
+***Abstract**: Modeling animatable human avatars from RGB videos is a long-standing and challenging problem. Recent works usually adopt MLP-based neural radiance fields (NeRF) to represent 3D humans, but it remains difficult for pure MLPs to regress pose-dependent garment details. To this end, we introduce Animatable Gaussians, a new avatar representation that leverages powerful 2D CNNs and 3D Gaussian splatting to create high-fidelity avatars. To associate 3D Gaussians with the animatable avatar, we learn a parametric template from the input videos, and then parameterize the template on two front & back canonical Gaussian maps where each pixel represents a 3D Gaussian. The learned template is adaptive to the wearing garments for modeling looser clothes like dresses. Such template-guided 2D parameterization enables us to employ a powerful StyleGAN-based CNN to learn the pose-dependent Gaussian maps for modeling detailed dynamic appearances. Furthermore, we introduce a pose projection strategy for better generalization given novel poses. Overall, our method can create lifelike avatars with dynamic, realistic and generalized appearances. Experiments show that our method outperforms other state-of-the-art approaches.*
+
+## Demo Results
+We show avatars animated by challenging motions from [AMASS](https://amass.is.tue.mpg.de/) dataset.
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/123b026a-3fac-473c-a263-c3dcdd2ecc4c
+More results (click to expand)
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/9abfa02f-65ec-46b3-9690-ac26191a5a7e
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/c4f1e499-9bea-419c-916b-8d9ec4169ac3
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/47b08e6f-a1f2-4597-bb75-d85e784cd97c
+
+
+# Installation
+0. Clone this repo.
+```
+git clone https://github.com/lizhe00/AnimatableGaussians.git
+# or
+git clone git@github.com:lizhe00/AnimatableGaussians.git
+```
+1. Install environments.
+```
+# install requirements
+pip install -r requirements.txt
+
+# install diff-gaussian-rasterization-depth-alpha
+cd gaussians/diff_gaussian_rasterization_depth_alpha
+python setup.py install
+cd ../..
+
+# install styleunet
+cd network/styleunet
+python setup.py install
+cd ../..
+```
+2. Download [SMPL-X](https://smpl-x.is.tue.mpg.de/download.php) model, and place pkl files to ```./smpl_files/smplx```.
+
+# Data Preparation
+## AvatarReX, ActorsHQ or THuman4.0 Dataset
+1. Download [AvatarReX](./AVATARREX_DATASET.md), [ActorsHQ](https://www.actors-hq.com/dataset), or [THuman4.0](https://github.com/ZhengZerong/THUman4.0-Dataset) datasets.
+2. Data preprocessing. We provide two manners below. The first way is recommended if you plan to employ our pretrained models, because the renderer utilized in preprocessing may cause slight differences.
+ 1. (Recommended) Download our preprocessed files from [PREPROCESSED_DATASET.md](PREPROCESSED_DATASET.md), and unzip them to the root path of each character.
+ 2. Follow the instructions in [gen_data/GEN_DATA.md](gen_data/GEN_DATA.md#Preprocessing) to preprocess the dataset.
+
+*Note for ActorsHQ dataset: 1) **DATA PATH.** The subject from ActorsHQ dataset may include more than one sequences, but we only utilize the first sequence, i.e., ```Sequence1```. The root path is ```ActorsHQ/Actor0*/Sequence1```. 2) **SMPL-X Registration.** We provide SMPL-X fitting for ActorsHQ dataset. You can download it from [here](https://drive.google.com/file/d/1DVk3k-eNbVqVCkLhGJhD_e9ILLCwhspR/view?usp=sharing), and place `smpl_params.npz` at the corresponding root path of each subject.*
+
+## Customized Dataset
+Please refer to [gen_data/GEN_DATA.md](gen_data/GEN_DATA.md) to run on your own data.
+
+# Avatar Training
+Take `avatarrex_zzr` from AvatarReX dataset as an example, run:
+```
+python main_avatar.py -c configs/avatarrex_zzr/avatar.yaml --mode=train
+```
+After training, the checkpoint will be saved in `./results/avatarrex_zzr/avatar`.
+
+# Avatar Animation
+1. Download pretrained checkpoint from [PRETRAINED_MODEL.md](./PRETRAINED_MODEL.md), unzip it to `./results/avatarrex_zzr/avatar`, or train the network from scratch.
+2. Download [THuman4.0_POSE](https://drive.google.com/file/d/1pbToBV6klq6-dXCorwjjsmnINXZCG8n9/view?usp=sharing) or [AMASS](https://amass.is.tue.mpg.de/) dataset for acquiring driving pose sequences.
+We list some awesome pose sequences from AMASS dataset in [configs/awesome_amass_poses.yaml](configs/awesome_amass_poses.yaml).
+Specify the testing pose path in [configs/avatarrex_zzr/avatar.yaml#L57](configs/avatarrex_zzr/avatar.yaml#L57).
+3. Run:
+```
+python main_avatar.py -c configs/avatarrex_zzr/avatar.yaml --mode=test
+```
+You will see the animation results like below in `./test_results/avatarrex_zzr/avatar`.
+
+https://github.com/lizhe00/AnimatableGaussians/assets/61936670/5aad39d2-2adb-4b7b-ab90-dea46240344a
+
+# Evaluation
+We provide evaluation metrics and example codes of comparison with body-only avatars in [eval/comparison_body_only_avatars.py](eval/comparison_body_only_avatars.py).
+
+# Acknowledgement
+Our code is based on these wonderful repos:
+- [3D Gaussian Splatting](https://github.com/graphdeco-inria/diff-gaussian-rasterization) and its [adapted version](https://github.com/ashawkey/diff-gaussian-rasterization)
+- [StyleAvatar](https://github.com/LizhenWangT/StyleAvatar)
+
+# Citation
+If you find our code or data is helpful to your research, please consider citing our paper.
+```bibtex
+@inproceedings{li2024animatablegaussians,
+ title={Animatable Gaussians: Learning Pose-dependent Gaussian Maps for High-fidelity Human Avatar Modeling},
+ author={Li, Zhe and Zheng, Zerong and Wang, Lizhen and Liu, Yebin},
+ booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
+ year={2024}
+}
+```
+
diff --git a/AnimatableGaussians/__pycache__/config.cpython-310.pyc b/AnimatableGaussians/__pycache__/config.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3c1182e1dcbe35ac7b238231caab9f4eaaa1cd8e
Binary files /dev/null and b/AnimatableGaussians/__pycache__/config.cpython-310.pyc differ
diff --git a/AnimatableGaussians/assets/avatarrex.jpg b/AnimatableGaussians/assets/avatarrex.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ac7bd884f3816fb05621cc578b1d4be69be7138e
Binary files /dev/null and b/AnimatableGaussians/assets/avatarrex.jpg differ
diff --git a/AnimatableGaussians/assets/avatarrex_dataset_demo.gif b/AnimatableGaussians/assets/avatarrex_dataset_demo.gif
new file mode 100644
index 0000000000000000000000000000000000000000..69da5feb193ac774d0744b695ef9ee050a9c9953
--- /dev/null
+++ b/AnimatableGaussians/assets/avatarrex_dataset_demo.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c0473f05f976dac2e4900102ff08a328c53a44a7b0f3c9cfacd80420fcb822e4
+size 1690599
diff --git a/AnimatableGaussians/assets/avatarrex_lbn1.jpg b/AnimatableGaussians/assets/avatarrex_lbn1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d3d2863044e8563563abf3c68743b7c812f5a9f2
Binary files /dev/null and b/AnimatableGaussians/assets/avatarrex_lbn1.jpg differ
diff --git a/AnimatableGaussians/assets/avatarrex_lbn2.jpg b/AnimatableGaussians/assets/avatarrex_lbn2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fdaec1da45e6417fd517bc1e925f7fd70180a221
Binary files /dev/null and b/AnimatableGaussians/assets/avatarrex_lbn2.jpg differ
diff --git a/AnimatableGaussians/assets/avatarrex_zzr.jpg b/AnimatableGaussians/assets/avatarrex_zzr.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..361d26cc5c51243419a1a83c1dd3ddb78bfc9f10
Binary files /dev/null and b/AnimatableGaussians/assets/avatarrex_zzr.jpg differ
diff --git a/AnimatableGaussians/assets/ball.obj b/AnimatableGaussians/assets/ball.obj
new file mode 100644
index 0000000000000000000000000000000000000000..346f0351a9161e49acb046b733b5c25f9923c080
--- /dev/null
+++ b/AnimatableGaussians/assets/ball.obj
@@ -0,0 +1,2214 @@
+# Blender v2.74 (sub 0) OBJ File: ''
+# www.blender.org
+v 0.000000 0.500000 -0.000000
+v 0.065300 0.495700 -0.000000
+v 0.129400 0.483000 -0.000000
+v 0.191300 0.461900 -0.000000
+v 0.250000 0.433000 -0.000000
+v 0.304400 0.396700 -0.000000
+v 0.353600 0.353600 -0.000000
+v 0.396700 0.304400 -0.000000
+v 0.433000 0.250000 -0.000000
+v 0.461900 0.191300 -0.000000
+v 0.483000 0.129400 -0.000000
+v 0.495700 0.065300 -0.000000
+v 0.500000 0.000000 0.000000
+v 0.495700 -0.065300 0.000000
+v 0.483000 -0.129400 0.000000
+v 0.461900 -0.191300 0.000000
+v 0.433000 -0.250000 0.000000
+v 0.396700 -0.304400 0.000000
+v 0.353600 -0.353600 0.000000
+v 0.304400 -0.396700 0.000000
+v 0.250000 -0.433000 0.000000
+v 0.191300 -0.461900 0.000000
+v 0.129400 -0.483000 0.000000
+v 0.065300 -0.495700 0.000000
+v 0.000000 -0.500000 0.000000
+v 0.063000 0.495700 0.016900
+v 0.125000 0.483000 0.033500
+v 0.184800 0.461900 0.049500
+v 0.241500 0.433000 0.064700
+v 0.294000 0.396700 0.078800
+v 0.341500 0.353600 0.091500
+v 0.383200 0.304400 0.102700
+v 0.418300 0.250000 0.112100
+v 0.446200 0.191300 0.119600
+v 0.466500 0.129400 0.125000
+v 0.478800 0.065300 0.128300
+v 0.483000 0.000000 0.129400
+v 0.478800 -0.065300 0.128300
+v 0.466500 -0.129400 0.125000
+v 0.446200 -0.191300 0.119600
+v 0.418300 -0.250000 0.112100
+v 0.383200 -0.304400 0.102700
+v 0.341500 -0.353600 0.091500
+v 0.294000 -0.396700 0.078800
+v 0.241500 -0.433000 0.064700
+v 0.184800 -0.461900 0.049500
+v 0.125000 -0.483000 0.033500
+v 0.063000 -0.495700 0.016900
+v 0.056500 0.495700 0.032600
+v 0.112100 0.483000 0.064700
+v 0.165700 0.461900 0.095700
+v 0.216500 0.433000 0.125000
+v 0.263600 0.396700 0.152200
+v 0.306200 0.353600 0.176800
+v 0.343500 0.304400 0.198300
+v 0.375000 0.250000 0.216500
+v 0.400100 0.191300 0.231000
+v 0.418300 0.129400 0.241500
+v 0.429300 0.065300 0.247900
+v 0.433000 0.000000 0.250000
+v 0.429300 -0.065300 0.247900
+v 0.418300 -0.129400 0.241500
+v 0.400100 -0.191300 0.231000
+v 0.375000 -0.250000 0.216500
+v 0.343500 -0.304400 0.198300
+v 0.306200 -0.353600 0.176800
+v 0.263600 -0.396700 0.152200
+v 0.216500 -0.433000 0.125000
+v 0.165700 -0.461900 0.095700
+v 0.112100 -0.483000 0.064700
+v 0.056500 -0.495700 0.032600
+v 0.046100 0.495700 0.046100
+v 0.091500 0.483000 0.091500
+v 0.135300 0.461900 0.135300
+v 0.176800 0.433000 0.176800
+v 0.215200 0.396700 0.215200
+v 0.250000 0.353600 0.250000
+v 0.280500 0.304400 0.280500
+v 0.306200 0.250000 0.306200
+v 0.326600 0.191300 0.326600
+v 0.341500 0.129400 0.341500
+v 0.350500 0.065300 0.350500
+v 0.353600 0.000000 0.353600
+v 0.350500 -0.065300 0.350500
+v 0.341500 -0.129400 0.341500
+v 0.326600 -0.191300 0.326600
+v 0.306200 -0.250000 0.306200
+v 0.280500 -0.304400 0.280500
+v 0.250000 -0.353600 0.250000
+v 0.215200 -0.396700 0.215200
+v 0.176800 -0.433000 0.176800
+v 0.135300 -0.461900 0.135300
+v 0.091500 -0.483000 0.091500
+v 0.046100 -0.495700 0.046100
+v 0.032600 0.495700 0.056500
+v 0.064700 0.483000 0.112100
+v 0.095700 0.461900 0.165700
+v 0.125000 0.433000 0.216500
+v 0.152200 0.396700 0.263600
+v 0.176800 0.353600 0.306200
+v 0.198300 0.304400 0.343500
+v 0.216500 0.250000 0.375000
+v 0.231000 0.191300 0.400100
+v 0.241500 0.129400 0.418300
+v 0.247900 0.065300 0.429300
+v 0.250000 0.000000 0.433000
+v 0.247900 -0.065300 0.429300
+v 0.241500 -0.129400 0.418300
+v 0.231000 -0.191300 0.400100
+v 0.216500 -0.250000 0.375000
+v 0.198300 -0.304400 0.343500
+v 0.176800 -0.353600 0.306200
+v 0.152200 -0.396700 0.263600
+v 0.125000 -0.433000 0.216500
+v 0.095700 -0.461900 0.165700
+v 0.064700 -0.483000 0.112100
+v 0.032600 -0.495700 0.056500
+v 0.016900 0.495700 0.063000
+v 0.033500 0.483000 0.125000
+v 0.049500 0.461900 0.184800
+v 0.064700 0.433000 0.241500
+v 0.078800 0.396700 0.294000
+v 0.091500 0.353600 0.341500
+v 0.102700 0.304400 0.383200
+v 0.112100 0.250000 0.418300
+v 0.119600 0.191300 0.446200
+v 0.125000 0.129400 0.466500
+v 0.128300 0.065300 0.478800
+v 0.129400 0.000000 0.483000
+v 0.128300 -0.065300 0.478800
+v 0.125000 -0.129400 0.466500
+v 0.119600 -0.191300 0.446200
+v 0.112100 -0.250000 0.418300
+v 0.102700 -0.304400 0.383200
+v 0.091500 -0.353600 0.341500
+v 0.078800 -0.396700 0.294000
+v 0.064700 -0.433000 0.241500
+v 0.049500 -0.461900 0.184800
+v 0.033500 -0.483000 0.125000
+v 0.016900 -0.495700 0.063000
+v 0.000000 0.495700 0.065300
+v 0.000000 0.483000 0.129400
+v 0.000000 0.461900 0.191300
+v 0.000000 0.433000 0.250000
+v 0.000000 0.396700 0.304400
+v 0.000000 0.353600 0.353600
+v 0.000000 0.304400 0.396700
+v 0.000000 0.250000 0.433000
+v 0.000000 0.191300 0.461900
+v 0.000000 0.129400 0.483000
+v 0.000000 0.065300 0.495700
+v 0.000000 0.000000 0.500000
+v 0.000000 -0.065300 0.495700
+v 0.000000 -0.129400 0.483000
+v 0.000000 -0.191300 0.461900
+v 0.000000 -0.250000 0.433000
+v 0.000000 -0.304400 0.396700
+v 0.000000 -0.353600 0.353600
+v 0.000000 -0.396700 0.304400
+v 0.000000 -0.433000 0.250000
+v 0.000000 -0.461900 0.191300
+v 0.000000 -0.483000 0.129400
+v 0.000000 -0.495700 0.065300
+v -0.016900 0.495700 0.063000
+v -0.033500 0.483000 0.125000
+v -0.049500 0.461900 0.184800
+v -0.064700 0.433000 0.241500
+v -0.078800 0.396700 0.294000
+v -0.091500 0.353600 0.341500
+v -0.102700 0.304400 0.383200
+v -0.112100 0.250000 0.418300
+v -0.119600 0.191300 0.446200
+v -0.125000 0.129400 0.466500
+v -0.128300 0.065300 0.478800
+v -0.129400 0.000000 0.483000
+v -0.128300 -0.065300 0.478800
+v -0.125000 -0.129400 0.466500
+v -0.119600 -0.191300 0.446200
+v -0.112100 -0.250000 0.418300
+v -0.102700 -0.304400 0.383200
+v -0.091500 -0.353600 0.341500
+v -0.078800 -0.396700 0.294000
+v -0.064700 -0.433000 0.241500
+v -0.049500 -0.461900 0.184800
+v -0.033500 -0.483000 0.125000
+v -0.016900 -0.495700 0.063000
+v -0.032600 0.495700 0.056500
+v -0.064700 0.483000 0.112100
+v -0.095700 0.461900 0.165700
+v -0.125000 0.433000 0.216500
+v -0.152200 0.396700 0.263600
+v -0.176800 0.353600 0.306200
+v -0.198300 0.304400 0.343500
+v -0.216500 0.250000 0.375000
+v -0.231000 0.191300 0.400100
+v -0.241500 0.129400 0.418300
+v -0.247900 0.065300 0.429300
+v -0.250000 0.000000 0.433000
+v -0.247900 -0.065300 0.429300
+v -0.241500 -0.129400 0.418300
+v -0.231000 -0.191300 0.400100
+v -0.216500 -0.250000 0.375000
+v -0.198300 -0.304400 0.343500
+v -0.176800 -0.353600 0.306200
+v -0.152200 -0.396700 0.263600
+v -0.125000 -0.433000 0.216500
+v -0.095700 -0.461900 0.165700
+v -0.064700 -0.483000 0.112100
+v -0.032600 -0.495700 0.056500
+v -0.046100 0.495700 0.046100
+v -0.091500 0.483000 0.091500
+v -0.135300 0.461900 0.135300
+v -0.176800 0.433000 0.176800
+v -0.215200 0.396700 0.215200
+v -0.250000 0.353600 0.250000
+v -0.280500 0.304400 0.280500
+v -0.306200 0.250000 0.306200
+v -0.326600 0.191300 0.326600
+v -0.341500 0.129400 0.341500
+v -0.350500 0.065300 0.350500
+v -0.353600 0.000000 0.353600
+v -0.350500 -0.065300 0.350500
+v -0.341500 -0.129400 0.341500
+v -0.326600 -0.191300 0.326600
+v -0.306200 -0.250000 0.306200
+v -0.280500 -0.304400 0.280500
+v -0.250000 -0.353600 0.250000
+v -0.215200 -0.396700 0.215200
+v -0.176800 -0.433000 0.176800
+v -0.135300 -0.461900 0.135300
+v -0.091500 -0.483000 0.091500
+v -0.046100 -0.495700 0.046100
+v -0.056500 0.495700 0.032600
+v -0.112100 0.483000 0.064700
+v -0.165700 0.461900 0.095700
+v -0.216500 0.433000 0.125000
+v -0.263600 0.396700 0.152200
+v -0.306200 0.353600 0.176800
+v -0.343500 0.304400 0.198300
+v -0.375000 0.250000 0.216500
+v -0.400100 0.191300 0.231000
+v -0.418300 0.129400 0.241500
+v -0.429300 0.065300 0.247900
+v -0.433000 0.000000 0.250000
+v -0.429300 -0.065300 0.247900
+v -0.418300 -0.129400 0.241500
+v -0.400100 -0.191300 0.231000
+v -0.375000 -0.250000 0.216500
+v -0.343500 -0.304400 0.198300
+v -0.306200 -0.353600 0.176800
+v -0.263600 -0.396700 0.152200
+v -0.216500 -0.433000 0.125000
+v -0.165700 -0.461900 0.095700
+v -0.112100 -0.483000 0.064700
+v -0.056500 -0.495700 0.032600
+v -0.063000 0.495700 0.016900
+v -0.125000 0.483000 0.033500
+v -0.184800 0.461900 0.049500
+v -0.241500 0.433000 0.064700
+v -0.294000 0.396700 0.078800
+v -0.341500 0.353600 0.091500
+v -0.383200 0.304400 0.102700
+v -0.418300 0.250000 0.112100
+v -0.446200 0.191300 0.119600
+v -0.466500 0.129400 0.125000
+v -0.478800 0.065300 0.128300
+v -0.483000 0.000000 0.129400
+v -0.478800 -0.065300 0.128300
+v -0.466500 -0.129400 0.125000
+v -0.446200 -0.191300 0.119600
+v -0.418300 -0.250000 0.112100
+v -0.383200 -0.304400 0.102700
+v -0.341500 -0.353600 0.091500
+v -0.294000 -0.396700 0.078800
+v -0.241500 -0.433000 0.064700
+v -0.184800 -0.461900 0.049500
+v -0.125000 -0.483000 0.033500
+v -0.063000 -0.495700 0.016900
+v -0.065300 0.495700 -0.000000
+v -0.129400 0.483000 -0.000000
+v -0.191300 0.461900 -0.000000
+v -0.250000 0.433000 -0.000000
+v -0.304400 0.396700 -0.000000
+v -0.353600 0.353600 -0.000000
+v -0.396700 0.304400 -0.000000
+v -0.433000 0.250000 -0.000000
+v -0.461900 0.191300 -0.000000
+v -0.483000 0.129400 -0.000000
+v -0.495700 0.065300 -0.000000
+v -0.500000 0.000000 0.000000
+v -0.495700 -0.065300 0.000000
+v -0.483000 -0.129400 0.000000
+v -0.461900 -0.191300 0.000000
+v -0.433000 -0.250000 0.000000
+v -0.396700 -0.304400 0.000000
+v -0.353600 -0.353600 0.000000
+v -0.304400 -0.396700 0.000000
+v -0.250000 -0.433000 0.000000
+v -0.191300 -0.461900 0.000000
+v -0.129400 -0.483000 0.000000
+v -0.065300 -0.495700 0.000000
+v -0.063000 0.495700 -0.016900
+v -0.125000 0.483000 -0.033500
+v -0.184800 0.461900 -0.049500
+v -0.241500 0.433000 -0.064700
+v -0.294000 0.396700 -0.078800
+v -0.341500 0.353600 -0.091500
+v -0.383200 0.304400 -0.102700
+v -0.418300 0.250000 -0.112100
+v -0.446200 0.191300 -0.119600
+v -0.466500 0.129400 -0.125000
+v -0.478800 0.065300 -0.128300
+v -0.483000 -0.000000 -0.129400
+v -0.478800 -0.065300 -0.128300
+v -0.466500 -0.129400 -0.125000
+v -0.446200 -0.191300 -0.119600
+v -0.418300 -0.250000 -0.112100
+v -0.383200 -0.304400 -0.102700
+v -0.341500 -0.353600 -0.091500
+v -0.294000 -0.396700 -0.078800
+v -0.241500 -0.433000 -0.064700
+v -0.184800 -0.461900 -0.049500
+v -0.125000 -0.483000 -0.033500
+v -0.063000 -0.495700 -0.016900
+v -0.056500 0.495700 -0.032600
+v -0.112100 0.483000 -0.064700
+v -0.165700 0.461900 -0.095700
+v -0.216500 0.433000 -0.125000
+v -0.263600 0.396700 -0.152200
+v -0.306200 0.353600 -0.176800
+v -0.343500 0.304400 -0.198300
+v -0.375000 0.250000 -0.216500
+v -0.400100 0.191300 -0.231000
+v -0.418300 0.129400 -0.241500
+v -0.429300 0.065300 -0.247900
+v -0.433000 -0.000000 -0.250000
+v -0.429300 -0.065300 -0.247900
+v -0.418300 -0.129400 -0.241500
+v -0.400100 -0.191300 -0.231000
+v -0.375000 -0.250000 -0.216500
+v -0.343500 -0.304400 -0.198300
+v -0.306200 -0.353600 -0.176800
+v -0.263600 -0.396700 -0.152200
+v -0.216500 -0.433000 -0.125000
+v -0.165700 -0.461900 -0.095700
+v -0.112100 -0.483000 -0.064700
+v -0.056500 -0.495700 -0.032600
+v -0.046100 0.495700 -0.046100
+v -0.091500 0.483000 -0.091500
+v -0.135300 0.461900 -0.135300
+v -0.176800 0.433000 -0.176800
+v -0.215200 0.396700 -0.215200
+v -0.250000 0.353600 -0.250000
+v -0.280500 0.304400 -0.280500
+v -0.306200 0.250000 -0.306200
+v -0.326600 0.191300 -0.326600
+v -0.341500 0.129400 -0.341500
+v -0.350500 0.065300 -0.350500
+v -0.353600 -0.000000 -0.353600
+v -0.350500 -0.065300 -0.350500
+v -0.341500 -0.129400 -0.341500
+v -0.326600 -0.191300 -0.326600
+v -0.306200 -0.250000 -0.306200
+v -0.280500 -0.304400 -0.280500
+v -0.250000 -0.353600 -0.250000
+v -0.215200 -0.396700 -0.215200
+v -0.176800 -0.433000 -0.176800
+v -0.135300 -0.461900 -0.135300
+v -0.091500 -0.483000 -0.091500
+v -0.046100 -0.495700 -0.046100
+v -0.032600 0.495700 -0.056500
+v -0.064700 0.483000 -0.112100
+v -0.095700 0.461900 -0.165700
+v -0.125000 0.433000 -0.216500
+v -0.152200 0.396700 -0.263600
+v -0.176800 0.353600 -0.306200
+v -0.198300 0.304400 -0.343500
+v -0.216500 0.250000 -0.375000
+v -0.231000 0.191300 -0.400100
+v -0.241500 0.129400 -0.418300
+v -0.247900 0.065300 -0.429300
+v -0.250000 -0.000000 -0.433000
+v -0.247900 -0.065300 -0.429300
+v -0.241500 -0.129400 -0.418300
+v -0.231000 -0.191300 -0.400100
+v -0.216500 -0.250000 -0.375000
+v -0.198300 -0.304400 -0.343500
+v -0.176800 -0.353600 -0.306200
+v -0.152200 -0.396700 -0.263600
+v -0.125000 -0.433000 -0.216500
+v -0.095700 -0.461900 -0.165700
+v -0.064700 -0.483000 -0.112100
+v -0.032600 -0.495700 -0.056500
+v -0.016900 0.495700 -0.063000
+v -0.033500 0.483000 -0.125000
+v -0.049500 0.461900 -0.184800
+v -0.064700 0.433000 -0.241500
+v -0.078800 0.396700 -0.294000
+v -0.091500 0.353600 -0.341500
+v -0.102700 0.304400 -0.383200
+v -0.112100 0.250000 -0.418300
+v -0.119600 0.191300 -0.446200
+v -0.125000 0.129400 -0.466500
+v -0.128300 0.065300 -0.478800
+v -0.129400 -0.000000 -0.483000
+v -0.128300 -0.065300 -0.478800
+v -0.125000 -0.129400 -0.466500
+v -0.119600 -0.191300 -0.446200
+v -0.112100 -0.250000 -0.418300
+v -0.102700 -0.304400 -0.383200
+v -0.091500 -0.353600 -0.341500
+v -0.078800 -0.396700 -0.294000
+v -0.064700 -0.433000 -0.241500
+v -0.049500 -0.461900 -0.184800
+v -0.033500 -0.483000 -0.125000
+v -0.016900 -0.495700 -0.063000
+v 0.000000 0.495700 -0.065300
+v 0.000000 0.483000 -0.129400
+v 0.000000 0.461900 -0.191300
+v 0.000000 0.433000 -0.250000
+v 0.000000 0.396700 -0.304400
+v 0.000000 0.353600 -0.353600
+v 0.000000 0.304400 -0.396700
+v 0.000000 0.250000 -0.433000
+v 0.000000 0.191300 -0.461900
+v 0.000000 0.129400 -0.483000
+v 0.000000 0.065300 -0.495700
+v 0.000000 -0.000000 -0.500000
+v 0.000000 -0.065300 -0.495700
+v 0.000000 -0.129400 -0.483000
+v 0.000000 -0.191300 -0.461900
+v 0.000000 -0.250000 -0.433000
+v 0.000000 -0.304400 -0.396700
+v 0.000000 -0.353600 -0.353600
+v 0.000000 -0.396700 -0.304400
+v 0.000000 -0.433000 -0.250000
+v 0.000000 -0.461900 -0.191300
+v 0.000000 -0.483000 -0.129400
+v 0.000000 -0.495700 -0.065300
+v 0.016900 0.495700 -0.063000
+v 0.033500 0.483000 -0.125000
+v 0.049500 0.461900 -0.184800
+v 0.064700 0.433000 -0.241500
+v 0.078800 0.396700 -0.294000
+v 0.091500 0.353600 -0.341500
+v 0.102700 0.304400 -0.383200
+v 0.112100 0.250000 -0.418300
+v 0.119600 0.191300 -0.446200
+v 0.125000 0.129400 -0.466500
+v 0.128300 0.065300 -0.478800
+v 0.129400 -0.000000 -0.483000
+v 0.128300 -0.065300 -0.478800
+v 0.125000 -0.129400 -0.466500
+v 0.119600 -0.191300 -0.446200
+v 0.112100 -0.250000 -0.418300
+v 0.102700 -0.304400 -0.383200
+v 0.091500 -0.353600 -0.341500
+v 0.078800 -0.396700 -0.294000
+v 0.064700 -0.433000 -0.241500
+v 0.049500 -0.461900 -0.184800
+v 0.033500 -0.483000 -0.125000
+v 0.016900 -0.495700 -0.063000
+v 0.032600 0.495700 -0.056500
+v 0.064700 0.483000 -0.112100
+v 0.095700 0.461900 -0.165700
+v 0.125000 0.433000 -0.216500
+v 0.152200 0.396700 -0.263600
+v 0.176800 0.353600 -0.306200
+v 0.198300 0.304400 -0.343500
+v 0.216500 0.250000 -0.375000
+v 0.231000 0.191300 -0.400100
+v 0.241500 0.129400 -0.418300
+v 0.247900 0.065300 -0.429300
+v 0.250000 -0.000000 -0.433000
+v 0.247900 -0.065300 -0.429300
+v 0.241500 -0.129400 -0.418300
+v 0.231000 -0.191300 -0.400100
+v 0.216500 -0.250000 -0.375000
+v 0.198300 -0.304400 -0.343500
+v 0.176800 -0.353600 -0.306200
+v 0.152200 -0.396700 -0.263600
+v 0.125000 -0.433000 -0.216500
+v 0.095700 -0.461900 -0.165700
+v 0.064700 -0.483000 -0.112100
+v 0.032600 -0.495700 -0.056500
+v 0.046100 0.495700 -0.046100
+v 0.091500 0.483000 -0.091500
+v 0.135300 0.461900 -0.135300
+v 0.176800 0.433000 -0.176800
+v 0.215200 0.396700 -0.215200
+v 0.250000 0.353600 -0.250000
+v 0.280500 0.304400 -0.280500
+v 0.306200 0.250000 -0.306200
+v 0.326600 0.191300 -0.326600
+v 0.341500 0.129400 -0.341500
+v 0.350500 0.065300 -0.350500
+v 0.353600 -0.000000 -0.353600
+v 0.350500 -0.065300 -0.350500
+v 0.341500 -0.129400 -0.341500
+v 0.326600 -0.191300 -0.326600
+v 0.306200 -0.250000 -0.306200
+v 0.280500 -0.304400 -0.280500
+v 0.250000 -0.353600 -0.250000
+v 0.215200 -0.396700 -0.215200
+v 0.176800 -0.433000 -0.176800
+v 0.135300 -0.461900 -0.135300
+v 0.091500 -0.483000 -0.091500
+v 0.046100 -0.495700 -0.046100
+v 0.056500 0.495700 -0.032600
+v 0.112100 0.483000 -0.064700
+v 0.165700 0.461900 -0.095700
+v 0.216500 0.433000 -0.125000
+v 0.263600 0.396700 -0.152200
+v 0.306200 0.353600 -0.176800
+v 0.343500 0.304400 -0.198300
+v 0.375000 0.250000 -0.216500
+v 0.400100 0.191300 -0.231000
+v 0.418300 0.129400 -0.241500
+v 0.429300 0.065300 -0.247900
+v 0.433000 -0.000000 -0.250000
+v 0.429300 -0.065300 -0.247900
+v 0.418300 -0.129400 -0.241500
+v 0.400100 -0.191300 -0.231000
+v 0.375000 -0.250000 -0.216500
+v 0.343500 -0.304400 -0.198300
+v 0.306200 -0.353600 -0.176800
+v 0.263600 -0.396700 -0.152200
+v 0.216500 -0.433000 -0.125000
+v 0.165700 -0.461900 -0.095700
+v 0.112100 -0.483000 -0.064700
+v 0.056500 -0.495700 -0.032600
+v 0.063000 0.495700 -0.016900
+v 0.125000 0.483000 -0.033500
+v 0.184800 0.461900 -0.049500
+v 0.241500 0.433000 -0.064700
+v 0.294000 0.396700 -0.078800
+v 0.341500 0.353600 -0.091500
+v 0.383200 0.304400 -0.102700
+v 0.418300 0.250000 -0.112100
+v 0.446200 0.191300 -0.119600
+v 0.466500 0.129400 -0.125000
+v 0.478800 0.065300 -0.128300
+v 0.483000 -0.000000 -0.129400
+v 0.478800 -0.065300 -0.128300
+v 0.466500 -0.129400 -0.125000
+v 0.446200 -0.191300 -0.119600
+v 0.418300 -0.250000 -0.112100
+v 0.383200 -0.304400 -0.102700
+v 0.341500 -0.353600 -0.091500
+v 0.294000 -0.396700 -0.078800
+v 0.241500 -0.433000 -0.064700
+v 0.184800 -0.461900 -0.049500
+v 0.125000 -0.483000 -0.033500
+v 0.063000 -0.495700 -0.016900
+vn 0.000000 1.000000 0.000000
+vn 0.130700 0.990800 0.035300
+vn 0.135700 0.990700 -0.000100
+vn 0.255100 0.964500 0.068300
+vn 0.264100 0.964500 -0.000000
+vn 0.374400 0.921800 0.100200
+vn 0.387500 0.921800 0.000000
+vn 0.486500 0.863900 0.130300
+vn 0.503500 0.863900 0.000000
+vn 0.591000 0.790900 0.158400
+vn 0.611700 0.791000 0.000100
+vn 0.685400 0.704500 0.183900
+vn 0.709800 0.704400 -0.000100
+vn 0.768100 0.606200 0.206100
+vn 0.795600 0.605800 -0.000100
+vn 0.838000 0.497300 0.224400
+vn 0.867700 0.497100 0.000000
+vn 0.893400 0.380400 0.239000
+vn 0.924600 0.381000 0.000100
+vn 0.933400 0.257400 0.249900
+vn 0.966200 0.257600 0.000000
+vn 0.957700 0.130000 0.256700
+vn 0.991500 0.129700 -0.000100
+vn 0.965900 0.000000 0.258800
+vn 1.000000 0.000000 0.000000
+vn 0.957700 -0.130100 0.256400
+vn 0.991500 -0.129700 0.000100
+vn 0.933400 -0.257300 0.250000
+vn 0.966200 -0.257600 -0.000000
+vn 0.893200 -0.380600 0.239300
+vn 0.924600 -0.381000 -0.000100
+vn 0.838000 -0.497300 0.224600
+vn 0.867700 -0.497100 0.000000
+vn 0.768200 -0.606100 0.206000
+vn 0.795600 -0.605800 0.000100
+vn 0.685400 -0.704600 0.183600
+vn 0.709800 -0.704400 0.000100
+vn 0.591000 -0.790900 0.158500
+vn 0.611700 -0.791000 -0.000100
+vn 0.486500 -0.863900 0.130400
+vn 0.503500 -0.863900 -0.000000
+vn 0.374300 -0.921800 0.100100
+vn 0.387500 -0.921800 0.000000
+vn 0.255100 -0.964500 0.068200
+vn 0.264100 -0.964500 0.000000
+vn 0.130800 -0.990800 0.035300
+vn 0.135700 -0.990700 0.000100
+vn 0.000000 -1.000000 0.000000
+vn 0.117300 0.990800 0.067800
+vn 0.228600 0.964500 0.132000
+vn 0.335800 0.921800 0.193700
+vn 0.436200 0.863900 0.251800
+vn 0.529700 0.791000 0.306000
+vn 0.614900 0.704200 0.354900
+vn 0.688900 0.606000 0.397800
+vn 0.750800 0.497900 0.433900
+vn 0.800500 0.381000 0.462500
+vn 0.836900 0.257300 0.483100
+vn 0.858700 0.129600 0.495700
+vn 0.866100 -0.000000 0.499900
+vn 0.858600 -0.129500 0.496000
+vn 0.836800 -0.257400 0.483200
+vn 0.800700 -0.380800 0.462400
+vn 0.751000 -0.497900 0.433500
+vn 0.688900 -0.605900 0.397800
+vn 0.614700 -0.704200 0.355100
+vn 0.529800 -0.790900 0.306000
+vn 0.436200 -0.863900 0.251700
+vn 0.335700 -0.921800 0.193800
+vn 0.228600 -0.964500 0.132000
+vn 0.117300 -0.990800 0.067800
+vn 0.095700 0.990800 0.095800
+vn 0.186600 0.964500 0.186700
+vn 0.274000 0.921800 0.274100
+vn 0.356300 0.863800 0.356200
+vn 0.432700 0.790900 0.432600
+vn 0.501700 0.704500 0.501900
+vn 0.562400 0.606000 0.562500
+vn 0.613700 0.497200 0.613300
+vn 0.653900 0.380700 0.653800
+vn 0.683200 0.257600 0.683300
+vn 0.700900 0.130300 0.701200
+vn 0.707100 0.000000 0.707100
+vn 0.701200 -0.130300 0.700900
+vn 0.683300 -0.257600 0.683200
+vn 0.653800 -0.380700 0.653900
+vn 0.613300 -0.497200 0.613700
+vn 0.562500 -0.606000 0.562400
+vn 0.501900 -0.704500 0.501700
+vn 0.432600 -0.790900 0.432700
+vn 0.356200 -0.863800 0.356300
+vn 0.274100 -0.921800 0.274000
+vn 0.186700 -0.964500 0.186600
+vn 0.095800 -0.990800 0.095700
+vn 0.067800 0.990800 0.117300
+vn 0.132000 0.964500 0.228600
+vn 0.193800 0.921800 0.335700
+vn 0.251700 0.863900 0.436200
+vn 0.306000 0.790900 0.529800
+vn 0.355100 0.704200 0.614700
+vn 0.397800 0.605900 0.688900
+vn 0.433500 0.497900 0.751000
+vn 0.462400 0.380800 0.800700
+vn 0.483200 0.257400 0.836800
+vn 0.496000 0.129500 0.858600
+vn 0.499900 0.000000 0.866100
+vn 0.495700 -0.129600 0.858700
+vn 0.483100 -0.257300 0.836900
+vn 0.462500 -0.381000 0.800500
+vn 0.433900 -0.497900 0.750800
+vn 0.397800 -0.606000 0.688900
+vn 0.354900 -0.704200 0.614900
+vn 0.306000 -0.791000 0.529700
+vn 0.251800 -0.863900 0.436200
+vn 0.193700 -0.921800 0.335800
+vn 0.132000 -0.964500 0.228600
+vn 0.067800 -0.990800 0.117300
+vn 0.035300 0.990800 0.130800
+vn 0.068200 0.964500 0.255100
+vn 0.100100 0.921800 0.374300
+vn 0.130400 0.863900 0.486500
+vn 0.158500 0.790900 0.591000
+vn 0.183600 0.704600 0.685400
+vn 0.206000 0.606100 0.768200
+vn 0.224600 0.497300 0.838000
+vn 0.239300 0.380600 0.893200
+vn 0.250000 0.257300 0.933400
+vn 0.256400 0.130100 0.957700
+vn 0.258800 -0.000000 0.965900
+vn 0.256700 -0.130000 0.957700
+vn 0.249900 -0.257400 0.933400
+vn 0.239000 -0.380400 0.893400
+vn 0.224400 -0.497300 0.838000
+vn 0.206100 -0.606200 0.768100
+vn 0.183900 -0.704500 0.685400
+vn 0.158400 -0.790900 0.591000
+vn 0.130300 -0.863900 0.486500
+vn 0.100200 -0.921800 0.374400
+vn 0.068200 -0.964500 0.255100
+vn 0.035300 -0.990800 0.130700
+vn 0.000100 0.990700 0.135700
+vn 0.000000 0.964500 0.264100
+vn 0.000000 0.921800 0.387500
+vn -0.000000 0.863900 0.503500
+vn -0.000100 0.791000 0.611700
+vn 0.000100 0.704400 0.709800
+vn 0.000100 0.605800 0.795600
+vn 0.000000 0.497100 0.867700
+vn -0.000100 0.381000 0.924600
+vn -0.000000 0.257600 0.966200
+vn 0.000100 0.129700 0.991500
+vn 0.000000 0.000000 1.000000
+vn -0.000100 -0.129700 0.991500
+vn 0.000000 -0.257600 0.966200
+vn 0.000100 -0.381000 0.924600
+vn 0.000000 -0.497100 0.867700
+vn -0.000100 -0.605800 0.795600
+vn -0.000100 -0.704400 0.709800
+vn 0.000100 -0.791000 0.611700
+vn 0.000000 -0.863900 0.503500
+vn 0.000000 -0.921800 0.387500
+vn -0.000000 -0.964500 0.264100
+vn -0.000100 -0.990700 0.135700
+vn -0.035300 0.990800 0.130700
+vn -0.068200 0.964500 0.255100
+vn -0.100200 0.921800 0.374400
+vn -0.130300 0.863900 0.486500
+vn -0.158400 0.790900 0.591000
+vn -0.183900 0.704500 0.685400
+vn -0.206100 0.606200 0.768100
+vn -0.224400 0.497300 0.838000
+vn -0.239000 0.380400 0.893400
+vn -0.249900 0.257400 0.933400
+vn -0.256700 0.130000 0.957700
+vn -0.258800 0.000000 0.965900
+vn -0.256400 -0.130100 0.957700
+vn -0.250000 -0.257300 0.933400
+vn -0.239300 -0.380600 0.893200
+vn -0.224600 -0.497300 0.838000
+vn -0.206000 -0.606100 0.768200
+vn -0.183600 -0.704600 0.685400
+vn -0.158500 -0.790900 0.591000
+vn -0.130400 -0.863900 0.486500
+vn -0.100100 -0.921800 0.374300
+vn -0.068200 -0.964500 0.255100
+vn -0.035300 -0.990800 0.130800
+vn -0.067800 0.990800 0.117300
+vn -0.132000 0.964500 0.228600
+vn -0.193700 0.921800 0.335800
+vn -0.251800 0.863900 0.436200
+vn -0.306000 0.791000 0.529700
+vn -0.354900 0.704200 0.614900
+vn -0.397800 0.606000 0.688900
+vn -0.433900 0.497900 0.750800
+vn -0.462500 0.381000 0.800500
+vn -0.483100 0.257300 0.836900
+vn -0.495700 0.129600 0.858700
+vn -0.499900 -0.000000 0.866100
+vn -0.496000 -0.129500 0.858600
+vn -0.483200 -0.257400 0.836800
+vn -0.462400 -0.380800 0.800700
+vn -0.433500 -0.497900 0.751000
+vn -0.397800 -0.605900 0.688900
+vn -0.355100 -0.704200 0.614700
+vn -0.306000 -0.790900 0.529800
+vn -0.251700 -0.863900 0.436200
+vn -0.193800 -0.921800 0.335700
+vn -0.132000 -0.964500 0.228600
+vn -0.067800 -0.990800 0.117300
+vn -0.095800 0.990800 0.095700
+vn -0.186700 0.964500 0.186600
+vn -0.274100 0.921800 0.274000
+vn -0.356200 0.863800 0.356300
+vn -0.432600 0.790900 0.432700
+vn -0.501900 0.704500 0.501700
+vn -0.562500 0.606000 0.562400
+vn -0.613300 0.497200 0.613700
+vn -0.653800 0.380700 0.653900
+vn -0.683300 0.257600 0.683200
+vn -0.701200 0.130300 0.700900
+vn -0.707100 0.000000 0.707100
+vn -0.700900 -0.130300 0.701200
+vn -0.683200 -0.257600 0.683300
+vn -0.653900 -0.380700 0.653800
+vn -0.613700 -0.497200 0.613300
+vn -0.562400 -0.606000 0.562500
+vn -0.501700 -0.704500 0.501900
+vn -0.432700 -0.790900 0.432600
+vn -0.356300 -0.863800 0.356200
+vn -0.274000 -0.921800 0.274100
+vn -0.186600 -0.964500 0.186700
+vn -0.095700 -0.990800 0.095800
+vn -0.117300 0.990800 0.067800
+vn -0.228600 0.964500 0.132000
+vn -0.335700 0.921800 0.193800
+vn -0.436200 0.863900 0.251700
+vn -0.529800 0.790900 0.306000
+vn -0.614700 0.704200 0.355100
+vn -0.688900 0.605900 0.397800
+vn -0.751000 0.497900 0.433500
+vn -0.800700 0.380800 0.462400
+vn -0.836800 0.257400 0.483200
+vn -0.858600 0.129500 0.496000
+vn -0.866100 0.000000 0.499900
+vn -0.858700 -0.129600 0.495700
+vn -0.836900 -0.257300 0.483100
+vn -0.800500 -0.381000 0.462500
+vn -0.750800 -0.497900 0.433900
+vn -0.688900 -0.606000 0.397800
+vn -0.614900 -0.704200 0.354900
+vn -0.529700 -0.791000 0.306000
+vn -0.436200 -0.863900 0.251800
+vn -0.335800 -0.921800 0.193700
+vn -0.228600 -0.964500 0.132000
+vn -0.117300 -0.990800 0.067800
+vn -0.130800 0.990800 0.035300
+vn -0.255100 0.964500 0.068200
+vn -0.374300 0.921800 0.100100
+vn -0.486500 0.863900 0.130400
+vn -0.591000 0.790900 0.158500
+vn -0.685400 0.704600 0.183600
+vn -0.768200 0.606100 0.206000
+vn -0.838000 0.497300 0.224600
+vn -0.893200 0.380600 0.239300
+vn -0.933400 0.257300 0.250000
+vn -0.957700 0.130100 0.256400
+vn -0.965900 -0.000000 0.258800
+vn -0.957700 -0.130000 0.256700
+vn -0.933400 -0.257400 0.249900
+vn -0.893400 -0.380400 0.239000
+vn -0.838000 -0.497300 0.224400
+vn -0.768100 -0.606200 0.206100
+vn -0.685400 -0.704500 0.183900
+vn -0.591000 -0.790900 0.158400
+vn -0.486500 -0.863900 0.130300
+vn -0.374400 -0.921800 0.100200
+vn -0.255100 -0.964500 0.068300
+vn -0.130700 -0.990800 0.035300
+vn -0.135700 0.990700 0.000100
+vn -0.264100 0.964500 0.000000
+vn -0.387500 0.921800 0.000000
+vn -0.503500 0.863900 -0.000000
+vn -0.611700 0.791000 -0.000100
+vn -0.709800 0.704400 0.000100
+vn -0.795600 0.605800 0.000100
+vn -0.867700 0.497100 0.000000
+vn -0.924600 0.381000 -0.000100
+vn -0.966200 0.257600 -0.000000
+vn -0.991500 0.129700 0.000100
+vn -1.000000 0.000000 0.000000
+vn -0.991500 -0.129700 -0.000100
+vn -0.966200 -0.257600 0.000000
+vn -0.924600 -0.381000 0.000100
+vn -0.867700 -0.497100 0.000000
+vn -0.795600 -0.605800 -0.000100
+vn -0.709800 -0.704400 -0.000100
+vn -0.611700 -0.791000 0.000100
+vn -0.503500 -0.863900 0.000000
+vn -0.387500 -0.921800 0.000000
+vn -0.264100 -0.964500 -0.000000
+vn -0.135700 -0.990700 -0.000100
+vn -0.130700 0.990800 -0.035300
+vn -0.255100 0.964500 -0.068300
+vn -0.374400 0.921800 -0.100200
+vn -0.486500 0.863900 -0.130300
+vn -0.591000 0.790900 -0.158400
+vn -0.685400 0.704500 -0.183900
+vn -0.768100 0.606200 -0.206100
+vn -0.838000 0.497300 -0.224400
+vn -0.893400 0.380400 -0.239000
+vn -0.933400 0.257400 -0.249900
+vn -0.957700 0.130000 -0.256700
+vn -0.965900 0.000000 -0.258800
+vn -0.957700 -0.130100 -0.256400
+vn -0.933400 -0.257300 -0.250000
+vn -0.893200 -0.380600 -0.239300
+vn -0.838000 -0.497300 -0.224600
+vn -0.768200 -0.606100 -0.206000
+vn -0.685400 -0.704600 -0.183600
+vn -0.591000 -0.790900 -0.158500
+vn -0.486500 -0.863900 -0.130400
+vn -0.374300 -0.921800 -0.100100
+vn -0.255100 -0.964500 -0.068200
+vn -0.130800 -0.990800 -0.035300
+vn -0.117300 0.990800 -0.067800
+vn -0.228600 0.964500 -0.132000
+vn -0.335800 0.921800 -0.193700
+vn -0.436200 0.863900 -0.251800
+vn -0.529700 0.791000 -0.306000
+vn -0.614900 0.704200 -0.354900
+vn -0.688900 0.606000 -0.397800
+vn -0.750800 0.497900 -0.433900
+vn -0.800500 0.381000 -0.462500
+vn -0.836900 0.257300 -0.483100
+vn -0.858700 0.129600 -0.495700
+vn -0.866100 -0.000000 -0.499900
+vn -0.858600 -0.129500 -0.496000
+vn -0.836800 -0.257400 -0.483200
+vn -0.800700 -0.380800 -0.462400
+vn -0.751000 -0.497900 -0.433500
+vn -0.688900 -0.605900 -0.397800
+vn -0.614700 -0.704200 -0.355100
+vn -0.529800 -0.790900 -0.306000
+vn -0.436200 -0.863900 -0.251700
+vn -0.335700 -0.921800 -0.193800
+vn -0.228600 -0.964500 -0.132000
+vn -0.117300 -0.990800 -0.067800
+vn -0.095700 0.990800 -0.095800
+vn -0.186600 0.964500 -0.186700
+vn -0.274000 0.921800 -0.274100
+vn -0.356300 0.863800 -0.356200
+vn -0.432700 0.790900 -0.432600
+vn -0.501700 0.704500 -0.501900
+vn -0.562400 0.606000 -0.562500
+vn -0.613700 0.497200 -0.613300
+vn -0.653900 0.380700 -0.653800
+vn -0.683200 0.257600 -0.683300
+vn -0.700900 0.130300 -0.701200
+vn -0.707100 0.000000 -0.707100
+vn -0.701200 -0.130300 -0.700900
+vn -0.683300 -0.257600 -0.683200
+vn -0.653800 -0.380700 -0.653900
+vn -0.613300 -0.497200 -0.613700
+vn -0.562500 -0.606000 -0.562400
+vn -0.501900 -0.704500 -0.501700
+vn -0.432600 -0.790900 -0.432700
+vn -0.356200 -0.863800 -0.356300
+vn -0.274100 -0.921800 -0.274000
+vn -0.186700 -0.964500 -0.186600
+vn -0.095800 -0.990800 -0.095700
+vn -0.067800 0.990800 -0.117300
+vn -0.132000 0.964500 -0.228600
+vn -0.193800 0.921800 -0.335700
+vn -0.251700 0.863900 -0.436200
+vn -0.306000 0.790900 -0.529800
+vn -0.355100 0.704200 -0.614700
+vn -0.397800 0.605900 -0.688900
+vn -0.433500 0.497900 -0.751000
+vn -0.462400 0.380800 -0.800700
+vn -0.483200 0.257400 -0.836800
+vn -0.496000 0.129500 -0.858600
+vn -0.499900 0.000000 -0.866100
+vn -0.495700 -0.129600 -0.858700
+vn -0.483100 -0.257300 -0.836900
+vn -0.462500 -0.381000 -0.800500
+vn -0.433900 -0.497900 -0.750800
+vn -0.397800 -0.606000 -0.688900
+vn -0.354900 -0.704200 -0.614900
+vn -0.306000 -0.791000 -0.529700
+vn -0.251800 -0.863900 -0.436200
+vn -0.193700 -0.921800 -0.335800
+vn -0.132000 -0.964500 -0.228600
+vn -0.067800 -0.990800 -0.117300
+vn -0.035300 0.990800 -0.130800
+vn -0.068200 0.964500 -0.255100
+vn -0.100100 0.921800 -0.374300
+vn -0.130400 0.863900 -0.486500
+vn -0.158500 0.790900 -0.591000
+vn -0.183600 0.704600 -0.685400
+vn -0.206000 0.606100 -0.768200
+vn -0.224600 0.497300 -0.838000
+vn -0.239300 0.380600 -0.893200
+vn -0.250000 0.257300 -0.933400
+vn -0.256400 0.130100 -0.957700
+vn -0.258800 -0.000000 -0.965900
+vn -0.256700 -0.130000 -0.957700
+vn -0.249900 -0.257400 -0.933400
+vn -0.239000 -0.380400 -0.893400
+vn -0.224400 -0.497300 -0.838000
+vn -0.206100 -0.606200 -0.768100
+vn -0.183900 -0.704500 -0.685400
+vn -0.158400 -0.790900 -0.591000
+vn -0.130300 -0.863900 -0.486500
+vn -0.100200 -0.921800 -0.374400
+vn -0.068200 -0.964500 -0.255100
+vn -0.035300 -0.990800 -0.130700
+vn -0.000100 0.990700 -0.135700
+vn -0.000000 0.964500 -0.264100
+vn 0.000000 0.921800 -0.387500
+vn 0.000000 0.863900 -0.503500
+vn 0.000100 0.791000 -0.611700
+vn -0.000100 0.704400 -0.709800
+vn -0.000100 0.605800 -0.795600
+vn 0.000000 0.497100 -0.867700
+vn 0.000100 0.381000 -0.924600
+vn 0.000000 0.257600 -0.966200
+vn -0.000100 0.129700 -0.991500
+vn 0.000000 0.000000 -1.000000
+vn 0.000100 -0.129700 -0.991500
+vn -0.000000 -0.257600 -0.966200
+vn -0.000100 -0.381000 -0.924600
+vn 0.000000 -0.497100 -0.867700
+vn 0.000100 -0.605800 -0.795600
+vn 0.000100 -0.704400 -0.709800
+vn -0.000100 -0.791000 -0.611700
+vn -0.000000 -0.863900 -0.503500
+vn 0.000000 -0.921800 -0.387500
+vn 0.000000 -0.964500 -0.264100
+vn 0.000100 -0.990700 -0.135700
+vn 0.035300 0.990800 -0.130700
+vn 0.068200 0.964500 -0.255100
+vn 0.100200 0.921800 -0.374400
+vn 0.130300 0.863900 -0.486500
+vn 0.158400 0.790900 -0.591000
+vn 0.183900 0.704500 -0.685400
+vn 0.206100 0.606200 -0.768100
+vn 0.224400 0.497300 -0.838000
+vn 0.239000 0.380400 -0.893400
+vn 0.249900 0.257400 -0.933400
+vn 0.256700 0.130000 -0.957700
+vn 0.258800 0.000000 -0.965900
+vn 0.256400 -0.130100 -0.957700
+vn 0.250000 -0.257300 -0.933400
+vn 0.239300 -0.380600 -0.893200
+vn 0.224600 -0.497300 -0.838000
+vn 0.206000 -0.606100 -0.768200
+vn 0.183600 -0.704600 -0.685400
+vn 0.158500 -0.790900 -0.591000
+vn 0.130400 -0.863900 -0.486500
+vn 0.100100 -0.921800 -0.374300
+vn 0.068200 -0.964500 -0.255100
+vn 0.035300 -0.990800 -0.130800
+vn 0.067800 0.990800 -0.117300
+vn 0.132000 0.964500 -0.228600
+vn 0.193700 0.921800 -0.335800
+vn 0.251800 0.863900 -0.436200
+vn 0.306000 0.791000 -0.529700
+vn 0.354900 0.704200 -0.614900
+vn 0.397800 0.606000 -0.688900
+vn 0.433900 0.497900 -0.750800
+vn 0.462500 0.381000 -0.800500
+vn 0.483100 0.257300 -0.836900
+vn 0.495700 0.129600 -0.858700
+vn 0.499900 -0.000000 -0.866100
+vn 0.496000 -0.129500 -0.858600
+vn 0.483200 -0.257400 -0.836800
+vn 0.462400 -0.380800 -0.800700
+vn 0.433500 -0.497900 -0.751000
+vn 0.397800 -0.605900 -0.688900
+vn 0.355100 -0.704200 -0.614700
+vn 0.306000 -0.790900 -0.529800
+vn 0.251700 -0.863900 -0.436200
+vn 0.193800 -0.921800 -0.335700
+vn 0.132000 -0.964500 -0.228600
+vn 0.067800 -0.990800 -0.117300
+vn 0.095800 0.990800 -0.095700
+vn 0.186700 0.964500 -0.186600
+vn 0.274100 0.921800 -0.274000
+vn 0.356200 0.863800 -0.356300
+vn 0.432600 0.790900 -0.432700
+vn 0.501900 0.704500 -0.501700
+vn 0.562500 0.606000 -0.562400
+vn 0.613300 0.497200 -0.613700
+vn 0.653800 0.380700 -0.653900
+vn 0.683300 0.257600 -0.683200
+vn 0.701200 0.130300 -0.700900
+vn 0.707100 0.000000 -0.707100
+vn 0.700900 -0.130300 -0.701200
+vn 0.683200 -0.257600 -0.683300
+vn 0.653900 -0.380700 -0.653800
+vn 0.613700 -0.497200 -0.613300
+vn 0.562400 -0.606000 -0.562500
+vn 0.501700 -0.704500 -0.501900
+vn 0.432700 -0.790900 -0.432600
+vn 0.356300 -0.863800 -0.356200
+vn 0.274000 -0.921800 -0.274100
+vn 0.186600 -0.964500 -0.186700
+vn 0.095700 -0.990800 -0.095800
+vn 0.117300 0.990800 -0.067800
+vn 0.228600 0.964500 -0.132000
+vn 0.335700 0.921800 -0.193800
+vn 0.436200 0.863900 -0.251700
+vn 0.529800 0.790900 -0.306000
+vn 0.614700 0.704200 -0.355100
+vn 0.688900 0.605900 -0.397800
+vn 0.751000 0.497900 -0.433500
+vn 0.800700 0.380800 -0.462400
+vn 0.836800 0.257400 -0.483200
+vn 0.858600 0.129500 -0.496000
+vn 0.866100 0.000000 -0.499900
+vn 0.858700 -0.129600 -0.495700
+vn 0.836900 -0.257300 -0.483100
+vn 0.800500 -0.381000 -0.462500
+vn 0.750800 -0.497900 -0.433900
+vn 0.688900 -0.606000 -0.397800
+vn 0.614900 -0.704200 -0.354900
+vn 0.529700 -0.791000 -0.306000
+vn 0.436200 -0.863900 -0.251800
+vn 0.335800 -0.921800 -0.193700
+vn 0.228600 -0.964500 -0.132000
+vn 0.117300 -0.990800 -0.067800
+vn 0.130800 0.990800 -0.035300
+vn 0.255100 0.964500 -0.068200
+vn 0.374300 0.921800 -0.100100
+vn 0.486500 0.863900 -0.130400
+vn 0.591000 0.790900 -0.158500
+vn 0.685400 0.704600 -0.183600
+vn 0.768200 0.606100 -0.206000
+vn 0.838000 0.497300 -0.224600
+vn 0.893200 0.380600 -0.239300
+vn 0.933400 0.257300 -0.250000
+vn 0.957700 0.130100 -0.256400
+vn 0.965900 -0.000000 -0.258800
+vn 0.957700 -0.130000 -0.256700
+vn 0.933400 -0.257400 -0.249900
+vn 0.893400 -0.380400 -0.239000
+vn 0.838000 -0.497300 -0.224400
+vn 0.768100 -0.606200 -0.206100
+vn 0.685400 -0.704500 -0.183900
+vn 0.591000 -0.790900 -0.158400
+vn 0.486500 -0.863900 -0.130300
+vn 0.374400 -0.921800 -0.100200
+vn 0.255100 -0.964500 -0.068300
+vn 0.130700 -0.990800 -0.035300
+f 1//1 26//2 2//3
+f 2//3 26//2 27//4
+f 2//3 27//4 3//5
+f 3//5 27//4 28//6
+f 3//5 28//6 4//7
+f 4//7 28//6 29//8
+f 4//7 29//8 5//9
+f 5//9 29//8 30//10
+f 5//9 30//10 6//11
+f 6//11 30//10 31//12
+f 6//11 31//12 7//13
+f 7//13 31//12 32//14
+f 7//13 32//14 8//15
+f 8//15 32//14 33//16
+f 8//15 33//16 9//17
+f 9//17 33//16 34//18
+f 9//17 34//18 10//19
+f 10//19 34//18 35//20
+f 10//19 35//20 11//21
+f 11//21 35//20 36//22
+f 11//21 36//22 12//23
+f 12//23 36//22 37//24
+f 12//23 37//24 13//25
+f 13//25 37//24 38//26
+f 13//25 38//26 14//27
+f 14//27 38//26 39//28
+f 14//27 39//28 15//29
+f 15//29 39//28 40//30
+f 15//29 40//30 16//31
+f 16//31 40//30 41//32
+f 16//31 41//32 17//33
+f 17//33 41//32 42//34
+f 17//33 42//34 18//35
+f 18//35 42//34 43//36
+f 18//35 43//36 19//37
+f 19//37 43//36 44//38
+f 19//37 44//38 20//39
+f 20//39 44//38 45//40
+f 20//39 45//40 21//41
+f 21//41 45//40 46//42
+f 21//41 46//42 22//43
+f 22//43 46//42 47//44
+f 22//43 47//44 23//45
+f 23//45 47//44 48//46
+f 23//45 48//46 24//47
+f 24//47 48//46 25//48
+f 1//1 49//49 26//2
+f 26//2 49//49 50//50
+f 26//2 50//50 27//4
+f 27//4 50//50 51//51
+f 27//4 51//51 28//6
+f 28//6 51//51 52//52
+f 28//6 52//52 29//8
+f 29//8 52//52 53//53
+f 29//8 53//53 30//10
+f 30//10 53//53 54//54
+f 30//10 54//54 31//12
+f 31//12 54//54 55//55
+f 31//12 55//55 32//14
+f 32//14 55//55 56//56
+f 32//14 56//56 33//16
+f 33//16 56//56 57//57
+f 33//16 57//57 34//18
+f 34//18 57//57 58//58
+f 34//18 58//58 35//20
+f 35//20 58//58 59//59
+f 35//20 59//59 36//22
+f 36//22 59//59 60//60
+f 36//22 60//60 37//24
+f 37//24 60//60 61//61
+f 37//24 61//61 38//26
+f 38//26 61//61 62//62
+f 38//26 62//62 39//28
+f 39//28 62//62 63//63
+f 39//28 63//63 40//30
+f 40//30 63//63 64//64
+f 40//30 64//64 41//32
+f 41//32 64//64 65//65
+f 41//32 65//65 42//34
+f 42//34 65//65 66//66
+f 42//34 66//66 43//36
+f 43//36 66//66 67//67
+f 43//36 67//67 44//38
+f 44//38 67//67 68//68
+f 44//38 68//68 45//40
+f 45//40 68//68 69//69
+f 45//40 69//69 46//42
+f 46//42 69//69 70//70
+f 46//42 70//70 47//44
+f 47//44 70//70 71//71
+f 47//44 71//71 48//46
+f 48//46 71//71 25//48
+f 1//1 72//72 49//49
+f 49//49 72//72 73//73
+f 49//49 73//73 50//50
+f 50//50 73//73 74//74
+f 50//50 74//74 51//51
+f 51//51 74//74 75//75
+f 51//51 75//75 52//52
+f 52//52 75//75 76//76
+f 52//52 76//76 53//53
+f 53//53 76//76 77//77
+f 53//53 77//77 54//54
+f 54//54 77//77 78//78
+f 54//54 78//78 55//55
+f 55//55 78//78 79//79
+f 55//55 79//79 56//56
+f 56//56 79//79 80//80
+f 56//56 80//80 57//57
+f 57//57 80//80 81//81
+f 57//57 81//81 58//58
+f 58//58 81//81 82//82
+f 58//58 82//82 59//59
+f 59//59 82//82 83//83
+f 59//59 83//83 60//60
+f 60//60 83//83 84//84
+f 60//60 84//84 61//61
+f 61//61 84//84 85//85
+f 61//61 85//85 62//62
+f 62//62 85//85 86//86
+f 62//62 86//86 63//63
+f 63//63 86//86 87//87
+f 63//63 87//87 64//64
+f 64//64 87//87 88//88
+f 64//64 88//88 65//65
+f 65//65 88//88 89//89
+f 65//65 89//89 66//66
+f 66//66 89//89 90//90
+f 66//66 90//90 67//67
+f 67//67 90//90 91//91
+f 67//67 91//91 68//68
+f 68//68 91//91 92//92
+f 68//68 92//92 69//69
+f 69//69 92//92 93//93
+f 69//69 93//93 70//70
+f 70//70 93//93 94//94
+f 70//70 94//94 71//71
+f 71//71 94//94 25//48
+f 1//1 95//95 72//72
+f 72//72 95//95 96//96
+f 72//72 96//96 73//73
+f 73//73 96//96 97//97
+f 73//73 97//97 74//74
+f 74//74 97//97 98//98
+f 74//74 98//98 75//75
+f 75//75 98//98 99//99
+f 75//75 99//99 76//76
+f 76//76 99//99 100//100
+f 76//76 100//100 77//77
+f 77//77 100//100 101//101
+f 77//77 101//101 78//78
+f 78//78 101//101 102//102
+f 78//78 102//102 79//79
+f 79//79 102//102 103//103
+f 79//79 103//103 80//80
+f 80//80 103//103 104//104
+f 80//80 104//104 81//81
+f 81//81 104//104 105//105
+f 81//81 105//105 82//82
+f 82//82 105//105 106//106
+f 82//82 106//106 83//83
+f 83//83 106//106 107//107
+f 83//83 107//107 84//84
+f 84//84 107//107 108//108
+f 84//84 108//108 85//85
+f 85//85 108//108 109//109
+f 85//85 109//109 86//86
+f 86//86 109//109 110//110
+f 86//86 110//110 87//87
+f 87//87 110//110 111//111
+f 87//87 111//111 88//88
+f 88//88 111//111 112//112
+f 88//88 112//112 89//89
+f 89//89 112//112 113//113
+f 89//89 113//113 90//90
+f 90//90 113//113 114//114
+f 90//90 114//114 91//91
+f 91//91 114//114 115//115
+f 91//91 115//115 92//92
+f 92//92 115//115 116//116
+f 92//92 116//116 93//93
+f 93//93 116//116 117//117
+f 93//93 117//117 94//94
+f 94//94 117//117 25//48
+f 1//1 118//118 95//95
+f 95//95 118//118 119//119
+f 95//95 119//119 96//96
+f 96//96 119//119 120//120
+f 96//96 120//120 97//97
+f 97//97 120//120 121//121
+f 97//97 121//121 98//98
+f 98//98 121//121 122//122
+f 98//98 122//122 99//99
+f 99//99 122//122 123//123
+f 99//99 123//123 100//100
+f 100//100 123//123 124//124
+f 100//100 124//124 101//101
+f 101//101 124//124 125//125
+f 101//101 125//125 102//102
+f 102//102 125//125 126//126
+f 102//102 126//126 103//103
+f 103//103 126//126 127//127
+f 103//103 127//127 104//104
+f 104//104 127//127 128//128
+f 104//104 128//128 105//105
+f 105//105 128//128 129//129
+f 105//105 129//129 106//106
+f 106//106 129//129 130//130
+f 106//106 130//130 107//107
+f 107//107 130//130 131//131
+f 107//107 131//131 108//108
+f 108//108 131//131 132//132
+f 108//108 132//132 109//109
+f 109//109 132//132 133//133
+f 109//109 133//133 110//110
+f 110//110 133//133 134//134
+f 110//110 134//134 111//111
+f 111//111 134//134 135//135
+f 111//111 135//135 112//112
+f 112//112 135//135 136//136
+f 112//112 136//136 113//113
+f 113//113 136//136 137//137
+f 113//113 137//137 114//114
+f 114//114 137//137 138//138
+f 114//114 138//138 115//115
+f 115//115 138//138 139//139
+f 115//115 139//139 116//116
+f 116//116 139//139 140//140
+f 116//116 140//140 117//117
+f 117//117 140//140 25//48
+f 1//1 141//141 118//118
+f 118//118 141//141 142//142
+f 118//118 142//142 119//119
+f 119//119 142//142 143//143
+f 119//119 143//143 120//120
+f 120//120 143//143 144//144
+f 120//120 144//144 121//121
+f 121//121 144//144 145//145
+f 121//121 145//145 122//122
+f 122//122 145//145 146//146
+f 122//122 146//146 123//123
+f 123//123 146//146 147//147
+f 123//123 147//147 124//124
+f 124//124 147//147 148//148
+f 124//124 148//148 125//125
+f 125//125 148//148 149//149
+f 125//125 149//149 126//126
+f 126//126 149//149 150//150
+f 126//126 150//150 127//127
+f 127//127 150//150 151//151
+f 127//127 151//151 128//128
+f 128//128 151//151 152//152
+f 128//128 152//152 129//129
+f 129//129 152//152 153//153
+f 129//129 153//153 130//130
+f 130//130 153//153 154//154
+f 130//130 154//154 131//131
+f 131//131 154//154 155//155
+f 131//131 155//155 132//132
+f 132//132 155//155 156//156
+f 132//132 156//156 133//133
+f 133//133 156//156 157//157
+f 133//133 157//157 134//134
+f 134//134 157//157 158//158
+f 134//134 158//158 135//135
+f 135//135 158//158 159//159
+f 135//135 159//159 136//136
+f 136//136 159//159 160//160
+f 136//136 160//160 137//137
+f 137//137 160//160 161//161
+f 137//137 161//161 138//138
+f 138//138 161//161 162//162
+f 138//138 162//162 139//139
+f 139//139 162//162 163//163
+f 139//139 163//163 140//140
+f 140//140 163//163 25//48
+f 1//1 164//164 141//141
+f 141//141 164//164 165//165
+f 141//141 165//165 142//142
+f 142//142 165//165 166//166
+f 142//142 166//166 143//143
+f 143//143 166//166 167//167
+f 143//143 167//167 144//144
+f 144//144 167//167 168//168
+f 144//144 168//168 145//145
+f 145//145 168//168 169//169
+f 145//145 169//169 146//146
+f 146//146 169//169 170//170
+f 146//146 170//170 147//147
+f 147//147 170//170 171//171
+f 147//147 171//171 148//148
+f 148//148 171//171 172//172
+f 148//148 172//172 149//149
+f 149//149 172//172 173//173
+f 149//149 173//173 150//150
+f 150//150 173//173 174//174
+f 150//150 174//174 151//151
+f 151//151 174//174 175//175
+f 151//151 175//175 152//152
+f 152//152 175//175 176//176
+f 152//152 176//176 153//153
+f 153//153 176//176 177//177
+f 153//153 177//177 154//154
+f 154//154 177//177 178//178
+f 154//154 178//178 155//155
+f 155//155 178//178 179//179
+f 155//155 179//179 156//156
+f 156//156 179//179 180//180
+f 156//156 180//180 157//157
+f 157//157 180//180 181//181
+f 157//157 181//181 158//158
+f 158//158 181//181 182//182
+f 158//158 182//182 159//159
+f 159//159 182//182 183//183
+f 159//159 183//183 160//160
+f 160//160 183//183 184//184
+f 160//160 184//184 161//161
+f 161//161 184//184 185//185
+f 161//161 185//185 162//162
+f 162//162 185//185 186//186
+f 162//162 186//186 163//163
+f 163//163 186//186 25//48
+f 1//1 187//187 164//164
+f 164//164 187//187 188//188
+f 164//164 188//188 165//165
+f 165//165 188//188 189//189
+f 165//165 189//189 166//166
+f 166//166 189//189 190//190
+f 166//166 190//190 167//167
+f 167//167 190//190 191//191
+f 167//167 191//191 168//168
+f 168//168 191//191 192//192
+f 168//168 192//192 169//169
+f 169//169 192//192 193//193
+f 169//169 193//193 170//170
+f 170//170 193//193 194//194
+f 170//170 194//194 171//171
+f 171//171 194//194 195//195
+f 171//171 195//195 172//172
+f 172//172 195//195 196//196
+f 172//172 196//196 173//173
+f 173//173 196//196 197//197
+f 173//173 197//197 174//174
+f 174//174 197//197 198//198
+f 174//174 198//198 175//175
+f 175//175 198//198 199//199
+f 175//175 199//199 176//176
+f 176//176 199//199 200//200
+f 176//176 200//200 177//177
+f 177//177 200//200 201//201
+f 177//177 201//201 178//178
+f 178//178 201//201 202//202
+f 178//178 202//202 179//179
+f 179//179 202//202 203//203
+f 179//179 203//203 180//180
+f 180//180 203//203 204//204
+f 180//180 204//204 181//181
+f 181//181 204//204 205//205
+f 181//181 205//205 182//182
+f 182//182 205//205 206//206
+f 182//182 206//206 183//183
+f 183//183 206//206 207//207
+f 183//183 207//207 184//184
+f 184//184 207//207 208//208
+f 184//184 208//208 185//185
+f 185//185 208//208 209//209
+f 185//185 209//209 186//186
+f 186//186 209//209 25//48
+f 1//1 210//210 187//187
+f 187//187 210//210 211//211
+f 187//187 211//211 188//188
+f 188//188 211//211 212//212
+f 188//188 212//212 189//189
+f 189//189 212//212 213//213
+f 189//189 213//213 190//190
+f 190//190 213//213 214//214
+f 190//190 214//214 191//191
+f 191//191 214//214 215//215
+f 191//191 215//215 192//192
+f 192//192 215//215 216//216
+f 192//192 216//216 193//193
+f 193//193 216//216 217//217
+f 193//193 217//217 194//194
+f 194//194 217//217 218//218
+f 194//194 218//218 195//195
+f 195//195 218//218 219//219
+f 195//195 219//219 196//196
+f 196//196 219//219 220//220
+f 196//196 220//220 197//197
+f 197//197 220//220 221//221
+f 197//197 221//221 198//198
+f 198//198 221//221 222//222
+f 198//198 222//222 199//199
+f 199//199 222//222 223//223
+f 199//199 223//223 200//200
+f 200//200 223//223 224//224
+f 200//200 224//224 201//201
+f 201//201 224//224 225//225
+f 201//201 225//225 202//202
+f 202//202 225//225 226//226
+f 202//202 226//226 203//203
+f 203//203 226//226 227//227
+f 203//203 227//227 204//204
+f 204//204 227//227 228//228
+f 204//204 228//228 205//205
+f 205//205 228//228 229//229
+f 205//205 229//229 206//206
+f 206//206 229//229 230//230
+f 206//206 230//230 207//207
+f 207//207 230//230 231//231
+f 207//207 231//231 208//208
+f 208//208 231//231 232//232
+f 208//208 232//232 209//209
+f 209//209 232//232 25//48
+f 1//1 233//233 210//210
+f 210//210 233//233 234//234
+f 210//210 234//234 211//211
+f 211//211 234//234 235//235
+f 211//211 235//235 212//212
+f 212//212 235//235 236//236
+f 212//212 236//236 213//213
+f 213//213 236//236 237//237
+f 213//213 237//237 214//214
+f 214//214 237//237 238//238
+f 214//214 238//238 215//215
+f 215//215 238//238 239//239
+f 215//215 239//239 216//216
+f 216//216 239//239 240//240
+f 216//216 240//240 217//217
+f 217//217 240//240 241//241
+f 217//217 241//241 218//218
+f 218//218 241//241 242//242
+f 218//218 242//242 219//219
+f 219//219 242//242 243//243
+f 219//219 243//243 220//220
+f 220//220 243//243 244//244
+f 220//220 244//244 221//221
+f 221//221 244//244 245//245
+f 221//221 245//245 222//222
+f 222//222 245//245 246//246
+f 222//222 246//246 223//223
+f 223//223 246//246 247//247
+f 223//223 247//247 224//224
+f 224//224 247//247 248//248
+f 224//224 248//248 225//225
+f 225//225 248//248 249//249
+f 225//225 249//249 226//226
+f 226//226 249//249 250//250
+f 226//226 250//250 227//227
+f 227//227 250//250 251//251
+f 227//227 251//251 228//228
+f 228//228 251//251 252//252
+f 228//228 252//252 229//229
+f 229//229 252//252 253//253
+f 229//229 253//253 230//230
+f 230//230 253//253 254//254
+f 230//230 254//254 231//231
+f 231//231 254//254 255//255
+f 231//231 255//255 232//232
+f 232//232 255//255 25//48
+f 1//1 256//256 233//233
+f 233//233 256//256 257//257
+f 233//233 257//257 234//234
+f 234//234 257//257 258//258
+f 234//234 258//258 235//235
+f 235//235 258//258 259//259
+f 235//235 259//259 236//236
+f 236//236 259//259 260//260
+f 236//236 260//260 237//237
+f 237//237 260//260 261//261
+f 237//237 261//261 238//238
+f 238//238 261//261 262//262
+f 238//238 262//262 239//239
+f 239//239 262//262 263//263
+f 239//239 263//263 240//240
+f 240//240 263//263 264//264
+f 240//240 264//264 241//241
+f 241//241 264//264 265//265
+f 241//241 265//265 242//242
+f 242//242 265//265 266//266
+f 242//242 266//266 243//243
+f 243//243 266//266 267//267
+f 243//243 267//267 244//244
+f 244//244 267//267 268//268
+f 244//244 268//268 245//245
+f 245//245 268//268 269//269
+f 245//245 269//269 246//246
+f 246//246 269//269 270//270
+f 246//246 270//270 247//247
+f 247//247 270//270 271//271
+f 247//247 271//271 248//248
+f 248//248 271//271 272//272
+f 248//248 272//272 249//249
+f 249//249 272//272 273//273
+f 249//249 273//273 250//250
+f 250//250 273//273 274//274
+f 250//250 274//274 251//251
+f 251//251 274//274 275//275
+f 251//251 275//275 252//252
+f 252//252 275//275 276//276
+f 252//252 276//276 253//253
+f 253//253 276//276 277//277
+f 253//253 277//277 254//254
+f 254//254 277//277 278//278
+f 254//254 278//278 255//255
+f 255//255 278//278 25//48
+f 1//1 279//279 256//256
+f 256//256 279//279 280//280
+f 256//256 280//280 257//257
+f 257//257 280//280 281//281
+f 257//257 281//281 258//258
+f 258//258 281//281 282//282
+f 258//258 282//282 259//259
+f 259//259 282//282 283//283
+f 259//259 283//283 260//260
+f 260//260 283//283 284//284
+f 260//260 284//284 261//261
+f 261//261 284//284 285//285
+f 261//261 285//285 262//262
+f 262//262 285//285 286//286
+f 262//262 286//286 263//263
+f 263//263 286//286 287//287
+f 263//263 287//287 264//264
+f 264//264 287//287 288//288
+f 264//264 288//288 265//265
+f 265//265 288//288 289//289
+f 265//265 289//289 266//266
+f 266//266 289//289 290//290
+f 266//266 290//290 267//267
+f 267//267 290//290 291//291
+f 267//267 291//291 268//268
+f 268//268 291//291 292//292
+f 268//268 292//292 269//269
+f 269//269 292//292 293//293
+f 269//269 293//293 270//270
+f 270//270 293//293 294//294
+f 270//270 294//294 271//271
+f 271//271 294//294 295//295
+f 271//271 295//295 272//272
+f 272//272 295//295 296//296
+f 272//272 296//296 273//273
+f 273//273 296//296 297//297
+f 273//273 297//297 274//274
+f 274//274 297//297 298//298
+f 274//274 298//298 275//275
+f 275//275 298//298 299//299
+f 275//275 299//299 276//276
+f 276//276 299//299 300//300
+f 276//276 300//300 277//277
+f 277//277 300//300 301//301
+f 277//277 301//301 278//278
+f 278//278 301//301 25//48
+f 1//1 302//302 279//279
+f 279//279 302//302 303//303
+f 279//279 303//303 280//280
+f 280//280 303//303 304//304
+f 280//280 304//304 281//281
+f 281//281 304//304 305//305
+f 281//281 305//305 282//282
+f 282//282 305//305 306//306
+f 282//282 306//306 283//283
+f 283//283 306//306 307//307
+f 283//283 307//307 284//284
+f 284//284 307//307 308//308
+f 284//284 308//308 285//285
+f 285//285 308//308 309//309
+f 285//285 309//309 286//286
+f 286//286 309//309 310//310
+f 286//286 310//310 287//287
+f 287//287 310//310 311//311
+f 287//287 311//311 288//288
+f 288//288 311//311 312//312
+f 288//288 312//312 289//289
+f 289//289 312//312 313//313
+f 289//289 313//313 290//290
+f 290//290 313//313 314//314
+f 290//290 314//314 291//291
+f 291//291 314//314 315//315
+f 291//291 315//315 292//292
+f 292//292 315//315 316//316
+f 292//292 316//316 293//293
+f 293//293 316//316 317//317
+f 293//293 317//317 294//294
+f 294//294 317//317 318//318
+f 294//294 318//318 295//295
+f 295//295 318//318 319//319
+f 295//295 319//319 296//296
+f 296//296 319//319 320//320
+f 296//296 320//320 297//297
+f 297//297 320//320 321//321
+f 297//297 321//321 298//298
+f 298//298 321//321 322//322
+f 298//298 322//322 299//299
+f 299//299 322//322 323//323
+f 299//299 323//323 300//300
+f 300//300 323//323 324//324
+f 300//300 324//324 301//301
+f 301//301 324//324 25//48
+f 1//1 325//325 302//302
+f 302//302 325//325 326//326
+f 302//302 326//326 303//303
+f 303//303 326//326 327//327
+f 303//303 327//327 304//304
+f 304//304 327//327 328//328
+f 304//304 328//328 305//305
+f 305//305 328//328 329//329
+f 305//305 329//329 306//306
+f 306//306 329//329 330//330
+f 306//306 330//330 307//307
+f 307//307 330//330 331//331
+f 307//307 331//331 308//308
+f 308//308 331//331 332//332
+f 308//308 332//332 309//309
+f 309//309 332//332 333//333
+f 309//309 333//333 310//310
+f 310//310 333//333 334//334
+f 310//310 334//334 311//311
+f 311//311 334//334 335//335
+f 311//311 335//335 312//312
+f 312//312 335//335 336//336
+f 312//312 336//336 313//313
+f 313//313 336//336 337//337
+f 313//313 337//337 314//314
+f 314//314 337//337 338//338
+f 314//314 338//338 315//315
+f 315//315 338//338 339//339
+f 315//315 339//339 316//316
+f 316//316 339//339 340//340
+f 316//316 340//340 317//317
+f 317//317 340//340 341//341
+f 317//317 341//341 318//318
+f 318//318 341//341 342//342
+f 318//318 342//342 319//319
+f 319//319 342//342 343//343
+f 319//319 343//343 320//320
+f 320//320 343//343 344//344
+f 320//320 344//344 321//321
+f 321//321 344//344 345//345
+f 321//321 345//345 322//322
+f 322//322 345//345 346//346
+f 322//322 346//346 323//323
+f 323//323 346//346 347//347
+f 323//323 347//347 324//324
+f 324//324 347//347 25//48
+f 1//1 348//348 325//325
+f 325//325 348//348 349//349
+f 325//325 349//349 326//326
+f 326//326 349//349 350//350
+f 326//326 350//350 327//327
+f 327//327 350//350 351//351
+f 327//327 351//351 328//328
+f 328//328 351//351 352//352
+f 328//328 352//352 329//329
+f 329//329 352//352 353//353
+f 329//329 353//353 330//330
+f 330//330 353//353 354//354
+f 330//330 354//354 331//331
+f 331//331 354//354 355//355
+f 331//331 355//355 332//332
+f 332//332 355//355 356//356
+f 332//332 356//356 333//333
+f 333//333 356//356 357//357
+f 333//333 357//357 334//334
+f 334//334 357//357 358//358
+f 334//334 358//358 335//335
+f 335//335 358//358 359//359
+f 335//335 359//359 336//336
+f 336//336 359//359 360//360
+f 336//336 360//360 337//337
+f 337//337 360//360 361//361
+f 337//337 361//361 338//338
+f 338//338 361//361 362//362
+f 338//338 362//362 339//339
+f 339//339 362//362 363//363
+f 339//339 363//363 340//340
+f 340//340 363//363 364//364
+f 340//340 364//364 341//341
+f 341//341 364//364 365//365
+f 341//341 365//365 342//342
+f 342//342 365//365 366//366
+f 342//342 366//366 343//343
+f 343//343 366//366 367//367
+f 343//343 367//367 344//344
+f 344//344 367//367 368//368
+f 344//344 368//368 345//345
+f 345//345 368//368 369//369
+f 345//345 369//369 346//346
+f 346//346 369//369 370//370
+f 346//346 370//370 347//347
+f 347//347 370//370 25//48
+f 1//1 371//371 348//348
+f 348//348 371//371 372//372
+f 348//348 372//372 349//349
+f 349//349 372//372 373//373
+f 349//349 373//373 350//350
+f 350//350 373//373 374//374
+f 350//350 374//374 351//351
+f 351//351 374//374 375//375
+f 351//351 375//375 352//352
+f 352//352 375//375 376//376
+f 352//352 376//376 353//353
+f 353//353 376//376 377//377
+f 353//353 377//377 354//354
+f 354//354 377//377 378//378
+f 354//354 378//378 355//355
+f 355//355 378//378 379//379
+f 355//355 379//379 356//356
+f 356//356 379//379 380//380
+f 356//356 380//380 357//357
+f 357//357 380//380 381//381
+f 357//357 381//381 358//358
+f 358//358 381//381 382//382
+f 358//358 382//382 359//359
+f 359//359 382//382 383//383
+f 359//359 383//383 360//360
+f 360//360 383//383 384//384
+f 360//360 384//384 361//361
+f 361//361 384//384 385//385
+f 361//361 385//385 362//362
+f 362//362 385//385 386//386
+f 362//362 386//386 363//363
+f 363//363 386//386 387//387
+f 363//363 387//387 364//364
+f 364//364 387//387 388//388
+f 364//364 388//388 365//365
+f 365//365 388//388 389//389
+f 365//365 389//389 366//366
+f 366//366 389//389 390//390
+f 366//366 390//390 367//367
+f 367//367 390//390 391//391
+f 367//367 391//391 368//368
+f 368//368 391//391 392//392
+f 368//368 392//392 369//369
+f 369//369 392//392 393//393
+f 369//369 393//393 370//370
+f 370//370 393//393 25//48
+f 1//1 394//394 371//371
+f 371//371 394//394 395//395
+f 371//371 395//395 372//372
+f 372//372 395//395 396//396
+f 372//372 396//396 373//373
+f 373//373 396//396 397//397
+f 373//373 397//397 374//374
+f 374//374 397//397 398//398
+f 374//374 398//398 375//375
+f 375//375 398//398 399//399
+f 375//375 399//399 376//376
+f 376//376 399//399 400//400
+f 376//376 400//400 377//377
+f 377//377 400//400 401//401
+f 377//377 401//401 378//378
+f 378//378 401//401 402//402
+f 378//378 402//402 379//379
+f 379//379 402//402 403//403
+f 379//379 403//403 380//380
+f 380//380 403//403 404//404
+f 380//380 404//404 381//381
+f 381//381 404//404 405//405
+f 381//381 405//405 382//382
+f 382//382 405//405 406//406
+f 382//382 406//406 383//383
+f 383//383 406//406 407//407
+f 383//383 407//407 384//384
+f 384//384 407//407 408//408
+f 384//384 408//408 385//385
+f 385//385 408//408 409//409
+f 385//385 409//409 386//386
+f 386//386 409//409 410//410
+f 386//386 410//410 387//387
+f 387//387 410//410 411//411
+f 387//387 411//411 388//388
+f 388//388 411//411 412//412
+f 388//388 412//412 389//389
+f 389//389 412//412 413//413
+f 389//389 413//413 390//390
+f 390//390 413//413 414//414
+f 390//390 414//414 391//391
+f 391//391 414//414 415//415
+f 391//391 415//415 392//392
+f 392//392 415//415 416//416
+f 392//392 416//416 393//393
+f 393//393 416//416 25//48
+f 1//1 417//417 394//394
+f 394//394 417//417 418//418
+f 394//394 418//418 395//395
+f 395//395 418//418 419//419
+f 395//395 419//419 396//396
+f 396//396 419//419 420//420
+f 396//396 420//420 397//397
+f 397//397 420//420 421//421
+f 397//397 421//421 398//398
+f 398//398 421//421 422//422
+f 398//398 422//422 399//399
+f 399//399 422//422 423//423
+f 399//399 423//423 400//400
+f 400//400 423//423 424//424
+f 400//400 424//424 401//401
+f 401//401 424//424 425//425
+f 401//401 425//425 402//402
+f 402//402 425//425 426//426
+f 402//402 426//426 403//403
+f 403//403 426//426 427//427
+f 403//403 427//427 404//404
+f 404//404 427//427 428//428
+f 404//404 428//428 405//405
+f 405//405 428//428 429//429
+f 405//405 429//429 406//406
+f 406//406 429//429 430//430
+f 406//406 430//430 407//407
+f 407//407 430//430 431//431
+f 407//407 431//431 408//408
+f 408//408 431//431 432//432
+f 408//408 432//432 409//409
+f 409//409 432//432 433//433
+f 409//409 433//433 410//410
+f 410//410 433//433 434//434
+f 410//410 434//434 411//411
+f 411//411 434//434 435//435
+f 411//411 435//435 412//412
+f 412//412 435//435 436//436
+f 412//412 436//436 413//413
+f 413//413 436//436 437//437
+f 413//413 437//437 414//414
+f 414//414 437//437 438//438
+f 414//414 438//438 415//415
+f 415//415 438//438 439//439
+f 415//415 439//439 416//416
+f 416//416 439//439 25//48
+f 1//1 440//440 417//417
+f 417//417 440//440 441//441
+f 417//417 441//441 418//418
+f 418//418 441//441 442//442
+f 418//418 442//442 419//419
+f 419//419 442//442 443//443
+f 419//419 443//443 420//420
+f 420//420 443//443 444//444
+f 420//420 444//444 421//421
+f 421//421 444//444 445//445
+f 421//421 445//445 422//422
+f 422//422 445//445 446//446
+f 422//422 446//446 423//423
+f 423//423 446//446 447//447
+f 423//423 447//447 424//424
+f 424//424 447//447 448//448
+f 424//424 448//448 425//425
+f 425//425 448//448 449//449
+f 425//425 449//449 426//426
+f 426//426 449//449 450//450
+f 426//426 450//450 427//427
+f 427//427 450//450 451//451
+f 427//427 451//451 428//428
+f 428//428 451//451 452//452
+f 428//428 452//452 429//429
+f 429//429 452//452 453//453
+f 429//429 453//453 430//430
+f 430//430 453//453 454//454
+f 430//430 454//454 431//431
+f 431//431 454//454 455//455
+f 431//431 455//455 432//432
+f 432//432 455//455 456//456
+f 432//432 456//456 433//433
+f 433//433 456//456 457//457
+f 433//433 457//457 434//434
+f 434//434 457//457 458//458
+f 434//434 458//458 435//435
+f 435//435 458//458 459//459
+f 435//435 459//459 436//436
+f 436//436 459//459 460//460
+f 436//436 460//460 437//437
+f 437//437 460//460 461//461
+f 437//437 461//461 438//438
+f 438//438 461//461 462//462
+f 438//438 462//462 439//439
+f 439//439 462//462 25//48
+f 1//1 463//463 440//440
+f 440//440 463//463 464//464
+f 440//440 464//464 441//441
+f 441//441 464//464 465//465
+f 441//441 465//465 442//442
+f 442//442 465//465 466//466
+f 442//442 466//466 443//443
+f 443//443 466//466 467//467
+f 443//443 467//467 444//444
+f 444//444 467//467 468//468
+f 444//444 468//468 445//445
+f 445//445 468//468 469//469
+f 445//445 469//469 446//446
+f 446//446 469//469 470//470
+f 446//446 470//470 447//447
+f 447//447 470//470 471//471
+f 447//447 471//471 448//448
+f 448//448 471//471 472//472
+f 448//448 472//472 449//449
+f 449//449 472//472 473//473
+f 449//449 473//473 450//450
+f 450//450 473//473 474//474
+f 450//450 474//474 451//451
+f 451//451 474//474 475//475
+f 451//451 475//475 452//452
+f 452//452 475//475 476//476
+f 452//452 476//476 453//453
+f 453//453 476//476 477//477
+f 453//453 477//477 454//454
+f 454//454 477//477 478//478
+f 454//454 478//478 455//455
+f 455//455 478//478 479//479
+f 455//455 479//479 456//456
+f 456//456 479//479 480//480
+f 456//456 480//480 457//457
+f 457//457 480//480 481//481
+f 457//457 481//481 458//458
+f 458//458 481//481 482//482
+f 458//458 482//482 459//459
+f 459//459 482//482 483//483
+f 459//459 483//483 460//460
+f 460//460 483//483 484//484
+f 460//460 484//484 461//461
+f 461//461 484//484 485//485
+f 461//461 485//485 462//462
+f 462//462 485//485 25//48
+f 1//1 486//486 463//463
+f 463//463 486//486 487//487
+f 463//463 487//487 464//464
+f 464//464 487//487 488//488
+f 464//464 488//488 465//465
+f 465//465 488//488 489//489
+f 465//465 489//489 466//466
+f 466//466 489//489 490//490
+f 466//466 490//490 467//467
+f 467//467 490//490 491//491
+f 467//467 491//491 468//468
+f 468//468 491//491 492//492
+f 468//468 492//492 469//469
+f 469//469 492//492 493//493
+f 469//469 493//493 470//470
+f 470//470 493//493 494//494
+f 470//470 494//494 471//471
+f 471//471 494//494 495//495
+f 471//471 495//495 472//472
+f 472//472 495//495 496//496
+f 472//472 496//496 473//473
+f 473//473 496//496 497//497
+f 473//473 497//497 474//474
+f 474//474 497//497 498//498
+f 474//474 498//498 475//475
+f 475//475 498//498 499//499
+f 475//475 499//499 476//476
+f 476//476 499//499 500//500
+f 476//476 500//500 477//477
+f 477//477 500//500 501//501
+f 477//477 501//501 478//478
+f 478//478 501//501 502//502
+f 478//478 502//502 479//479
+f 479//479 502//502 503//503
+f 479//479 503//503 480//480
+f 480//480 503//503 504//504
+f 480//480 504//504 481//481
+f 481//481 504//504 505//505
+f 481//481 505//505 482//482
+f 482//482 505//505 506//506
+f 482//482 506//506 483//483
+f 483//483 506//506 507//507
+f 483//483 507//507 484//484
+f 484//484 507//507 508//508
+f 484//484 508//508 485//485
+f 485//485 508//508 25//48
+f 1//1 509//509 486//486
+f 486//486 509//509 510//510
+f 486//486 510//510 487//487
+f 487//487 510//510 511//511
+f 487//487 511//511 488//488
+f 488//488 511//511 512//512
+f 488//488 512//512 489//489
+f 489//489 512//512 513//513
+f 489//489 513//513 490//490
+f 490//490 513//513 514//514
+f 490//490 514//514 491//491
+f 491//491 514//514 515//515
+f 491//491 515//515 492//492
+f 492//492 515//515 516//516
+f 492//492 516//516 493//493
+f 493//493 516//516 517//517
+f 493//493 517//517 494//494
+f 494//494 517//517 518//518
+f 494//494 518//518 495//495
+f 495//495 518//518 519//519
+f 495//495 519//519 496//496
+f 496//496 519//519 520//520
+f 496//496 520//520 497//497
+f 497//497 520//520 521//521
+f 497//497 521//521 498//498
+f 498//498 521//521 522//522
+f 498//498 522//522 499//499
+f 499//499 522//522 523//523
+f 499//499 523//523 500//500
+f 500//500 523//523 524//524
+f 500//500 524//524 501//501
+f 501//501 524//524 525//525
+f 501//501 525//525 502//502
+f 502//502 525//525 526//526
+f 502//502 526//526 503//503
+f 503//503 526//526 527//527
+f 503//503 527//527 504//504
+f 504//504 527//527 528//528
+f 504//504 528//528 505//505
+f 505//505 528//528 529//529
+f 505//505 529//529 506//506
+f 506//506 529//529 530//530
+f 506//506 530//530 507//507
+f 507//507 530//530 531//531
+f 507//507 531//531 508//508
+f 508//508 531//531 25//48
+f 1//1 532//532 509//509
+f 509//509 532//532 533//533
+f 509//509 533//533 510//510
+f 510//510 533//533 534//534
+f 510//510 534//534 511//511
+f 511//511 534//534 535//535
+f 511//511 535//535 512//512
+f 512//512 535//535 536//536
+f 512//512 536//536 513//513
+f 513//513 536//536 537//537
+f 513//513 537//537 514//514
+f 514//514 537//537 538//538
+f 514//514 538//538 515//515
+f 515//515 538//538 539//539
+f 515//515 539//539 516//516
+f 516//516 539//539 540//540
+f 516//516 540//540 517//517
+f 517//517 540//540 541//541
+f 517//517 541//541 518//518
+f 518//518 541//541 542//542
+f 518//518 542//542 519//519
+f 519//519 542//542 543//543
+f 519//519 543//543 520//520
+f 520//520 543//543 544//544
+f 520//520 544//544 521//521
+f 521//521 544//544 545//545
+f 521//521 545//545 522//522
+f 522//522 545//545 546//546
+f 522//522 546//546 523//523
+f 523//523 546//546 547//547
+f 523//523 547//547 524//524
+f 524//524 547//547 548//548
+f 524//524 548//548 525//525
+f 525//525 548//548 549//549
+f 525//525 549//549 526//526
+f 526//526 549//549 550//550
+f 526//526 550//550 527//527
+f 527//527 550//550 551//551
+f 527//527 551//551 528//528
+f 528//528 551//551 552//552
+f 528//528 552//552 529//529
+f 529//529 552//552 553//553
+f 529//529 553//553 530//530
+f 530//530 553//553 554//554
+f 530//530 554//554 531//531
+f 531//531 554//554 25//48
+f 1//1 2//3 532//532
+f 532//532 2//3 3//5
+f 532//532 3//5 533//533
+f 533//533 3//5 4//7
+f 533//533 4//7 534//534
+f 534//534 4//7 5//9
+f 534//534 5//9 535//535
+f 535//535 5//9 6//11
+f 535//535 6//11 536//536
+f 536//536 6//11 7//13
+f 536//536 7//13 537//537
+f 537//537 7//13 8//15
+f 537//537 8//15 538//538
+f 538//538 8//15 9//17
+f 538//538 9//17 539//539
+f 539//539 9//17 10//19
+f 539//539 10//19 540//540
+f 540//540 10//19 11//21
+f 540//540 11//21 541//541
+f 541//541 11//21 12//23
+f 541//541 12//23 542//542
+f 542//542 12//23 13//25
+f 542//542 13//25 543//543
+f 543//543 13//25 14//27
+f 543//543 14//27 544//544
+f 544//544 14//27 15//29
+f 544//544 15//29 545//545
+f 545//545 15//29 16//31
+f 545//545 16//31 546//546
+f 546//546 16//31 17//33
+f 546//546 17//33 547//547
+f 547//547 17//33 18//35
+f 547//547 18//35 548//548
+f 548//548 18//35 19//37
+f 548//548 19//37 549//549
+f 549//549 19//37 20//39
+f 549//549 20//39 550//550
+f 550//550 20//39 21//41
+f 550//550 21//41 551//551
+f 551//551 21//41 22//43
+f 551//551 22//43 552//552
+f 552//552 22//43 23//45
+f 552//552 23//45 553//553
+f 553//553 23//45 24//47
+f 553//553 24//47 554//554
+f 554//554 24//47 25//48
diff --git a/AnimatableGaussians/assets/cylinder.obj b/AnimatableGaussians/assets/cylinder.obj
new file mode 100644
index 0000000000000000000000000000000000000000..77ce899b4526b7781a159467d8f976059c5e8d3a
--- /dev/null
+++ b/AnimatableGaussians/assets/cylinder.obj
@@ -0,0 +1,198 @@
+# Blender v2.74 (sub 0) OBJ File: ''
+# www.blender.org
+v 0.000000 0.500000 0.500000
+v 0.129400 0.500000 0.483000
+v 0.250000 0.500000 0.433000
+v 0.353600 0.500000 0.353600
+v 0.433000 0.500000 0.250000
+v 0.483000 0.500000 0.129400
+v 0.500000 0.500000 0.000000
+v 0.483000 0.500000 -0.129400
+v 0.433000 0.500000 -0.250000
+v 0.353600 0.500000 -0.353600
+v 0.250000 0.500000 -0.433000
+v 0.129400 0.500000 -0.483000
+v 0.000000 0.500000 -0.500000
+v -0.129400 0.500000 -0.483000
+v -0.250000 0.500000 -0.433000
+v -0.353600 0.500000 -0.353600
+v -0.433000 0.500000 -0.250000
+v -0.483000 0.500000 -0.129400
+v -0.500000 0.500000 0.000000
+v -0.483000 0.500000 0.129400
+v -0.433000 0.500000 0.250000
+v -0.353600 0.500000 0.353600
+v -0.250000 0.500000 0.433000
+v -0.129400 0.500000 0.483000
+v 0.000000 -0.500000 0.500000
+v 0.129400 -0.500000 0.483000
+v 0.250000 -0.500000 0.433000
+v 0.353600 -0.500000 0.353600
+v 0.433000 -0.500000 0.250000
+v 0.483000 -0.500000 0.129400
+v 0.500000 -0.500000 0.000000
+v 0.483000 -0.500000 -0.129400
+v 0.433000 -0.500000 -0.250000
+v 0.353600 -0.500000 -0.353600
+v 0.250000 -0.500000 -0.433000
+v 0.129400 -0.500000 -0.483000
+v 0.000000 -0.500000 -0.500000
+v -0.129400 -0.500000 -0.483000
+v -0.250000 -0.500000 -0.433000
+v -0.353600 -0.500000 -0.353600
+v -0.433000 -0.500000 -0.250000
+v -0.483000 -0.500000 -0.129400
+v -0.500000 -0.500000 0.000000
+v -0.483000 -0.500000 0.129400
+v -0.433000 -0.500000 0.250000
+v -0.353600 -0.500000 0.353600
+v -0.250000 -0.500000 0.433000
+v -0.129400 -0.500000 0.483000
+v 0.000000 0.500000 0.000000
+v 0.000000 -0.500000 0.000000
+vn 0.000000 0.678900 0.734200
+vn 0.000000 -0.678900 0.734200
+vn 0.190100 -0.678800 0.709300
+vn 0.190100 0.678800 0.709300
+vn 0.367000 -0.678900 0.635900
+vn 0.367000 0.678900 0.635900
+vn 0.519300 -0.678700 0.519300
+vn 0.519300 0.678700 0.519300
+vn 0.635900 -0.678900 0.367000
+vn 0.635900 0.678900 0.367000
+vn 0.709300 -0.678800 0.190100
+vn 0.709300 0.678800 0.190100
+vn 0.734200 -0.678900 0.000000
+vn 0.734200 0.678900 0.000000
+vn 0.709300 -0.678800 -0.190100
+vn 0.709300 0.678800 -0.190100
+vn 0.635900 -0.678900 -0.367000
+vn 0.635900 0.678900 -0.367000
+vn 0.519300 -0.678700 -0.519300
+vn 0.519300 0.678700 -0.519300
+vn 0.367000 -0.678900 -0.635900
+vn 0.367000 0.678900 -0.635900
+vn 0.190100 -0.678800 -0.709300
+vn 0.190100 0.678800 -0.709300
+vn 0.000000 -0.678900 -0.734200
+vn 0.000000 0.678900 -0.734200
+vn -0.190100 -0.678800 -0.709300
+vn -0.190100 0.678800 -0.709300
+vn -0.367000 -0.678900 -0.635900
+vn -0.367000 0.678900 -0.635900
+vn -0.519300 -0.678700 -0.519300
+vn -0.519300 0.678700 -0.519300
+vn -0.635900 -0.678900 -0.367000
+vn -0.635900 0.678900 -0.367000
+vn -0.709300 -0.678800 -0.190100
+vn -0.709300 0.678800 -0.190100
+vn -0.734200 -0.678900 0.000000
+vn -0.734200 0.678900 0.000000
+vn -0.709300 -0.678800 0.190100
+vn -0.709300 0.678800 0.190100
+vn -0.635900 -0.678900 0.367000
+vn -0.635900 0.678900 0.367000
+vn -0.519300 -0.678700 0.519300
+vn -0.519300 0.678700 0.519300
+vn -0.367000 -0.678900 0.635900
+vn -0.367000 0.678900 0.635900
+vn -0.190100 -0.678800 0.709300
+vn -0.190100 0.678800 0.709300
+vn 0.000000 1.000000 0.000000
+vn 0.000000 -1.000000 0.000000
+f 1//1 25//2 26//3
+f 1//1 26//3 2//4
+f 2//4 26//3 27//5
+f 2//4 27//5 3//6
+f 3//6 27//5 28//7
+f 3//6 28//7 4//8
+f 4//8 28//7 29//9
+f 4//8 29//9 5//10
+f 5//10 29//9 30//11
+f 5//10 30//11 6//12
+f 6//12 30//11 31//13
+f 6//12 31//13 7//14
+f 7//14 31//13 32//15
+f 7//14 32//15 8//16
+f 8//16 32//15 33//17
+f 8//16 33//17 9//18
+f 9//18 33//17 34//19
+f 9//18 34//19 10//20
+f 10//20 34//19 35//21
+f 10//20 35//21 11//22
+f 11//22 35//21 36//23
+f 11//22 36//23 12//24
+f 12//24 36//23 37//25
+f 12//24 37//25 13//26
+f 13//26 37//25 38//27
+f 13//26 38//27 14//28
+f 14//28 38//27 39//29
+f 14//28 39//29 15//30
+f 15//30 39//29 40//31
+f 15//30 40//31 16//32
+f 16//32 40//31 41//33
+f 16//32 41//33 17//34
+f 17//34 41//33 42//35
+f 17//34 42//35 18//36
+f 18//36 42//35 43//37
+f 18//36 43//37 19//38
+f 19//38 43//37 44//39
+f 19//38 44//39 20//40
+f 20//40 44//39 45//41
+f 20//40 45//41 21//42
+f 21//42 45//41 46//43
+f 21//42 46//43 22//44
+f 22//44 46//43 47//45
+f 22//44 47//45 23//46
+f 23//46 47//45 48//47
+f 23//46 48//47 24//48
+f 24//48 48//47 25//2
+f 24//48 25//2 1//1
+f 1//1 2//4 49//49
+f 2//4 3//6 49//49
+f 3//6 4//8 49//49
+f 4//8 5//10 49//49
+f 5//10 6//12 49//49
+f 6//12 7//14 49//49
+f 7//14 8//16 49//49
+f 8//16 9//18 49//49
+f 9//18 10//20 49//49
+f 10//20 11//22 49//49
+f 11//22 12//24 49//49
+f 12//24 13//26 49//49
+f 13//26 14//28 49//49
+f 14//28 15//30 49//49
+f 15//30 16//32 49//49
+f 16//32 17//34 49//49
+f 17//34 18//36 49//49
+f 18//36 19//38 49//49
+f 19//38 20//40 49//49
+f 20//40 21//42 49//49
+f 21//42 22//44 49//49
+f 22//44 23//46 49//49
+f 23//46 24//48 49//49
+f 24//48 1//1 49//49
+f 26//3 25//2 50//50
+f 27//5 26//3 50//50
+f 28//7 27//5 50//50
+f 29//9 28//7 50//50
+f 30//11 29//9 50//50
+f 31//13 30//11 50//50
+f 32//15 31//13 50//50
+f 33//17 32//15 50//50
+f 34//19 33//17 50//50
+f 35//21 34//19 50//50
+f 36//23 35//21 50//50
+f 37//25 36//23 50//50
+f 38//27 37//25 50//50
+f 39//29 38//27 50//50
+f 40//31 39//29 50//50
+f 41//33 40//31 50//50
+f 42//35 41//33 50//50
+f 43//37 42//35 50//50
+f 44//39 43//37 50//50
+f 45//41 44//39 50//50
+f 46//43 45//41 50//50
+f 47//45 46//43 50//50
+f 48//47 47//45 50//50
+f 25//2 48//47 50//50
diff --git a/AnimatableGaussians/base_trainer.py b/AnimatableGaussians/base_trainer.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff1b9ae20824d385f811a8568c695991a1620b15
--- /dev/null
+++ b/AnimatableGaussians/base_trainer.py
@@ -0,0 +1,258 @@
+import os
+import platform
+import time
+import yaml
+import torch
+import datetime
+from torch.utils.tensorboard import SummaryWriter
+import torch.utils.data
+import numpy as np
+import glob
+import shutil
+
+from utils.net_util import to_cuda
+
+
+def worker_init_fn(worker_id): # set numpy's random seed
+ seed = torch.initial_seed()
+ seed = seed % (2 ** 32)
+ np.random.seed(seed + worker_id)
+
+
+class BaseTrainer:
+ def __init__(self, opt):
+ self.opt = opt
+
+ self.dataset = None
+ self.network = None
+ self.net_dict = {}
+ self.optm_dict = {}
+ self.update_keys = None
+ self.lr_schedule_dict = {}
+ self.iter_idx = 0
+ self.epoch_idx = 0
+ self.iter_num = 9999999999
+
+ self.loss_weight = self.opt['train']['loss_weight']
+
+ @staticmethod
+ def load_pretrained(path, dict_):
+ data = torch.load(path)
+ for k in dict_:
+ if k in data:
+ print('# Loading %s...' % k)
+ dict_[k].load_state_dict(data[k])
+ else:
+ print('# %s not found!' % k)
+ return data.get('epoch_idx', None)
+
+ def load_ckpt(self, path, load_optm = True):
+ epoch_idx = self.load_pretrained(path + '/net.pt', self.net_dict)
+ if load_optm:
+ if os.path.exists(path + '/optm.pt'):
+ self.load_pretrained(path + '/optm.pt', self.optm_dict)
+ else:
+ print('# Optimizer not found!')
+ return epoch_idx
+
+ # @staticmethod
+ def save_trained(self, path, dict_):
+ data = {}
+ for k in dict_:
+ data[k] = dict_[k].state_dict()
+ data.update({
+ 'epoch_idx': self.epoch_idx,
+ })
+ torch.save(data, path)
+
+ def save_ckpt(self, path, save_optm = True):
+ self.save_trained(path + '/net.pt', self.net_dict)
+ if save_optm:
+ self.save_trained(path + '/optm.pt', self.optm_dict)
+
+ def zero_grad(self):
+ if self.update_keys is None:
+ update_keys = self.optm_dict.keys()
+ else:
+ update_keys = self.update_keys
+ for k in update_keys:
+ self.optm_dict[k].zero_grad()
+
+ def step(self):
+ if self.update_keys is None:
+ update_keys = self.optm_dict.keys()
+ else:
+ update_keys = self.update_keys
+ for k in update_keys:
+ self.optm_dict[k].step()
+
+ def update_lr(self, iter_idx):
+ lr_dict = {}
+ if self.update_keys is None:
+ update_keys = self.optm_dict.keys()
+ else:
+ update_keys = self.update_keys
+ for k in update_keys:
+ lr = self.lr_schedule_dict[k].get_learning_rate(iter_idx)
+ for param_group in self.optm_dict[k].param_groups:
+ param_group['lr'] = lr
+ lr_dict[k] = lr
+ return lr_dict
+
+ def set_dataset(self, dataset):
+ self.dataset = dataset
+
+ def set_network(self, network):
+ self.network = network
+
+ def set_net_dict(self, net_dict):
+ self.net_dict = net_dict
+
+ def set_optm_dict(self, optm_dict):
+ self.optm_dict = optm_dict
+
+ def set_update_keys(self, update_keys):
+ self.update_keys = update_keys
+
+ def set_lr_schedule_dict(self, lr_schedule_dict):
+ self.lr_schedule_dict = lr_schedule_dict
+
+ def set_train(self, flag = True):
+ if flag:
+ for k, net in self.net_dict.items():
+ if k in self.update_keys:
+ net.train()
+ else:
+ net.eval()
+ else:
+ for k, net in self.net_dict.items():
+ net.eval()
+
+ def train(self):
+ # log
+ os.makedirs(self.opt['train']['net_ckpt_dir'], exist_ok = True)
+ log_dir = self.opt['train']['net_ckpt_dir'] + '/' + datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
+ os.makedirs(log_dir, exist_ok = True)
+ writer = SummaryWriter(log_dir)
+ yaml.dump(self.opt, open(log_dir + '/config_bk.yaml', 'w'), sort_keys = False)
+
+ self.set_train()
+ self.dataset.training = True
+ batch_size = self.opt['train'].get('batch_size', 1)
+ num_workers = self.opt['train'].get('num_workers', 0)
+ dataloader = torch.utils.data.DataLoader(self.dataset,
+ batch_size = batch_size,
+ shuffle = True,
+ num_workers = num_workers,
+ worker_init_fn = worker_init_fn,
+ drop_last = True)
+ self.batch_num = len(self.dataset) // batch_size
+
+ if self.opt['train'].get('save_init_ckpt', False) and self.opt['train'].get('start_epoch', 0) == 0:
+ init_folder = self.opt['train']['net_ckpt_dir'] + '/init_ckpt'
+ if not os.path.exists(init_folder) or self.opt['train']['start_epoch'] == 0:
+ os.makedirs(init_folder, exist_ok = True)
+ self.save_ckpt(init_folder, False)
+ else:
+ print('# Init checkpoint has been saved!')
+
+ if self.opt['train']['prev_ckpt'] is not None:
+ start_epoch = self.load_ckpt(self.opt['train']['prev_ckpt']) + 1
+ else:
+ prev_ckpt_path = self.opt['train']['net_ckpt_dir'] + '/epoch_latest'
+ if os.path.exists(prev_ckpt_path):
+ start_epoch = self.load_ckpt(prev_ckpt_path) + 1
+ else:
+ start_epoch = None
+
+ if start_epoch is None:
+ start_epoch = self.opt['train'].get('start_epoch', 0)
+ end_epoch = self.opt['train'].get('end_epoch', 999)
+
+ forward_one_pass = self.forward_one_pass
+
+ for epoch_idx in range(start_epoch, end_epoch):
+ self.epoch_idx = epoch_idx
+ self.update_config_before_epoch(epoch_idx)
+ epoch_losses = dict()
+
+ time0 = time.time()
+ for batch_idx, items in enumerate(dataloader):
+ iter_idx = batch_idx + self.batch_num * epoch_idx
+ self.iter_idx = iter_idx
+ lr_dict = self.update_lr(iter_idx)
+ items = to_cuda(items)
+
+ loss, batch_losses = forward_one_pass(items)
+ # self.zero_grad()
+ # loss.backward()
+ # self.step()
+
+ # record batch loss
+ log_info = 'epoch %d, batch %d, ' % (epoch_idx, batch_idx)
+ log_info += 'lr: '
+ for k in lr_dict.keys():
+ log_info += '%s %e, ' % (k, lr_dict[k])
+ for key in batch_losses.keys():
+ log_info = log_info + ('%s: %f, ' % (key, batch_losses[key]))
+ writer.add_scalar('%s/Batch' % key, batch_losses[key], iter_idx)
+ if key in epoch_losses:
+ epoch_losses[key] += batch_losses[key]
+ else:
+ epoch_losses[key] = batch_losses[key]
+ print(log_info)
+
+ with open(os.path.join(log_dir, 'loss.txt'), 'a') as fp:
+ # record loss weight
+ if batch_idx == 0:
+ loss_weights_info = ''
+ for k in self.opt['train']['loss_weight'].keys():
+ loss_weights_info += '%s: %f, ' % (k, self.opt['train']['loss_weight'][k])
+ fp.write('# Loss weights: \n' + loss_weights_info + '\n')
+ fp.write(log_info + '\n')
+
+ if iter_idx % self.opt['train']['ckpt_interval']['batch'] == 0 and iter_idx != 0:
+ for folder in glob.glob(self.opt['train']['net_ckpt_dir'] + '/batch_*'):
+ shutil.rmtree(folder)
+ model_folder = self.opt['train']['net_ckpt_dir'] + '/batch_%d' % iter_idx
+ os.makedirs(model_folder, exist_ok = True)
+ self.save_ckpt(model_folder, save_optm = False)
+
+ if iter_idx % self.opt['train']['eval_interval'] == 0 and iter_idx != 0:
+ # if True:
+ self.mini_test()
+ self.set_train()
+ time1 = time.time()
+ print('One iteration costs %f secs' % (time1 - time0))
+ time0 = time1
+
+ if iter_idx == self.iter_num:
+ return
+
+ """ EPOCH """
+ # record epoch loss
+ for key in epoch_losses.keys():
+ epoch_losses[key] /= self.batch_num
+ writer.add_scalar('%s/Epoch' % key, epoch_losses[key], epoch_idx)
+
+ if epoch_idx % self.opt['train']['ckpt_interval']['epoch'] == 0:
+ model_folder = self.opt['train']['net_ckpt_dir'] + '/epoch_%d' % epoch_idx
+ os.makedirs(model_folder, exist_ok = True)
+ self.save_ckpt(model_folder)
+
+ if self.batch_num > 50:
+ latest_folder = self.opt['train']['net_ckpt_dir'] + '/epoch_latest'
+ os.makedirs(latest_folder, exist_ok = True)
+ self.save_ckpt(latest_folder)
+ writer.close()
+
+ @torch.no_grad()
+ def mini_test(self):
+ """ Test during training """
+ pass
+
+ def forward_one_pass(self, items):
+ raise NotImplementedError('"forward_one_pass" method is not implemented!')
+
+ def update_config_before_epoch(self, epoch_idx):
+ pass
diff --git a/AnimatableGaussians/cat.sh b/AnimatableGaussians/cat.sh
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/AnimatableGaussians/config.py b/AnimatableGaussians/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..7057242c57f6e6c5bdff30aa5d1d0009093a3dc5
--- /dev/null
+++ b/AnimatableGaussians/config.py
@@ -0,0 +1,35 @@
+import torch
+import numpy as np
+import math
+import os
+
+device = torch.device('cuda:0')
+
+# SMPL related
+cano_smpl_pose = np.zeros(75, dtype = np.float32)
+cano_smpl_pose[3+3*1+2] = math.radians(25)
+cano_smpl_pose[3+3*2+2] = math.radians(-25)
+cano_smpl_pose = torch.from_numpy(cano_smpl_pose)
+cano_smpl_transl = cano_smpl_pose[:3]
+cano_smpl_global_orient = cano_smpl_pose[3:6]
+cano_smpl_body_pose = cano_smpl_pose[6:69]
+
+# fist pose
+left_hand_pose = torch.tensor([0.09001956135034561, 0.1604590266942978, -0.3295670449733734, 0.12445037066936493, -0.11897698789834976, -1.5051144361495972, -0.1194705069065094, -0.16281449794769287, -0.6292539834976196, -0.27713727951049805, 0.035170216113328934, -0.5893177390098572, -0.20759613811969757, 0.07492011040449142, -1.4485805034637451, -0.017797302454710007, -0.12478633224964142, -0.7844052314758301, -0.4157009720802307, -0.5140947103500366, -0.2961726784706116, -0.7421528100967407, -0.11505582183599472, -0.7972996830940247, -0.29345276951789856, -0.18898937106132507, -0.6230823397636414, -0.18764786422252655, -0.2696149945259094, -0.5542467832565308, -0.47717514634132385, -0.12663133442401886, -1.2747308015823364, -0.23940050601959229, -0.1586960405111313, -0.7655659914016724, 0.8745182156562805, 0.5848557353019714, -0.07204405218362808, -0.5052485466003418, 0.1797526329755783, 0.3281439244747162, 0.5276764035224915, -0.008714836090803146, -0.4373648762702942], dtype = torch.float32)
+right_hand_pose = torch.tensor([0.034751810133457184, -0.12605343759059906, 0.5510415434837341, 0.19454114139080048, 0.11147838830947876, 1.4676157236099243, -0.14799435436725616, 0.17293521761894226, 0.4679432511329651, -0.3042353689670563, 0.007868679240345955, 0.8570928573608398, -0.1827319711446762, -0.07225851714611053, 1.307037591934204, -0.02989627793431282, 0.1208646297454834, 0.7142824530601501, -0.3403030335903168, 0.5368582606315613, 0.3839572072029114, -0.9722614884376526, 0.17358140647411346, 0.911861002445221, -0.29665058851242065, 0.21779759228229523, 0.7269846796989441, -0.15343312919139862, 0.3083758056163788, 0.7146623730659485, -0.5153037309646606, 0.1721675992012024, 1.2982604503631592, -0.2590428292751312, 0.12812566757202148, 0.7502076029777527, 0.8694817423820496, -0.5263001322746277, 0.06934576481580734, -0.4630220830440521, -0.19237111508846283, -0.25436165928840637, 0.5972414612770081, -0.08250168710947037, 0.5013565421104431], dtype = torch.float32)
+
+
+# project
+PROJ_DIR = os.path.dirname(os.path.realpath(__file__))
+
+opt = dict()
+
+
+def load_global_opt(path):
+ import yaml
+ global opt
+ opt = yaml.load(open(path, encoding = 'UTF-8'), Loader = yaml.FullLoader)
+
+def set_opt(new_opt):
+ global opt
+ opt = new_opt
diff --git a/AnimatableGaussians/configs/awesome_amass_poses.yaml b/AnimatableGaussians/configs/awesome_amass_poses.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..32f98d0497150dc49e6391d1c9585b55620bd171
--- /dev/null
+++ b/AnimatableGaussians/configs/awesome_amass_poses.yaml
@@ -0,0 +1,25 @@
+# CMU sub-dataset
+basketball:
+ - ./CMU/06/06_13_poses.npz
+ - ./CMU/06/06_14_poses.npz
+tennis:
+ - ./CMU/02/02_08_poses.npz
+ - ./CMU/02/02_09_poses.npz
+football:
+ - ./CMU/10/10_05_poses.npz
+ - ./CMU/11/11_01_poses.npz
+punch:
+ - ./CMU/15/15_13_poses.npz
+kick:
+ - ./CMU/144/144_05_poses.npz
+others:
+ - ./CMU/144/144_28_poses.npz
+dancing:
+ - ./CMU/131/131_03_poses.npz
+
+# MPI_mosh sub-dataset
+dancing2:
+ - ./MPI_mosh/00059/misc_poses.npz
+ - ./MPI_mosh/00093/irish_dance_poses.npz
+ - ./MPI_mosh/00093/misc_poses.npz
+ - ./MPI_mosh/50004/misc_poses.npz
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/huawei_0425/avatar.yaml b/AnimatableGaussians/configs/huawei_0425/avatar.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..985d689529742c4485028c2108612feb47f21c06
--- /dev/null
+++ b/AnimatableGaussians/configs/huawei_0425/avatar.yaml
@@ -0,0 +1,75 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: huawei0425
+ data_dir: ../data/body_data
+ frame_range: &id001
+ - 124
+ - 144
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: ../data/body_data
+ frame_range: [0, 500]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/test_poses_ours.npz
+ frame_range: [0, 1000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 1.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_avatar
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/huawei_0425/avatar1.yaml b/AnimatableGaussians/configs/huawei_0425/avatar1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..19c51485f5e4ba5404d8e15bb520057e1751525a
--- /dev/null
+++ b/AnimatableGaussians/configs/huawei_0425/avatar1.yaml
@@ -0,0 +1,75 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: dx1test
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: &id001
+ - 124
+ - 144
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar1
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: [0, 500]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_pred_new.npz
+ frame_range: [0, 128]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 1.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_new/body
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/huawei_0425/avatar2.yaml b/AnimatableGaussians/configs/huawei_0425/avatar2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fcb46376e0902e58fc0d1420f9f0877bc9a6137e
--- /dev/null
+++ b/AnimatableGaussians/configs/huawei_0425/avatar2.yaml
@@ -0,0 +1,75 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: dx_long_1_debug
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: &id001
+ - 124
+ - 144
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: [0, 500]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_long_1_debug.npz
+ frame_range: [0, 270]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 1.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_new/body
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/huawei_0425/nzc.yaml b/AnimatableGaussians/configs/huawei_0425/nzc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7e9dcfa3e0011bd6073f604b793db555a865b851
--- /dev/null
+++ b/AnimatableGaussians/configs/huawei_0425/nzc.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: nzc_test_data_0916_comb_v2
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam_new
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam_new
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0916_comb_v2.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_new_v2/body
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/huawei_0425/nzc_new.yaml b/AnimatableGaussians/configs/huawei_0425/nzc_new.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e09c8ff1c2b04f03f1a6169ea242a120da498f8d
--- /dev/null
+++ b/AnimatableGaussians/configs/huawei_0425/nzc_new.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0921_nzc_lz
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0916_comb_v2.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_new/body
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/new0829/avatar.yaml b/AnimatableGaussians/configs/new0829/avatar.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..830d6d6f596bfd944a60ad286b0ac7b25c89fca2
--- /dev/null
+++ b/AnimatableGaussians/configs/new0829/avatar.yaml
@@ -0,0 +1,75 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: new0829
+ data_dir: ../data/body_data
+ frame_range: &id001
+ - 124
+ - 144
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: ../data/body_data
+ frame_range: [0, 500]
+ subject_name: new0829
+ pose_data:
+ data_path: ../data/AMASS/test_poses_ours.npz
+ frame_range: [0, 1000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 1.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_new/body
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0921_nzc_ckpt_ys.yaml b/AnimatableGaussians/configs/pengcheng/0921_nzc_ckpt_ys.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b5e6128f847fc9858624e9a64e3fc4bf193fc7cb
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0921_nzc_ckpt_ys.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0921_nzc_lz
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam_new
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/ag_gha/smplparam_lz
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0916_comb_v2.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints_cys/body12
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0923_cys.yaml b/AnimatableGaussians/configs/pengcheng/0923_cys.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..106cb029009bc2e3256b01fb0857c2961c6d9673
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0923_cys.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0923_cys
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0916_comb_v2.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0924_nzc_new_pose.yaml b/AnimatableGaussians/configs/pengcheng/0924_nzc_new_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..994f7330b5a813e39ce15dc09a30964227d3daae
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0924_nzc_new_pose.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0924_new_pose
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0924.npz
+ frame_range: [0, 200]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0925_nzc_new_pose.yaml b/AnimatableGaussians/configs/pengcheng/0925_nzc_new_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..acdf9e0c7ef6c0a9a0bad81d6b39992986a84bb4
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0925_nzc_new_pose.yaml
@@ -0,0 +1,77 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0926_new_pose
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/0926_dx_happy.npz
+ frame_range: [0, 200]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0926_nzc_new_pose.yaml b/AnimatableGaussians/configs/pengcheng/0926_nzc_new_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..76890be368c05eabc74779c9a9cedd7e344711d2
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0926_nzc_new_pose.yaml
@@ -0,0 +1,78 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0926_pose_long
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0926_long_v1.npz
+ frame_range: [0, 2000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: degree120
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0929_lodge.yaml b/AnimatableGaussians/configs/pengcheng/0929_lodge.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5836b72afd3a3bf74fa5098fddbc715fa9a88135
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0929_lodge.yaml
@@ -0,0 +1,78 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0929_lodge_012
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/012.npz
+ frame_range: [0, 2000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: front
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/0930_sing.yaml b/AnimatableGaussians/configs/pengcheng/0930_sing.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eadf64254bddeec5d2ecafad19e9db7a79f6f73d
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/0930_sing.yaml
@@ -0,0 +1,78 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 0930_sing_free
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/0930_sing.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: free
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/1002_nzc_new_pose.yaml b/AnimatableGaussians/configs/pengcheng/1002_nzc_new_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9f07efdecdb735f05fd2b50659852b4f6501ad95
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/1002_nzc_new_pose.yaml
@@ -0,0 +1,79 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 1002_nzc_360_no_global
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/dx_0926_long_v1.npz
+ frame_range: [0, 360]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ # view_setting: degree120
+ view_setting: free
+ render_view_idx: 13
+ global_orient: false
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/1002_train_pose.yaml b/AnimatableGaussians/configs/pengcheng/1002_train_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f1d623a209184a56b559f3ea269adbe76ad66405
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/1002_train_pose.yaml
@@ -0,0 +1,79 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 1002_train_pose
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/train_data_v4.npz
+ frame_range: [0, 300]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ # view_setting: degree120
+ view_setting: free
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/1003_cat_pose.yaml b/AnimatableGaussians/configs/pengcheng/1003_cat_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ef410a048ebd282e695ffac54fe46ccfe6be4928
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/1003_cat_pose.yaml
@@ -0,0 +1,79 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 1003_cat_pose_false
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/1003_cat_data.npz
+ frame_range: [0, 2000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: degree120
+ # view_setting: free
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/1004_smooth_train_pose.yaml b/AnimatableGaussians/configs/pengcheng/1004_smooth_train_pose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f319fcd19d0d593c32d7dd9354bf3839977e22c6
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/1004_smooth_train_pose.yaml
@@ -0,0 +1,79 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 1006_smooth_train_pose
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/1004_smooth_train_data.npz
+ frame_range: [0, 2000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: degree120
+ # view_setting: free
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/configs/pengcheng/1007_slow10.yaml b/AnimatableGaussians/configs/pengcheng/1007_slow10.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2f815441d064ecd86bf4890571021601e7dfec2a
--- /dev/null
+++ b/AnimatableGaussians/configs/pengcheng/1007_slow10.yaml
@@ -0,0 +1,79 @@
+mode: train
+train:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ subject_name: 1007_slow10
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: &id001
+ - 0
+ - 200
+ - 1
+ used_cam_ids:
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 14
+ - 15
+ load_smpl_pos_map: true
+ pretrained_dir: null
+ net_ckpt_dir: ./results/huawei0425/avatar2
+ prev_ckpt: null
+ ckpt_interval:
+ epoch: 10
+ batch: 50000
+ eval_interval: 1000
+ eval_training_ids:
+ - 190
+ - 7
+ eval_testing_ids:
+ - 354
+ - 7
+ eval_img_factor: 1.0
+ lr_init: 0.0005
+ loss_weight:
+ l1: 1.0
+ lpips: 0.1
+ offset: 0.005
+ finetune_color: false
+ batch_size: 1
+ num_workers: 8
+ random_bg_color: true
+test:
+ dataset: MvRgbDatasetAvatarReX
+ data:
+ data_dir: /home/pengc02/pengcheng/projects/gaussian_avatar/avatar_final/data/pos_map_ys/body_mix
+ frame_range: [0, 800]
+ subject_name: huawei0425
+ pose_data:
+ data_path: ../data/AMASS/1007_train_data_slow10.npz
+ frame_range: [0, 2000]
+# data_path: Z:/Data/Pose/AMASS/CMU/06/06_13_poses.npz
+# data_path: Z:/Data/Pose/AMASS/CMU/10/10_05_poses.npz
+# frame_interval: 4
+ # view_setting: front
+ view_setting: degree90
+ # view_setting: free
+ render_view_idx: 13
+ global_orient: true
+ img_scale: 2.0
+ save_mesh: false
+ render_skeleton: false
+ save_tex_map: false
+ save_ply: true
+ fix_hand: true
+ fix_hand_id: 23
+ n_pca: 20
+ sigma_pca: 2.0
+ prev_ckpt: ../checkpoints/body_ys
+model:
+ with_viewdirs: true
+ random_style: false
\ No newline at end of file
diff --git a/AnimatableGaussians/dataset/__pycache__/commons.cpython-310.pyc b/AnimatableGaussians/dataset/__pycache__/commons.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..de054b8be7d0276c5f2a5ff4d887faf2d01cf842
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/commons.cpython-310.pyc differ
diff --git a/AnimatableGaussians/dataset/__pycache__/commons.cpython-38.pyc b/AnimatableGaussians/dataset/__pycache__/commons.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..15bf7dc51e037d2b4ab011534547b0a146423bbb
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/commons.cpython-38.pyc differ
diff --git a/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-310.pyc b/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..279546fceeaf179aaa26759baa6b183e461b86eb
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-310.pyc differ
diff --git a/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-38.pyc b/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e8ee9d4907ab61307af8c059c500e619d96d8f3c
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/dataset_mv_rgb.cpython-38.pyc differ
diff --git a/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-310.pyc b/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e33d35be950cd27ee01ab6544032c150002fa283
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-310.pyc differ
diff --git a/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-38.pyc b/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8786537d65cffa975d8239d259728fd317f78057
Binary files /dev/null and b/AnimatableGaussians/dataset/__pycache__/dataset_pose.cpython-38.pyc differ
diff --git a/AnimatableGaussians/dataset/commons.py b/AnimatableGaussians/dataset/commons.py
new file mode 100644
index 0000000000000000000000000000000000000000..99040868317a55621e2778022f3178c3ee71a5ea
--- /dev/null
+++ b/AnimatableGaussians/dataset/commons.py
@@ -0,0 +1,31 @@
+import numpy as np
+import torch
+import trimesh
+
+import AnimatableGaussians.config as config
+
+
+def _initialize_hands(self):
+ smplx_lhand_to_mano_rhand_data = np.load(config.PROJ_DIR + '/smpl_files/mano/smplx_lhand_to_mano_rhand.npz', allow_pickle = True)
+ smplx_rhand_to_mano_rhand_data = np.load(config.PROJ_DIR + '/smpl_files/mano/smplx_rhand_to_mano_rhand.npz', allow_pickle = True)
+ smpl_lhand_vert_id = np.copy(smplx_lhand_to_mano_rhand_data['smpl_vert_id_to_mano'])
+ smpl_rhand_vert_id = np.copy(smplx_rhand_to_mano_rhand_data['smpl_vert_id_to_mano'])
+ self.smpl_lhand_vert_id = torch.from_numpy(smpl_lhand_vert_id)
+ self.smpl_rhand_vert_id = torch.from_numpy(smpl_rhand_vert_id)
+ self.smpl_hands_vert_id = torch.cat([self.smpl_lhand_vert_id, self.smpl_rhand_vert_id], 0)
+ mano_face_closed = np.loadtxt(config.PROJ_DIR + '/smpl_files/mano/mano_face_close.txt').astype(np.int64)
+ self.mano_face_closed = torch.from_numpy(mano_face_closed)
+ self.mano_face_closed_turned = self.mano_face_closed[:, [2, 1, 0]]
+ self.mano_face_closed_2hand = torch.cat([self.mano_face_closed[:, [2, 1, 0]], self.mano_face_closed + self.smpl_lhand_vert_id.shape[0]], 0)
+
+
+def generate_two_manos(self, smplx_verts: torch.Tensor):
+ left_mano_v = smplx_verts[self.smpl_lhand_vert_id].cpu().numpy()
+ left_mano_trimesh = trimesh.Trimesh(left_mano_v, self.mano_face_closed_turned, process = False)
+ left_mano_n = left_mano_trimesh.vertex_normals.astype(np.float32)
+
+ right_mano_v = smplx_verts[self.smpl_rhand_vert_id].cpu().numpy()
+ right_mano_trimesh = trimesh.Trimesh(right_mano_v, self.mano_face_closed, process = False)
+ right_mano_n = right_mano_trimesh.vertex_normals.astype(np.float32)
+
+ return left_mano_v, left_mano_n, right_mano_v, right_mano_n
diff --git a/AnimatableGaussians/dataset/dataset_mv_rgb.py b/AnimatableGaussians/dataset/dataset_mv_rgb.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffdd2ed67eb650edbb6dad09d019ca6556162d05
--- /dev/null
+++ b/AnimatableGaussians/dataset/dataset_mv_rgb.py
@@ -0,0 +1,506 @@
+import glob
+import os
+import numpy as np
+import cv2 as cv
+from sympy import li
+import torch
+from torch.utils.data import Dataset
+
+import AnimatableGaussians.smplx as smplx
+import AnimatableGaussians.config as config
+import AnimatableGaussians.utils.nerf_util as nerf_util
+import AnimatableGaussians.utils.visualize_util as visualize_util
+import AnimatableGaussians.dataset.commons as commons
+
+
+class MvRgbDatasetBase(Dataset):
+ @torch.no_grad()
+ def __init__(
+ self,
+ data_dir,
+ frame_range = None,
+ used_cam_ids = None,
+ training = True,
+ subject_name = None,
+ load_smpl_pos_map = False,
+ load_smpl_nml_map = False,
+ mode = '3dgs'
+ ):
+ super(MvRgbDatasetBase, self).__init__()
+
+ self.data_dir = data_dir
+ self.training = training
+ self.subject_name = subject_name
+ if self.subject_name is None:
+ self.subject_name = os.path.basename(self.data_dir)
+ self.load_smpl_pos_map = load_smpl_pos_map
+ self.load_smpl_nml_map = load_smpl_nml_map
+ self.mode = mode # '3dgs' or 'nerf'
+
+ self.load_cam_data()
+ self.load_smpl_data()
+
+ self.smpl_model = smplx.SMPLX(model_path = config.PROJ_DIR + '/smpl_files/smplx', gender = 'neutral', use_pca = False, num_pca_comps = 45, flat_hand_mean = True, batch_size = 1)
+ pose_list = list(range(self.smpl_data['body_pose'].shape[0]))
+ if frame_range is not None:
+ # print('# Selected frame range: ', frame_range)
+ # print(isinstance(frame_range, list))
+ # print(type(frame_range))
+ # to list
+ frame_range = list(frame_range)
+ if isinstance(frame_range, list):
+ if len(frame_range) == 2:
+ print(f'# Selected frame indices: range({frame_range[0]}, {frame_range[1]})')
+ frame_range = range(frame_range[0], frame_range[1])
+ elif len(frame_range) == 3:
+ print(f'# Selected frame indices: range({frame_range[0]}, {frame_range[1]}, {frame_range[2]})')
+ frame_range = range(frame_range[0], frame_range[1], frame_range[2])
+ elif isinstance(frame_range, str):
+ frame_range = np.loadtxt(self.data_dir + '/' + frame_range).astype(np.int).tolist()
+ print(f'# Selected frame indices: {frame_range}')
+ else:
+ raise TypeError('Invalid frame_range!')
+ self.pose_list = list(frame_range)
+ else:
+ self.pose_list = pose_list
+
+ if self.training:
+ if used_cam_ids is None:
+ self.used_cam_ids = list(range(self.view_num))
+ else:
+ self.used_cam_ids = used_cam_ids
+ print('# Used camera ids: ', self.used_cam_ids)
+ self.data_list = []
+ for pose_idx in self.pose_list:
+ for view_idx in self.used_cam_ids:
+ self.data_list.append((pose_idx, view_idx))
+ # filter missing files
+ self.filter_missing_files()
+
+ print('# Dataset contains %d items' % len(self))
+
+ # SMPL related
+ ret = self.smpl_model.forward(betas = self.smpl_data['betas'][0][None],
+ global_orient = config.cano_smpl_global_orient[None],
+ transl = config.cano_smpl_transl[None],
+ body_pose = config.cano_smpl_body_pose[None])
+
+ self.cano_smpl = {k: v[0] for k, v in ret.items() if isinstance(v, torch.Tensor)}
+ self.inv_cano_jnt_mats = torch.linalg.inv(self.cano_smpl['A'])
+ min_xyz = self.cano_smpl['vertices'].min(0)[0]
+ max_xyz = self.cano_smpl['vertices'].max(0)[0]
+ self.cano_smpl_center = 0.5 * (min_xyz + max_xyz)
+ min_xyz[:2] -= 0.05
+ max_xyz[:2] += 0.05
+ min_xyz[2] -= 0.15
+ max_xyz[2] += 0.15
+ self.cano_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).numpy()
+ self.smpl_faces = self.smpl_model.faces.astype(np.int32)
+
+ commons._initialize_hands(self)
+
+ def __len__(self):
+ if self.training:
+ return len(self.data_list)
+ else:
+ return len(self.pose_list)
+
+ def __getitem__(self, index):
+ return self.getitem(index, self.training)
+
+ def getitem(self, index, training = True, **kwargs):
+ if training or kwargs.get('eval', False): # training or evaluation
+ pose_idx, view_idx = self.data_list[index]
+ pose_idx = kwargs['pose_idx'] if 'pose_idx' in kwargs else pose_idx
+ view_idx = kwargs['view_idx'] if 'view_idx' in kwargs else view_idx
+ data_idx = (pose_idx, view_idx)
+ if not training:
+ print('data index: (%d, %d)' % (pose_idx, view_idx))
+ else: # testing
+ pose_idx = self.pose_list[index]
+ data_idx = pose_idx
+ print('data index: %d' % pose_idx)
+
+ # SMPL
+ with torch.no_grad():
+ live_smpl = self.smpl_model.forward(
+ betas = self.smpl_data['betas'][0][None],
+ global_orient = self.smpl_data['global_orient'][pose_idx][None],
+ transl = self.smpl_data['transl'][pose_idx][None],
+ body_pose = self.smpl_data['body_pose'][pose_idx][None],
+ jaw_pose = self.smpl_data['jaw_pose'][pose_idx][None],
+ expression = self.smpl_data['expression'][pose_idx][None],
+ left_hand_pose = self.smpl_data['left_hand_pose'][pose_idx][None],
+ right_hand_pose = self.smpl_data['right_hand_pose'][pose_idx][None]
+ )
+ cano_smpl = self.smpl_model.forward(
+ betas = self.smpl_data['betas'][0][None],
+ global_orient = config.cano_smpl_global_orient[None],
+ transl = config.cano_smpl_transl[None],
+ body_pose = config.cano_smpl_body_pose[None],
+ jaw_pose = self.smpl_data['jaw_pose'][pose_idx][None],
+ expression = self.smpl_data['expression'][pose_idx][None],
+ )
+ live_smpl_woRoot = self.smpl_model.forward(
+ betas = self.smpl_data['betas'][0][None],
+ body_pose = self.smpl_data['body_pose'][pose_idx][None],
+ jaw_pose = self.smpl_data['jaw_pose'][pose_idx][None],
+ expression = self.smpl_data['expression'][pose_idx][None],
+ )
+
+ data_item = dict()
+ if self.load_smpl_pos_map:
+ smpl_pos_map = cv.imread(self.data_dir + '/smpl_pos_map/%08d.exr' % pose_idx, cv.IMREAD_UNCHANGED)
+ pos_map_size = smpl_pos_map.shape[1] // 2
+ smpl_pos_map = np.concatenate([smpl_pos_map[:, :pos_map_size], smpl_pos_map[:, pos_map_size:]], 2)
+ smpl_pos_map = smpl_pos_map.transpose((2, 0, 1))
+ data_item['smpl_pos_map'] = smpl_pos_map
+
+ if self.load_smpl_nml_map:
+ smpl_nml_map = cv.imread(self.data_dir + '/smpl_nml_map/%08d.jpg' % pose_idx, cv.IMREAD_UNCHANGED)
+ smpl_nml_map = (smpl_nml_map / 255.).astype(np.float32)
+ nml_map_size = smpl_nml_map.shape[1] // 2
+ smpl_nml_map = np.concatenate([smpl_nml_map[:, :nml_map_size], smpl_nml_map[:, nml_map_size:]], 2)
+ smpl_nml_map = smpl_nml_map.transpose((2, 0, 1))
+ data_item['smpl_nml_map'] = smpl_nml_map
+
+ data_item['joints'] = live_smpl.joints[0, :22]
+ data_item['kin_parent'] = self.smpl_model.parents[:22].to(torch.long)
+ data_item['item_idx'] = index
+ data_item['data_idx'] = data_idx
+ data_item['time_stamp'] = np.array(pose_idx, np.float32)
+ data_item['global_orient'] = self.smpl_data['global_orient'][pose_idx]
+ data_item['transl'] = self.smpl_data['transl'][pose_idx]
+ data_item['live_smpl_v'] = live_smpl.vertices[0]
+ data_item['live_smpl_v_woRoot'] = live_smpl_woRoot.vertices[0]
+ data_item['cano_smpl_v'] = cano_smpl.vertices[0]
+ data_item['cano_jnts'] = cano_smpl.joints[0]
+ data_item['cano2live_jnt_mats'] = torch.matmul(live_smpl.A[0], torch.linalg.inv(cano_smpl.A[0]))
+ data_item['cano2live_jnt_mats_woRoot'] = torch.matmul(live_smpl_woRoot.A[0], torch.linalg.inv(cano_smpl.A[0]))
+ data_item['cano_smpl_center'] = self.cano_smpl_center
+ data_item['cano_bounds'] = self.cano_bounds
+ data_item['smpl_faces'] = self.smpl_faces
+ min_xyz = live_smpl.vertices[0].min(0)[0] - 0.15
+ max_xyz = live_smpl.vertices[0].max(0)[0] + 0.15
+ live_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).numpy()
+ data_item['live_bounds'] = live_bounds
+
+ if training:
+ color_img, mask_img = self.load_color_mask_images(pose_idx, view_idx)
+
+ color_img = (color_img / 255.).astype(np.float32)
+
+ boundary_mask_img, mask_img = self.get_boundary_mask(mask_img)
+
+ if self.mode == '3dgs':
+ data_item.update({
+ 'img_h': color_img.shape[0],
+ 'img_w': color_img.shape[1],
+ 'extr': self.extr_mats[view_idx],
+ 'intr': self.intr_mats[view_idx],
+ 'color_img': color_img,
+ 'mask_img': mask_img,
+ 'boundary_mask_img': boundary_mask_img
+ })
+ elif self.mode == 'nerf':
+ depth_img = np.zeros(color_img.shape[:2], np.float32)
+ nerf_random = nerf_util.sample_randomly_for_nerf_rendering(
+ color_img, mask_img, depth_img,
+ self.extr_mats[view_idx], self.intr_mats[view_idx],
+ live_bounds,
+ unsample_region_mask = boundary_mask_img
+ )
+ data_item.update({
+ 'nerf_random': nerf_random,
+ 'extr': self.extr_mats[view_idx],
+ 'intr': self.intr_mats[view_idx]
+ })
+ else:
+ raise ValueError('Invalid dataset mode!')
+ else:
+ """ synthesis config """
+ img_h = 512 if 'img_h' not in kwargs else kwargs['img_h']
+ img_w = 512 if 'img_w' not in kwargs else kwargs['img_w']
+ intr = np.array([[550, 0, 256], [0, 550, 256], [0, 0, 1]], np.float32) if 'intr' not in kwargs else kwargs['intr']
+ if 'extr' not in kwargs:
+ extr = visualize_util.calc_front_mv(live_bounds.mean(0), tar_pos = np.array([0, 0, 2.5]))
+ else:
+ extr = kwargs['extr']
+
+ data_item.update({
+ 'img_h': img_h,
+ 'img_w': img_w,
+ 'extr': extr,
+ 'intr': intr
+ })
+
+ if self.mode == 'nerf' or self.mode == '3dgs' and not training:
+ # mano
+ data_item['left_cano_mano_v'], data_item['left_cano_mano_n'], data_item['right_cano_mano_v'], data_item['right_cano_mano_n'] \
+ = commons.generate_two_manos(self, self.cano_smpl['vertices'])
+ data_item['left_live_mano_v'], data_item['left_live_mano_n'], data_item['right_live_mano_v'], data_item['right_live_mano_n'] \
+ = commons.generate_two_manos(self, live_smpl.vertices[0])
+
+ return data_item
+
+ def load_cam_data(self):
+ """
+ Initialize:
+ self.cam_names, self.view_num, self.extr_mats, self.intr_mats,
+ self.img_widths, self.img_heights
+ """
+ raise NotImplementedError
+
+ def load_smpl_data(self):
+ """
+ Initialize:
+ self.cam_data, a dict including ['body_pose', 'global_orient', 'transl', 'betas', ...]
+ """
+ smpl_data = np.load(self.data_dir + '/smpl_params.npz', allow_pickle = True)
+ smpl_data = dict(smpl_data)
+ self.smpl_data = {k: torch.from_numpy(v.astype(np.float32)) for k, v in smpl_data.items()}
+
+ def filter_missing_files(self):
+ pass
+
+ def load_color_mask_images(self, pose_idx, view_idx):
+ raise NotImplementedError
+
+ @staticmethod
+ def get_boundary_mask(mask, kernel_size = 5):
+ """
+ :param mask: np.uint8
+ :param kernel_size:
+ :return:
+ """
+ mask_bk = mask.copy()
+ thres = 128
+ mask[mask < thres] = 0
+ mask[mask > thres] = 1
+ kernel = np.ones((kernel_size, kernel_size), np.uint8)
+ mask_erode = cv.erode(mask.copy(), kernel)
+ mask_dilate = cv.dilate(mask.copy(), kernel)
+ boundary_mask = (mask_dilate - mask_erode) == 1
+ boundary_mask = np.logical_or(boundary_mask,
+ np.logical_and(mask_bk > 5, mask_bk < 250))
+
+ # boundary_mask_resized = cv.resize(boundary_mask.astype(np.uint8), (0, 0), fx = 0.5, fy = 0.5)
+ # cv.imshow('boundary_mask', boundary_mask_resized.astype(np.uint8) * 255)
+ # cv.waitKey(0)
+
+ return boundary_mask, mask == 1
+
+ def compute_pca(self, n_components = 10):
+ from sklearn.decomposition import PCA
+ from tqdm import tqdm
+ import joblib
+
+ if not os.path.exists(self.data_dir + '/smpl_pos_map/pca_%d.ckpt' % n_components):
+ pose_conds = []
+ mask = None
+ for pose_idx in tqdm(self.pose_list, desc = 'Loading position maps...'):
+ pose_map = cv.imread(self.data_dir + '/smpl_pos_map/%08d.exr' % pose_idx, cv.IMREAD_UNCHANGED)
+ pose_map = pose_map[:, :pose_map.shape[1] // 2]
+ if mask is None:
+ mask = np.linalg.norm(pose_map, axis = -1) > 1e-6
+ pose_conds.append(pose_map[mask])
+ pose_conds = np.stack(pose_conds, 0)
+ pose_conds = pose_conds.reshape(pose_conds.shape[0], -1)
+ self.pca = PCA(n_components = n_components)
+ self.pca.fit(pose_conds)
+ joblib.dump(self.pca, self.data_dir + '/smpl_pos_map/pca_%d.ckpt' % n_components)
+ self.pos_map_mask = mask
+ else:
+ self.pca = joblib.load(self.data_dir + '/smpl_pos_map/pca_%d.ckpt' % n_components)
+ pose_map = cv.imread(sorted(glob.glob(self.data_dir + '/smpl_pos_map/0*.exr'))[0], cv.IMREAD_UNCHANGED)
+ pose_map = pose_map[:, :pose_map.shape[1] // 2]
+ self.pos_map_mask = np.linalg.norm(pose_map, axis = -1) > 1e-6
+
+ def transform_pca(self, pose_conds, sigma_pca = 2.):
+ pose_conds = pose_conds.reshape(1, -1)
+ lowdim_pose_conds = self.pca.transform(pose_conds)
+ std = np.sqrt(self.pca.explained_variance_)
+ lowdim_pose_conds = np.maximum(lowdim_pose_conds, -sigma_pca * std)
+ lowdim_pose_conds = np.minimum(lowdim_pose_conds, sigma_pca * std)
+ new_pose_conds = self.pca.inverse_transform(lowdim_pose_conds)
+ new_pose_conds = new_pose_conds.reshape(-1, 3)
+ return new_pose_conds
+
+
+class MvRgbDatasetTHuman4(MvRgbDatasetBase):
+ def __init__(
+ self,
+ data_dir,
+ frame_range = None,
+ used_cam_ids = None,
+ training = True,
+ subject_name = None,
+ load_smpl_pos_map = False,
+ load_smpl_nml_map = False,
+ mode = '3dgs'
+ ):
+ super(MvRgbDatasetTHuman4, self).__init__(
+ data_dir,
+ frame_range,
+ used_cam_ids,
+ training,
+ subject_name,
+ load_smpl_pos_map,
+ load_smpl_nml_map,
+ mode
+ )
+
+ def load_cam_data(self):
+ import json
+ cam_data = json.load(open(self.data_dir + '/calibration.json', 'r'))
+ self.view_num = len(cam_data)
+ self.extr_mats = []
+ self.cam_names = ['cam%02d' % view_idx for view_idx in range(self.view_num)]
+ for view_idx in range(self.view_num):
+ extr_mat = np.identity(4, np.float32)
+ extr_mat[:3, :3] = np.array(cam_data['cam%02d' % view_idx]['R'], np.float32).reshape(3, 3)
+ extr_mat[:3, 3] = np.array(cam_data['cam%02d' % view_idx]['T'], np.float32)
+ self.extr_mats.append(extr_mat)
+ self.intr_mats = [np.array(cam_data['cam%02d' % view_idx]['K'], np.float32).reshape(3, 3) for view_idx in range(self.view_num)]
+ self.img_heights = [cam_data['cam%02d' % view_idx]['imgSize'][1] for view_idx in range(self.view_num)]
+ self.img_widths = [cam_data['cam%02d' % view_idx]['imgSize'][0] for view_idx in range(self.view_num)]
+
+ def filter_missing_files(self):
+ missing_data_list = []
+ with open(self.data_dir + '/missing_img_files.txt', 'r') as fp:
+ lines = fp.readlines()
+ for line in lines:
+ line = line.replace('\\', '/') # considering both Windows and Ubuntu file system
+ frame_idx = int(os.path.basename(line).replace('.jpg', ''))
+ view_idx = int(os.path.basename(os.path.dirname(line)).replace('cam', ''))
+ missing_data_list.append((frame_idx, view_idx))
+ for missing_data_idx in missing_data_list:
+ if missing_data_idx in self.data_list:
+ self.data_list.remove(missing_data_idx)
+
+ def load_color_mask_images(self, pose_idx, view_idx):
+ color_img = cv.imread(self.data_dir + '/images/cam%02d/%08d.jpg' % (view_idx, pose_idx), cv.IMREAD_UNCHANGED)
+ mask_img = cv.imread(self.data_dir + '/masks/cam%02d/%08d.jpg' % (view_idx, pose_idx), cv.IMREAD_UNCHANGED)
+ return color_img, mask_img
+
+
+class MvRgbDatasetAvatarReX(MvRgbDatasetBase):
+ def __init__(
+ self,
+ data_dir,
+ frame_range = None,
+ used_cam_ids = None,
+ training = True,
+ subject_name = None,
+ load_smpl_pos_map = False,
+ load_smpl_nml_map = False,
+ mode = '3dgs'
+ ):
+ super(MvRgbDatasetAvatarReX, self).__init__(
+ data_dir,
+ frame_range,
+ used_cam_ids,
+ training,
+ subject_name,
+ load_smpl_pos_map,
+ load_smpl_nml_map,
+ mode
+ )
+
+ def load_cam_data(self):
+ import json
+ cam_data = json.load(open(self.data_dir + '/calibration_full.json', 'r'))
+ self.cam_names = list(cam_data.keys())
+ self.view_num = len(self.cam_names)
+ self.extr_mats = []
+ for view_idx in range(self.view_num):
+ extr_mat = np.identity(4, np.float32)
+ extr_mat[:3, :3] = np.array(cam_data[self.cam_names[view_idx]]['R'], np.float32).reshape(3, 3)
+ extr_mat[:3, 3] = np.array(cam_data[self.cam_names[view_idx]]['T'], np.float32)
+ self.extr_mats.append(extr_mat)
+ self.intr_mats = [np.array(cam_data[self.cam_names[view_idx]]['K'], np.float32).reshape(3, 3) for view_idx in range(self.view_num)]
+ self.img_heights = [cam_data[self.cam_names[view_idx]]['imgSize'][1] for view_idx in range(self.view_num)]
+ self.img_widths = [cam_data[self.cam_names[view_idx]]['imgSize'][0] for view_idx in range(self.view_num)]
+
+ def filter_missing_files(self):
+ if os.path.exists(self.data_dir + '/missing_img_files.txt'):
+ missing_data_list = []
+ with open(self.data_dir + '/missing_img_files.txt', 'r') as fp:
+ lines = fp.readlines()
+ for line in lines:
+ line = line.replace('\\', '/') # considering both Windows and Ubuntu file system
+ frame_idx = int(os.path.basename(line).replace('.jpg', ''))
+ view_idx = self.cam_names.index(os.path.basename(os.path.dirname(line)))
+ missing_data_list.append((frame_idx, view_idx))
+ for missing_data_idx in missing_data_list:
+ if missing_data_idx in self.data_list:
+ self.data_list.remove(missing_data_idx)
+
+ def load_color_mask_images(self, pose_idx, view_idx):
+ cam_name = self.cam_names[view_idx]
+ color_img = cv.imread(self.data_dir + '/%s/%08d.jpg' % (cam_name, pose_idx), cv.IMREAD_UNCHANGED)
+ mask_img = cv.imread(self.data_dir + '/%s/mask/pha/%08d.jpg' % (cam_name, pose_idx), cv.IMREAD_UNCHANGED)
+ return color_img, mask_img
+
+
+class MvRgbDatasetActorsHQ(MvRgbDatasetBase):
+ def __init__(
+ self,
+ data_dir,
+ frame_range = None,
+ used_cam_ids = None,
+ training = True,
+ subject_name = None,
+ load_smpl_pos_map = False,
+ load_smpl_nml_map = False,
+ mode = '3dgs'
+ ):
+ super(MvRgbDatasetActorsHQ, self).__init__(
+ data_dir,
+ frame_range,
+ used_cam_ids,
+ training,
+ subject_name,
+ load_smpl_pos_map,
+ load_smpl_nml_map,
+ mode
+ )
+
+ if subject_name is None:
+ self.subject_name = os.path.basename(os.path.dirname(self.data_dir))
+
+ def load_cam_data(self):
+ import csv
+ cam_names = []
+ extr_mats = []
+ intr_mats = []
+ img_widths = []
+ img_heights = []
+ with open(self.data_dir + '/4x/calibration.csv', "r", newline = "", encoding = 'utf-8') as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ cam_names.append(row['name'])
+ img_widths.append(int(row['w']))
+ img_heights.append(int(row['h']))
+
+ extr_mat = np.identity(4, np.float32)
+ extr_mat[:3, :3] = cv.Rodrigues(np.array([float(row['rx']), float(row['ry']), float(row['rz'])], np.float32))[0]
+ extr_mat[:3, 3] = np.array([float(row['tx']), float(row['ty']), float(row['tz'])])
+ extr_mat = np.linalg.inv(extr_mat)
+ extr_mats.append(extr_mat)
+
+ intr_mat = np.identity(3, np.float32)
+ intr_mat[0, 0] = float(row['fx']) * float(row['w'])
+ intr_mat[0, 2] = float(row['px']) * float(row['w'])
+ intr_mat[1, 1] = float(row['fy']) * float(row['h'])
+ intr_mat[1, 2] = float(row['py']) * float(row['h'])
+ intr_mats.append(intr_mat)
+
+ self.cam_names, self.img_widths, self.img_heights, self.extr_mats, self.intr_mats \
+ = cam_names, img_widths, img_heights, extr_mats, intr_mats
+
+ def load_color_mask_images(self, pose_idx, view_idx):
+ cam_name = self.cam_names[view_idx]
+ color_img = cv.imread(self.data_dir + '/4x/rgbs/%s/%s_rgb%06d.jpg' % (cam_name, cam_name, pose_idx), cv.IMREAD_UNCHANGED)
+ mask_img = cv.imread(self.data_dir + '/4x/masks/%s/%s_mask%06d.png' % (cam_name, cam_name, pose_idx), cv.IMREAD_UNCHANGED)
+ return color_img, mask_img
diff --git a/AnimatableGaussians/dataset/dataset_pose.py b/AnimatableGaussians/dataset/dataset_pose.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ce1a8824e1c40134d3bee6ab6899cd17c1b220a
--- /dev/null
+++ b/AnimatableGaussians/dataset/dataset_pose.py
@@ -0,0 +1,573 @@
+import glob
+import os
+import pickle
+import numpy as np
+import cv2 as cv
+import torch
+import trimesh
+from torch.utils.data import Dataset
+import yaml
+import json
+import AnimatableGaussians.smplx as smplx
+
+import AnimatableGaussians.dataset.commons as commons
+import AnimatableGaussians.utils.nerf_util as nerf_util
+import AnimatableGaussians.utils.visualize_util as visualize_util
+import AnimatableGaussians.config as config
+
+
+class PoseDataset(Dataset):
+ @torch.no_grad()
+ def __init__(
+ self,
+ data_path,
+ frame_range = None,
+ frame_interval = 1,
+ smpl_shape = None,
+ gender = 'neutral',
+ frame_win = 0,
+ fix_head_pose = True,
+ fix_hand_pose = True,
+ denoise = False,
+ hand_pose_type = 'ori',
+ constrain_leg_pose = False,
+ device = 'cuda:0'
+ ):
+ super(PoseDataset, self).__init__()
+
+ self.data_path = data_path
+ self.training = False
+
+ self.gender = gender
+
+ data_name, ext = os.path.splitext(os.path.basename(data_path))
+ print(data_name)
+ if ext == '.pkl':
+ smpl_data = pickle.load(open(data_path, 'rb'))
+ smpl_data = dict(smpl_data)
+ self.body_poses = torch.from_numpy(smpl_data['smpl_poses']).to(torch.float32)
+ self.transl = torch.from_numpy(smpl_data['smpl_trans']).to(torch.float32) * 1e-3
+ self.dataset_name = 'aist++'
+ self.seq_name = data_name
+ elif ext == '.npz':
+ potential_datasets = ['thuman4', 'actorshq', 'avatarrex', 'AMASS']
+ for i, potential_dataset in enumerate(potential_datasets):
+ start_pos = data_path.find(potential_dataset)
+ if start_pos == -1:
+ if i < len(potential_datasets) - 1:
+ continue
+ else:
+ raise ValueError('Invalid data_path!')
+ self.dataset_name = potential_dataset
+ self.seq_name = data_path[start_pos:].replace(self.dataset_name, '').replace('/', '_').replace('\\', '_').replace('.npz', '')
+ break
+ # print(self.dataset_name)
+ # print(f'# Dataset name: {self.dataset_name}, sequence name: {self.seq_name}')
+ if self.dataset_name == 'thuman4' or self.dataset_name == 'actorshq' or self.dataset_name == 'avatarrex':
+ smpl_data = np.load(data_path)
+ # if smpl_data.shape[1] == 156:
+ # # build dict
+ # smpl_data = {
+ # 'betas': smpl_data[:, :10],
+ # 'global_orient': smpl_data[:, 10:13],
+ # 'transl': smpl_data[:, 13:16],
+ # 'body_pose': smpl_data[:, 16:88],
+ # 'left_hand_pose': smpl_data[:, 88:133],
+ # 'right_hand_pose': smpl_data[:, 133:]
+ # }
+ smpl_data = dict(smpl_data)
+ for k in smpl_data.keys():
+ print(k, smpl_data[k].shape)
+ else: # AMASS dataset
+ pose_file = np.load(data_path)
+ smpl_data = {
+ 'betas': np.zeros((1, 10), np.float32),
+ 'global_orient': pose_file['poses'][:, :3],
+ 'transl': pose_file['trans'],
+ 'body_pose': pose_file['poses'][:, 3: 22 * 3],
+ 'left_hand_pose': pose_file['poses'][:, 22 * 3: 37 * 3],
+ 'right_hand_pose': pose_file['poses'][:, 37 * 3:]
+ }
+
+ # smpl_data['body_pose'][:, 13 * 3 + 2] -= 0.3
+ # smpl_data['body_pose'][:, 12 * 3 + 2] += 0.3
+ # # smpl_data['body_pose'][:, 16 * 3 + 2] -= 0.1
+ # # smpl_data['body_pose'][:, 15 * 3 + 2] += 0.1
+ # smpl_data['body_pose'][:, 19 * 3: 20 * 3] = 0.
+ # smpl_data['body_pose'][:, 20 * 3: 21 * 3] = 0.
+ # smpl_data['body_pose'][:, 14 * 3] = 0.
+ # print(smpl_data['body_pose'].shape)
+ if self.seq_name == '_actor01':
+ smpl_data['body_pose'][:, 6*3: 7*3] = 0.
+ smpl_data['body_pose'][:, 7*3: 8*3] = 0.
+
+ smpl_data = {k: torch.from_numpy(v).to(torch.float32) for k, v in smpl_data.items()}
+ frame_num = smpl_data['body_pose'].shape[0]
+ self.body_poses = torch.zeros((frame_num, 72), dtype = torch.float32)
+ self.body_poses[:, :3] = smpl_data['global_orient']
+ self.body_poses[:, 3:3+21*3] = smpl_data['body_pose']
+ self.transl = smpl_data['transl']
+ # print(self.body_poses)
+
+ data_dir = os.path.dirname(data_path)
+ calib_path = os.path.basename(data_path).replace('.npz', '.json').replace('pose', 'calibration')
+ calib_path = data_dir + '/' + calib_path
+ if os.path.exists(calib_path):
+ cam_data = json.load(open(calib_path, 'r'))
+ self.view_num = len(cam_data)
+ self.extr_mats = []
+ self.cam_names = list(cam_data.keys())
+ for view_idx in range(self.view_num):
+ extr_mat = np.identity(4, np.float32)
+ extr_mat[:3, :3] = np.array(cam_data[self.cam_names[view_idx]]['R'], np.float32).reshape(3, 3)
+ extr_mat[:3, 3] = np.array(cam_data[self.cam_names[view_idx]]['T'], np.float32)
+ self.extr_mats.append(extr_mat)
+ self.intr_mats = [np.array(cam_data[self.cam_names[view_idx]]['K'], np.float32).reshape(3, 3) for view_idx in range(self.view_num)]
+ self.img_heights = [cam_data[self.cam_names[view_idx]]['imgSize'][1] for view_idx in range(self.view_num)]
+ self.img_widths = [cam_data[self.cam_names[view_idx]]['imgSize'][0] for view_idx in range(self.view_num)]
+ else:
+ raise AssertionError('Invalid data_path!')
+
+ if 'left_hand_pose' in smpl_data:
+ self.left_hand_pose = smpl_data['left_hand_pose']
+ else:
+ self.left_hand_pose = config.left_hand_pose[None].expand(self.body_poses.shape[0], -1)
+ if 'right_hand_pose' in smpl_data:
+ self.right_hand_pose = smpl_data['right_hand_pose']
+ else:
+ self.right_hand_pose = config.right_hand_pose[None].expand(self.body_poses.shape[0], -1)
+
+ self.body_poses = self.body_poses.to(device)
+ self.transl = self.transl.to(device)
+
+ self.fix_head_pose = fix_head_pose
+ self.fix_hand_pose = fix_hand_pose
+
+ self.smpl_model = smplx.SMPLX(model_path = config.PROJ_DIR + '/smpl_files/smplx', gender = self.gender, use_pca = False, num_pca_comps = 45, flat_hand_mean = True, batch_size = 1).to(device)
+
+ pose_list = list(range(0, self.body_poses.shape[0], frame_interval))
+ if frame_range is not None:
+ frame_range = list(frame_range)
+ if isinstance(frame_range, list):
+ if isinstance(frame_range[0], list):
+ self.pose_list = []
+ for interval in frame_range:
+ if len(interval) == 2 or len(interval) == 3:
+ self.pose_list += list(range(*interval))
+ else:
+ for i in range(interval[3]):
+ self.pose_list += list(range(interval[0], interval[1], interval[2]))
+ else:
+ if len(frame_range) == 2:
+ print(f'# Selected frame indices: range({frame_range[0]}, {frame_range[1]})')
+ frame_range = range(frame_range[0], frame_range[1])
+ elif len(frame_range) == 3:
+ print(f'# Selected frame indices: range({frame_range[0]}, {frame_range[1]}, {frame_range[2]})')
+ frame_range = range(frame_range[0], frame_range[1], frame_range[2])
+ self.pose_list = list(frame_range)
+ else:
+ self.pose_list = pose_list
+
+ print('# Pose list: ', self.pose_list)
+ print('# Dataset contains %d items' % len(self))
+
+ # SMPL related
+ self.smpl_shape = smpl_shape.to(torch.float32).to(device) if smpl_shape is not None else torch.zeros(10, dtype = torch.float32)
+ ret = self.smpl_model.forward(betas = self.smpl_shape[None],
+ global_orient = config.cano_smpl_global_orient[None].to(device),
+ transl = config.cano_smpl_transl[None].to(device),
+ body_pose = config.cano_smpl_body_pose[None].to(device),
+ # left_hand_pose = config.left_hand_pose[None],
+ # right_hand_pose = config.right_hand_pose[None]
+ )
+ self.cano_smpl = {k: v[0] for k, v in ret.items() if isinstance(v, torch.Tensor)}
+ self.inv_cano_jnt_mats = torch.linalg.inv(self.cano_smpl['A'])
+ min_xyz = self.cano_smpl['vertices'].min(0)[0]
+ max_xyz = self.cano_smpl['vertices'].max(0)[0]
+ self.cano_smpl_center = 0.5 * (min_xyz + max_xyz)
+ min_xyz[:2] -= 0.05
+ max_xyz[:2] += 0.05
+ min_xyz[2] -= 0.15
+ max_xyz[2] += 0.15
+ self.cano_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).cpu().numpy()
+ self.smpl_faces = self.smpl_model.faces.astype(np.int32)
+
+ self.frame_win = int(frame_win)
+ self.denoise = denoise
+ if self.denoise:
+ win_size = 1
+ body_poses_clone = self.body_poses.clone()
+ transl_clone = self.transl.clone()
+ frame_num = body_poses_clone.shape[0]
+ self.body_poses[win_size: frame_num-win_size] = 0
+ self.transl[win_size: frame_num-win_size] = 0
+ for i in range(-win_size, win_size + 1):
+ self.body_poses[win_size: frame_num-win_size] += body_poses_clone[win_size+i: frame_num-win_size+i]
+ self.transl[win_size: frame_num-win_size] += transl_clone[win_size+i: frame_num-win_size+i]
+ self.body_poses[win_size: frame_num-win_size] /= (2 * win_size + 1)
+ self.transl[win_size: frame_num-win_size] /= (2 * win_size + 1)
+
+ self.hand_pose_type = hand_pose_type
+
+ self.device = device
+ self.last_data_idx = 0
+
+ commons._initialize_hands(self)
+ self.left_cano_mano_v, self.left_cano_mano_n, self.right_cano_mano_v, self.right_cano_mano_n \
+ = commons.generate_two_manos(self, self.cano_smpl['vertices'])
+
+ if constrain_leg_pose:
+ # a = 14.
+ # # print(self.body_poses[284, 1*3:2*3])
+ # # print(self.body_poses[284, 2*3:3*3])
+ # self.body_poses[:, 1*3] = torch.clip(self.body_poses[:, 1 * 3], -np.pi / a, np.pi / a)
+ # self.body_poses[:, 2*3] = torch.clip(self.body_poses[:, 2 * 3], -np.pi / a, np.pi / a)
+ # self.body_poses[:, 1 * 3+2] = torch.clip(self.body_poses[:, 1 * 3+2], -np.pi / a, np.pi / a)
+ # self.body_poses[:, 2 * 3+2] = torch.clip(self.body_poses[:, 2 * 3+2], -np.pi / a, np.pi / a)
+ # exit(1)
+
+ self.body_poses[:, 4*3] = torch.clip(self.body_poses[:, 4*3], -0.3, 0.3)
+ self.body_poses[:, 5*3] = torch.clip(self.body_poses[:, 5*3], -0.3, 0.3)
+
+ def __len__(self):
+ return len(self.pose_list)
+
+ def __getitem__(self, index):
+ return self.getitem(index)
+
+ @torch.no_grad()
+ def getitem(self, index, **kwargs):
+ pose_idx = self.pose_list[index]
+ if pose_idx == 0 or pose_idx > self.pose_list[min(index - 1, 0)]:
+ data_idx = pose_idx
+ else:
+ data_idx = self.last_data_idx + 1
+ # print('data index: %d, pose index: %d' % (data_idx, pose_idx))
+
+ if self.hand_pose_type == 'fist':
+ left_hand_pose = config.left_hand_pose.to(self.device).clone()
+ right_hand_pose = config.right_hand_pose.to(self.device).clone()
+ left_hand_pose[:3] = 0.
+ right_hand_pose[:3] = 0.
+ elif self.hand_pose_type == 'normal':
+ left_hand_pose = torch.tensor([0.10859203338623047, 0.10181399434804916, -0.2822268009185791, 0.10211331397294998, -0.09689036756753922, -0.4484838545322418, -0.11360692232847214, -0.023141659796237946, 0.10571160167455673, -0.08793719857931137, -0.026760095730423927, -0.41390693187713623, -0.0923849567770958, 0.10266668349504471, -0.36039748787879944, 0.02140655182301998, -0.07156527787446976, -0.04903153330087662, -0.22358819842338562, -0.3716682195663452, -0.2683027982711792, -0.1506909281015396, 0.07079305499792099, -0.34404537081718445, -0.168443500995636, -0.014021224342286587, 0.09489774703979492, -0.050323735922575, -0.18992969393730164, -0.43895423412323, -0.1806418001651764, 0.0198075994849205, -0.25444355607032776, -0.10171788930892944, -0.10680688172578812, -0.09953738003969193, 0.8094075918197632, 0.5156061053276062, -0.07900168001651764, -0.45094889402389526, 0.24947893619537354, 0.23369410634040833, 0.45277315378189087, -0.17375235259532928, -0.3077943027019501], dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.tensor([0.06415501981973648, -0.06942438334226608, 0.282951682806015, 0.09073827415704727, 0.0775153785943985, 0.2961004376411438, -0.07659692317247391, 0.004730052314698696, -0.12084470689296722, 0.007974660955369473, 0.05222926288843155, 0.32775357365608215, -0.10166633129119873, -0.06862349808216095, 0.174485981464386, -0.0023323255591094494, 0.04998664930462837, -0.03490559384226799, 0.12949667870998383, 0.26883721351623535, 0.06881044059991837, -0.18259745836257935, -0.08183271437883377, 0.17669665813446045, -0.08099694550037384, 0.04115655645728111, -0.17928685247898102, 0.07734024524688721, 0.13419172167778015, 0.2600148022174835, -0.151871919631958, -0.01772170141339302, 0.1267814189195633, -0.08800505846738815, 0.09480107575654984, 0.0016392067773267627, 0.6149336695671082, -0.32634419202804565, 0.02278662845492363, -0.39148610830307007, -0.22757330536842346, -0.07884717732667923, 0.38199105858802795, 0.13064607977867126, 0.20154500007629395], dtype = torch.float32, device = self.device)
+ elif self.hand_pose_type == 'zero':
+ left_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ elif self.hand_pose_type == 'ori':
+ left_hand_pose = self.left_hand_pose[pose_idx].to(self.device)
+ right_hand_pose = self.right_hand_pose[pose_idx].to(self.device)
+ else:
+ raise ValueError('Invalid hand_pose_type!')
+
+ # SMPL
+ live_smpl = self.smpl_model.forward(betas = self.smpl_shape[None],
+ global_orient = self.body_poses[pose_idx, :3][None],
+ transl = self.transl[pose_idx][None],
+ body_pose = self.body_poses[pose_idx, 3: 66][None],
+ left_hand_pose = left_hand_pose[None],
+ right_hand_pose = right_hand_pose[None]
+ )
+
+ # live_smpl_trimesh = trimesh.Trimesh(vertices = live_smpl.vertices[0].cpu().numpy(), faces = self.smpl_model.faces, process = False)
+ # live_smpl_trimesh.export('./debug/smpl_amass.ply')
+ # exit(1)
+
+ live_smpl_woRoot = self.smpl_model.forward(betas = self.smpl_shape[None],
+ # global_orient = self.body_poses[pose_idx, :3][None],
+ # transl = self.transl[pose_idx][None],
+ body_pose = self.body_poses[pose_idx, 3: 66][None],
+ # left_hand_pose = config.left_hand_pose[None],
+ # right_hand_pose = config.right_hand_pose[None]
+ )
+
+ # cano_smpl = self.smpl_model.forward(betas=self.smpl_shape[None],
+ # global_orient=config.cano_smpl_global_orient[None],
+ # transl=config.cano_smpl_transl[None],
+ # body_pose=config.cano_smpl_body_pose[None],
+ # # left_hand_pose = left_hand_pose[None],
+ # # right_hand_pose = right_hand_pose[None]
+ # )
+
+ data_item = dict()
+ data_item['item_idx'] = index
+ data_item['data_idx'] = data_idx
+ data_item['global_orient'] = self.body_poses[pose_idx, :3]
+ data_item['transl'] = self.transl[pose_idx]
+ data_item['joints'] = live_smpl.joints[0, :22]
+ data_item['kin_parent'] = self.smpl_model.parents[:22].to(torch.long)
+ data_item['pose_1st'] = self.body_poses[0, 3: 66]
+ if self.frame_win > 0:
+ total_frame_num = len(self.pose_list)
+ selected_frames = self.pose_list[max(0, index - self.frame_win): min(total_frame_num, index + self.frame_win + 1)]
+ data_item['pose'] = self.body_poses[selected_frames, 3: 66].clone()
+ else:
+ data_item['pose'] = self.body_poses[pose_idx, 3: 66].clone()
+
+ if self.fix_head_pose:
+ data_item['pose'][..., 3 * 11: 3 * 11 + 3] = 0.
+ data_item['pose'][..., 3 * 14: 3 * 14 + 3] = 0.
+ if self.fix_hand_pose:
+ data_item['pose'][..., 3 * 19: 3 * 19 + 3] = 0.
+ data_item['pose'][..., 3 * 20: 3 * 20 + 3] = 0.
+ data_item['lhand_pose'] = torch.zeros_like(config.left_hand_pose)
+ data_item['rhand_pose'] = torch.zeros_like(config.right_hand_pose)
+ data_item['time_stamp'] = np.array(pose_idx, np.float32)
+ data_item['live_smpl_v'] = live_smpl.vertices[0]
+ data_item['live_smpl_v_woRoot'] = live_smpl_woRoot.vertices[0]
+ data_item['cano_smpl_v'] = self.cano_smpl['vertices']
+ data_item['cano_jnts'] = self.cano_smpl['joints']
+ inv_cano_jnt_mats = torch.linalg.inv(self.cano_smpl['A'])
+ data_item['cano2live_jnt_mats'] = torch.matmul(live_smpl.A[0], inv_cano_jnt_mats)
+ data_item['cano2live_jnt_mats_woRoot'] = torch.matmul(live_smpl_woRoot.A[0], inv_cano_jnt_mats)
+ data_item['cano_smpl_center'] = self.cano_smpl_center
+ data_item['cano_bounds'] = self.cano_bounds
+ data_item['smpl_faces'] = self.smpl_faces
+ min_xyz = live_smpl.vertices[0].min(0)[0] - 0.15
+ max_xyz = live_smpl.vertices[0].max(0)[0] + 0.15
+ live_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).cpu().numpy()
+ data_item['live_bounds'] = live_bounds
+
+ # # mano
+ # data_item['left_cano_mano_v'], data_item['left_cano_mano_n'], data_item['right_cano_mano_v'], data_item['right_cano_mano_n']\
+ # = commons.generate_two_manos(self, self.cano_smpl['vertices'])
+ # data_item['left_live_mano_v'], data_item['left_live_mano_n'], data_item['right_live_mano_v'], data_item['right_live_mano_n'] \
+ # = commons.generate_two_manos(self, live_smpl.vertices[0])
+
+ """ synthesis config """
+ img_h = 512 if 'img_h' not in kwargs else kwargs['img_h']
+ img_w = 512 if 'img_w' not in kwargs else kwargs['img_w']
+ intr = np.array([[550, 0, 256], [0, 550, 256], [0, 0, 1]], np.float32) if 'intr' not in kwargs else kwargs['intr']
+ if 'extr' not in kwargs:
+ extr = visualize_util.calc_front_mv(live_bounds.mean(0), tar_pos = np.array([0, 0, 2.5]))
+ else:
+ extr = kwargs['extr']
+
+ """ training data config of view_idx """
+ # view_idx = 0
+ # img_h = self.img_heights[view_idx]
+ # img_w = self.img_widths[view_idx]
+ # intr = self.intr_mats[view_idx]
+ # extr = self.extr_mats[view_idx]
+
+ uv = self.gen_uv(img_w, img_h)
+ uv = uv.reshape(-1, 2)
+ ray_d, ray_o = nerf_util.get_rays(uv, extr, intr)
+ near, far, mask_at_bound = nerf_util.get_near_far(live_bounds, ray_o, ray_d)
+ uv = uv[mask_at_bound]
+ ray_o = ray_o[mask_at_bound]
+ ray_d = ray_d[mask_at_bound]
+
+ data_item.update({
+ 'uv': uv,
+ 'ray_o': ray_o,
+ 'ray_d': ray_d,
+ 'near': near,
+ 'far': far,
+ 'dist': np.zeros_like(near),
+ 'img_h': img_h,
+ 'img_w': img_w,
+ 'extr': extr,
+ 'intr': intr
+ })
+
+ return data_item
+
+ def getitem_fast(self, index, **kwargs):
+ pose_idx = self.pose_list[index]
+ if pose_idx == 0 or pose_idx > self.last_data_idx:
+ data_idx = pose_idx
+ else:
+ data_idx = self.last_data_idx + 1
+ # print('data index: %d, pose index: %d' % (data_idx, pose_idx))
+
+ if self.hand_pose_type == 'fist':
+ left_hand_pose = config.left_hand_pose.to(self.device)
+ right_hand_pose = config.right_hand_pose.to(self.device)
+ elif self.hand_pose_type == 'normal':
+ left_hand_pose = torch.tensor(
+ [0.10859203338623047, 0.10181399434804916, -0.2822268009185791, 0.10211331397294998, -0.09689036756753922, -0.4484838545322418, -0.11360692232847214, -0.023141659796237946, 0.10571160167455673, -0.08793719857931137, -0.026760095730423927, -0.41390693187713623, -0.0923849567770958, 0.10266668349504471, -0.36039748787879944, 0.02140655182301998, -0.07156527787446976, -0.04903153330087662, -0.22358819842338562, -0.3716682195663452, -0.2683027982711792, -0.1506909281015396,
+ 0.07079305499792099, -0.34404537081718445, -0.168443500995636, -0.014021224342286587, 0.09489774703979492, -0.050323735922575, -0.18992969393730164, -0.43895423412323, -0.1806418001651764, 0.0198075994849205, -0.25444355607032776, -0.10171788930892944, -0.10680688172578812, -0.09953738003969193, 0.8094075918197632, 0.5156061053276062, -0.07900168001651764, -0.45094889402389526, 0.24947893619537354, 0.23369410634040833, 0.45277315378189087, -0.17375235259532928,
+ -0.3077943027019501], dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.tensor(
+ [0.06415501981973648, -0.06942438334226608, 0.282951682806015, 0.09073827415704727, 0.0775153785943985, 0.2961004376411438, -0.07659692317247391, 0.004730052314698696, -0.12084470689296722, 0.007974660955369473, 0.05222926288843155, 0.32775357365608215, -0.10166633129119873, -0.06862349808216095, 0.174485981464386, -0.0023323255591094494, 0.04998664930462837, -0.03490559384226799, 0.12949667870998383, 0.26883721351623535, 0.06881044059991837, -0.18259745836257935,
+ -0.08183271437883377, 0.17669665813446045, -0.08099694550037384, 0.04115655645728111, -0.17928685247898102, 0.07734024524688721, 0.13419172167778015, 0.2600148022174835, -0.151871919631958, -0.01772170141339302, 0.1267814189195633, -0.08800505846738815, 0.09480107575654984, 0.0016392067773267627, 0.6149336695671082, -0.32634419202804565, 0.02278662845492363, -0.39148610830307007, -0.22757330536842346, -0.07884717732667923, 0.38199105858802795, 0.13064607977867126,
+ 0.20154500007629395], dtype = torch.float32, device = self.device)
+ elif self.hand_pose_type == 'zero':
+ left_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ elif self.hand_pose_type == 'ori':
+ left_hand_pose = self.left_hand_pose[pose_idx].to(self.device)
+ right_hand_pose = self.right_hand_pose[pose_idx].to(self.device)
+ else:
+ raise ValueError('Invalid hand_pose_type!')
+
+ # SMPL
+ live_smpl = self.smpl_model.forward(betas = self.smpl_shape[None],
+ global_orient = self.body_poses[pose_idx, :3][None],
+ transl = self.transl[pose_idx][None],
+ body_pose = self.body_poses[pose_idx, 3: 66][None],
+ left_hand_pose = left_hand_pose[None],
+ right_hand_pose = right_hand_pose[None]
+ )
+
+ live_smpl_woRoot = self.smpl_model.forward(betas = self.smpl_shape[None],
+ # global_orient = self.body_poses[pose_idx, :3][None],
+ # transl = self.transl[pose_idx][None],
+ body_pose = self.body_poses[pose_idx, 3: 66][None],
+ # left_hand_pose = config.left_hand_pose[None],
+ # right_hand_pose = config.right_hand_pose[None]
+ )
+
+ # cano_smpl = self.smpl_model.forward(betas = self.smpl_shape[None],
+ # global_orient = config.cano_smpl_global_orient[None],
+ # transl = config.cano_smpl_transl[None],
+ # body_pose = config.cano_smpl_body_pose[None],
+ # # left_hand_pose = left_hand_pose[None],
+ # # right_hand_pose = right_hand_pose[None]
+ # )
+
+ data_item = dict()
+ data_item['item_idx'] = index
+ data_item['data_idx'] = data_idx
+ data_item['global_orient'] = self.body_poses[pose_idx, :3]
+ data_item['body_pose'] = self.body_poses[pose_idx, 3:66]
+ data_item['transl'] = self.transl[pose_idx]
+ data_item['joints'] = live_smpl.joints[0, :22]
+ data_item['kin_parent'] = self.smpl_model.parents[:22].to(torch.long)
+ data_item['live_smpl_v'] = live_smpl.vertices[0]
+ data_item['live_smpl_v_woRoot'] = live_smpl_woRoot.vertices[0]
+ data_item['cano_smpl_v'] = self.cano_smpl['vertices']
+ data_item['cano_jnts'] = self.cano_smpl['joints']
+ inv_cano_jnt_mats = torch.linalg.inv(self.cano_smpl['A'])
+ data_item['cano2live_jnt_mats'] = torch.matmul(live_smpl.A[0], inv_cano_jnt_mats)
+ data_item['cano2live_jnt_mats_woRoot'] = torch.matmul(live_smpl_woRoot.A[0], inv_cano_jnt_mats)
+ data_item['cano_smpl_center'] = self.cano_smpl_center
+ data_item['cano_bounds'] = self.cano_bounds
+ data_item['smpl_faces'] = self.smpl_faces
+ min_xyz = live_smpl.vertices[0].min(0)[0] - 0.15
+ max_xyz = live_smpl.vertices[0].max(0)[0] + 0.15
+ live_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).cpu().numpy()
+ data_item['live_bounds'] = live_bounds
+
+ data_item['left_cano_mano_v'], data_item['left_cano_mano_n'], data_item['right_cano_mano_v'], data_item['right_cano_mano_n'] \
+ = self.left_cano_mano_v, self.left_cano_mano_n, self.right_cano_mano_v, self.right_cano_mano_n
+
+ """ synthesis config """
+ img_h = 512 if 'img_h' not in kwargs else kwargs['img_h']
+ img_w = 512 if 'img_w' not in kwargs else kwargs['img_w']
+ intr = np.array([[550, 0, 256], [0, 550, 256], [0, 0, 1]], np.float32) if 'intr' not in kwargs else kwargs['intr']
+ if 'extr' not in kwargs:
+ extr = visualize_util.calc_front_mv(live_bounds.mean(0), tar_pos = np.array([0, 0, 2.5]))
+ else:
+ extr = kwargs['extr']
+
+ data_item.update({
+ 'img_h': img_h,
+ 'img_w': img_w,
+ 'extr': extr,
+ 'intr': intr
+ })
+
+ self.last_data_idx = data_idx
+
+ return data_item
+
+ def getitem_a_pose(self, **kwargs):
+ hand_pose_type = 'fist'
+ if hand_pose_type == 'fist':
+ left_hand_pose = config.left_hand_pose.to(self.device)
+ right_hand_pose = config.right_hand_pose.to(self.device)
+ elif hand_pose_type == 'normal':
+ left_hand_pose = torch.tensor(
+ [0.10859203338623047, 0.10181399434804916, -0.2822268009185791, 0.10211331397294998, -0.09689036756753922, -0.4484838545322418, -0.11360692232847214, -0.023141659796237946, 0.10571160167455673, -0.08793719857931137, -0.026760095730423927, -0.41390693187713623, -0.0923849567770958, 0.10266668349504471, -0.36039748787879944, 0.02140655182301998, -0.07156527787446976, -0.04903153330087662, -0.22358819842338562, -0.3716682195663452, -0.2683027982711792, -0.1506909281015396,
+ 0.07079305499792099, -0.34404537081718445, -0.168443500995636, -0.014021224342286587, 0.09489774703979492, -0.050323735922575, -0.18992969393730164, -0.43895423412323, -0.1806418001651764, 0.0198075994849205, -0.25444355607032776, -0.10171788930892944, -0.10680688172578812, -0.09953738003969193, 0.8094075918197632, 0.5156061053276062, -0.07900168001651764, -0.45094889402389526, 0.24947893619537354, 0.23369410634040833, 0.45277315378189087, -0.17375235259532928,
+ -0.3077943027019501], dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.tensor(
+ [0.06415501981973648, -0.06942438334226608, 0.282951682806015, 0.09073827415704727, 0.0775153785943985, 0.2961004376411438, -0.07659692317247391, 0.004730052314698696, -0.12084470689296722, 0.007974660955369473, 0.05222926288843155, 0.32775357365608215, -0.10166633129119873, -0.06862349808216095, 0.174485981464386, -0.0023323255591094494, 0.04998664930462837, -0.03490559384226799, 0.12949667870998383, 0.26883721351623535, 0.06881044059991837, -0.18259745836257935,
+ -0.08183271437883377, 0.17669665813446045, -0.08099694550037384, 0.04115655645728111, -0.17928685247898102, 0.07734024524688721, 0.13419172167778015, 0.2600148022174835, -0.151871919631958, -0.01772170141339302, 0.1267814189195633, -0.08800505846738815, 0.09480107575654984, 0.0016392067773267627, 0.6149336695671082, -0.32634419202804565, 0.02278662845492363, -0.39148610830307007, -0.22757330536842346, -0.07884717732667923, 0.38199105858802795, 0.13064607977867126,
+ 0.20154500007629395], dtype = torch.float32, device = self.device)
+ elif self.hand_pose_type == 'zero':
+ left_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ right_hand_pose = torch.zeros(45, dtype = torch.float32, device = self.device)
+ else:
+ raise ValueError('Invalid hand_pose_type!')
+
+ body_pose = torch.zeros(21 * 3, dtype = torch.float32).to(self.device)
+ body_pose[15 * 3 + 2] += -0.8
+ body_pose[16 * 3 + 2] += 0.8
+
+ # SMPL
+ live_smpl = self.smpl_model.forward(betas = self.smpl_shape[None],
+ global_orient = None,
+ transl = None,
+ body_pose = body_pose[None],
+ left_hand_pose = left_hand_pose[None],
+ right_hand_pose = right_hand_pose[None]
+ )
+
+ live_smpl_woRoot = self.smpl_model.forward(betas = self.smpl_shape[None],
+ # global_orient = self.body_poses[pose_idx, :3][None],
+ # transl = self.transl[pose_idx][None],
+ body_pose = body_pose[None],
+ # left_hand_pose = config.left_hand_pose[None],
+ # right_hand_pose = config.right_hand_pose[None]
+ )
+
+ # cano_smpl = self.smpl_model.forward(betas = self.smpl_shape[None],
+ # global_orient = config.cano_smpl_global_orient[None],
+ # transl = config.cano_smpl_transl[None],
+ # body_pose = config.cano_smpl_body_pose[None],
+ # # left_hand_pose = left_hand_pose[None],
+ # # right_hand_pose = right_hand_pose[None]
+ # )
+
+ data_item = dict()
+ data_item['item_idx'] = 0
+ data_item['data_idx'] = 0
+ data_item['global_orient'] = torch.zeros(3, dtype = torch.float32)
+ data_item['joints'] = live_smpl.joints[0, :22]
+ data_item['kin_parent'] = self.smpl_model.parents[:22].to(torch.long)
+ data_item['live_smpl_v'] = live_smpl.vertices[0]
+ data_item['live_smpl_v_woRoot'] = live_smpl_woRoot.vertices[0]
+ data_item['cano_smpl_v'] = self.cano_smpl['vertices']
+ data_item['cano_jnts'] = self.cano_smpl['joints']
+ inv_cano_jnt_mats = torch.linalg.inv(self.cano_smpl['A'])
+ data_item['cano2live_jnt_mats'] = torch.matmul(live_smpl.A[0], inv_cano_jnt_mats)
+ data_item['cano2live_jnt_mats_woRoot'] = torch.matmul(live_smpl_woRoot.A[0], inv_cano_jnt_mats)
+ data_item['cano_smpl_center'] = self.cano_smpl_center
+ data_item['cano_bounds'] = self.cano_bounds
+ data_item['smpl_faces'] = self.smpl_faces
+ min_xyz = live_smpl.vertices[0].min(0)[0] - 0.15
+ max_xyz = live_smpl.vertices[0].max(0)[0] + 0.15
+ live_bounds = torch.stack([min_xyz, max_xyz], 0).to(torch.float32).cpu().numpy()
+ data_item['live_bounds'] = live_bounds
+
+ data_item['left_cano_mano_v'], data_item['left_cano_mano_n'], data_item['right_cano_mano_v'], data_item['right_cano_mano_n'] \
+ = self.left_cano_mano_v, self.left_cano_mano_n, self.right_cano_mano_v, self.right_cano_mano_n
+
+ """ synthesis config """
+ img_h = 512 if 'img_h' not in kwargs else kwargs['img_h']
+ img_w = 300 if 'img_w' not in kwargs else kwargs['img_w']
+ intr = np.array([[550, 0, 150], [0, 550, 256], [0, 0, 1]], np.float32) if 'intr' not in kwargs else kwargs['intr']
+ if 'extr' not in kwargs:
+ extr = visualize_util.calc_front_mv(live_bounds.mean(0), tar_pos = np.array([0, 0, 2.5]))
+ else:
+ extr = kwargs['extr']
+
+ data_item.update({
+ 'img_h': img_h,
+ 'img_w': img_w,
+ 'extr': extr,
+ 'intr': intr
+ })
+
+ return data_item
+
+ @staticmethod
+ def gen_uv(img_w, img_h):
+ x, y = np.meshgrid(np.linspace(0, img_w - 1, img_w, dtype = np.int32),
+ np.linspace(0, img_h - 1, img_h, dtype = np.int32))
+ uv = np.stack([x, y], axis = -1)
+ return uv
diff --git a/AnimatableGaussians/eval/comparison_body_only_avatars.py b/AnimatableGaussians/eval/comparison_body_only_avatars.py
new file mode 100644
index 0000000000000000000000000000000000000000..929576b29f2454c2ef629dce874e410a7f9b8feb
--- /dev/null
+++ b/AnimatableGaussians/eval/comparison_body_only_avatars.py
@@ -0,0 +1,114 @@
+# To compute FID, first install pytorch_fid
+# pip install pytorch-fid
+
+import os
+import cv2 as cv
+from tqdm import tqdm
+import shutil
+
+from eval.score import *
+
+cam_id = 18
+ours_dir = './test_results/subject00/styleunet_gaussians3/testing__cam_%03d/batch_750000/rgb_map' % cam_id
+posevocab_dir = './test_results/subject00/posevocab/testing__cam_%03d/rgb_map' % cam_id
+tava_dir = './test_results/subject00/tava/cam_%03d' % cam_id
+arah_dir = './test_results/subject00/arah/cam_%03d' % cam_id
+slrf_dir = './test_results/subject00/slrf/cam_%03d' % cam_id
+gt_dir = 'Z:/MultiviewRGB/THuman4/subject00/images/cam%02d' % cam_id
+mask_dir = 'Z:/MultiviewRGB/THuman4/subject00/masks/cam%02d' % cam_id
+
+frame_list = list(range(2000, 2500, 1))
+
+
+if __name__ == '__main__':
+ ours_metrics = Metrics()
+ posevocab_metrics = Metrics()
+ slrf_metrics = Metrics()
+ arah_metrics = Metrics()
+ tava_metrics = Metrics()
+
+ shutil.rmtree('./tmp_quant')
+ os.makedirs('./tmp_quant/ours', exist_ok = True)
+ os.makedirs('./tmp_quant/posevocab', exist_ok = True)
+ os.makedirs('./tmp_quant/slrf', exist_ok = True)
+ os.makedirs('./tmp_quant/arah', exist_ok = True)
+ os.makedirs('./tmp_quant/tava', exist_ok = True)
+ os.makedirs('./tmp_quant/gt', exist_ok = True)
+
+ for frame_id in tqdm(frame_list):
+ ours_img = (cv.imread(ours_dir + '/%08d.jpg' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ posevocab_img = (cv.imread(posevocab_dir + '/%08d.jpg' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ slrf_img = (cv.imread(slrf_dir + '/%08d.png' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ tava_img = (cv.imread(tava_dir + '/%d.jpg' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ arah_img = (cv.imread(arah_dir + '/%d.jpg' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ gt_img = (cv.imread(gt_dir + '/%08d.jpg' % frame_id, cv.IMREAD_UNCHANGED) / 255.).astype(np.float32)
+ mask_img = cv.imread(mask_dir + '/%08d.jpg' % frame_id, cv.IMREAD_UNCHANGED) > 128
+ gt_img[~mask_img] = 1.
+
+ ours_img_cropped, posevocab_img_cropped, slrf_img_cropped, tava_img_cropped, arah_img_cropped, gt_img_cropped = \
+ crop_image(
+ mask_img,
+ 512,
+ ours_img,
+ posevocab_img,
+ slrf_img,
+ tava_img,
+ arah_img,
+ gt_img
+ )
+
+ cv.imwrite('./tmp_quant/ours/%08d.png' % frame_id, (ours_img_cropped * 255).astype(np.uint8))
+ cv.imwrite('./tmp_quant/posevocab/%08d.png' % frame_id, (posevocab_img_cropped * 255).astype(np.uint8))
+ cv.imwrite('./tmp_quant/slrf/%08d.png' % frame_id, (slrf_img_cropped * 255).astype(np.uint8))
+ cv.imwrite('./tmp_quant/tava/%08d.png' % frame_id, (tava_img_cropped * 255).astype(np.uint8))
+ cv.imwrite('./tmp_quant/arah/%08d.png' % frame_id, (arah_img_cropped * 255).astype(np.uint8))
+ cv.imwrite('./tmp_quant/gt/%08d.png' % frame_id, (gt_img_cropped * 255).astype(np.uint8))
+
+ if ours_img is not None:
+ ours_metrics.psnr += compute_psnr(ours_img, gt_img)
+ ours_metrics.ssim += compute_ssim(ours_img, gt_img)
+ ours_metrics.lpips += compute_lpips(ours_img_cropped, gt_img_cropped)
+ ours_metrics.count += 1
+
+ if posevocab_img is not None:
+ posevocab_metrics.psnr += compute_psnr(posevocab_img, gt_img)
+ posevocab_metrics.ssim += compute_ssim(posevocab_img, gt_img)
+ posevocab_metrics.lpips += compute_lpips(posevocab_img_cropped, gt_img_cropped)
+ posevocab_metrics.count += 1
+
+ if slrf_img is not None:
+ slrf_metrics.psnr += compute_psnr(slrf_img, gt_img)
+ slrf_metrics.ssim += compute_ssim(slrf_img, gt_img)
+ slrf_metrics.lpips += compute_lpips(slrf_img_cropped, gt_img_cropped)
+ slrf_metrics.count += 1
+
+ if arah_img is not None:
+ arah_metrics.psnr += compute_psnr(arah_img, gt_img)
+ arah_metrics.ssim += compute_ssim(arah_img, gt_img)
+ arah_metrics.lpips += compute_lpips(arah_img_cropped, gt_img_cropped)
+ arah_metrics.count += 1
+
+ if tava_img is not None:
+ tava_metrics.psnr += compute_psnr(tava_img, gt_img)
+ tava_metrics.ssim += compute_ssim(tava_img, gt_img)
+ tava_metrics.lpips += compute_lpips(tava_img_cropped, gt_img_cropped)
+ tava_metrics.count += 1
+
+ print('Ours metrics: ', ours_metrics)
+ print('PoseVocab metrics: ', posevocab_metrics)
+ print('SLRF metrics: ', slrf_metrics)
+ print('ARAH metrics: ', arah_metrics)
+ print('TAVA metrics: ', tava_metrics)
+
+ print('--- Ours ---')
+ os.system('python -m pytorch_fid --device cuda {} {}'.format('./tmp_quant/ours', './tmp_quant/gt'))
+ print('--- PoseVocab ---')
+ os.system('python -m pytorch_fid --device cuda {} {}'.format('./tmp_quant/posevocab', './tmp_quant/gt'))
+ print('--- SLRF ---')
+ os.system('python -m pytorch_fid --device cuda {} {}'.format('./tmp_quant/slrf', './tmp_quant/gt'))
+ print('--- ARAH ---')
+ os.system('python -m pytorch_fid --device cuda {} {}'.format('./tmp_quant/arah', './tmp_quant/gt'))
+ print('--- TAVA ---')
+ os.system('python -m pytorch_fid --device cuda {} {}'.format('./tmp_quant/tava', './tmp_quant/gt'))
+
+
diff --git a/AnimatableGaussians/eval/score.py b/AnimatableGaussians/eval/score.py
new file mode 100644
index 0000000000000000000000000000000000000000..568d97058e6a2106b2bcf3a90e7b14b3815f84d5
--- /dev/null
+++ b/AnimatableGaussians/eval/score.py
@@ -0,0 +1,108 @@
+import skimage.metrics
+import numpy as np
+import torch
+import cv2 as cv
+
+from network.lpips import LPIPS
+
+
+class Metrics:
+ def __init__(self):
+ self.psnr = 0.
+ self.ssim = 0.
+ self.lpips = 0.
+ self.count = 0
+
+ def __repr__(self):
+ if self.count > 0:
+ return f'Count: {self.count}, PSNR: {self.psnr / self.count}, SSIM: {self.ssim / self.count}, LPIPS: {self.lpips / self.count}'
+ else:
+ return 'count is 0!'
+
+
+def crop_image(gt_mask, patch_size, *args):
+ """
+ :param gt_mask: (H, W)
+ :param patch_size: resize the cropped patch to the given patch_size
+ :param args: some images with shape of (H, W, C)
+ """
+ mask_uv = np.argwhere(gt_mask > 0.)
+ min_v, min_u = mask_uv.min(0)
+ max_v, max_u = mask_uv.max(0)
+ pad_size = 50
+ min_v = (min_v - pad_size).clip(0, gt_mask.shape[0])
+ min_u = (min_u - pad_size).clip(0, gt_mask.shape[1])
+ max_v = (max_v + pad_size).clip(0, gt_mask.shape[0])
+ max_u = (max_u + pad_size).clip(0, gt_mask.shape[1])
+ len_v = max_v - min_v
+ len_u = max_u - min_u
+ max_size = max(len_v, len_u)
+
+ cropped_images = []
+ for image in args:
+ if image is None:
+ cropped_images.append(None)
+ else:
+ cropped_image = np.ones((max_size, max_size, 3), dtype = image.dtype)
+ if len_v > len_u:
+ start_u = (max_size - len_u) // 2
+ cropped_image[:, start_u: start_u + len_u] = image[min_v: max_v, min_u: max_u]
+ else:
+ start_v = (max_size - len_v) // 2
+ cropped_image[start_v: start_v + len_v, :] = image[min_v: max_v, min_u: max_u]
+
+ cropped_image = cv.resize(cropped_image, (patch_size, patch_size), interpolation = cv.INTER_LINEAR)
+ cropped_images.append(cropped_image)
+
+ if len(cropped_images) > 1:
+ return cropped_images
+ else:
+ return cropped_images[0]
+
+
+def to_tensor(array, device = 'cuda'):
+ if isinstance(array, np.ndarray):
+ array = torch.from_numpy(array).to(device)
+ elif isinstance(array, torch.Tensor):
+ array = array.to(device)
+ else:
+ raise TypeError('Invalid type of array.')
+ return array
+
+
+def cut_rect(img):
+ h, w = img.shape[:2]
+ size = max(h, w)
+ img_ = torch.ones((size, size, img.shape[2])).to(img)
+ if h < w:
+ img_[:h] = img
+ else:
+ img_[:, :w] = img
+ return img_
+
+
+lpips_net = None
+
+
+def compute_lpips(src, tar, device = 'cuda'):
+ src = to_tensor(src, device)
+ tar = to_tensor(tar, device)
+ global lpips_net
+ if lpips_net is None:
+ lpips_net = LPIPS(net = 'vgg').to(device)
+ if src.shape[0] != src.shape[1]:
+ src = cut_rect(src)
+ tar = cut_rect(tar)
+ with torch.no_grad():
+ lpips = lpips_net.forward(src.permute(2, 0, 1)[None], tar.permute(2, 0, 1)[None], normalize = True).mean()
+ return lpips.item()
+
+
+def compute_psnr(src, tar):
+ psnr = skimage.metrics.peak_signal_noise_ratio(tar, src, data_range=1)
+ return psnr
+
+
+def compute_ssim(src, tar):
+ ssim = skimage.metrics.structural_similarity(src, tar, multichannel = True, data_range = 1)
+ return ssim
diff --git a/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-310.pyc b/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e03cefc35a5e63d61e7813abd0cf5ce1315c22f9
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-310.pyc differ
diff --git a/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-38.pyc b/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e610e5483cec95bd6f9e29c3049381d9fd6a52e5
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/gaussian_model.cpython-38.pyc differ
diff --git a/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-310.pyc b/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..17e832f9ce58e4d2a4c8c8506cf38baefac6b7c1
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-310.pyc differ
diff --git a/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-38.pyc b/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bb7fd9aa233eb64eccbc779462869c35ae65c905
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/gaussian_renderer.cpython-38.pyc differ
diff --git a/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-310.pyc b/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c41cdcab047426f64017ef103b6903cb9f68ac06
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-310.pyc differ
diff --git a/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-38.pyc b/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4c86cf66e96e3552d4657093ca8f2a8eced7fc1d
Binary files /dev/null and b/AnimatableGaussians/gaussians/__pycache__/obj_io.cpython-38.pyc differ
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/.gitignore b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..faabab8435132c722ba96e9a0398e83b226a4e61
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/.gitignore
@@ -0,0 +1,8 @@
+build/
+diff_gaussian_rasterization_depth_alpha.egg-info/
+dist/
+
+__pycache__
+
+*.so
+*.idea
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/CMakeLists.txt b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..10cf07b471ab6d032f03f051c92f5b4612712e75
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/CMakeLists.txt
@@ -0,0 +1,36 @@
+#
+# Copyright (C) 2023, Inria
+# GRAPHDECO research group, https://team.inria.fr/graphdeco
+# All rights reserved.
+#
+# This software is free for non-commercial, research and evaluation use
+# under the terms of the LICENSE.md file.
+#
+# For inquiries contact george.drettakis@inria.fr
+#
+
+cmake_minimum_required(VERSION 3.20)
+
+project(DiffRast LANGUAGES CUDA CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_CUDA_STANDARD 17)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+
+add_library(CudaRasterizer
+ cuda_rasterizer/backward.h
+ cuda_rasterizer/backward.cu
+ cuda_rasterizer/forward.h
+ cuda_rasterizer/forward.cu
+ cuda_rasterizer/auxiliary.h
+ cuda_rasterizer/rasterizer_impl.cu
+ cuda_rasterizer/rasterizer_impl.h
+ cuda_rasterizer/rasterizer.h
+)
+
+set_target_properties(CudaRasterizer PROPERTIES CUDA_ARCHITECTURES "75;86")
+
+target_include_directories(CudaRasterizer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/cuda_rasterizer)
+target_include_directories(CudaRasterizer PRIVATE third_party/glm ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/LICENSE.md b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/LICENSE.md
new file mode 100644
index 0000000000000000000000000000000000000000..535c75ea6c094abed18382a67a590dfd5ac92413
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/LICENSE.md
@@ -0,0 +1,83 @@
+Gaussian-Splatting License
+===========================
+
+**Inria** and **the Max Planck Institut for Informatik (MPII)** hold all the ownership rights on the *Software* named **gaussian-splatting**.
+The *Software* is in the process of being registered with the Agence pour la Protection des
+Programmes (APP).
+
+The *Software* is still being developed by the *Licensor*.
+
+*Licensor*'s goal is to allow the research community to use, test and evaluate
+the *Software*.
+
+## 1. Definitions
+
+*Licensee* means any person or entity that uses the *Software* and distributes
+its *Work*.
+
+*Licensor* means the owners of the *Software*, i.e Inria and MPII
+
+*Software* means the original work of authorship made available under this
+License ie gaussian-splatting.
+
+*Work* means the *Software* and any additions to or derivative works of the
+*Software* that are made available under this License.
+
+
+## 2. Purpose
+This license is intended to define the rights granted to the *Licensee* by
+Licensors under the *Software*.
+
+## 3. Rights granted
+
+For the above reasons Licensors have decided to distribute the *Software*.
+Licensors grant non-exclusive rights to use the *Software* for research purposes
+to research users (both academic and industrial), free of charge, without right
+to sublicense.. The *Software* may be used "non-commercially", i.e., for research
+and/or evaluation purposes only.
+
+Subject to the terms and conditions of this License, you are granted a
+non-exclusive, royalty-free, license to reproduce, prepare derivative works of,
+publicly display, publicly perform and distribute its *Work* and any resulting
+derivative works in any form.
+
+## 4. Limitations
+
+**4.1 Redistribution.** You may reproduce or distribute the *Work* only if (a) you do
+so under this License, (b) you include a complete copy of this License with
+your distribution, and (c) you retain without modification any copyright,
+patent, trademark, or attribution notices that are present in the *Work*.
+
+**4.2 Derivative Works.** You may specify that additional or different terms apply
+to the use, reproduction, and distribution of your derivative works of the *Work*
+("Your Terms") only if (a) Your Terms provide that the use limitation in
+Section 2 applies to your derivative works, and (b) you identify the specific
+derivative works that are subject to Your Terms. Notwithstanding Your Terms,
+this License (including the redistribution requirements in Section 3.1) will
+continue to apply to the *Work* itself.
+
+**4.3** Any other use without of prior consent of Licensors is prohibited. Research
+users explicitly acknowledge having received from Licensors all information
+allowing to appreciate the adequacy between of the *Software* and their needs and
+to undertake all necessary precautions for its execution and use.
+
+**4.4** The *Software* is provided both as a compiled library file and as source
+code. In case of using the *Software* for a publication or other results obtained
+through the use of the *Software*, users are strongly encouraged to cite the
+corresponding publications as explained in the documentation of the *Software*.
+
+## 5. Disclaimer
+
+THE USER CANNOT USE, EXPLOIT OR DISTRIBUTE THE *SOFTWARE* FOR COMMERCIAL PURPOSES
+WITHOUT PRIOR AND EXPLICIT CONSENT OF LICENSORS. YOU MUST CONTACT INRIA FOR ANY
+UNAUTHORIZED USE: stip-sophia.transfert@inria.fr . ANY SUCH ACTION WILL
+CONSTITUTE A FORGERY. THIS *SOFTWARE* IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES
+OF ANY NATURE AND ANY EXPRESS OR IMPLIED WARRANTIES, WITH REGARDS TO COMMERCIAL
+USE, PROFESSIONNAL USE, LEGAL OR NOT, OR OTHER, OR COMMERCIALISATION OR
+ADAPTATION. UNLESS EXPLICITLY PROVIDED BY LAW, IN NO EVENT, SHALL INRIA OR THE
+AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE *SOFTWARE* OR THE USE OR OTHER DEALINGS IN THE *SOFTWARE*.
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/README.md b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5bc12949c9f31e97e53c902925c6127bd669e0f0
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/README.md
@@ -0,0 +1,35 @@
+# Differential Gaussian Rasterization
+
+**NOTE**: this is a modified version to support depth & alpha rendering (both forward and backward) from the [original repository](https://github.com/graphdeco-inria/diff-gaussian-rasterization).
+
+```python
+rendered_image, radii, rendered_depth, rendered_alpha = rasterizer(
+ means3D=means3D,
+ means2D=means2D,
+ shs=shs,
+ colors_precomp=colors_precomp,
+ opacities=opacity,
+ scales=scales,
+ rotations=rotations,
+ cov3D_precomp=cov3D_precomp,
+)
+```
+
+
+Used as the rasterization engine for the paper "3D Gaussian Splatting for Real-Time Rendering of Radiance Fields". If you can make use of it in your own research, please be so kind to cite us.
+
+
+
+
BibTeX
+
@Article{kerbl3Dgaussians,
+ author = {Kerbl, Bernhard and Kopanas, Georgios and Leimk{\"u}hler, Thomas and Drettakis, George},
+ title = {3D Gaussian Splatting for Real-Time Radiance Field Rendering},
+ journal = {ACM Transactions on Graphics},
+ number = {4},
+ volume = {42},
+ month = {July},
+ year = {2023},
+ url = {https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/}
+}
+
+
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/auxiliary.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/auxiliary.h
new file mode 100644
index 0000000000000000000000000000000000000000..cef35bd7ee80c7abd7203b1140987cdbb0819ebe
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/auxiliary.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#ifndef CUDA_RASTERIZER_AUXILIARY_H_INCLUDED
+#define CUDA_RASTERIZER_AUXILIARY_H_INCLUDED
+
+#include "config.h"
+#include "stdio.h"
+
+#define BLOCK_SIZE (BLOCK_X * BLOCK_Y)
+#define NUM_WARPS (BLOCK_SIZE/32)
+
+// Spherical harmonics coefficients
+__device__ const float SH_C0 = 0.28209479177387814f;
+__device__ const float SH_C1 = 0.4886025119029199f;
+__device__ const float SH_C2[] = {
+ 1.0925484305920792f,
+ -1.0925484305920792f,
+ 0.31539156525252005f,
+ -1.0925484305920792f,
+ 0.5462742152960396f
+};
+__device__ const float SH_C3[] = {
+ -0.5900435899266435f,
+ 2.890611442640554f,
+ -0.4570457994644658f,
+ 0.3731763325901154f,
+ -0.4570457994644658f,
+ 1.445305721320277f,
+ -0.5900435899266435f
+};
+
+__forceinline__ __device__ float ndc2Pix(float v, int S)
+{
+ return ((v + 1.0) * S - 1.0) * 0.5;
+}
+
+__forceinline__ __device__ void getRect(const float2 p, int max_radius, uint2& rect_min, uint2& rect_max, dim3 grid)
+{
+ rect_min = {
+ min(grid.x, max((int)0, (int)((p.x - max_radius) / BLOCK_X))),
+ min(grid.y, max((int)0, (int)((p.y - max_radius) / BLOCK_Y)))
+ };
+ rect_max = {
+ min(grid.x, max((int)0, (int)((p.x + max_radius + BLOCK_X - 1) / BLOCK_X))),
+ min(grid.y, max((int)0, (int)((p.y + max_radius + BLOCK_Y - 1) / BLOCK_Y)))
+ };
+}
+
+__forceinline__ __device__ float3 transformPoint4x3(const float3& p, const float* matrix)
+{
+ float3 transformed = {
+ matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z + matrix[12],
+ matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z + matrix[13],
+ matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z + matrix[14],
+ };
+ return transformed;
+}
+
+__forceinline__ __device__ float4 transformPoint4x4(const float3& p, const float* matrix)
+{
+ float4 transformed = {
+ matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z + matrix[12],
+ matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z + matrix[13],
+ matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z + matrix[14],
+ matrix[3] * p.x + matrix[7] * p.y + matrix[11] * p.z + matrix[15]
+ };
+ return transformed;
+}
+
+__forceinline__ __device__ float3 transformVec4x3(const float3& p, const float* matrix)
+{
+ float3 transformed = {
+ matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z,
+ matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z,
+ matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z,
+ };
+ return transformed;
+}
+
+__forceinline__ __device__ float3 transformVec4x3Transpose(const float3& p, const float* matrix)
+{
+ float3 transformed = {
+ matrix[0] * p.x + matrix[1] * p.y + matrix[2] * p.z,
+ matrix[4] * p.x + matrix[5] * p.y + matrix[6] * p.z,
+ matrix[8] * p.x + matrix[9] * p.y + matrix[10] * p.z,
+ };
+ return transformed;
+}
+
+__forceinline__ __device__ float dnormvdz(float3 v, float3 dv)
+{
+ float sum2 = v.x * v.x + v.y * v.y + v.z * v.z;
+ float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
+ float dnormvdz = (-v.x * v.z * dv.x - v.y * v.z * dv.y + (sum2 - v.z * v.z) * dv.z) * invsum32;
+ return dnormvdz;
+}
+
+__forceinline__ __device__ float3 dnormvdv(float3 v, float3 dv)
+{
+ float sum2 = v.x * v.x + v.y * v.y + v.z * v.z;
+ float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
+
+ float3 dnormvdv;
+ dnormvdv.x = ((+sum2 - v.x * v.x) * dv.x - v.y * v.x * dv.y - v.z * v.x * dv.z) * invsum32;
+ dnormvdv.y = (-v.x * v.y * dv.x + (sum2 - v.y * v.y) * dv.y - v.z * v.y * dv.z) * invsum32;
+ dnormvdv.z = (-v.x * v.z * dv.x - v.y * v.z * dv.y + (sum2 - v.z * v.z) * dv.z) * invsum32;
+ return dnormvdv;
+}
+
+__forceinline__ __device__ float4 dnormvdv(float4 v, float4 dv)
+{
+ float sum2 = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
+ float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
+
+ float4 vdv = { v.x * dv.x, v.y * dv.y, v.z * dv.z, v.w * dv.w };
+ float vdv_sum = vdv.x + vdv.y + vdv.z + vdv.w;
+ float4 dnormvdv;
+ dnormvdv.x = ((sum2 - v.x * v.x) * dv.x - v.x * (vdv_sum - vdv.x)) * invsum32;
+ dnormvdv.y = ((sum2 - v.y * v.y) * dv.y - v.y * (vdv_sum - vdv.y)) * invsum32;
+ dnormvdv.z = ((sum2 - v.z * v.z) * dv.z - v.z * (vdv_sum - vdv.z)) * invsum32;
+ dnormvdv.w = ((sum2 - v.w * v.w) * dv.w - v.w * (vdv_sum - vdv.w)) * invsum32;
+ return dnormvdv;
+}
+
+__forceinline__ __device__ float sigmoid(float x)
+{
+ return 1.0f / (1.0f + expf(-x));
+}
+
+__forceinline__ __device__ bool in_frustum(int idx,
+ const float* orig_points,
+ const float* viewmatrix,
+ const float* projmatrix,
+ bool prefiltered,
+ float3& p_view)
+{
+ float3 p_orig = { orig_points[3 * idx], orig_points[3 * idx + 1], orig_points[3 * idx + 2] };
+
+ // Bring points to screen space
+ float4 p_hom = transformPoint4x4(p_orig, projmatrix);
+ float p_w = 1.0f / (p_hom.w + 0.0000001f);
+ float3 p_proj = { p_hom.x * p_w, p_hom.y * p_w, p_hom.z * p_w };
+ p_view = transformPoint4x3(p_orig, viewmatrix);
+
+ if (p_view.z <= 0.2f)// || ((p_proj.x < -1.3 || p_proj.x > 1.3 || p_proj.y < -1.3 || p_proj.y > 1.3)))
+ {
+ if (prefiltered)
+ {
+ printf("Point is filtered although prefiltered is set. This shouldn't happen!");
+ __trap();
+ }
+ return false;
+ }
+ return true;
+}
+
+#define CHECK_CUDA(A, debug) \
+A; if(debug) { \
+auto ret = cudaDeviceSynchronize(); \
+if (ret != cudaSuccess) { \
+std::cerr << "\n[CUDA ERROR] in " << __FILE__ << "\nLine " << __LINE__ << ": " << cudaGetErrorString(ret); \
+throw std::runtime_error(cudaGetErrorString(ret)); \
+} \
+}
+
+#endif
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.cu b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.cu
new file mode 100644
index 0000000000000000000000000000000000000000..1899c29f25f2052133ffdfe05e35b488f2627c9f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.cu
@@ -0,0 +1,712 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#include "backward.h"
+#include "auxiliary.h"
+#include
+#include
+namespace cg = cooperative_groups;
+
+// Backward pass for conversion of spherical harmonics to RGB for
+// each Gaussian.
+__device__ void computeColorFromSH(int idx, int deg, int max_coeffs, const glm::vec3* means, glm::vec3 campos, const float* shs, const bool* clamped, const glm::vec3* dL_dcolor, glm::vec3* dL_dmeans, glm::vec3* dL_dshs)
+{
+ // Compute intermediate values, as it is done during forward
+ glm::vec3 pos = means[idx];
+ glm::vec3 dir_orig = pos - campos;
+ glm::vec3 dir = dir_orig / glm::length(dir_orig);
+
+ glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs;
+
+ // Use PyTorch rule for clamping: if clamping was applied,
+ // gradient becomes 0.
+ glm::vec3 dL_dRGB = dL_dcolor[idx];
+ dL_dRGB.x *= clamped[3 * idx + 0] ? 0 : 1;
+ dL_dRGB.y *= clamped[3 * idx + 1] ? 0 : 1;
+ dL_dRGB.z *= clamped[3 * idx + 2] ? 0 : 1;
+
+ glm::vec3 dRGBdx(0, 0, 0);
+ glm::vec3 dRGBdy(0, 0, 0);
+ glm::vec3 dRGBdz(0, 0, 0);
+ float x = dir.x;
+ float y = dir.y;
+ float z = dir.z;
+
+ // Target location for this Gaussian to write SH gradients to
+ glm::vec3* dL_dsh = dL_dshs + idx * max_coeffs;
+
+ // No tricks here, just high school-level calculus.
+ float dRGBdsh0 = SH_C0;
+ dL_dsh[0] = dRGBdsh0 * dL_dRGB;
+ if (deg > 0)
+ {
+ float dRGBdsh1 = -SH_C1 * y;
+ float dRGBdsh2 = SH_C1 * z;
+ float dRGBdsh3 = -SH_C1 * x;
+ dL_dsh[1] = dRGBdsh1 * dL_dRGB;
+ dL_dsh[2] = dRGBdsh2 * dL_dRGB;
+ dL_dsh[3] = dRGBdsh3 * dL_dRGB;
+
+ dRGBdx = -SH_C1 * sh[3];
+ dRGBdy = -SH_C1 * sh[1];
+ dRGBdz = SH_C1 * sh[2];
+
+ if (deg > 1)
+ {
+ float xx = x * x, yy = y * y, zz = z * z;
+ float xy = x * y, yz = y * z, xz = x * z;
+
+ float dRGBdsh4 = SH_C2[0] * xy;
+ float dRGBdsh5 = SH_C2[1] * yz;
+ float dRGBdsh6 = SH_C2[2] * (2.f * zz - xx - yy);
+ float dRGBdsh7 = SH_C2[3] * xz;
+ float dRGBdsh8 = SH_C2[4] * (xx - yy);
+ dL_dsh[4] = dRGBdsh4 * dL_dRGB;
+ dL_dsh[5] = dRGBdsh5 * dL_dRGB;
+ dL_dsh[6] = dRGBdsh6 * dL_dRGB;
+ dL_dsh[7] = dRGBdsh7 * dL_dRGB;
+ dL_dsh[8] = dRGBdsh8 * dL_dRGB;
+
+ dRGBdx += SH_C2[0] * y * sh[4] + SH_C2[2] * 2.f * -x * sh[6] + SH_C2[3] * z * sh[7] + SH_C2[4] * 2.f * x * sh[8];
+ dRGBdy += SH_C2[0] * x * sh[4] + SH_C2[1] * z * sh[5] + SH_C2[2] * 2.f * -y * sh[6] + SH_C2[4] * 2.f * -y * sh[8];
+ dRGBdz += SH_C2[1] * y * sh[5] + SH_C2[2] * 2.f * 2.f * z * sh[6] + SH_C2[3] * x * sh[7];
+
+ if (deg > 2)
+ {
+ float dRGBdsh9 = SH_C3[0] * y * (3.f * xx - yy);
+ float dRGBdsh10 = SH_C3[1] * xy * z;
+ float dRGBdsh11 = SH_C3[2] * y * (4.f * zz - xx - yy);
+ float dRGBdsh12 = SH_C3[3] * z * (2.f * zz - 3.f * xx - 3.f * yy);
+ float dRGBdsh13 = SH_C3[4] * x * (4.f * zz - xx - yy);
+ float dRGBdsh14 = SH_C3[5] * z * (xx - yy);
+ float dRGBdsh15 = SH_C3[6] * x * (xx - 3.f * yy);
+ dL_dsh[9] = dRGBdsh9 * dL_dRGB;
+ dL_dsh[10] = dRGBdsh10 * dL_dRGB;
+ dL_dsh[11] = dRGBdsh11 * dL_dRGB;
+ dL_dsh[12] = dRGBdsh12 * dL_dRGB;
+ dL_dsh[13] = dRGBdsh13 * dL_dRGB;
+ dL_dsh[14] = dRGBdsh14 * dL_dRGB;
+ dL_dsh[15] = dRGBdsh15 * dL_dRGB;
+
+ dRGBdx += (
+ SH_C3[0] * sh[9] * 3.f * 2.f * xy +
+ SH_C3[1] * sh[10] * yz +
+ SH_C3[2] * sh[11] * -2.f * xy +
+ SH_C3[3] * sh[12] * -3.f * 2.f * xz +
+ SH_C3[4] * sh[13] * (-3.f * xx + 4.f * zz - yy) +
+ SH_C3[5] * sh[14] * 2.f * xz +
+ SH_C3[6] * sh[15] * 3.f * (xx - yy));
+
+ dRGBdy += (
+ SH_C3[0] * sh[9] * 3.f * (xx - yy) +
+ SH_C3[1] * sh[10] * xz +
+ SH_C3[2] * sh[11] * (-3.f * yy + 4.f * zz - xx) +
+ SH_C3[3] * sh[12] * -3.f * 2.f * yz +
+ SH_C3[4] * sh[13] * -2.f * xy +
+ SH_C3[5] * sh[14] * -2.f * yz +
+ SH_C3[6] * sh[15] * -3.f * 2.f * xy);
+
+ dRGBdz += (
+ SH_C3[1] * sh[10] * xy +
+ SH_C3[2] * sh[11] * 4.f * 2.f * yz +
+ SH_C3[3] * sh[12] * 3.f * (2.f * zz - xx - yy) +
+ SH_C3[4] * sh[13] * 4.f * 2.f * xz +
+ SH_C3[5] * sh[14] * (xx - yy));
+ }
+ }
+ }
+
+ // The view direction is an input to the computation. View direction
+ // is influenced by the Gaussian's mean, so SHs gradients
+ // must propagate back into 3D position.
+ glm::vec3 dL_ddir(glm::dot(dRGBdx, dL_dRGB), glm::dot(dRGBdy, dL_dRGB), glm::dot(dRGBdz, dL_dRGB));
+
+ // Account for normalization of direction
+ float3 dL_dmean = dnormvdv(float3{ dir_orig.x, dir_orig.y, dir_orig.z }, float3{ dL_ddir.x, dL_ddir.y, dL_ddir.z });
+
+ // Gradients of loss w.r.t. Gaussian means, but only the portion
+ // that is caused because the mean affects the view-dependent color.
+ // Additional mean gradient is accumulated in below methods.
+ dL_dmeans[idx] += glm::vec3(dL_dmean.x, dL_dmean.y, dL_dmean.z);
+}
+
+// Backward version of INVERSE 2D covariance matrix computation
+// (due to length launched as separate kernel before other
+// backward steps contained in preprocess)
+__global__ void computeCov2DCUDA(int P,
+ const float3* means,
+ const int* radii,
+ const float* cov3Ds,
+ const float h_x, float h_y,
+ const float tan_fovx, float tan_fovy,
+ const float* view_matrix,
+ const float* dL_dconics,
+ float3* dL_dmeans,
+ float* dL_dcov)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= P || !(radii[idx] > 0))
+ return;
+
+ // Reading location of 3D covariance for this Gaussian
+ const float* cov3D = cov3Ds + 6 * idx;
+
+ // Fetch gradients, recompute 2D covariance and relevant
+ // intermediate forward results needed in the backward.
+ float3 mean = means[idx];
+ float3 dL_dconic = { dL_dconics[4 * idx], dL_dconics[4 * idx + 1], dL_dconics[4 * idx + 3] };
+ float3 t = transformPoint4x3(mean, view_matrix);
+
+ const float limx = 1.3f * tan_fovx;
+ const float limy = 1.3f * tan_fovy;
+ const float txtz = t.x / t.z;
+ const float tytz = t.y / t.z;
+ t.x = min(limx, max(-limx, txtz)) * t.z;
+ t.y = min(limy, max(-limy, tytz)) * t.z;
+
+ const float x_grad_mul = txtz < -limx || txtz > limx ? 0 : 1;
+ const float y_grad_mul = tytz < -limy || tytz > limy ? 0 : 1;
+
+ glm::mat3 J = glm::mat3(h_x / t.z, 0.0f, -(h_x * t.x) / (t.z * t.z),
+ 0.0f, h_y / t.z, -(h_y * t.y) / (t.z * t.z),
+ 0, 0, 0);
+
+ glm::mat3 W = glm::mat3(
+ view_matrix[0], view_matrix[4], view_matrix[8],
+ view_matrix[1], view_matrix[5], view_matrix[9],
+ view_matrix[2], view_matrix[6], view_matrix[10]);
+
+ glm::mat3 Vrk = glm::mat3(
+ cov3D[0], cov3D[1], cov3D[2],
+ cov3D[1], cov3D[3], cov3D[4],
+ cov3D[2], cov3D[4], cov3D[5]);
+
+ glm::mat3 T = W * J;
+
+ glm::mat3 cov2D = glm::transpose(T) * glm::transpose(Vrk) * T;
+
+ // Use helper variables for 2D covariance entries. More compact.
+ float a = cov2D[0][0] += 0.3f;
+ float b = cov2D[0][1];
+ float c = cov2D[1][1] += 0.3f;
+
+ float denom = a * c - b * b;
+ float dL_da = 0, dL_db = 0, dL_dc = 0;
+ float denom2inv = 1.0f / ((denom * denom) + 0.0000001f);
+
+ if (denom2inv != 0)
+ {
+ // Gradients of loss w.r.t. entries of 2D covariance matrix,
+ // given gradients of loss w.r.t. conic matrix (inverse covariance matrix).
+ // e.g., dL / da = dL / d_conic_a * d_conic_a / d_a
+ dL_da = denom2inv * (-c * c * dL_dconic.x + 2 * b * c * dL_dconic.y + (denom - a * c) * dL_dconic.z);
+ dL_dc = denom2inv * (-a * a * dL_dconic.z + 2 * a * b * dL_dconic.y + (denom - a * c) * dL_dconic.x);
+ dL_db = denom2inv * 2 * (b * c * dL_dconic.x - (denom + 2 * b * b) * dL_dconic.y + a * b * dL_dconic.z);
+
+ // Gradients of loss L w.r.t. each 3D covariance matrix (Vrk) entry,
+ // given gradients w.r.t. 2D covariance matrix (diagonal).
+ // cov2D = transpose(T) * transpose(Vrk) * T;
+ dL_dcov[6 * idx + 0] = (T[0][0] * T[0][0] * dL_da + T[0][0] * T[1][0] * dL_db + T[1][0] * T[1][0] * dL_dc);
+ dL_dcov[6 * idx + 3] = (T[0][1] * T[0][1] * dL_da + T[0][1] * T[1][1] * dL_db + T[1][1] * T[1][1] * dL_dc);
+ dL_dcov[6 * idx + 5] = (T[0][2] * T[0][2] * dL_da + T[0][2] * T[1][2] * dL_db + T[1][2] * T[1][2] * dL_dc);
+
+ // Gradients of loss L w.r.t. each 3D covariance matrix (Vrk) entry,
+ // given gradients w.r.t. 2D covariance matrix (off-diagonal).
+ // Off-diagonal elements appear twice --> double the gradient.
+ // cov2D = transpose(T) * transpose(Vrk) * T;
+ dL_dcov[6 * idx + 1] = 2 * T[0][0] * T[0][1] * dL_da + (T[0][0] * T[1][1] + T[0][1] * T[1][0]) * dL_db + 2 * T[1][0] * T[1][1] * dL_dc;
+ dL_dcov[6 * idx + 2] = 2 * T[0][0] * T[0][2] * dL_da + (T[0][0] * T[1][2] + T[0][2] * T[1][0]) * dL_db + 2 * T[1][0] * T[1][2] * dL_dc;
+ dL_dcov[6 * idx + 4] = 2 * T[0][2] * T[0][1] * dL_da + (T[0][1] * T[1][2] + T[0][2] * T[1][1]) * dL_db + 2 * T[1][1] * T[1][2] * dL_dc;
+ }
+ else
+ {
+ for (int i = 0; i < 6; i++)
+ dL_dcov[6 * idx + i] = 0;
+ }
+
+ // Gradients of loss w.r.t. upper 2x3 portion of intermediate matrix T
+ // cov2D = transpose(T) * transpose(Vrk) * T;
+ float dL_dT00 = 2 * (T[0][0] * Vrk[0][0] + T[0][1] * Vrk[0][1] + T[0][2] * Vrk[0][2]) * dL_da +
+ (T[1][0] * Vrk[0][0] + T[1][1] * Vrk[0][1] + T[1][2] * Vrk[0][2]) * dL_db;
+ float dL_dT01 = 2 * (T[0][0] * Vrk[1][0] + T[0][1] * Vrk[1][1] + T[0][2] * Vrk[1][2]) * dL_da +
+ (T[1][0] * Vrk[1][0] + T[1][1] * Vrk[1][1] + T[1][2] * Vrk[1][2]) * dL_db;
+ float dL_dT02 = 2 * (T[0][0] * Vrk[2][0] + T[0][1] * Vrk[2][1] + T[0][2] * Vrk[2][2]) * dL_da +
+ (T[1][0] * Vrk[2][0] + T[1][1] * Vrk[2][1] + T[1][2] * Vrk[2][2]) * dL_db;
+ float dL_dT10 = 2 * (T[1][0] * Vrk[0][0] + T[1][1] * Vrk[0][1] + T[1][2] * Vrk[0][2]) * dL_dc +
+ (T[0][0] * Vrk[0][0] + T[0][1] * Vrk[0][1] + T[0][2] * Vrk[0][2]) * dL_db;
+ float dL_dT11 = 2 * (T[1][0] * Vrk[1][0] + T[1][1] * Vrk[1][1] + T[1][2] * Vrk[1][2]) * dL_dc +
+ (T[0][0] * Vrk[1][0] + T[0][1] * Vrk[1][1] + T[0][2] * Vrk[1][2]) * dL_db;
+ float dL_dT12 = 2 * (T[1][0] * Vrk[2][0] + T[1][1] * Vrk[2][1] + T[1][2] * Vrk[2][2]) * dL_dc +
+ (T[0][0] * Vrk[2][0] + T[0][1] * Vrk[2][1] + T[0][2] * Vrk[2][2]) * dL_db;
+
+ // Gradients of loss w.r.t. upper 3x2 non-zero entries of Jacobian matrix
+ // T = W * J
+ float dL_dJ00 = W[0][0] * dL_dT00 + W[0][1] * dL_dT01 + W[0][2] * dL_dT02;
+ float dL_dJ02 = W[2][0] * dL_dT00 + W[2][1] * dL_dT01 + W[2][2] * dL_dT02;
+ float dL_dJ11 = W[1][0] * dL_dT10 + W[1][1] * dL_dT11 + W[1][2] * dL_dT12;
+ float dL_dJ12 = W[2][0] * dL_dT10 + W[2][1] * dL_dT11 + W[2][2] * dL_dT12;
+
+ float tz = 1.f / t.z;
+ float tz2 = tz * tz;
+ float tz3 = tz2 * tz;
+
+ // Gradients of loss w.r.t. transformed Gaussian mean t
+ float dL_dtx = x_grad_mul * -h_x * tz2 * dL_dJ02;
+ float dL_dty = y_grad_mul * -h_y * tz2 * dL_dJ12;
+ float dL_dtz = -h_x * tz2 * dL_dJ00 - h_y * tz2 * dL_dJ11 + (2 * h_x * t.x) * tz3 * dL_dJ02 + (2 * h_y * t.y) * tz3 * dL_dJ12;
+
+ // Account for transformation of mean to t
+ // t = transformPoint4x3(mean, view_matrix);
+ float3 dL_dmean = transformVec4x3Transpose({ dL_dtx, dL_dty, dL_dtz }, view_matrix);
+
+ // Gradients of loss w.r.t. Gaussian means, but only the portion
+ // that is caused because the mean affects the covariance matrix.
+ // Additional mean gradient is accumulated in BACKWARD::preprocess.
+ dL_dmeans[idx] = dL_dmean;
+}
+
+// Backward pass for the conversion of scale and rotation to a
+// 3D covariance matrix for each Gaussian.
+__device__ void computeCov3D(int idx, const glm::vec3 scale, float mod, const glm::vec4 rot, const float* dL_dcov3Ds, glm::vec3* dL_dscales, glm::vec4* dL_drots)
+{
+ // Recompute (intermediate) results for the 3D covariance computation.
+ glm::vec4 q = rot;// / glm::length(rot);
+ float r = q.x;
+ float x = q.y;
+ float y = q.z;
+ float z = q.w;
+
+ glm::mat3 R = glm::mat3(
+ 1.f - 2.f * (y * y + z * z), 2.f * (x * y - r * z), 2.f * (x * z + r * y),
+ 2.f * (x * y + r * z), 1.f - 2.f * (x * x + z * z), 2.f * (y * z - r * x),
+ 2.f * (x * z - r * y), 2.f * (y * z + r * x), 1.f - 2.f * (x * x + y * y)
+ );
+
+ glm::mat3 S = glm::mat3(1.0f);
+
+ glm::vec3 s = mod * scale;
+ S[0][0] = s.x;
+ S[1][1] = s.y;
+ S[2][2] = s.z;
+
+ glm::mat3 M = S * R;
+
+ const float* dL_dcov3D = dL_dcov3Ds + 6 * idx;
+
+ glm::vec3 dunc(dL_dcov3D[0], dL_dcov3D[3], dL_dcov3D[5]);
+ glm::vec3 ounc = 0.5f * glm::vec3(dL_dcov3D[1], dL_dcov3D[2], dL_dcov3D[4]);
+
+ // Convert per-element covariance loss gradients to matrix form
+ glm::mat3 dL_dSigma = glm::mat3(
+ dL_dcov3D[0], 0.5f * dL_dcov3D[1], 0.5f * dL_dcov3D[2],
+ 0.5f * dL_dcov3D[1], dL_dcov3D[3], 0.5f * dL_dcov3D[4],
+ 0.5f * dL_dcov3D[2], 0.5f * dL_dcov3D[4], dL_dcov3D[5]
+ );
+
+ // Compute loss gradient w.r.t. matrix M
+ // dSigma_dM = 2 * M
+ glm::mat3 dL_dM = 2.0f * M * dL_dSigma;
+
+ glm::mat3 Rt = glm::transpose(R);
+ glm::mat3 dL_dMt = glm::transpose(dL_dM);
+
+ // Gradients of loss w.r.t. scale
+ glm::vec3* dL_dscale = dL_dscales + idx;
+ dL_dscale->x = glm::dot(Rt[0], dL_dMt[0]);
+ dL_dscale->y = glm::dot(Rt[1], dL_dMt[1]);
+ dL_dscale->z = glm::dot(Rt[2], dL_dMt[2]);
+
+ dL_dMt[0] *= s.x;
+ dL_dMt[1] *= s.y;
+ dL_dMt[2] *= s.z;
+
+ // Gradients of loss w.r.t. normalized quaternion
+ glm::vec4 dL_dq;
+ dL_dq.x = 2 * z * (dL_dMt[0][1] - dL_dMt[1][0]) + 2 * y * (dL_dMt[2][0] - dL_dMt[0][2]) + 2 * x * (dL_dMt[1][2] - dL_dMt[2][1]);
+ dL_dq.y = 2 * y * (dL_dMt[1][0] + dL_dMt[0][1]) + 2 * z * (dL_dMt[2][0] + dL_dMt[0][2]) + 2 * r * (dL_dMt[1][2] - dL_dMt[2][1]) - 4 * x * (dL_dMt[2][2] + dL_dMt[1][1]);
+ dL_dq.z = 2 * x * (dL_dMt[1][0] + dL_dMt[0][1]) + 2 * r * (dL_dMt[2][0] - dL_dMt[0][2]) + 2 * z * (dL_dMt[1][2] + dL_dMt[2][1]) - 4 * y * (dL_dMt[2][2] + dL_dMt[0][0]);
+ dL_dq.w = 2 * r * (dL_dMt[0][1] - dL_dMt[1][0]) + 2 * x * (dL_dMt[2][0] + dL_dMt[0][2]) + 2 * y * (dL_dMt[1][2] + dL_dMt[2][1]) - 4 * z * (dL_dMt[1][1] + dL_dMt[0][0]);
+
+ // Gradients of loss w.r.t. unnormalized quaternion
+ float4* dL_drot = (float4*)(dL_drots + idx);
+ *dL_drot = float4{ dL_dq.x, dL_dq.y, dL_dq.z, dL_dq.w };//dnormvdv(float4{ rot.x, rot.y, rot.z, rot.w }, float4{ dL_dq.x, dL_dq.y, dL_dq.z, dL_dq.w });
+}
+
+// Backward pass of the preprocessing steps, except
+// for the covariance computation and inversion
+// (those are handled by a previous kernel call)
+template
+__global__ void preprocessCUDA(
+ int P, int D, int M,
+ const float3* means,
+ const int* radii,
+ const float* shs,
+ const bool* clamped,
+ const glm::vec3* scales,
+ const glm::vec4* rotations,
+ const float scale_modifier,
+ const float* view,
+ const float* proj,
+ const glm::vec3* campos,
+ const float3* dL_dmean2D,
+ glm::vec3* dL_dmeans,
+ float* dL_dcolor,
+ float* dL_ddepth,
+ float* dL_dcov3D,
+ float* dL_dsh,
+ glm::vec3* dL_dscale,
+ glm::vec4* dL_drot)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= P || !(radii[idx] > 0))
+ return;
+
+ float3 m = means[idx];
+
+ // Taking care of gradients from the screenspace points
+ float4 m_hom = transformPoint4x4(m, proj);
+ float m_w = 1.0f / (m_hom.w + 0.0000001f);
+
+ // Compute loss gradient w.r.t. 3D means due to gradients of 2D means
+ // from rendering procedure
+ glm::vec3 dL_dmean;
+ float mul1 = (proj[0] * m.x + proj[4] * m.y + proj[8] * m.z + proj[12]) * m_w * m_w;
+ float mul2 = (proj[1] * m.x + proj[5] * m.y + proj[9] * m.z + proj[13]) * m_w * m_w;
+ dL_dmean.x = (proj[0] * m_w - proj[3] * mul1) * dL_dmean2D[idx].x + (proj[1] * m_w - proj[3] * mul2) * dL_dmean2D[idx].y;
+ dL_dmean.y = (proj[4] * m_w - proj[7] * mul1) * dL_dmean2D[idx].x + (proj[5] * m_w - proj[7] * mul2) * dL_dmean2D[idx].y;
+ dL_dmean.z = (proj[8] * m_w - proj[11] * mul1) * dL_dmean2D[idx].x + (proj[9] * m_w - proj[11] * mul2) * dL_dmean2D[idx].y;
+
+ // That's the second part of the mean gradient. Previous computation
+ // of cov2D and following SH conversion also affects it.
+ dL_dmeans[idx] += dL_dmean;
+
+ // the w must be equal to 1 for view^T * [x,y,z,1]
+ float3 m_view = transformPoint4x3(m, view);
+
+ // Compute loss gradient w.r.t. 3D means due to gradients of depth
+ // from rendering procedure
+ glm::vec3 dL_dmean2;
+ float mul3 = view[2] * m.x + view[6] * m.y + view[10] * m.z + view[14];
+ dL_dmean2.x = (view[2] - view[3] * mul3) * dL_ddepth[idx];
+ dL_dmean2.y = (view[6] - view[7] * mul3) * dL_ddepth[idx];
+ dL_dmean2.z = (view[10] - view[11] * mul3) * dL_ddepth[idx];
+
+ // That's the third part of the mean gradient.
+ dL_dmeans[idx] += dL_dmean2;
+
+ // Compute gradient updates due to computing colors from SHs
+ if (shs)
+ computeColorFromSH(idx, D, M, (glm::vec3*)means, *campos, shs, clamped, (glm::vec3*)dL_dcolor, (glm::vec3*)dL_dmeans, (glm::vec3*)dL_dsh);
+
+ // Compute gradient updates due to computing covariance from scale/rotation
+ if (scales)
+ computeCov3D(idx, scales[idx], scale_modifier, rotations[idx], dL_dcov3D, dL_dscale, dL_drot);
+}
+
+// Backward version of the rendering procedure.
+template
+__global__ void __launch_bounds__(BLOCK_X * BLOCK_Y)
+renderCUDA(
+ const uint2* __restrict__ ranges,
+ const uint32_t* __restrict__ point_list,
+ int W, int H,
+ const float* __restrict__ bg_color,
+ const float2* __restrict__ points_xy_image,
+ const float4* __restrict__ conic_opacity,
+ const float* __restrict__ colors,
+ const float* __restrict__ depths,
+ const float* __restrict__ alphas,
+ const uint32_t* __restrict__ n_contrib,
+ const float* __restrict__ dL_dpixels,
+ const float* __restrict__ dL_dpixel_depths,
+ const float* __restrict__ dL_dalphas,
+ float3* __restrict__ dL_dmean2D,
+ float4* __restrict__ dL_dconic2D,
+ float* __restrict__ dL_dopacity,
+ float* __restrict__ dL_dcolors,
+ float* __restrict__ dL_ddepths
+)
+{
+ // We rasterize again. Compute necessary block info.
+ auto block = cg::this_thread_block();
+ const uint32_t horizontal_blocks = (W + BLOCK_X - 1) / BLOCK_X;
+ const uint2 pix_min = { block.group_index().x * BLOCK_X, block.group_index().y * BLOCK_Y };
+ const uint2 pix_max = { min(pix_min.x + BLOCK_X, W), min(pix_min.y + BLOCK_Y , H) };
+ const uint2 pix = { pix_min.x + block.thread_index().x, pix_min.y + block.thread_index().y };
+ const uint32_t pix_id = W * pix.y + pix.x;
+ const float2 pixf = { (float)pix.x, (float)pix.y };
+
+ const bool inside = pix.x < W&& pix.y < H;
+ const uint2 range = ranges[block.group_index().y * horizontal_blocks + block.group_index().x];
+
+ const int rounds = ((range.y - range.x + BLOCK_SIZE - 1) / BLOCK_SIZE);
+
+ bool done = !inside;
+ int toDo = range.y - range.x;
+
+ __shared__ int collected_id[BLOCK_SIZE];
+ __shared__ float2 collected_xy[BLOCK_SIZE];
+ __shared__ float4 collected_conic_opacity[BLOCK_SIZE];
+ __shared__ float collected_colors[C * BLOCK_SIZE];
+ __shared__ float collected_depths[BLOCK_SIZE];
+
+ // In the forward, we stored the final value for T, the
+ // product of all (1 - alpha) factors.
+ const float T_final = inside ? (1 - alphas[pix_id]) : 0;
+ float T = T_final;
+
+ // We start from the back. The ID of the last contributing
+ // Gaussian is known from each pixel from the forward.
+ uint32_t contributor = toDo;
+ const int last_contributor = inside ? n_contrib[pix_id] : 0;
+
+ float accum_rec[C] = { 0 };
+ float dL_dpixel[C];
+ float accum_depth_rec = 0;
+ float dL_dpixel_depth;
+ float accum_alpha_rec = 0;
+ float dL_dalpha;
+ if (inside) {
+ for (int i = 0; i < C; i++)
+ dL_dpixel[i] = dL_dpixels[i * H * W + pix_id];
+ dL_dpixel_depth = dL_dpixel_depths[pix_id];
+ dL_dalpha = dL_dalphas[pix_id];
+ }
+
+ float last_alpha = 0;
+ float last_color[C] = { 0 };
+ float last_depth = 0;
+
+ // Gradient of pixel coordinate w.r.t. normalized
+ // screen-space viewport corrdinates (-1 to 1)
+ const float ddelx_dx = 0.5 * W;
+ const float ddely_dy = 0.5 * H;
+
+ // Traverse all Gaussians
+ for (int i = 0; i < rounds; i++, toDo -= BLOCK_SIZE)
+ {
+ // Load auxiliary data into shared memory, start in the BACK
+ // and load them in revers order.
+ block.sync();
+ const int progress = i * BLOCK_SIZE + block.thread_rank();
+ if (range.x + progress < range.y)
+ {
+ const int coll_id = point_list[range.y - progress - 1];
+ collected_id[block.thread_rank()] = coll_id;
+ collected_xy[block.thread_rank()] = points_xy_image[coll_id];
+ collected_conic_opacity[block.thread_rank()] = conic_opacity[coll_id];
+ for (int i = 0; i < C; i++)
+ collected_colors[i * BLOCK_SIZE + block.thread_rank()] = colors[coll_id * C + i];
+ collected_depths[block.thread_rank()] = depths[coll_id];
+ }
+ block.sync();
+
+ // Iterate over Gaussians
+ for (int j = 0; !done && j < min(BLOCK_SIZE, toDo); j++)
+ {
+ // Keep track of current Gaussian ID. Skip, if this one
+ // is behind the last contributor for this pixel.
+ contributor--;
+ if (contributor >= last_contributor)
+ continue;
+
+ // Compute blending values, as before.
+ const float2 xy = collected_xy[j];
+ const float2 d = { xy.x - pixf.x, xy.y - pixf.y };
+ const float4 con_o = collected_conic_opacity[j];
+ const float power = -0.5f * (con_o.x * d.x * d.x + con_o.z * d.y * d.y) - con_o.y * d.x * d.y;
+ if (power > 0.0f)
+ continue;
+
+ const float G = exp(power);
+ const float alpha = min(0.99f, con_o.w * G);
+ if (alpha < 1.0f / 255.0f)
+ continue;
+
+ T = T / (1.f - alpha);
+ const float dchannel_dcolor = alpha * T;
+ const float dpixel_depth_ddepth = alpha * T;
+
+ // Propagate gradients to per-Gaussian colors and keep
+ // gradients w.r.t. alpha (blending factor for a Gaussian/pixel
+ // pair).
+ float dL_dopa = 0.0f;
+ const int global_id = collected_id[j];
+ for (int ch = 0; ch < C; ch++)
+ {
+ const float c = collected_colors[ch * BLOCK_SIZE + j];
+ // Update last color (to be used in the next iteration)
+ accum_rec[ch] = last_alpha * last_color[ch] + (1.f - last_alpha) * accum_rec[ch];
+ last_color[ch] = c;
+
+ const float dL_dchannel = dL_dpixel[ch];
+ dL_dopa += (c - accum_rec[ch]) * dL_dchannel;
+ // Update the gradients w.r.t. color of the Gaussian.
+ // Atomic, since this pixel is just one of potentially
+ // many that were affected by this Gaussian.
+ atomicAdd(&(dL_dcolors[global_id * C + ch]), dchannel_dcolor * dL_dchannel);
+ }
+
+ // Propagate gradients from pixel depth to opacity
+ const float c_d = collected_depths[j];
+ accum_depth_rec = last_alpha * last_depth + (1.f - last_alpha) * accum_depth_rec;
+ last_depth = c_d;
+ dL_dopa += (c_d - accum_depth_rec) * dL_dpixel_depth;
+ atomicAdd(&(dL_ddepths[global_id]), dpixel_depth_ddepth * dL_dpixel_depth);
+
+ // Propagate gradients from pixel alpha (weights_sum) to opacity
+ accum_alpha_rec = last_alpha + (1.f - last_alpha) * accum_alpha_rec;
+ dL_dopa += (1 - accum_alpha_rec) * dL_dalpha; //- (alpha - accum_alpha_rec) * dL_dalpha;
+
+ dL_dopa *= T;
+ // Update last alpha (to be used in the next iteration)
+ last_alpha = alpha;
+
+ // Account for fact that alpha also influences how much of
+ // the background color is added if nothing left to blend
+ float bg_dot_dpixel = 0;
+ for (int i = 0; i < C; i++)
+ bg_dot_dpixel += bg_color[i] * dL_dpixel[i];
+ dL_dopa += (-T_final / (1.f - alpha)) * bg_dot_dpixel;
+
+
+ // Helpful reusable temporary variables
+ const float dL_dG = con_o.w * dL_dopa;
+ const float gdx = G * d.x;
+ const float gdy = G * d.y;
+ const float dG_ddelx = -gdx * con_o.x - gdy * con_o.y;
+ const float dG_ddely = -gdy * con_o.z - gdx * con_o.y;
+
+ // Update gradients w.r.t. 2D mean position of the Gaussian
+ atomicAdd(&dL_dmean2D[global_id].x, dL_dG * dG_ddelx * ddelx_dx);
+ atomicAdd(&dL_dmean2D[global_id].y, dL_dG * dG_ddely * ddely_dy);
+
+ // Update gradients w.r.t. 2D covariance (2x2 matrix, symmetric)
+ atomicAdd(&dL_dconic2D[global_id].x, -0.5f * gdx * d.x * dL_dG);
+ atomicAdd(&dL_dconic2D[global_id].y, -0.5f * gdx * d.y * dL_dG);
+ atomicAdd(&dL_dconic2D[global_id].w, -0.5f * gdy * d.y * dL_dG);
+
+ // Update gradients w.r.t. opacity of the Gaussian
+ atomicAdd(&(dL_dopacity[global_id]), G * dL_dopa);
+ }
+ }
+}
+
+void BACKWARD::preprocess(
+ int P, int D, int M,
+ const float3* means3D,
+ const int* radii,
+ const float* shs,
+ const bool* clamped,
+ const glm::vec3* scales,
+ const glm::vec4* rotations,
+ const float scale_modifier,
+ const float* cov3Ds,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const float focal_x, float focal_y,
+ const float tan_fovx, float tan_fovy,
+ const glm::vec3* campos,
+ const float3* dL_dmean2D,
+ const float* dL_dconic,
+ glm::vec3* dL_dmean3D,
+ float* dL_dcolor,
+ float* dL_ddepth,
+ float* dL_dcov3D,
+ float* dL_dsh,
+ glm::vec3* dL_dscale,
+ glm::vec4* dL_drot)
+{
+ // Propagate gradients for the path of 2D conic matrix computation.
+ // Somewhat long, thus it is its own kernel rather than being part of
+ // "preprocess". When done, loss gradient w.r.t. 3D means has been
+ // modified and gradient w.r.t. 3D covariance matrix has been computed.
+ computeCov2DCUDA << <(P + 255) / 256, 256 >> > (
+ P,
+ means3D,
+ radii,
+ cov3Ds,
+ focal_x,
+ focal_y,
+ tan_fovx,
+ tan_fovy,
+ viewmatrix,
+ dL_dconic,
+ (float3*)dL_dmean3D,
+ dL_dcov3D);
+
+ // Propagate gradients for remaining steps: finish 3D mean gradients,
+ // propagate color gradients to SH (if desireD), propagate 3D covariance
+ // matrix gradients to scale and rotation.
+ preprocessCUDA << < (P + 255) / 256, 256 >> > (
+ P, D, M,
+ (float3*)means3D,
+ radii,
+ shs,
+ clamped,
+ (glm::vec3*)scales,
+ (glm::vec4*)rotations,
+ scale_modifier,
+ viewmatrix,
+ projmatrix,
+ campos,
+ (float3*)dL_dmean2D,
+ (glm::vec3*)dL_dmean3D,
+ dL_dcolor,
+ dL_ddepth,
+ dL_dcov3D,
+ dL_dsh,
+ dL_dscale,
+ dL_drot);
+}
+
+void BACKWARD::render(
+ const dim3 grid, const dim3 block,
+ const uint2* ranges,
+ const uint32_t* point_list,
+ int W, int H,
+ const float* bg_color,
+ const float2* means2D,
+ const float4* conic_opacity,
+ const float* colors,
+ const float* depths,
+ const float* alphas,
+ const uint32_t* n_contrib,
+ const float* dL_dpixels,
+ const float* dL_dpixel_depths,
+ const float* dL_dalphas,
+ float3* dL_dmean2D,
+ float4* dL_dconic2D,
+ float* dL_dopacity,
+ float* dL_dcolors,
+ float* dL_ddepths)
+{
+ renderCUDA << > >(
+ ranges,
+ point_list,
+ W, H,
+ bg_color,
+ means2D,
+ conic_opacity,
+ colors,
+ depths,
+ alphas,
+ n_contrib,
+ dL_dpixels,
+ dL_dpixel_depths,
+ dL_dalphas,
+ dL_dmean2D,
+ dL_dconic2D,
+ dL_dopacity,
+ dL_dcolors,
+ dL_ddepths
+ );
+}
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aa5e735b2a6e5bcfabd79e0c11ca8b252b2971f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/backward.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#ifndef CUDA_RASTERIZER_BACKWARD_H_INCLUDED
+#define CUDA_RASTERIZER_BACKWARD_H_INCLUDED
+
+#include
+#include "cuda_runtime.h"
+#include "device_launch_parameters.h"
+#define GLM_FORCE_CUDA
+#include
+
+namespace BACKWARD
+{
+ void render(
+ const dim3 grid, dim3 block,
+ const uint2* ranges,
+ const uint32_t* point_list,
+ int W, int H,
+ const float* bg_color,
+ const float2* means2D,
+ const float4* conic_opacity,
+ const float* colors,
+ const float* depths,
+ const float* alphas,
+ const uint32_t* n_contrib,
+ const float* dL_dpixels,
+ const float* dL_dpixel_depths,
+ const float* dL_dalphas,
+ float3* dL_dmean2D,
+ float4* dL_dconic2D,
+ float* dL_dopacity,
+ float* dL_dcolors,
+ float* dL_ddepths);
+
+ void preprocess(
+ int P, int D, int M,
+ const float3* means,
+ const int* radii,
+ const float* shs,
+ const bool* clamped,
+ const glm::vec3* scales,
+ const glm::vec4* rotations,
+ const float scale_modifier,
+ const float* cov3Ds,
+ const float* view,
+ const float* proj,
+ const float focal_x, float focal_y,
+ const float tan_fovx, float tan_fovy,
+ const glm::vec3* campos,
+ const float3* dL_dmean2D,
+ const float* dL_dconics,
+ glm::vec3* dL_dmeans,
+ float* dL_dcolor,
+ float* dL_ddepth,
+ float* dL_dcov3D,
+ float* dL_dsh,
+ glm::vec3* dL_dscale,
+ glm::vec4* dL_drot);
+}
+
+#endif
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/config.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/config.h
new file mode 100644
index 0000000000000000000000000000000000000000..68374144a79d881c58ba3ae1a903d9fd066351e0
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/config.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#ifndef CUDA_RASTERIZER_CONFIG_H_INCLUDED
+#define CUDA_RASTERIZER_CONFIG_H_INCLUDED
+
+#define NUM_CHANNELS 3 // Default 3, RGB
+#define BLOCK_X 16
+#define BLOCK_Y 16
+
+#endif
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.cu b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.cu
new file mode 100644
index 0000000000000000000000000000000000000000..4e493ddeaeace4a283613c42ba7b097a588aeee5
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.cu
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#include "forward.h"
+#include "auxiliary.h"
+#include
+#include
+namespace cg = cooperative_groups;
+
+// Forward method for converting the input spherical harmonics
+// coefficients of each Gaussian to a simple RGB color.
+__device__ glm::vec3 computeColorFromSH(int idx, int deg, int max_coeffs, const glm::vec3* means, glm::vec3 campos, const float* shs, bool* clamped)
+{
+ // The implementation is loosely based on code for
+ // "Differentiable Point-Based Radiance Fields for
+ // Efficient View Synthesis" by Zhang et al. (2022)
+ glm::vec3 pos = means[idx];
+ glm::vec3 dir = pos - campos;
+ dir = dir / glm::length(dir);
+
+ glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs;
+ glm::vec3 result = SH_C0 * sh[0];
+
+ if (deg > 0)
+ {
+ float x = dir.x;
+ float y = dir.y;
+ float z = dir.z;
+ result = result - SH_C1 * y * sh[1] + SH_C1 * z * sh[2] - SH_C1 * x * sh[3];
+
+ if (deg > 1)
+ {
+ float xx = x * x, yy = y * y, zz = z * z;
+ float xy = x * y, yz = y * z, xz = x * z;
+ result = result +
+ SH_C2[0] * xy * sh[4] +
+ SH_C2[1] * yz * sh[5] +
+ SH_C2[2] * (2.0f * zz - xx - yy) * sh[6] +
+ SH_C2[3] * xz * sh[7] +
+ SH_C2[4] * (xx - yy) * sh[8];
+
+ if (deg > 2)
+ {
+ result = result +
+ SH_C3[0] * y * (3.0f * xx - yy) * sh[9] +
+ SH_C3[1] * xy * z * sh[10] +
+ SH_C3[2] * y * (4.0f * zz - xx - yy) * sh[11] +
+ SH_C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * sh[12] +
+ SH_C3[4] * x * (4.0f * zz - xx - yy) * sh[13] +
+ SH_C3[5] * z * (xx - yy) * sh[14] +
+ SH_C3[6] * x * (xx - 3.0f * yy) * sh[15];
+ }
+ }
+ }
+ result += 0.5f;
+
+ // RGB colors are clamped to positive values. If values are
+ // clamped, we need to keep track of this for the backward pass.
+ clamped[3 * idx + 0] = (result.x < 0);
+ clamped[3 * idx + 1] = (result.y < 0);
+ clamped[3 * idx + 2] = (result.z < 0);
+ return glm::max(result, 0.0f);
+}
+
+// Forward version of 2D covariance matrix computation
+__device__ float3 computeCov2D(const float3& mean, float focal_x, float focal_y, float tan_fovx, float tan_fovy, const float* cov3D, const float* viewmatrix)
+{
+ // The following models the steps outlined by equations 29
+ // and 31 in "EWA Splatting" (Zwicker et al., 2002).
+ // Additionally considers aspect / scaling of viewport.
+ // Transposes used to account for row-/column-major conventions.
+ float3 t = transformPoint4x3(mean, viewmatrix);
+
+ const float limx = 1.3f * tan_fovx;
+ const float limy = 1.3f * tan_fovy;
+ const float txtz = t.x / t.z;
+ const float tytz = t.y / t.z;
+ t.x = min(limx, max(-limx, txtz)) * t.z;
+ t.y = min(limy, max(-limy, tytz)) * t.z;
+
+ glm::mat3 J = glm::mat3(
+ focal_x / t.z, 0.0f, -(focal_x * t.x) / (t.z * t.z),
+ 0.0f, focal_y / t.z, -(focal_y * t.y) / (t.z * t.z),
+ 0, 0, 0);
+
+ glm::mat3 W = glm::mat3(
+ viewmatrix[0], viewmatrix[4], viewmatrix[8],
+ viewmatrix[1], viewmatrix[5], viewmatrix[9],
+ viewmatrix[2], viewmatrix[6], viewmatrix[10]);
+
+ glm::mat3 T = W * J;
+
+ glm::mat3 Vrk = glm::mat3(
+ cov3D[0], cov3D[1], cov3D[2],
+ cov3D[1], cov3D[3], cov3D[4],
+ cov3D[2], cov3D[4], cov3D[5]);
+
+ glm::mat3 cov = glm::transpose(T) * glm::transpose(Vrk) * T;
+
+ // Apply low-pass filter: every Gaussian should be at least
+ // one pixel wide/high. Discard 3rd row and column.
+ cov[0][0] += 0.3f;
+ cov[1][1] += 0.3f;
+ return { float(cov[0][0]), float(cov[0][1]), float(cov[1][1]) };
+}
+
+// Forward method for converting scale and rotation properties of each
+// Gaussian to a 3D covariance matrix in world space. Also takes care
+// of quaternion normalization.
+__device__ void computeCov3D(const glm::vec3 scale, float mod, const glm::vec4 rot, float* cov3D)
+{
+ // Create scaling matrix
+ glm::mat3 S = glm::mat3(1.0f);
+ S[0][0] = mod * scale.x;
+ S[1][1] = mod * scale.y;
+ S[2][2] = mod * scale.z;
+
+ // Normalize quaternion to get valid rotation
+ glm::vec4 q = rot;// / glm::length(rot);
+ float r = q.x;
+ float x = q.y;
+ float y = q.z;
+ float z = q.w;
+
+ // Compute rotation matrix from quaternion
+ glm::mat3 R = glm::mat3(
+ 1.f - 2.f * (y * y + z * z), 2.f * (x * y - r * z), 2.f * (x * z + r * y),
+ 2.f * (x * y + r * z), 1.f - 2.f * (x * x + z * z), 2.f * (y * z - r * x),
+ 2.f * (x * z - r * y), 2.f * (y * z + r * x), 1.f - 2.f * (x * x + y * y)
+ );
+
+ glm::mat3 M = S * R;
+
+ // Compute 3D world covariance matrix Sigma
+ glm::mat3 Sigma = glm::transpose(M) * M;
+
+ // Covariance is symmetric, only store upper right
+ cov3D[0] = Sigma[0][0];
+ cov3D[1] = Sigma[0][1];
+ cov3D[2] = Sigma[0][2];
+ cov3D[3] = Sigma[1][1];
+ cov3D[4] = Sigma[1][2];
+ cov3D[5] = Sigma[2][2];
+}
+
+// Perform initial steps for each Gaussian prior to rasterization.
+template
+__global__ void preprocessCUDA(int P, int D, int M,
+ const float* orig_points,
+ const glm::vec3* scales,
+ const float scale_modifier,
+ const glm::vec4* rotations,
+ const float* opacities,
+ const float* shs,
+ bool* clamped,
+ const float* cov3D_precomp,
+ const float* colors_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const glm::vec3* cam_pos,
+ const int W, int H,
+ const float tan_fovx, float tan_fovy,
+ const float focal_x, float focal_y,
+ int* radii,
+ float2* points_xy_image,
+ float* depths,
+ float* cov3Ds,
+ float* rgb,
+ float4* conic_opacity,
+ const dim3 grid,
+ uint32_t* tiles_touched,
+ bool prefiltered)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= P)
+ return;
+
+ // Initialize radius and touched tiles to 0. If this isn't changed,
+ // this Gaussian will not be processed further.
+ radii[idx] = 0;
+ tiles_touched[idx] = 0;
+
+ // Perform near culling, quit if outside.
+ float3 p_view;
+ if (!in_frustum(idx, orig_points, viewmatrix, projmatrix, prefiltered, p_view))
+ return;
+
+ // Transform point by projecting
+ float3 p_orig = { orig_points[3 * idx], orig_points[3 * idx + 1], orig_points[3 * idx + 2] };
+ float4 p_hom = transformPoint4x4(p_orig, projmatrix);
+ float p_w = 1.0f / (p_hom.w + 0.0000001f);
+ float3 p_proj = { p_hom.x * p_w, p_hom.y * p_w, p_hom.z * p_w };
+
+ // If 3D covariance matrix is precomputed, use it, otherwise compute
+ // from scaling and rotation parameters.
+ const float* cov3D;
+ if (cov3D_precomp != nullptr)
+ {
+ cov3D = cov3D_precomp + idx * 6;
+ }
+ else
+ {
+ computeCov3D(scales[idx], scale_modifier, rotations[idx], cov3Ds + idx * 6);
+ cov3D = cov3Ds + idx * 6;
+ }
+
+ // Compute 2D screen-space covariance matrix
+ float3 cov = computeCov2D(p_orig, focal_x, focal_y, tan_fovx, tan_fovy, cov3D, viewmatrix);
+
+ // Invert covariance (EWA algorithm)
+ float det = (cov.x * cov.z - cov.y * cov.y);
+ if (det == 0.0f)
+ return;
+ float det_inv = 1.f / det;
+ float3 conic = { cov.z * det_inv, -cov.y * det_inv, cov.x * det_inv };
+
+ // Compute extent in screen space (by finding eigenvalues of
+ // 2D covariance matrix). Use extent to compute a bounding rectangle
+ // of screen-space tiles that this Gaussian overlaps with. Quit if
+ // rectangle covers 0 tiles.
+ float mid = 0.5f * (cov.x + cov.z);
+ float lambda1 = mid + sqrt(max(0.1f, mid * mid - det));
+ float lambda2 = mid - sqrt(max(0.1f, mid * mid - det));
+ float my_radius = ceil(3.f * sqrt(max(lambda1, lambda2)));
+ float2 point_image = { ndc2Pix(p_proj.x, W), ndc2Pix(p_proj.y, H) };
+ uint2 rect_min, rect_max;
+ getRect(point_image, my_radius, rect_min, rect_max, grid);
+ if ((rect_max.x - rect_min.x) * (rect_max.y - rect_min.y) == 0)
+ return;
+
+ // If colors have been precomputed, use them, otherwise convert
+ // spherical harmonics coefficients to RGB color.
+ if (colors_precomp == nullptr)
+ {
+ glm::vec3 result = computeColorFromSH(idx, D, M, (glm::vec3*)orig_points, *cam_pos, shs, clamped);
+ rgb[idx * C + 0] = result.x;
+ rgb[idx * C + 1] = result.y;
+ rgb[idx * C + 2] = result.z;
+ }
+
+ // Store some useful helper data for the next steps.
+ depths[idx] = p_view.z;
+ radii[idx] = my_radius;
+ points_xy_image[idx] = point_image;
+ // Inverse 2D covariance and opacity neatly pack into one float4
+ conic_opacity[idx] = { conic.x, conic.y, conic.z, opacities[idx] };
+ tiles_touched[idx] = (rect_max.y - rect_min.y) * (rect_max.x - rect_min.x);
+}
+
+// Main rasterization method. Collaboratively works on one tile per
+// block, each thread treats one pixel. Alternates between fetching
+// and rasterizing data.
+template
+__global__ void __launch_bounds__(BLOCK_X * BLOCK_Y)
+renderCUDA(
+ const uint2* __restrict__ ranges,
+ const uint32_t* __restrict__ point_list,
+ int W, int H,
+ const float2* __restrict__ points_xy_image,
+ const float* __restrict__ features,
+ const float* __restrict__ depths,
+ const float4* __restrict__ conic_opacity,
+ float* __restrict__ out_alpha,
+ uint32_t* __restrict__ n_contrib,
+ const float* __restrict__ bg_color,
+ float* __restrict__ out_color,
+ float* __restrict__ out_depth)
+{
+ // Identify current tile and associated min/max pixel range.
+ auto block = cg::this_thread_block();
+ uint32_t horizontal_blocks = (W + BLOCK_X - 1) / BLOCK_X;
+ uint2 pix_min = { block.group_index().x * BLOCK_X, block.group_index().y * BLOCK_Y };
+ uint2 pix_max = { min(pix_min.x + BLOCK_X, W), min(pix_min.y + BLOCK_Y , H) };
+ uint2 pix = { pix_min.x + block.thread_index().x, pix_min.y + block.thread_index().y };
+ uint32_t pix_id = W * pix.y + pix.x;
+ float2 pixf = { (float)pix.x, (float)pix.y };
+
+ // Check if this thread is associated with a valid pixel or outside.
+ bool inside = pix.x < W&& pix.y < H;
+ // Done threads can help with fetching, but don't rasterize
+ bool done = !inside;
+
+ // Load start/end range of IDs to process in bit sorted list.
+ uint2 range = ranges[block.group_index().y * horizontal_blocks + block.group_index().x];
+ const int rounds = ((range.y - range.x + BLOCK_SIZE - 1) / BLOCK_SIZE);
+ int toDo = range.y - range.x;
+
+ // Allocate storage for batches of collectively fetched data.
+ __shared__ int collected_id[BLOCK_SIZE];
+ __shared__ float2 collected_xy[BLOCK_SIZE];
+ __shared__ float4 collected_conic_opacity[BLOCK_SIZE];
+
+ // Initialize helper variables
+ float T = 1.0f;
+ uint32_t contributor = 0;
+ uint32_t last_contributor = 0;
+ float C[CHANNELS] = { 0 };
+ float weight = 0;
+ float D = 0;
+
+ // Iterate over batches until all done or range is complete
+ for (int i = 0; i < rounds; i++, toDo -= BLOCK_SIZE)
+ {
+ // End if entire block votes that it is done rasterizing
+ int num_done = __syncthreads_count(done);
+ if (num_done == BLOCK_SIZE)
+ break;
+
+ // Collectively fetch per-Gaussian data from global to shared
+ int progress = i * BLOCK_SIZE + block.thread_rank();
+ if (range.x + progress < range.y)
+ {
+ int coll_id = point_list[range.x + progress];
+ collected_id[block.thread_rank()] = coll_id;
+ collected_xy[block.thread_rank()] = points_xy_image[coll_id];
+ collected_conic_opacity[block.thread_rank()] = conic_opacity[coll_id];
+ }
+ block.sync();
+
+ // Iterate over current batch
+ for (int j = 0; !done && j < min(BLOCK_SIZE, toDo); j++)
+ {
+ // Keep track of current position in range
+ contributor++;
+
+ // Resample using conic matrix (cf. "Surface
+ // Splatting" by Zwicker et al., 2001)
+ float2 xy = collected_xy[j];
+ float2 d = { xy.x - pixf.x, xy.y - pixf.y };
+ float4 con_o = collected_conic_opacity[j];
+ float power = -0.5f * (con_o.x * d.x * d.x + con_o.z * d.y * d.y) - con_o.y * d.x * d.y;
+ if (power > 0.0f)
+ continue;
+
+ // Eq. (2) from 3D Gaussian splatting paper.
+ // Obtain alpha by multiplying with Gaussian opacity
+ // and its exponential falloff from mean.
+ // Avoid numerical instabilities (see paper appendix).
+ float alpha = min(0.99f, con_o.w * exp(power));
+ if (alpha < 1.0f / 255.0f)
+ continue;
+ float test_T = T * (1 - alpha);
+ if (test_T < 0.0001f)
+ {
+ done = true;
+ continue;
+ }
+
+ // Eq. (3) from 3D Gaussian splatting paper.
+ for (int ch = 0; ch < CHANNELS; ch++)
+ C[ch] += features[collected_id[j] * CHANNELS + ch] * alpha * T;
+ weight += alpha * T;
+ D += depths[collected_id[j]] * alpha * T;
+
+ T = test_T;
+
+ // Keep track of last range entry to update this
+ // pixel.
+ last_contributor = contributor;
+ }
+ }
+
+ // All threads that treat valid pixel write out their final
+ // rendering data to the frame and auxiliary buffers.
+ if (inside)
+ {
+ n_contrib[pix_id] = last_contributor;
+ for (int ch = 0; ch < CHANNELS; ch++)
+ out_color[ch * H * W + pix_id] = C[ch] + T * bg_color[ch];
+ out_alpha[pix_id] = weight; //1 - T;
+ out_depth[pix_id] = D;
+ }
+}
+
+void FORWARD::render(
+ const dim3 grid, dim3 block,
+ const uint2* ranges,
+ const uint32_t* point_list,
+ int W, int H,
+ const float2* means2D,
+ const float* colors,
+ const float* depths,
+ const float4* conic_opacity,
+ float* out_alpha,
+ uint32_t* n_contrib,
+ const float* bg_color,
+ float* out_color,
+ float* out_depth)
+{
+ renderCUDA << > > (
+ ranges,
+ point_list,
+ W, H,
+ means2D,
+ colors,
+ depths,
+ conic_opacity,
+ out_alpha,
+ n_contrib,
+ bg_color,
+ out_color,
+ out_depth);
+}
+
+void FORWARD::preprocess(int P, int D, int M,
+ const float* means3D,
+ const glm::vec3* scales,
+ const float scale_modifier,
+ const glm::vec4* rotations,
+ const float* opacities,
+ const float* shs,
+ bool* clamped,
+ const float* cov3D_precomp,
+ const float* colors_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const glm::vec3* cam_pos,
+ const int W, int H,
+ const float focal_x, float focal_y,
+ const float tan_fovx, float tan_fovy,
+ int* radii,
+ float2* means2D,
+ float* depths,
+ float* cov3Ds,
+ float* rgb,
+ float4* conic_opacity,
+ const dim3 grid,
+ uint32_t* tiles_touched,
+ bool prefiltered)
+{
+ preprocessCUDA << <(P + 255) / 256, 256 >> > (
+ P, D, M,
+ means3D,
+ scales,
+ scale_modifier,
+ rotations,
+ opacities,
+ shs,
+ clamped,
+ cov3D_precomp,
+ colors_precomp,
+ viewmatrix,
+ projmatrix,
+ cam_pos,
+ W, H,
+ tan_fovx, tan_fovy,
+ focal_x, focal_y,
+ radii,
+ means2D,
+ depths,
+ cov3Ds,
+ rgb,
+ conic_opacity,
+ grid,
+ tiles_touched,
+ prefiltered
+ );
+}
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.h
new file mode 100644
index 0000000000000000000000000000000000000000..71955f95d16fb32a3f7a70512be7ed269f06d0d4
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/forward.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#ifndef CUDA_RASTERIZER_FORWARD_H_INCLUDED
+#define CUDA_RASTERIZER_FORWARD_H_INCLUDED
+
+#include
+#include "cuda_runtime.h"
+#include "device_launch_parameters.h"
+#define GLM_FORCE_CUDA
+#include
+
+namespace FORWARD
+{
+ // Perform initial steps for each Gaussian prior to rasterization.
+ void preprocess(int P, int D, int M,
+ const float* orig_points,
+ const glm::vec3* scales,
+ const float scale_modifier,
+ const glm::vec4* rotations,
+ const float* opacities,
+ const float* shs,
+ bool* clamped,
+ const float* cov3D_precomp,
+ const float* colors_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const glm::vec3* cam_pos,
+ const int W, int H,
+ const float focal_x, float focal_y,
+ const float tan_fovx, float tan_fovy,
+ int* radii,
+ float2* points_xy_image,
+ float* depths,
+ float* cov3Ds,
+ float* colors,
+ float4* conic_opacity,
+ const dim3 grid,
+ uint32_t* tiles_touched,
+ bool prefiltered);
+
+ // Main rasterization method.
+ void render(
+ const dim3 grid, dim3 block,
+ const uint2* ranges,
+ const uint32_t* point_list,
+ int W, int H,
+ const float2* points_xy_image,
+ const float* features,
+ const float* depths,
+ const float4* conic_opacity,
+ float* out_alpha,
+ uint32_t* n_contrib,
+ const float* bg_color,
+ float* out_color,
+ float* out_depth);
+}
+
+
+#endif
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..3458eb4520b5990e4b5bdc2f4de42ecde45dbe9f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#ifndef CUDA_RASTERIZER_H_INCLUDED
+#define CUDA_RASTERIZER_H_INCLUDED
+
+#include
+#include
+
+namespace CudaRasterizer
+{
+ class Rasterizer
+ {
+ public:
+
+ static void markVisible(
+ int P,
+ float* means3D,
+ float* viewmatrix,
+ float* projmatrix,
+ bool* present);
+
+ static int forward(
+ std::function geometryBuffer,
+ std::function binningBuffer,
+ std::function imageBuffer,
+ const int P, int D, int M,
+ const float* background,
+ const int width, int height,
+ const float* means3D,
+ const float* shs,
+ const float* colors_precomp,
+ const float* opacities,
+ const float* scales,
+ const float scale_modifier,
+ const float* rotations,
+ const float* cov3D_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const float* cam_pos,
+ const float tan_fovx, float tan_fovy,
+ const bool prefiltered,
+ float* out_color,
+ float* out_depth,
+ float* out_alpha,
+ int* radii = nullptr,
+ bool debug = false);
+
+ static void backward(
+ const int P, int D, int M, int R,
+ const float* background,
+ const int width, int height,
+ const float* means3D,
+ const float* shs,
+ const float* colors_precomp,
+ const float* alphas,
+ const float* scales,
+ const float scale_modifier,
+ const float* rotations,
+ const float* cov3D_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const float* campos,
+ const float tan_fovx, float tan_fovy,
+ const int* radii,
+ char* geom_buffer,
+ char* binning_buffer,
+ char* image_buffer,
+ const float* dL_dpix,
+ const float* dL_dpix_depth,
+ const float* dL_dalphas,
+ float* dL_dmean2D,
+ float* dL_dconic,
+ float* dL_dopacity,
+ float* dL_dcolor,
+ float* dL_ddepth,
+ float* dL_dmean3D,
+ float* dL_dcov3D,
+ float* dL_dsh,
+ float* dL_dscale,
+ float* dL_drot,
+ bool debug);
+ };
+};
+
+#endif
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.cu b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.cu
new file mode 100644
index 0000000000000000000000000000000000000000..13d30b896639d28c5ebe1ec9f9c87dca97226eae
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.cu
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#include "rasterizer_impl.h"
+#include
+#include
+#include
+#include
+#include
+#include "cuda_runtime.h"
+#include "device_launch_parameters.h"
+#include
+#include
+#define GLM_FORCE_CUDA
+#include
+
+#include
+#include
+namespace cg = cooperative_groups;
+
+#include "auxiliary.h"
+#include "forward.h"
+#include "backward.h"
+
+// Helper function to find the next-highest bit of the MSB
+// on the CPU.
+uint32_t getHigherMsb(uint32_t n)
+{
+ uint32_t msb = sizeof(n) * 4;
+ uint32_t step = msb;
+ while (step > 1)
+ {
+ step /= 2;
+ if (n >> msb)
+ msb += step;
+ else
+ msb -= step;
+ }
+ if (n >> msb)
+ msb++;
+ return msb;
+}
+
+// Wrapper method to call auxiliary coarse frustum containment test.
+// Mark all Gaussians that pass it.
+__global__ void checkFrustum(int P,
+ const float* orig_points,
+ const float* viewmatrix,
+ const float* projmatrix,
+ bool* present)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= P)
+ return;
+
+ float3 p_view;
+ present[idx] = in_frustum(idx, orig_points, viewmatrix, projmatrix, false, p_view);
+}
+
+// Generates one key/value pair for all Gaussian / tile overlaps.
+// Run once per Gaussian (1:N mapping).
+__global__ void duplicateWithKeys(
+ int P,
+ const float2* points_xy,
+ const float* depths,
+ const uint32_t* offsets,
+ uint64_t* gaussian_keys_unsorted,
+ uint32_t* gaussian_values_unsorted,
+ int* radii,
+ dim3 grid)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= P)
+ return;
+
+ // Generate no key/value pair for invisible Gaussians
+ if (radii[idx] > 0)
+ {
+ // Find this Gaussian's offset in buffer for writing keys/values.
+ uint32_t off = (idx == 0) ? 0 : offsets[idx - 1];
+ uint2 rect_min, rect_max;
+
+ getRect(points_xy[idx], radii[idx], rect_min, rect_max, grid);
+
+ // For each tile that the bounding rect overlaps, emit a
+ // key/value pair. The key is | tile ID | depth |,
+ // and the value is the ID of the Gaussian. Sorting the values
+ // with this key yields Gaussian IDs in a list, such that they
+ // are first sorted by tile and then by depth.
+ for (int y = rect_min.y; y < rect_max.y; y++)
+ {
+ for (int x = rect_min.x; x < rect_max.x; x++)
+ {
+ uint64_t key = y * grid.x + x;
+ key <<= 32;
+ key |= *((uint32_t*)&depths[idx]);
+ gaussian_keys_unsorted[off] = key;
+ gaussian_values_unsorted[off] = idx;
+ off++;
+ }
+ }
+ }
+}
+
+// Check keys to see if it is at the start/end of one tile's range in
+// the full sorted list. If yes, write start/end of this tile.
+// Run once per instanced (duplicated) Gaussian ID.
+__global__ void identifyTileRanges(int L, uint64_t* point_list_keys, uint2* ranges)
+{
+ auto idx = cg::this_grid().thread_rank();
+ if (idx >= L)
+ return;
+
+ // Read tile ID from key. Update start/end of tile range if at limit.
+ uint64_t key = point_list_keys[idx];
+ uint32_t currtile = key >> 32;
+ if (idx == 0)
+ ranges[currtile].x = 0;
+ else
+ {
+ uint32_t prevtile = point_list_keys[idx - 1] >> 32;
+ if (currtile != prevtile)
+ {
+ ranges[prevtile].y = idx;
+ ranges[currtile].x = idx;
+ }
+ }
+ if (idx == L - 1)
+ ranges[currtile].y = L;
+}
+
+// Mark Gaussians as visible/invisible, based on view frustum testing
+void CudaRasterizer::Rasterizer::markVisible(
+ int P,
+ float* means3D,
+ float* viewmatrix,
+ float* projmatrix,
+ bool* present)
+{
+ checkFrustum << <(P + 255) / 256, 256 >> > (
+ P,
+ means3D,
+ viewmatrix, projmatrix,
+ present);
+}
+
+CudaRasterizer::GeometryState CudaRasterizer::GeometryState::fromChunk(char*& chunk, size_t P)
+{
+ GeometryState geom;
+ obtain(chunk, geom.depths, P, 128);
+ obtain(chunk, geom.clamped, P * 3, 128);
+ obtain(chunk, geom.internal_radii, P, 128);
+ obtain(chunk, geom.means2D, P, 128);
+ obtain(chunk, geom.cov3D, P * 6, 128);
+ obtain(chunk, geom.conic_opacity, P, 128);
+ obtain(chunk, geom.rgb, P * 3, 128);
+ obtain(chunk, geom.tiles_touched, P, 128);
+ cub::DeviceScan::InclusiveSum(nullptr, geom.scan_size, geom.tiles_touched, geom.tiles_touched, P);
+ obtain(chunk, geom.scanning_space, geom.scan_size, 128);
+ obtain(chunk, geom.point_offsets, P, 128);
+ return geom;
+}
+
+CudaRasterizer::ImageState CudaRasterizer::ImageState::fromChunk(char*& chunk, size_t N)
+{
+ ImageState img;
+ obtain(chunk, img.n_contrib, N, 128);
+ obtain(chunk, img.ranges, N, 128);
+ return img;
+}
+
+CudaRasterizer::BinningState CudaRasterizer::BinningState::fromChunk(char*& chunk, size_t P)
+{
+ BinningState binning;
+ obtain(chunk, binning.point_list, P, 128);
+ obtain(chunk, binning.point_list_unsorted, P, 128);
+ obtain(chunk, binning.point_list_keys, P, 128);
+ obtain(chunk, binning.point_list_keys_unsorted, P, 128);
+ cub::DeviceRadixSort::SortPairs(
+ nullptr, binning.sorting_size,
+ binning.point_list_keys_unsorted, binning.point_list_keys,
+ binning.point_list_unsorted, binning.point_list, P);
+ obtain(chunk, binning.list_sorting_space, binning.sorting_size, 128);
+ return binning;
+}
+
+// Forward rendering procedure for differentiable rasterization
+// of Gaussians.
+int CudaRasterizer::Rasterizer::forward(
+ std::function geometryBuffer,
+ std::function binningBuffer,
+ std::function imageBuffer,
+ const int P, int D, int M,
+ const float* background,
+ const int width, int height,
+ const float* means3D,
+ const float* shs,
+ const float* colors_precomp,
+ const float* opacities,
+ const float* scales,
+ const float scale_modifier,
+ const float* rotations,
+ const float* cov3D_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const float* cam_pos,
+ const float tan_fovx, float tan_fovy,
+ const bool prefiltered,
+ float* out_color,
+ float* out_depth,
+ float* out_alpha,
+ int* radii,
+ bool debug)
+{
+ const float focal_y = height / (2.0f * tan_fovy);
+ const float focal_x = width / (2.0f * tan_fovx);
+
+ size_t chunk_size = required(P);
+ char* chunkptr = geometryBuffer(chunk_size);
+ GeometryState geomState = GeometryState::fromChunk(chunkptr, P);
+
+ if (radii == nullptr)
+ {
+ radii = geomState.internal_radii;
+ }
+
+ dim3 tile_grid((width + BLOCK_X - 1) / BLOCK_X, (height + BLOCK_Y - 1) / BLOCK_Y, 1);
+ dim3 block(BLOCK_X, BLOCK_Y, 1);
+
+ // Dynamically resize image-based auxiliary buffers during training
+ size_t img_chunk_size = required(width * height);
+ char* img_chunkptr = imageBuffer(img_chunk_size);
+ ImageState imgState = ImageState::fromChunk(img_chunkptr, width * height);
+
+ if (NUM_CHANNELS != 3 && colors_precomp == nullptr)
+ {
+ throw std::runtime_error("For non-RGB, provide precomputed Gaussian colors!");
+ }
+
+ // Run preprocessing per-Gaussian (transformation, bounding, conversion of SHs to RGB)
+ CHECK_CUDA(FORWARD::preprocess(
+ P, D, M,
+ means3D,
+ (glm::vec3*)scales,
+ scale_modifier,
+ (glm::vec4*)rotations,
+ opacities,
+ shs,
+ geomState.clamped,
+ cov3D_precomp,
+ colors_precomp,
+ viewmatrix, projmatrix,
+ (glm::vec3*)cam_pos,
+ width, height,
+ focal_x, focal_y,
+ tan_fovx, tan_fovy,
+ radii,
+ geomState.means2D,
+ geomState.depths,
+ geomState.cov3D,
+ geomState.rgb,
+ geomState.conic_opacity,
+ tile_grid,
+ geomState.tiles_touched,
+ prefiltered
+ ), debug)
+
+ // Compute prefix sum over full list of touched tile counts by Gaussians
+ // E.g., [2, 3, 0, 2, 1] -> [2, 5, 5, 7, 8]
+ CHECK_CUDA(cub::DeviceScan::InclusiveSum(geomState.scanning_space, geomState.scan_size, geomState.tiles_touched, geomState.point_offsets, P), debug)
+
+ // Retrieve total number of Gaussian instances to launch and resize aux buffers
+ int num_rendered;
+ CHECK_CUDA(cudaMemcpy(&num_rendered, geomState.point_offsets + P - 1, sizeof(int), cudaMemcpyDeviceToHost), debug);
+
+ size_t binning_chunk_size = required(num_rendered);
+ char* binning_chunkptr = binningBuffer(binning_chunk_size);
+ BinningState binningState = BinningState::fromChunk(binning_chunkptr, num_rendered);
+
+ // For each instance to be rendered, produce adequate [ tile | depth ] key
+ // and corresponding dublicated Gaussian indices to be sorted
+ duplicateWithKeys << <(P + 255) / 256, 256 >> > (
+ P,
+ geomState.means2D,
+ geomState.depths,
+ geomState.point_offsets,
+ binningState.point_list_keys_unsorted,
+ binningState.point_list_unsorted,
+ radii,
+ tile_grid)
+ CHECK_CUDA(, debug)
+
+ int bit = getHigherMsb(tile_grid.x * tile_grid.y);
+
+ // Sort complete list of (duplicated) Gaussian indices by keys
+ CHECK_CUDA(cub::DeviceRadixSort::SortPairs(
+ binningState.list_sorting_space,
+ binningState.sorting_size,
+ binningState.point_list_keys_unsorted, binningState.point_list_keys,
+ binningState.point_list_unsorted, binningState.point_list,
+ num_rendered, 0, 32 + bit), debug)
+
+ CHECK_CUDA(cudaMemset(imgState.ranges, 0, tile_grid.x * tile_grid.y * sizeof(uint2)), debug);
+
+ // Identify start and end of per-tile workloads in sorted list
+ if (num_rendered > 0)
+ identifyTileRanges << <(num_rendered + 255) / 256, 256 >> > (
+ num_rendered,
+ binningState.point_list_keys,
+ imgState.ranges);
+ CHECK_CUDA(, debug);
+
+ // Let each tile blend its range of Gaussians independently in parallel
+ const float* feature_ptr = colors_precomp != nullptr ? colors_precomp : geomState.rgb;
+ CHECK_CUDA(FORWARD::render(
+ tile_grid, block,
+ imgState.ranges,
+ binningState.point_list,
+ width, height,
+ geomState.means2D,
+ feature_ptr,
+ geomState.depths,
+ geomState.conic_opacity,
+ out_alpha,
+ imgState.n_contrib,
+ background,
+ out_color,
+ out_depth), debug);
+
+ return num_rendered;
+}
+
+// Produce necessary gradients for optimization, corresponding
+// to forward render pass
+void CudaRasterizer::Rasterizer::backward(
+ const int P, int D, int M, int R,
+ const float* background,
+ const int width, int height,
+ const float* means3D,
+ const float* shs,
+ const float* colors_precomp,
+ const float* alphas,
+ const float* scales,
+ const float scale_modifier,
+ const float* rotations,
+ const float* cov3D_precomp,
+ const float* viewmatrix,
+ const float* projmatrix,
+ const float* campos,
+ const float tan_fovx, float tan_fovy,
+ const int* radii,
+ char* geom_buffer,
+ char* binning_buffer,
+ char* img_buffer,
+ const float* dL_dpix,
+ const float* dL_dpix_depth,
+ const float* dL_dalphas,
+ float* dL_dmean2D,
+ float* dL_dconic,
+ float* dL_dopacity,
+ float* dL_dcolor,
+ float* dL_ddepth,
+ float* dL_dmean3D,
+ float* dL_dcov3D,
+ float* dL_dsh,
+ float* dL_dscale,
+ float* dL_drot,
+ bool debug)
+{
+ GeometryState geomState = GeometryState::fromChunk(geom_buffer, P);
+ BinningState binningState = BinningState::fromChunk(binning_buffer, R);
+ ImageState imgState = ImageState::fromChunk(img_buffer, width * height);
+
+ if (radii == nullptr)
+ {
+ radii = geomState.internal_radii;
+ }
+
+ const float focal_y = height / (2.0f * tan_fovy);
+ const float focal_x = width / (2.0f * tan_fovx);
+
+ const dim3 tile_grid((width + BLOCK_X - 1) / BLOCK_X, (height + BLOCK_Y - 1) / BLOCK_Y, 1);
+ const dim3 block(BLOCK_X, BLOCK_Y, 1);
+
+ // Compute loss gradients w.r.t. 2D mean position, conic matrix,
+ // opacity and RGB of Gaussians from per-pixel loss gradients.
+ // If we were given precomputed colors and not SHs, use them.
+ const float* color_ptr = (colors_precomp != nullptr) ? colors_precomp : geomState.rgb;
+ const float* depth_ptr = geomState.depths;
+ CHECK_CUDA(BACKWARD::render(
+ tile_grid,
+ block,
+ imgState.ranges,
+ binningState.point_list,
+ width, height,
+ background,
+ geomState.means2D,
+ geomState.conic_opacity,
+ color_ptr,
+ depth_ptr,
+ alphas,
+ imgState.n_contrib,
+ dL_dpix,
+ dL_dpix_depth,
+ dL_dalphas,
+ (float3*)dL_dmean2D,
+ (float4*)dL_dconic,
+ dL_dopacity,
+ dL_dcolor,
+ dL_ddepth), debug)
+
+ // Take care of the rest of preprocessing. Was the precomputed covariance
+ // given to us or a scales/rot pair? If precomputed, pass that. If not,
+ // use the one we computed ourselves.
+ const float* cov3D_ptr = (cov3D_precomp != nullptr) ? cov3D_precomp : geomState.cov3D;
+ CHECK_CUDA(BACKWARD::preprocess(P, D, M,
+ (float3*)means3D,
+ radii,
+ shs,
+ geomState.clamped,
+ (glm::vec3*)scales,
+ (glm::vec4*)rotations,
+ scale_modifier,
+ cov3D_ptr,
+ viewmatrix,
+ projmatrix,
+ focal_x, focal_y,
+ tan_fovx, tan_fovy,
+ (glm::vec3*)campos,
+ (float3*)dL_dmean2D,
+ dL_dconic,
+ (glm::vec3*)dL_dmean3D,
+ dL_dcolor,
+ dL_ddepth,
+ dL_dcov3D,
+ dL_dsh,
+ (glm::vec3*)dL_dscale,
+ (glm::vec4*)dL_drot), debug)
+}
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..13dd5ec3d256dba0e6ea0d9ee9468bda21ed0632
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/cuda_rasterizer/rasterizer_impl.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#pragma once
+
+#include
+#include
+#include "rasterizer.h"
+#include
+
+namespace CudaRasterizer
+{
+ template
+ static void obtain(char*& chunk, T*& ptr, std::size_t count, std::size_t alignment)
+ {
+ std::size_t offset = (reinterpret_cast(chunk) + alignment - 1) & ~(alignment - 1);
+ ptr = reinterpret_cast(offset);
+ chunk = reinterpret_cast(ptr + count);
+ }
+
+ struct GeometryState
+ {
+ size_t scan_size;
+ float* depths;
+ char* scanning_space;
+ bool* clamped;
+ int* internal_radii;
+ float2* means2D;
+ float* cov3D;
+ float4* conic_opacity;
+ float* rgb;
+ uint32_t* point_offsets;
+ uint32_t* tiles_touched;
+
+ static GeometryState fromChunk(char*& chunk, size_t P);
+ };
+
+ struct ImageState
+ {
+ uint2* ranges;
+ uint32_t* n_contrib;
+
+ static ImageState fromChunk(char*& chunk, size_t N);
+ };
+
+ struct BinningState
+ {
+ size_t sorting_size;
+ uint64_t* point_list_keys_unsorted;
+ uint64_t* point_list_keys;
+ uint32_t* point_list_unsorted;
+ uint32_t* point_list;
+ char* list_sorting_space;
+
+ static BinningState fromChunk(char*& chunk, size_t P);
+ };
+
+ template
+ size_t required(size_t P)
+ {
+ char* size = nullptr;
+ T::fromChunk(size, P);
+ return ((size_t)size) + 128;
+ }
+};
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/diff_gaussian_rasterization_depth_alpha/__init__.py b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/diff_gaussian_rasterization_depth_alpha/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..c10d152357429e1b30e2b38d0f8e3ca0f3906839
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/diff_gaussian_rasterization_depth_alpha/__init__.py
@@ -0,0 +1,224 @@
+#
+# Copyright (C) 2023, Inria
+# GRAPHDECO research group, https://team.inria.fr/graphdeco
+# All rights reserved.
+#
+# This software is free for non-commercial, research and evaluation use
+# under the terms of the LICENSE.md file.
+#
+# For inquiries contact george.drettakis@inria.fr
+#
+
+from typing import NamedTuple
+import torch.nn as nn
+import torch
+from . import _C
+
+def cpu_deep_copy_tuple(input_tuple):
+ copied_tensors = [item.cpu().clone() if isinstance(item, torch.Tensor) else item for item in input_tuple]
+ return tuple(copied_tensors)
+
+def rasterize_gaussians(
+ means3D,
+ means2D,
+ sh,
+ colors_precomp,
+ opacities,
+ scales,
+ rotations,
+ cov3Ds_precomp,
+ raster_settings,
+):
+ return _RasterizeGaussians.apply(
+ means3D,
+ means2D,
+ sh,
+ colors_precomp,
+ opacities,
+ scales,
+ rotations,
+ cov3Ds_precomp,
+ raster_settings,
+ )
+
+class _RasterizeGaussians(torch.autograd.Function):
+ @staticmethod
+ def forward(
+ ctx,
+ means3D,
+ means2D,
+ sh,
+ colors_precomp,
+ opacities,
+ scales,
+ rotations,
+ cov3Ds_precomp,
+ raster_settings,
+ ):
+
+ # Restructure arguments the way that the C++ lib expects them
+ args = (
+ raster_settings.bg,
+ means3D,
+ colors_precomp,
+ opacities,
+ scales,
+ rotations,
+ raster_settings.scale_modifier,
+ cov3Ds_precomp,
+ raster_settings.viewmatrix,
+ raster_settings.projmatrix,
+ raster_settings.tanfovx,
+ raster_settings.tanfovy,
+ raster_settings.image_height,
+ raster_settings.image_width,
+ sh,
+ raster_settings.sh_degree,
+ raster_settings.campos,
+ raster_settings.prefiltered,
+ raster_settings.debug
+ )
+
+ # Invoke C++/CUDA rasterizer
+ if raster_settings.debug:
+ cpu_args = cpu_deep_copy_tuple(args) # Copy them before they can be corrupted
+ try:
+ num_rendered, color, depth, alpha, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)
+ except Exception as ex:
+ torch.save(cpu_args, "snapshot_fw.dump")
+ print("\nAn error occured in forward. Please forward snapshot_fw.dump for debugging.")
+ raise ex
+ else:
+ num_rendered, color, depth, alpha, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)
+
+ # Keep relevant tensors for backward
+ ctx.raster_settings = raster_settings
+ ctx.num_rendered = num_rendered
+ ctx.save_for_backward(colors_precomp, means3D, scales, rotations, cov3Ds_precomp, radii, sh, geomBuffer, binningBuffer, imgBuffer, alpha)
+ return color, radii, depth, alpha
+
+ @staticmethod
+ def backward(ctx, grad_color, grad_radii, grad_depth, grad_alpha):
+
+ # Restore necessary values from context
+ num_rendered = ctx.num_rendered
+ raster_settings = ctx.raster_settings
+ colors_precomp, means3D, scales, rotations, cov3Ds_precomp, radii, sh, geomBuffer, binningBuffer, imgBuffer, alpha = ctx.saved_tensors
+
+ # Restructure args as C++ method expects them
+ args = (raster_settings.bg,
+ means3D,
+ radii,
+ colors_precomp,
+ scales,
+ rotations,
+ raster_settings.scale_modifier,
+ cov3Ds_precomp,
+ raster_settings.viewmatrix,
+ raster_settings.projmatrix,
+ raster_settings.tanfovx,
+ raster_settings.tanfovy,
+ grad_color,
+ grad_depth,
+ grad_alpha,
+ sh,
+ raster_settings.sh_degree,
+ raster_settings.campos,
+ geomBuffer,
+ num_rendered,
+ binningBuffer,
+ imgBuffer,
+ alpha,
+ raster_settings.debug)
+
+ # Compute gradients for relevant tensors by invoking backward method
+ if raster_settings.debug:
+ cpu_args = cpu_deep_copy_tuple(args) # Copy them before they can be corrupted
+ try:
+ grad_means2D, grad_colors_precomp, grad_opacities, grad_means3D, grad_cov3Ds_precomp, grad_sh, grad_scales, grad_rotations = _C.rasterize_gaussians_backward(*args)
+ except Exception as ex:
+ torch.save(cpu_args, "snapshot_bw.dump")
+ print("\nAn error occured in backward. Writing snapshot_bw.dump for debugging.\n")
+ raise ex
+ else:
+ grad_means2D, grad_colors_precomp, grad_opacities, grad_means3D, grad_cov3Ds_precomp, grad_sh, grad_scales, grad_rotations = _C.rasterize_gaussians_backward(*args)
+
+ grads = (
+ grad_means3D,
+ grad_means2D,
+ grad_sh,
+ grad_colors_precomp,
+ grad_opacities,
+ grad_scales,
+ grad_rotations,
+ grad_cov3Ds_precomp,
+ None,
+ )
+
+ return grads
+
+class GaussianRasterizationSettings(NamedTuple):
+ image_height: int
+ image_width: int
+ tanfovx : float
+ tanfovy : float
+ bg : torch.Tensor
+ scale_modifier : float
+ viewmatrix : torch.Tensor
+ projmatrix : torch.Tensor
+ sh_degree : int
+ campos : torch.Tensor
+ prefiltered : bool
+ debug : bool
+
+class GaussianRasterizer(nn.Module):
+ def __init__(self, raster_settings):
+ super().__init__()
+ self.raster_settings = raster_settings
+
+ def markVisible(self, positions):
+ # Mark visible points (based on frustum culling for camera) with a boolean
+ with torch.no_grad():
+ raster_settings = self.raster_settings
+ visible = _C.mark_visible(
+ positions,
+ raster_settings.viewmatrix,
+ raster_settings.projmatrix)
+
+ return visible
+
+ def forward(self, means3D, means2D, opacities, shs = None, colors_precomp = None, scales = None, rotations = None, cov3D_precomp = None):
+
+ raster_settings = self.raster_settings
+
+ if (shs is None and colors_precomp is None) or (shs is not None and colors_precomp is not None):
+ raise Exception('Please provide excatly one of either SHs or precomputed colors!')
+
+ if ((scales is None or rotations is None) and cov3D_precomp is None) or ((scales is not None or rotations is not None) and cov3D_precomp is not None):
+ raise Exception('Please provide exactly one of either scale/rotation pair or precomputed 3D covariance!')
+
+ if shs is None:
+ shs = torch.Tensor([])
+ if colors_precomp is None:
+ colors_precomp = torch.Tensor([])
+
+ if scales is None:
+ scales = torch.Tensor([])
+ if rotations is None:
+ rotations = torch.Tensor([])
+ if cov3D_precomp is None:
+ cov3D_precomp = torch.Tensor([])
+
+ # Invoke C++/CUDA rasterization routine
+ return rasterize_gaussians(
+ means3D,
+ means2D,
+ shs,
+ colors_precomp,
+ opacities,
+ scales,
+ rotations,
+ cov3D_precomp,
+ raster_settings,
+ )
+
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/ext.cpp b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/ext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fea1ee17ca01d8625f5eaab844658bc4a8eebd7f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/ext.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#include
+#include "rasterize_points.h"
+
+PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
+ m.def("rasterize_gaussians", &RasterizeGaussiansCUDA);
+ m.def("rasterize_gaussians_backward", &RasterizeGaussiansBackwardCUDA);
+ m.def("mark_visible", &markVisible);
+}
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.cu b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.cu
new file mode 100644
index 0000000000000000000000000000000000000000..474647862336c9a9434356e8819584cc4a73de2d
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.cu
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "cuda_rasterizer/config.h"
+#include "cuda_rasterizer/rasterizer.h"
+#include
+#include
+#include
+
+std::function resizeFunctional(torch::Tensor& t) {
+ auto lambda = [&t](size_t N) {
+ t.resize_({(long long)N});
+ return reinterpret_cast(t.contiguous().data_ptr());
+ };
+ return lambda;
+}
+
+std::tuple
+RasterizeGaussiansCUDA(
+ const torch::Tensor& background,
+ const torch::Tensor& means3D,
+ const torch::Tensor& colors,
+ const torch::Tensor& opacity,
+ const torch::Tensor& scales,
+ const torch::Tensor& rotations,
+ const float scale_modifier,
+ const torch::Tensor& cov3D_precomp,
+ const torch::Tensor& viewmatrix,
+ const torch::Tensor& projmatrix,
+ const float tan_fovx,
+ const float tan_fovy,
+ const int image_height,
+ const int image_width,
+ const torch::Tensor& sh,
+ const int degree,
+ const torch::Tensor& campos,
+ const bool prefiltered,
+ const bool debug)
+{
+ if (means3D.ndimension() != 2 || means3D.size(1) != 3) {
+ AT_ERROR("means3D must have dimensions (num_points, 3)");
+ }
+
+ const int P = means3D.size(0);
+ const int H = image_height;
+ const int W = image_width;
+
+ auto int_opts = means3D.options().dtype(torch::kInt32);
+ auto float_opts = means3D.options().dtype(torch::kFloat32);
+
+ torch::Tensor out_color = torch::full({NUM_CHANNELS, H, W}, 0.0, float_opts);
+ torch::Tensor out_depth = torch::full({1, H, W}, 0.0, float_opts);
+ torch::Tensor out_alpha = torch::full({1, H, W}, 0.0, float_opts);
+ torch::Tensor radii = torch::full({P}, 0, means3D.options().dtype(torch::kInt32));
+
+ torch::Device device(torch::kCUDA);
+ torch::TensorOptions options(torch::kByte);
+ torch::Tensor geomBuffer = torch::empty({0}, options.device(device));
+ torch::Tensor binningBuffer = torch::empty({0}, options.device(device));
+ torch::Tensor imgBuffer = torch::empty({0}, options.device(device));
+ std::function geomFunc = resizeFunctional(geomBuffer);
+ std::function binningFunc = resizeFunctional(binningBuffer);
+ std::function imgFunc = resizeFunctional(imgBuffer);
+
+ int rendered = 0;
+ if(P != 0)
+ {
+ int M = 0;
+ if(sh.size(0) != 0)
+ {
+ M = sh.size(1);
+ }
+
+ rendered = CudaRasterizer::Rasterizer::forward(
+ geomFunc,
+ binningFunc,
+ imgFunc,
+ P, degree, M,
+ background.contiguous().data(),
+ W, H,
+ means3D.contiguous().data(),
+ sh.contiguous().data_ptr(),
+ colors.contiguous().data(),
+ opacity.contiguous().data(),
+ scales.contiguous().data_ptr(),
+ scale_modifier,
+ rotations.contiguous().data_ptr(),
+ cov3D_precomp.contiguous().data(),
+ viewmatrix.contiguous().data(),
+ projmatrix.contiguous().data(),
+ campos.contiguous().data(),
+ tan_fovx,
+ tan_fovy,
+ prefiltered,
+ out_color.contiguous().data(),
+ out_depth.contiguous().data(),
+ out_alpha.contiguous().data(),
+ radii.contiguous().data(),
+ debug);
+ }
+ return std::make_tuple(rendered, out_color, out_depth, out_alpha, radii, geomBuffer, binningBuffer, imgBuffer);
+}
+
+std::tuple
+ RasterizeGaussiansBackwardCUDA(
+ const torch::Tensor& background,
+ const torch::Tensor& means3D,
+ const torch::Tensor& radii,
+ const torch::Tensor& colors,
+ const torch::Tensor& scales,
+ const torch::Tensor& rotations,
+ const float scale_modifier,
+ const torch::Tensor& cov3D_precomp,
+ const torch::Tensor& viewmatrix,
+ const torch::Tensor& projmatrix,
+ const float tan_fovx,
+ const float tan_fovy,
+ const torch::Tensor& dL_dout_color,
+ const torch::Tensor& dL_dout_depth,
+ const torch::Tensor& dL_dout_alpha,
+ const torch::Tensor& sh,
+ const int degree,
+ const torch::Tensor& campos,
+ const torch::Tensor& geomBuffer,
+ const int R,
+ const torch::Tensor& binningBuffer,
+ const torch::Tensor& imageBuffer,
+ const torch::Tensor& alphas,
+ const bool debug)
+{
+ const int P = means3D.size(0);
+ const int H = dL_dout_color.size(1);
+ const int W = dL_dout_color.size(2);
+
+ int M = 0;
+ if(sh.size(0) != 0)
+ {
+ M = sh.size(1);
+ }
+
+ torch::Tensor dL_dmeans3D = torch::zeros({P, 3}, means3D.options());
+ torch::Tensor dL_dmeans2D = torch::zeros({P, 3}, means3D.options());
+ torch::Tensor dL_dcolors = torch::zeros({P, NUM_CHANNELS}, means3D.options());
+ torch::Tensor dL_ddepths = torch::zeros({P, 1}, means3D.options());
+ torch::Tensor dL_dconic = torch::zeros({P, 2, 2}, means3D.options());
+ torch::Tensor dL_dopacity = torch::zeros({P, 1}, means3D.options());
+ torch::Tensor dL_dcov3D = torch::zeros({P, 6}, means3D.options());
+ torch::Tensor dL_dsh = torch::zeros({P, M, 3}, means3D.options());
+ torch::Tensor dL_dscales = torch::zeros({P, 3}, means3D.options());
+ torch::Tensor dL_drotations = torch::zeros({P, 4}, means3D.options());
+
+ if(P != 0)
+ {
+ CudaRasterizer::Rasterizer::backward(P, degree, M, R,
+ background.contiguous().data(),
+ W, H,
+ means3D.contiguous().data(),
+ sh.contiguous().data(),
+ colors.contiguous().data(),
+ alphas.contiguous().data(),
+ scales.data_ptr(),
+ scale_modifier,
+ rotations.data_ptr(),
+ cov3D_precomp.contiguous().data(),
+ viewmatrix.contiguous().data(),
+ projmatrix.contiguous().data(),
+ campos.contiguous().data(),
+ tan_fovx,
+ tan_fovy,
+ radii.contiguous().data(),
+ reinterpret_cast(geomBuffer.contiguous().data_ptr()),
+ reinterpret_cast(binningBuffer.contiguous().data_ptr()),
+ reinterpret_cast(imageBuffer.contiguous().data_ptr()),
+ dL_dout_color.contiguous().data(),
+ dL_dout_depth.contiguous().data(),
+ dL_dout_alpha.contiguous().data(),
+ dL_dmeans2D.contiguous().data(),
+ dL_dconic.contiguous().data(),
+ dL_dopacity.contiguous().data(),
+ dL_dcolors.contiguous().data(),
+ dL_ddepths.contiguous().data(),
+ dL_dmeans3D.contiguous().data(),
+ dL_dcov3D.contiguous().data(),
+ dL_dsh.contiguous().data(),
+ dL_dscales.contiguous().data(),
+ dL_drotations.contiguous().data(),
+ debug);
+ }
+
+ return std::make_tuple(dL_dmeans2D, dL_dcolors, dL_dopacity, dL_dmeans3D, dL_dcov3D, dL_dsh, dL_dscales, dL_drotations);
+}
+
+torch::Tensor markVisible(
+ torch::Tensor& means3D,
+ torch::Tensor& viewmatrix,
+ torch::Tensor& projmatrix)
+{
+ const int P = means3D.size(0);
+
+ torch::Tensor present = torch::full({P}, false, means3D.options().dtype(at::kBool));
+
+ if(P != 0)
+ {
+ CudaRasterizer::Rasterizer::markVisible(P,
+ means3D.contiguous().data(),
+ viewmatrix.contiguous().data(),
+ projmatrix.contiguous().data(),
+ present.contiguous().data());
+ }
+
+ return present;
+}
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.h b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.h
new file mode 100644
index 0000000000000000000000000000000000000000..da47d442737f7fa569f7986cbef671a814e96401
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/rasterize_points.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023, Inria
+ * GRAPHDECO research group, https://team.inria.fr/graphdeco
+ * All rights reserved.
+ *
+ * This software is free for non-commercial, research and evaluation use
+ * under the terms of the LICENSE.md file.
+ *
+ * For inquiries contact george.drettakis@inria.fr
+ */
+
+#pragma once
+#include
+#include
+#include
+#include
+
+std::tuple
+RasterizeGaussiansCUDA(
+ const torch::Tensor& background,
+ const torch::Tensor& means3D,
+ const torch::Tensor& colors,
+ const torch::Tensor& opacity,
+ const torch::Tensor& scales,
+ const torch::Tensor& rotations,
+ const float scale_modifier,
+ const torch::Tensor& cov3D_precomp,
+ const torch::Tensor& viewmatrix,
+ const torch::Tensor& projmatrix,
+ const float tan_fovx,
+ const float tan_fovy,
+ const int image_height,
+ const int image_width,
+ const torch::Tensor& sh,
+ const int degree,
+ const torch::Tensor& campos,
+ const bool prefiltered,
+ const bool debug);
+
+std::tuple
+ RasterizeGaussiansBackwardCUDA(
+ const torch::Tensor& background,
+ const torch::Tensor& means3D,
+ const torch::Tensor& radii,
+ const torch::Tensor& colors,
+ const torch::Tensor& scales,
+ const torch::Tensor& rotations,
+ const float scale_modifier,
+ const torch::Tensor& cov3D_precomp,
+ const torch::Tensor& viewmatrix,
+ const torch::Tensor& projmatrix,
+ const float tan_fovx,
+ const float tan_fovy,
+ const torch::Tensor& dL_dout_color,
+ const torch::Tensor& dL_dout_depth,
+ const torch::Tensor& dL_dout_alpha,
+ const torch::Tensor& sh,
+ const int degree,
+ const torch::Tensor& campos,
+ const torch::Tensor& geomBuffer,
+ const int R,
+ const torch::Tensor& binningBuffer,
+ const torch::Tensor& imageBuffer,
+ const torch::Tensor& alpha,
+ const bool debug);
+
+torch::Tensor markVisible(
+ torch::Tensor& means3D,
+ torch::Tensor& viewmatrix,
+ torch::Tensor& projmatrix);
\ No newline at end of file
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/setup.py b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a90725b7c3af59c639790533146ab8651d02e9f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/setup.py
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2023, Inria
+# GRAPHDECO research group, https://team.inria.fr/graphdeco
+# All rights reserved.
+#
+# This software is free for non-commercial, research and evaluation use
+# under the terms of the LICENSE.md file.
+#
+# For inquiries contact george.drettakis@inria.fr
+#
+
+from setuptools import setup
+from torch.utils.cpp_extension import CUDAExtension, BuildExtension
+import os
+
+setup(
+ name="diff_gaussian_rasterization_depth_alpha",
+ packages=['diff_gaussian_rasterization_depth_alpha'],
+ ext_modules=[
+ CUDAExtension(
+ name="diff_gaussian_rasterization_depth_alpha._C",
+ sources=[
+ "cuda_rasterizer/rasterizer_impl.cu",
+ "cuda_rasterizer/forward.cu",
+ "cuda_rasterizer/backward.cu",
+ "rasterize_points.cu",
+ "ext.cpp"],
+ extra_compile_args={"nvcc": ["-I" + os.path.join(os.path.dirname(os.path.abspath(__file__)), "third_party/glm/")]})
+ ],
+ cmdclass={
+ 'build_ext': BuildExtension
+ }
+)
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.appveyor.yml b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.appveyor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f8618b285a582bbea199c6b24c7c0c1e90685c4c
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.appveyor.yml
@@ -0,0 +1,92 @@
+shallow_clone: true
+
+platform:
+ - x86
+ - x64
+
+configuration:
+ - Debug
+ - Release
+
+image:
+ - Visual Studio 2013
+ - Visual Studio 2015
+ - Visual Studio 2017
+ - Visual Studio 2019
+
+environment:
+ matrix:
+ - GLM_ARGUMENTS: -DGLM_TEST_FORCE_PURE=ON
+ - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
+ - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
+ - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
+ - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
+
+matrix:
+ exclude:
+ - image: Visual Studio 2013
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
+ - image: Visual Studio 2013
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
+ - image: Visual Studio 2013
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
+ - image: Visual Studio 2013
+ configuration: Debug
+ - image: Visual Studio 2015
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
+ - image: Visual Studio 2015
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
+ - image: Visual Studio 2015
+ GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
+ - image: Visual Studio 2015
+ platform: x86
+ - image: Visual Studio 2015
+ configuration: Debug
+ - image: Visual Studio 2017
+ platform: x86
+ - image: Visual Studio 2017
+ configuration: Debug
+ - image: Visual Studio 2019
+ platform: x64
+
+branches:
+ only:
+ - master
+
+before_build:
+ - ps: |
+ mkdir build
+ cd build
+
+ if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2013") {
+ $env:generator="Visual Studio 12 2013"
+ }
+ if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
+ $env:generator="Visual Studio 14 2015"
+ }
+ if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2017") {
+ $env:generator="Visual Studio 15 2017"
+ }
+ if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2019") {
+ $env:generator="Visual Studio 16 2019"
+ }
+ if ($env:PLATFORM -eq "x64") {
+ $env:generator="$env:generator Win64"
+ }
+ echo generator="$env:generator"
+ cmake .. -G "$env:generator" -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/install" -DGLM_QUIET=ON -DGLM_TEST_ENABLE=ON "$env:GLM_ARGUMENTS"
+
+build_script:
+ - cmake --build . --parallel --config %CONFIGURATION% -- /m /v:minimal
+ - cmake --build . --target install --parallel --config %CONFIGURATION% -- /m /v:minimal
+
+test_script:
+ - ctest --parallel 4 --verbose -C %CONFIGURATION%
+ - cd ..
+ - ps: |
+ mkdir build_test_cmake
+ cd build_test_cmake
+ cmake ..\test\cmake\ -G "$env:generator" -DCMAKE_PREFIX_PATH="$env:APPVEYOR_BUILD_FOLDER/install"
+ - cmake --build . --parallel --config %CONFIGURATION% -- /m /v:minimal
+
+deploy: off
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.gitignore b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4de8a4b247c7546d43c0e782a8936f1847f7601f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.gitignore
@@ -0,0 +1,61 @@
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# CMake
+CMakeCache.txt
+CMakeFiles
+cmake_install.cmake
+install_manifest.txt
+*.cmake
+!glmConfig.cmake
+!glmConfig-version.cmake
+# ^ May need to add future .cmake files as exceptions
+
+# Test logs
+Testing/*
+
+# Test input
+test/gtc/*.dds
+
+# Project Files
+Makefile
+*.cbp
+*.user
+
+# Misc.
+*.log
+
+# local build(s)
+build*
+
+/.vs
+/.vscode
+/CMakeSettings.json
+.DS_Store
+*.swp
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.travis.yml b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..166d5a17fdf114e349f11e7bfc76fa18f4ac9e25
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/.travis.yml
@@ -0,0 +1,388 @@
+language: cpp
+
+branches:
+ only:
+ - master
+ - stable
+
+jobs:
+ include:
+ - name: "Xcode 7.3 C++98 pure release"
+ os: osx
+ osx_image: xcode7.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
+
+ - name: "Xcode 7.3 C++98 sse2 release"
+ os: osx
+ osx_image: xcode7.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+
+ - name: "Xcode 7.3 C++98 ms release"
+ os: osx
+ osx_image: xcode7.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
+
+ - name: "XCode 7.3 C++11 pure release"
+ os: osx
+ osx_image: xcode7.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON"
+
+ - name: "XCode 7.3 C++11 sse2 release"
+ os: osx
+ osx_image: xcode7.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
+
+ - name: "XCode 10.3 C++11 sse2 release"
+ os: osx
+ osx_image: xcode10.3
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
+
+ - name: "XCode 12.2 C++11 sse2 release"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++11 sse2 debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++11 avx debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++14 avx debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++14 pure debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++17 pure debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++17 sse2 debug"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++17 sse2 release"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "XCode 12.2 C++17 avx release"
+ os: osx
+ osx_image: xcode12.2
+ env:
+ - MATRIX_EVAL=""
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 4.9 C++98 pure release"
+ os: linux
+ dist: Xenial
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 4.9 C++98 pure debug"
+ os: linux
+ dist: Xenial
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 4.9 C++98 ms debug"
+ os: linux
+ dist: Xenial
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 4.9 C++11 ms debug"
+ os: linux
+ dist: Xenial
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 4.9 C++11 pure debug"
+ os: linux
+ dist: Xenial
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 6 C++14 pure debug"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-6
+ env:
+ - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 6 C++14 ms debug"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-6
+ env:
+ - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 7 C++17 ms debug"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-7
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 7 C++17 pure debug"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-7
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 10 C++17 pure debug"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-10
+ env:
+ - MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "GCC 10 C++17 pure release"
+ os: linux
+ dist: bionic
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-10
+ env:
+ - MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++14 pure release"
+ os: linux
+ dist: Xenial
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++14 pure debug"
+ os: linux
+ dist: Xenial
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++14 sse2 debug"
+ os: linux
+ dist: Xenial
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++14 sse2 debug"
+ os: linux
+ dist: focal
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++17 sse2 debug"
+ os: linux
+ dist: focal
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++17 avx2 debug"
+ os: linux
+ dist: focal
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX2=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++17 pure debug"
+ os: linux
+ dist: focal
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+ - name: "Clang C++17 pure release"
+ os: linux
+ dist: focal
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+ - CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
+ - CTEST_ENV="--parallel 4 --output-on-failure"
+ - CMAKE_ENV="--parallel"
+
+before_script:
+ - cmake --version
+ - eval "${MATRIX_EVAL}"
+
+script:
+ - ${CC} --version
+ - mkdir ./build
+ - cd ./build
+ - cmake -DCMAKE_INSTALL_PREFIX=$TRAVIS_BUILD_DIR/install -DCMAKE_CXX_COMPILER=$COMPILER ${CMAKE_BUILD_ENV} ..
+ - cmake --build . ${CMAKE_ENV}
+ - ctest ${CTEST_ENV}
+ - cmake --build . --target install ${CMAKE_ENV}
+ - cd $TRAVIS_BUILD_DIR
+ - mkdir ./build_test_cmake
+ - cd ./build_test_cmake
+ - cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -DCMAKE_PREFIX_PATH=$TRAVIS_BUILD_DIR/install
+ - cmake --build .
+
+
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/CMakeLists.txt b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cfaa625c47fc5ac9f4fd0d7b0324a26131778ffa
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
+cmake_policy(VERSION 3.2)
+
+
+file(READ "glm/detail/setup.hpp" GLM_SETUP_FILE)
+string(REGEX MATCH "#define[ ]+GLM_VERSION_MAJOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
+set(GLM_VERSION_MAJOR "${CMAKE_MATCH_1}")
+string(REGEX MATCH "#define[ ]+GLM_VERSION_MINOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
+set(GLM_VERSION_MINOR "${CMAKE_MATCH_1}")
+string(REGEX MATCH "#define[ ]+GLM_VERSION_PATCH[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
+set(GLM_VERSION_PATCH "${CMAKE_MATCH_1}")
+string(REGEX MATCH "#define[ ]+GLM_VERSION_REVISION[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
+set(GLM_VERSION_REVISION "${CMAKE_MATCH_1}")
+
+set(GLM_VERSION ${GLM_VERSION_MAJOR}.${GLM_VERSION_MINOR}.${GLM_VERSION_PATCH}.${GLM_VERSION_REVISION})
+project(glm VERSION ${GLM_VERSION} LANGUAGES CXX)
+message(STATUS "GLM: Version " ${GLM_VERSION})
+
+add_subdirectory(glm)
+add_library(glm::glm ALIAS glm)
+
+if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+
+ include(CPack)
+ install(DIRECTORY glm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PATTERN "CMakeLists.txt" EXCLUDE)
+ install(EXPORT glm FILE glmConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glm NAMESPACE glm::)
+ include(CMakePackageConfigHelpers)
+ write_basic_package_version_file("glmConfigVersion.cmake" COMPATIBILITY AnyNewerVersion)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/glmConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glm)
+
+ include(CTest)
+ if(BUILD_TESTING)
+ add_subdirectory(test)
+ endif()
+
+endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+
+if (NOT TARGET uninstall)
+configure_file(cmake/cmake_uninstall.cmake.in
+ cmake_uninstall.cmake IMMEDIATE @ONLY)
+
+add_custom_target(uninstall
+ "${CMAKE_COMMAND}" -P
+ "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake")
+endif()
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/cmake/cmake_uninstall.cmake.in b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/cmake/cmake_uninstall.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..f3005c10e4baafc9006214b9a075780ea0903427
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/cmake/cmake_uninstall.cmake.in
@@ -0,0 +1,21 @@
+if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
+endif()
+
+file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+foreach(file ${files})
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ exec_program(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
+ endif()
+ else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif()
+endforeach()
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/copying.txt b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/copying.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5c43d396fa84cd790089673c52d9edc7719835d1
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/copying.txt
@@ -0,0 +1,54 @@
+================================================================================
+OpenGL Mathematics (GLM)
+--------------------------------------------------------------------------------
+GLM is licensed under The Happy Bunny License or MIT License
+
+================================================================================
+The Happy Bunny License (Modified MIT License)
+--------------------------------------------------------------------------------
+Copyright (c) 2005 - G-Truc Creation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Restrictions:
+ By making use of the Software for military purposes, you choose to make a
+ Bunny unhappy.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+================================================================================
+The MIT License
+--------------------------------------------------------------------------------
+Copyright (c) 2005 - G-Truc Creation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/CMakeLists.txt b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4248abc8b351b5b232abe8e6aac57ae5557e6fac
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/CMakeLists.txt
@@ -0,0 +1,78 @@
+file(GLOB ROOT_SOURCE *.cpp)
+file(GLOB ROOT_INLINE *.inl)
+file(GLOB ROOT_HEADER *.hpp)
+file(GLOB ROOT_TEXT ../*.txt)
+file(GLOB ROOT_MD ../*.md)
+file(GLOB ROOT_NAT ../util/glm.natvis)
+
+file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp)
+file(GLOB_RECURSE CORE_INLINE ./detail/*.inl)
+file(GLOB_RECURSE CORE_HEADER ./detail/*.hpp)
+
+file(GLOB_RECURSE EXT_SOURCE ./ext/*.cpp)
+file(GLOB_RECURSE EXT_INLINE ./ext/*.inl)
+file(GLOB_RECURSE EXT_HEADER ./ext/*.hpp)
+
+file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp)
+file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl)
+file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp)
+
+file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp)
+file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl)
+file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp)
+
+file(GLOB_RECURSE SIMD_SOURCE ./simd/*.cpp)
+file(GLOB_RECURSE SIMD_INLINE ./simd/*.inl)
+file(GLOB_RECURSE SIMD_HEADER ./simd/*.h)
+
+source_group("Text Files" FILES ${ROOT_TEXT} ${ROOT_MD})
+source_group("Core Files" FILES ${CORE_SOURCE})
+source_group("Core Files" FILES ${CORE_INLINE})
+source_group("Core Files" FILES ${CORE_HEADER})
+source_group("EXT Files" FILES ${EXT_SOURCE})
+source_group("EXT Files" FILES ${EXT_INLINE})
+source_group("EXT Files" FILES ${EXT_HEADER})
+source_group("GTC Files" FILES ${GTC_SOURCE})
+source_group("GTC Files" FILES ${GTC_INLINE})
+source_group("GTC Files" FILES ${GTC_HEADER})
+source_group("GTX Files" FILES ${GTX_SOURCE})
+source_group("GTX Files" FILES ${GTX_INLINE})
+source_group("GTX Files" FILES ${GTX_HEADER})
+source_group("SIMD Files" FILES ${SIMD_SOURCE})
+source_group("SIMD Files" FILES ${SIMD_INLINE})
+source_group("SIMD Files" FILES ${SIMD_HEADER})
+
+add_library(glm INTERFACE)
+
+include(GNUInstallDirs)
+
+target_include_directories(glm INTERFACE
+ $
+ $
+)
+
+install(TARGETS glm EXPORT glm)
+
+if(BUILD_STATIC_LIBS)
+add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT}
+ ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER}
+ ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER}
+ ${EXT_SOURCE} ${EXT_INLINE} ${EXT_HEADER}
+ ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
+ ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
+ ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER})
+ target_link_libraries(glm_static PUBLIC glm)
+ add_library(glm::glm_static ALIAS glm_static)
+endif()
+
+if(BUILD_SHARED_LIBS)
+add_library(glm_shared SHARED ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT}
+ ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER}
+ ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER}
+ ${EXT_SOURCE} ${EXT_INLINE} ${EXT_HEADER}
+ ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
+ ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
+ ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER})
+ target_link_libraries(glm_shared PUBLIC glm)
+ add_library(glm::glm_shared ALIAS glm_shared)
+endif()
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/common.hpp b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/common.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..06d783bc9e8a42e616de97b5cd2a41a5ebdbf74f
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/common.hpp
@@ -0,0 +1,539 @@
+/// @ref core
+/// @file glm/common.hpp
+///
+/// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+///
+/// @defgroup core_func_common Common functions
+/// @ingroup core
+///
+/// Provides GLSL common functions
+///
+/// These all operate component-wise. The description is per component.
+///
+/// Include to use these core features.
+
+#pragma once
+
+#include "detail/qualifier.hpp"
+#include "detail/_fixes.hpp"
+
+namespace glm
+{
+ /// @addtogroup core_func_common
+ /// @{
+
+ /// Returns x if x >= 0; otherwise, it returns -x.
+ ///
+ /// @tparam genType floating-point or signed integer; scalar or vector types.
+ ///
+ /// @see GLSL abs man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x);
+
+ /// Returns x if x >= 0; otherwise, it returns -x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or signed integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL abs man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec abs(vec const& x);
+
+ /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL sign man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec sign(vec const& x);
+
+ /// Returns a value equal to the nearest integer that is less then or equal to x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL floor man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec floor(vec const& x);
+
+ /// Returns a value equal to the nearest integer to x
+ /// whose absolute value is not larger than the absolute value of x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL trunc man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec trunc(vec const& x);
+
+ /// Returns a value equal to the nearest integer to x.
+ /// The fraction 0.5 will round in a direction chosen by the
+ /// implementation, presumably the direction that is fastest.
+ /// This includes the possibility that round(x) returns the
+ /// same value as roundEven(x) for all values of x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL round man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec round(vec const& x);
+
+ /// Returns a value equal to the nearest integer to x.
+ /// A fractional part of 0.5 will round toward the nearest even
+ /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL roundEven man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ /// @see New round to even technique
+ template
+ GLM_FUNC_DECL vec roundEven(vec const& x);
+
+ /// Returns a value equal to the nearest integer
+ /// that is greater than or equal to x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL ceil man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec ceil(vec const& x);
+
+ /// Return x - floor(x).
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL fract man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType fract(genType x);
+
+ /// Return x - floor(x).
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL fract man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec fract(vec const& x);
+
+ template
+ GLM_FUNC_DECL genType mod(genType x, genType y);
+
+ template
+ GLM_FUNC_DECL vec mod(vec const& x, T y);
+
+ /// Modulus. Returns x - y * floor(x / y)
+ /// for each component in x using the floating point value y.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types, include glm/gtc/integer for integer scalar types support
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL mod man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec mod(vec const& x, vec const& y);
+
+ /// Returns the fractional part of x and sets i to the integer
+ /// part (as a whole number floating point value). Both the
+ /// return value and the output parameter will have the same
+ /// sign as x.
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL modf man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType modf(genType x, genType& i);
+
+ /// Returns y if y < x; otherwise, it returns x.
+ ///
+ /// @tparam genType Floating-point or integer; scalar or vector types.
+ ///
+ /// @see GLSL min man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR genType min(genType x, genType y);
+
+ /// Returns y if y < x; otherwise, it returns x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL min man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, T y);
+
+ /// Returns y if y < x; otherwise, it returns x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL min man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, vec const& y);
+
+ /// Returns y if x < y; otherwise, it returns x.
+ ///
+ /// @tparam genType Floating-point or integer; scalar or vector types.
+ ///
+ /// @see GLSL max man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR genType max(genType x, genType y);
+
+ /// Returns y if x < y; otherwise, it returns x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL max man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, T y);
+
+ /// Returns y if x < y; otherwise, it returns x.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL max man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, vec const& y);
+
+ /// Returns min(max(x, minVal), maxVal) for each component in x
+ /// using the floating-point values minVal and maxVal.
+ ///
+ /// @tparam genType Floating-point or integer; scalar or vector types.
+ ///
+ /// @see GLSL clamp man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal);
+
+ /// Returns min(max(x, minVal), maxVal) for each component in x
+ /// using the floating-point values minVal and maxVal.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL clamp man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, T minVal, T maxVal);
+
+ /// Returns min(max(x, minVal), maxVal) for each component in x
+ /// using the floating-point values minVal and maxVal.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point or integer scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL clamp man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, vec const& minVal, vec const& maxVal);
+
+ /// If genTypeU is a floating scalar or vector:
+ /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of
+ /// x and y using the floating-point value a.
+ /// The value for a is not restricted to the range [0, 1].
+ ///
+ /// If genTypeU is a boolean scalar or vector:
+ /// Selects which vector each returned component comes
+ /// from. For a component of 'a' that is false, the
+ /// corresponding component of 'x' is returned. For a
+ /// component of 'a' that is true, the corresponding
+ /// component of 'y' is returned. Components of 'x' and 'y' that
+ /// are not selected are allowed to be invalid floating point
+ /// values and will have no effect on the results. Thus, this
+ /// provides different functionality than
+ /// genType mix(genType x, genType y, genType(a))
+ /// where a is a Boolean vector.
+ ///
+ /// @see GLSL mix man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ ///
+ /// @param[in] x Value to interpolate.
+ /// @param[in] y Value to interpolate.
+ /// @param[in] a Interpolant.
+ ///
+ /// @tparam genTypeT Floating point scalar or vector.
+ /// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT.
+ ///
+ /// @code
+ /// #include
+ /// ...
+ /// float a;
+ /// bool b;
+ /// glm::dvec3 e;
+ /// glm::dvec3 f;
+ /// glm::vec4 g;
+ /// glm::vec4 h;
+ /// ...
+ /// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors.
+ /// glm::vec4 s = glm::mix(g, h, b); // Returns g or h;
+ /// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second.
+ /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter.
+ /// @endcode
+ template
+ GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a);
+
+ template
+ GLM_FUNC_DECL vec mix(vec const& x, vec const& y, vec const& a);
+
+ template
+ GLM_FUNC_DECL vec mix(vec const& x, vec const& y, U a);
+
+ /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType.
+ ///
+ /// @see GLSL step man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType step(genType edge, genType x);
+
+ /// Returns 0.0 if x < edge, otherwise it returns 1.0.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL step man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec step(T edge, vec const& x);
+
+ /// Returns 0.0 if x < edge, otherwise it returns 1.0.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL step man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec step(vec const& edge, vec const& x);
+
+ /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
+ /// performs smooth Hermite interpolation between 0 and 1
+ /// when edge0 < x < edge1. This is useful in cases where
+ /// you would want a threshold function with a smooth
+ /// transition. This is equivalent to:
+ /// genType t;
+ /// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
+ /// return t * t * (3 - 2 * t);
+ /// Results are undefined if edge0 >= edge1.
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL smoothstep man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType smoothstep(genType edge0, genType edge1, genType x);
+
+ template
+ GLM_FUNC_DECL vec smoothstep(T edge0, T edge1, vec const& x);
+
+ template
+ GLM_FUNC_DECL vec smoothstep(vec const& edge0, vec const& edge1, vec const& x);
+
+ /// Returns true if x holds a NaN (not a number)
+ /// representation in the underlying implementation's set of
+ /// floating point representations. Returns false otherwise,
+ /// including for implementations with no NaN
+ /// representations.
+ ///
+ /// /!\ When using compiler fast math, this function may fail.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL isnan man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec isnan(vec const& x);
+
+ /// Returns true if x holds a positive infinity or negative
+ /// infinity representation in the underlying implementation's
+ /// set of floating point representations. Returns false
+ /// otherwise, including for implementations with no infinity
+ /// representations.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam T Floating-point scalar types
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL isinf man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec isinf(vec const& x);
+
+ /// Returns a signed integer value representing
+ /// the encoding of a floating-point value. The floating-point
+ /// value's bit-level representation is preserved.
+ ///
+ /// @see GLSL floatBitsToInt man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ GLM_FUNC_DECL int floatBitsToInt(float const& v);
+
+ /// Returns a signed integer value representing
+ /// the encoding of a floating-point value. The floatingpoint
+ /// value's bit-level representation is preserved.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL floatBitsToInt man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec floatBitsToInt(vec const& v);
+
+ /// Returns a unsigned integer value representing
+ /// the encoding of a floating-point value. The floatingpoint
+ /// value's bit-level representation is preserved.
+ ///
+ /// @see GLSL floatBitsToUint man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ GLM_FUNC_DECL uint floatBitsToUint(float const& v);
+
+ /// Returns a unsigned integer value representing
+ /// the encoding of a floating-point value. The floatingpoint
+ /// value's bit-level representation is preserved.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL floatBitsToUint man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec floatBitsToUint(vec const& v);
+
+ /// Returns a floating-point value corresponding to a signed
+ /// integer encoding of a floating-point value.
+ /// If an inf or NaN is passed in, it will not signal, and the
+ /// resulting floating point value is unspecified. Otherwise,
+ /// the bit-level representation is preserved.
+ ///
+ /// @see GLSL intBitsToFloat man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ GLM_FUNC_DECL float intBitsToFloat(int const& v);
+
+ /// Returns a floating-point value corresponding to a signed
+ /// integer encoding of a floating-point value.
+ /// If an inf or NaN is passed in, it will not signal, and the
+ /// resulting floating point value is unspecified. Otherwise,
+ /// the bit-level representation is preserved.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL intBitsToFloat man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec intBitsToFloat(vec const& v);
+
+ /// Returns a floating-point value corresponding to a
+ /// unsigned integer encoding of a floating-point value.
+ /// If an inf or NaN is passed in, it will not signal, and the
+ /// resulting floating point value is unspecified. Otherwise,
+ /// the bit-level representation is preserved.
+ ///
+ /// @see GLSL uintBitsToFloat man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ GLM_FUNC_DECL float uintBitsToFloat(uint const& v);
+
+ /// Returns a floating-point value corresponding to a
+ /// unsigned integer encoding of a floating-point value.
+ /// If an inf or NaN is passed in, it will not signal, and the
+ /// resulting floating point value is unspecified. Otherwise,
+ /// the bit-level representation is preserved.
+ ///
+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+ /// @tparam Q Value from qualifier enum
+ ///
+ /// @see GLSL uintBitsToFloat man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL vec uintBitsToFloat(vec const& v);
+
+ /// Computes and returns a * b + c.
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL fma man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType fma(genType const& a, genType const& b, genType const& c);
+
+ /// Splits x into a floating-point significand in the range
+ /// [0.5, 1.0) and an integral exponent of two, such that:
+ /// x = significand * exp(2, exponent)
+ ///
+ /// The significand is returned by the function and the
+ /// exponent is returned in the parameter exp. For a
+ /// floating-point value of zero, the significant and exponent
+ /// are both zero. For a floating-point value that is an
+ /// infinity or is not a number, the results are undefined.
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL frexp man page
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType frexp(genType x, int& exp);
+
+ template
+ GLM_FUNC_DECL vec frexp(vec const& v, vec& exp);
+
+ /// Builds a floating-point number from x and the
+ /// corresponding integral exponent of two in exp, returning:
+ /// significand * exp(2, exponent)
+ ///
+ /// If this product is too large to be represented in the
+ /// floating-point type, the result is undefined.
+ ///
+ /// @tparam genType Floating-point scalar or vector types.
+ ///
+ /// @see GLSL ldexp man page;
+ /// @see GLSL 4.20.8 specification, section 8.3 Common Functions
+ template
+ GLM_FUNC_DECL genType ldexp(genType const& x, int const& exp);
+
+ template
+ GLM_FUNC_DECL vec ldexp(vec const& v, vec const& exp);
+
+ /// @}
+}//namespace glm
+
+#include "detail/func_common.inl"
+
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_features.hpp b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_features.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..43069514fe5746a9767b687bfd8e94368aa87f5a
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_features.hpp
@@ -0,0 +1,394 @@
+#pragma once
+
+// #define GLM_CXX98_EXCEPTIONS
+// #define GLM_CXX98_RTTI
+
+// #define GLM_CXX11_RVALUE_REFERENCES
+// Rvalue references - GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
+
+// GLM_CXX11_TRAILING_RETURN
+// Rvalue references for *this - GCC not supported
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
+
+// GLM_CXX11_NONSTATIC_MEMBER_INIT
+// Initialization of class objects by rvalues - GCC any
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html
+
+// GLM_CXX11_NONSTATIC_MEMBER_INIT
+// Non-static data member initializers - GCC 4.7
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm
+
+// #define GLM_CXX11_VARIADIC_TEMPLATE
+// Variadic templates - GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
+
+//
+// Extending variadic template template parameters - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
+
+// #define GLM_CXX11_GENERALIZED_INITIALIZERS
+// Initializer lists - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
+
+// #define GLM_CXX11_STATIC_ASSERT
+// Static assertions - GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
+
+// #define GLM_CXX11_AUTO_TYPE
+// auto-typed variables - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf
+
+// #define GLM_CXX11_AUTO_TYPE
+// Multi-declarator auto - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf
+
+// #define GLM_CXX11_AUTO_TYPE
+// Removal of auto as a storage-class specifier - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm
+
+// #define GLM_CXX11_AUTO_TYPE
+// New function declarator syntax - GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm
+
+// #define GLM_CXX11_LAMBDAS
+// New wording for C++0x lambdas - GCC 4.5
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf
+
+// #define GLM_CXX11_DECLTYPE
+// Declared type of an expression - GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf
+
+//
+// Right angle brackets - GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
+
+//
+// Default template arguments for function templates DR226 GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226
+
+//
+// Solving the SFINAE problem for expressions DR339 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html
+
+// #define GLM_CXX11_ALIAS_TEMPLATE
+// Template aliases N2258 GCC 4.7
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf
+
+//
+// Extern templates N1987 Yes
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm
+
+// #define GLM_CXX11_NULLPTR
+// Null pointer constant N2431 GCC 4.6
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
+
+// #define GLM_CXX11_STRONG_ENUMS
+// Strongly-typed enums N2347 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf
+
+//
+// Forward declarations for enums N2764 GCC 4.6
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf
+
+//
+// Generalized attributes N2761 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf
+
+//
+// Generalized constant expressions N2235 GCC 4.6
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
+
+//
+// Alignment support N2341 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf
+
+// #define GLM_CXX11_DELEGATING_CONSTRUCTORS
+// Delegating constructors N1986 GCC 4.7
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
+
+//
+// Inheriting constructors N2540 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm
+
+// #define GLM_CXX11_EXPLICIT_CONVERSIONS
+// Explicit conversion operators N2437 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
+
+//
+// New character types N2249 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html
+
+//
+// Unicode string literals N2442 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
+
+//
+// Raw string literals N2442 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
+
+//
+// Universal character name literals N2170 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html
+
+// #define GLM_CXX11_USER_LITERALS
+// User-defined literals N2765 GCC 4.7
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf
+
+//
+// Standard Layout Types N2342 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
+
+// #define GLM_CXX11_DEFAULTED_FUNCTIONS
+// #define GLM_CXX11_DELETED_FUNCTIONS
+// Defaulted and deleted functions N2346 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
+
+//
+// Extended friend declarations N1791 GCC 4.7
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf
+
+//
+// Extending sizeof N2253 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html
+
+// #define GLM_CXX11_INLINE_NAMESPACES
+// Inline namespaces N2535 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm
+
+// #define GLM_CXX11_UNRESTRICTED_UNIONS
+// Unrestricted unions N2544 GCC 4.6
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
+
+// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
+// Local and unnamed types as template arguments N2657 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
+
+// #define GLM_CXX11_RANGE_FOR
+// Range-based for N2930 GCC 4.6
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html
+
+// #define GLM_CXX11_OVERRIDE_CONTROL
+// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
+
+//
+// Minimal support for garbage collection and reachability-based leak detection N2670 No
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm
+
+// #define GLM_CXX11_NOEXCEPT
+// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only)
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html
+
+//
+// Defining move special member functions N3053 GCC 4.6
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html
+
+//
+// Sequence points N2239 Yes
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
+
+//
+// Atomic operations N2427 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
+
+//
+// Strong Compare and Exchange N2748 GCC 4.5
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
+
+//
+// Bidirectional Fences N2752 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm
+
+//
+// Memory model N2429 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm
+
+//
+// Data-dependency ordering: atomics and memory model N2664 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm
+
+//
+// Propagating exceptions N2179 GCC 4.4
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html
+
+//
+// Abandoning a process and at_quick_exit N2440 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm
+
+//
+// Allow atomics use in signal handlers N2547 Yes
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm
+
+//
+// Thread-local storage N2659 GCC 4.8
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm
+
+//
+// Dynamic initialization and destruction with concurrency N2660 GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm
+
+//
+// __func__ predefined identifier N2340 GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm
+
+//
+// C99 preprocessor N1653 GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm
+
+//
+// long long N1811 GCC 4.3
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf
+
+//
+// Extended integral types N1988 Yes
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf
+
+#if(GLM_COMPILER & GLM_COMPILER_GCC)
+
+# define GLM_CXX11_STATIC_ASSERT
+
+#elif(GLM_COMPILER & GLM_COMPILER_CLANG)
+# if(__has_feature(cxx_exceptions))
+# define GLM_CXX98_EXCEPTIONS
+# endif
+
+# if(__has_feature(cxx_rtti))
+# define GLM_CXX98_RTTI
+# endif
+
+# if(__has_feature(cxx_access_control_sfinae))
+# define GLM_CXX11_ACCESS_CONTROL_SFINAE
+# endif
+
+# if(__has_feature(cxx_alias_templates))
+# define GLM_CXX11_ALIAS_TEMPLATE
+# endif
+
+# if(__has_feature(cxx_alignas))
+# define GLM_CXX11_ALIGNAS
+# endif
+
+# if(__has_feature(cxx_attributes))
+# define GLM_CXX11_ATTRIBUTES
+# endif
+
+# if(__has_feature(cxx_constexpr))
+# define GLM_CXX11_CONSTEXPR
+# endif
+
+# if(__has_feature(cxx_decltype))
+# define GLM_CXX11_DECLTYPE
+# endif
+
+# if(__has_feature(cxx_default_function_template_args))
+# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
+# endif
+
+# if(__has_feature(cxx_defaulted_functions))
+# define GLM_CXX11_DEFAULTED_FUNCTIONS
+# endif
+
+# if(__has_feature(cxx_delegating_constructors))
+# define GLM_CXX11_DELEGATING_CONSTRUCTORS
+# endif
+
+# if(__has_feature(cxx_deleted_functions))
+# define GLM_CXX11_DELETED_FUNCTIONS
+# endif
+
+# if(__has_feature(cxx_explicit_conversions))
+# define GLM_CXX11_EXPLICIT_CONVERSIONS
+# endif
+
+# if(__has_feature(cxx_generalized_initializers))
+# define GLM_CXX11_GENERALIZED_INITIALIZERS
+# endif
+
+# if(__has_feature(cxx_implicit_moves))
+# define GLM_CXX11_IMPLICIT_MOVES
+# endif
+
+# if(__has_feature(cxx_inheriting_constructors))
+# define GLM_CXX11_INHERITING_CONSTRUCTORS
+# endif
+
+# if(__has_feature(cxx_inline_namespaces))
+# define GLM_CXX11_INLINE_NAMESPACES
+# endif
+
+# if(__has_feature(cxx_lambdas))
+# define GLM_CXX11_LAMBDAS
+# endif
+
+# if(__has_feature(cxx_local_type_template_args))
+# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
+# endif
+
+# if(__has_feature(cxx_noexcept))
+# define GLM_CXX11_NOEXCEPT
+# endif
+
+# if(__has_feature(cxx_nonstatic_member_init))
+# define GLM_CXX11_NONSTATIC_MEMBER_INIT
+# endif
+
+# if(__has_feature(cxx_nullptr))
+# define GLM_CXX11_NULLPTR
+# endif
+
+# if(__has_feature(cxx_override_control))
+# define GLM_CXX11_OVERRIDE_CONTROL
+# endif
+
+# if(__has_feature(cxx_reference_qualified_functions))
+# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
+# endif
+
+# if(__has_feature(cxx_range_for))
+# define GLM_CXX11_RANGE_FOR
+# endif
+
+# if(__has_feature(cxx_raw_string_literals))
+# define GLM_CXX11_RAW_STRING_LITERALS
+# endif
+
+# if(__has_feature(cxx_rvalue_references))
+# define GLM_CXX11_RVALUE_REFERENCES
+# endif
+
+# if(__has_feature(cxx_static_assert))
+# define GLM_CXX11_STATIC_ASSERT
+# endif
+
+# if(__has_feature(cxx_auto_type))
+# define GLM_CXX11_AUTO_TYPE
+# endif
+
+# if(__has_feature(cxx_strong_enums))
+# define GLM_CXX11_STRONG_ENUMS
+# endif
+
+# if(__has_feature(cxx_trailing_return))
+# define GLM_CXX11_TRAILING_RETURN
+# endif
+
+# if(__has_feature(cxx_unicode_literals))
+# define GLM_CXX11_UNICODE_LITERALS
+# endif
+
+# if(__has_feature(cxx_unrestricted_unions))
+# define GLM_CXX11_UNRESTRICTED_UNIONS
+# endif
+
+# if(__has_feature(cxx_user_literals))
+# define GLM_CXX11_USER_LITERALS
+# endif
+
+# if(__has_feature(cxx_variadic_templates))
+# define GLM_CXX11_VARIADIC_TEMPLATES
+# endif
+
+#endif//(GLM_COMPILER & GLM_COMPILER_CLANG)
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_fixes.hpp b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_fixes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1f06c2d4bb1ac8b093a3075414d48ba602e0387
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_fixes.hpp
@@ -0,0 +1,27 @@
+#include
+
+//! Workaround for compatibility with other libraries
+#ifdef max
+#undef max
+#endif
+
+//! Workaround for compatibility with other libraries
+#ifdef min
+#undef min
+#endif
+
+//! Workaround for Android
+#ifdef isnan
+#undef isnan
+#endif
+
+//! Workaround for Android
+#ifdef isinf
+#undef isinf
+#endif
+
+//! Workaround for Chrone Native Client
+#ifdef log2
+#undef log2
+#endif
+
diff --git a/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_noise.hpp b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_noise.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a1285f0043e147d8a6f9382e25c2d7fa55f4a08
--- /dev/null
+++ b/AnimatableGaussians/gaussians/diff_gaussian_rasterization_depth_alpha/third_party/glm/glm/detail/_noise.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include "../common.hpp"
+
+namespace glm{
+namespace detail
+{
+ template
+ GLM_FUNC_QUALIFIER T mod289(T const& x)
+ {
+ return x - floor(x * (static_cast(1.0) / static_cast(289.0))) * static_cast(289.0);
+ }
+
+ template
+ GLM_FUNC_QUALIFIER T permute(T const& x)
+ {
+ return mod289(((x * static_cast(34)) + static_cast(1)) * x);
+ }
+
+ template
+ GLM_FUNC_QUALIFIER vec<2, T, Q> permute(vec<2, T, Q> const& x)
+ {
+ return mod289(((x * static_cast(34)) + static_cast(1)) * x);
+ }
+
+ template
+ GLM_FUNC_QUALIFIER vec<3, T, Q> permute(vec<3, T, Q> const& x)
+ {
+ return mod289(((x * static_cast(34)) + static_cast