diff --git a/.gitattributes b/.gitattributes
index a6344aac8c09253b3b630fb776ae94478aa0275b..c36abf627736c7e3f524bfa9cce6c5e432f3f13f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -33,3 +33,103 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
+assets/_demo/1.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/10.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/2.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/3.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/4.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/5.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/6.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/7.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/8.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/9.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog/pas.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog/sd15.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog/sd35m.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_elevest/pas.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_elevest/sd15.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_elevest/sd35m.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_empty/pas.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_empty/sd15.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_frog_empty/sd35m.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_toy_robot/pas.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_toy_robot/sd15.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/a_toy_robot/sd35m.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/book.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/cookie.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/iron_robot.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/panda.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/plush_dog_toy.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/controlnet/teddy_bear.gif filter=lfs diff=lfs merge=lfs -text
+assets/_demo/overview.png filter=lfs diff=lfs merge=lfs -text
+assets/crm/astronaut.webp filter=lfs diff=lfs merge=lfs -text
+assets/crm/大头泡泡马特.webp filter=lfs diff=lfs merge=lfs -text
+assets/crm/武器-剑.webp filter=lfs diff=lfs merge=lfs -text
+assets/crm/毛线衣.webp filter=lfs diff=lfs merge=lfs -text
+assets/crm/翅膀道具.webp filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/1_wukong_avatar.png filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/2_wukong_sculpture.png filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/3_wukong_toy.png filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/4_mask.png filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/5_bajie.png filter=lfs diff=lfs merge=lfs -text
+assets/diffsplat/6_armor.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/17_dalle3_rockingchair1.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/19_dalle3_stump1.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/astronaut.webp filter=lfs diff=lfs merge=lfs -text
+assets/grm/coat.webp filter=lfs diff=lfs merge=lfs -text
+assets/grm/david.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/dreamcraft3d_00.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/dreamcraft3d_01.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/dreamcraft3d_02.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/frog.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/girl1_padded.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/girl2_copy.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/image.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/ironman_helmet.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/panda.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/sculpture_0.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/turtle.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/unicorn.png filter=lfs diff=lfs merge=lfs -text
+assets/grm/zebra.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/blue_cat.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/bubble_mart_blue.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/bulldog.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/cartoon_dinosaur.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/cartoon_panda.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/chair_armed.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/chair_watermelon.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/cute_horse.jpg filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/pikachu.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/sea_turtle.png filter=lfs diff=lfs merge=lfs -text
+assets/instantmesh/sword.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealinputsonly.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmesh.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealpointcloud.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/meshlab.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/sibr_classes_v2.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/AssetStreamer/seq_assetStreamer.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_insideOut.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_stream.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_v3_landscape.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_rendering.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_texture_upload.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_cmake.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/jesnault_git_cheat_sheet.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/multimeshmanager.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/multiviewmanager.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/SIBR_viewers/docs/img/ulr_screenshot.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/assets/teaser.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/paper.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/submodules/diff-gaussian-rasterization/dist/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/submodules/diff-gaussian-rasterization/third_party/glm/doc/manual/frontpage1.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/submodules/diff-gaussian-rasterization/third_party/glm/doc/manual/frontpage2.png filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/submodules/diff-gaussian-rasterization/third_party/glm/doc/manual.pdf filter=lfs diff=lfs merge=lfs -text
+extensions/RaDe-GS/submodules/frpc_linux_amd64_v0.2 filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/22/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/33a17050938079dd150f/_a[[:space:]]toy[[:space:]]robot..._013020.ply filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/22/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/9084f12000e4d0861282/_a[[:space:]]cute[[:space:]]panda..._013020.ply filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/22/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/927242333ba684b13bb2/_a[[:space:]]book..._013020.ply filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/23/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/1174ce83af0bcabb215a/_a[[:space:]]book..._013020.ply filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/23/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/743ad8490995e372c5f3/_a[[:space:]]cute[[:space:]]panda..._013020.ply filter=lfs diff=lfs merge=lfs -text
+gradio_cached_examples/23/3D[[:space:]]Gaussians[[:space:]]ply[[:space:]]format/e611dc2e9fbf1acd1cfc/_a[[:space:]]toy[[:space:]]robot..._013020.ply filter=lfs diff=lfs merge=lfs -text
+tmp/input_image.png filter=lfs diff=lfs merge=lfs -text
+wheel/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..18f9e7487a4ab4017d77b4c8b0cfc8b5c8938b1f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+__pycache__/
+build/
+*.egg-info/
+out/
+temp/
+log/
+download/*.json
+download/*.csv
+temp*.*
+*.tar*
+*.vsix
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..85695fe20a34ca2e220e9afb554a65ebeb256264
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Chenguo Lin
+
+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.
\ No newline at end of file
diff --git a/README.md b/README.md
index 609e3f8f55f50b88e27f2b6ce9a9ba08993fda79..b82351077d7207b47c59cb4f7304f16b6004d5db 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,306 @@
---
-title: Diffsplat
-emoji: ⚡
-colorFrom: yellow
-colorTo: gray
-sdk: gradio
-sdk_version: 5.15.0
+title: DiffSplat
app_file: app.py
-pinned: false
-license: mit
+sdk: gradio
+sdk_version: 4.44.1
---
+# [ICLR 2025] DiffSplat
+
+
+
+DiffSplat: Repurposing Image Diffusion Models for Scalable Gaussian Splat Generation
+
+[Chenguo Lin](https://chenguolin.github.io), [Panwang Pan](https://paulpanwang.github.io), [Bangbang Yang](https://ybbbbt.com), [Zeming Li](https://www.zemingli.com), [Yadong Mu](http://www.muyadong.com)
+
+[](https://arxiv.org/abs/2501.16764)
+[](https://chenguolin.github.io/projects/DiffSplat)
+[](https://huggingface.co/chenguolin/DiffSplat)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This repository contains the official implementation of the paper: [DiffSplat: Repurposing Image Diffusion Models for Scalable Gaussian Splat Generation](https://arxiv.org/abs/2501.16764), which is accepted to ICLR 2025.
+DiffSplat is a generative framework to synthesize 3D Gaussian Splats from text prompts & single-view images in 1~2 seconds. It is fine-tuned directly from a pretrained text-to-image diffusion model.
+
+Feel free to contact me (chenguolin@stu.pku.edu.cn) or open an issue if you have any questions or suggestions.
+
+
+## 📢 News
+
+- **2025-02-02**: Inference instructions (text-conditioned & image-conditioned & controlnet) are provided.
+- **2025-01-29**: The source code and pretrained models are released. Happy 🐍 Chinese New Year 🎆!
+- **2025-01-22**: InstructScene is accepted to ICLR 2025.
+
+
+## 📋 TODO
+
+- [x] Provide detailed instructions for inference.
+- [ ] Provide detailed instructions for training.
+- [ ] Implement a Gradio demo.
+
+
+## 🔧 Installation
+
+You may need to modify the specific version of `torch` in `settings/setup.sh` according to your CUDA version.
+There are not restrictions on the `torch` version, feel free to use your preferred one.
+```bash
+git clone https://github.com/chenguolin/DiffSplat.git
+cd DiffSplat
+bash settings/setup.sh
+```
+
+
+## 📊 Dataset
+
+- We use [G-Objaverse](https://github.com/modelscope/richdreamer/tree/main/dataset/gobjaverse) with about 265K 3D objects and 10.6M rendered images (265K x 40 views, including RGB, normal and depth maps) for `GSRecon` and `GSVAE` training. [Its subset](https://github.com/ashawkey/objaverse_filter) with about 83K 3D objects provided by [LGM](https://me.kiui.moe/lgm) is used for `DiffSplat` training. Their text descriptions are provided by the latest version of [Cap3D](https://huggingface.co/datasets/tiange/Cap3D) (i.e., refined by [DiffuRank](https://arxiv.org/abs/2404.07984)).
+- We find the filtering is crucial for the generation quality of `DiffSplat`, and a larger dataset is beneficial for the performance of `GSRecon` and `GSVAE`.
+- We store the dataset in an internal HDFS cluster in this project. Thus, the training code can NOT be directly run on your local machine. Please implement your own dataloading logic referring to our provided dataset & dataloader code.
+
+
+## 🚀 Usage
+
+### 📷 Camera Conventions
+
+The camera and world coordinate systems in this project are both defined in the `OpenGL` convention, i.e., X: right, Y: up, Z: backward. The camera is located at `(0, 0, 1.4)` in the world coordinate system, and the camera looks at the origin `(0, 0, 0)`.
+Please refer to [kiuikit camera doc](https://kit.kiui.moe/camera) for visualizations of the camera and world coordinate systems.
+
+### 🤗 Pretrained Models
+
+All pretrained models are available at [HuggingFace🤗](https://huggingface.co/chenguolin/DiffSplat).
+
+| **Model Name** | **Fine-tined From** | **#Param.** | **Link** | **Note** |
+|-------------------------------|---------------------|-------------|----------|----------|
+| **GSRecon** | From scratch | 42M | [gsrecon_gobj265k_cnp_even4](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsrecon_gobj265k_cnp_even4) | Feed-forward reconstruct per-pixel 3DGS from (RGB, normal, point) maps |
+| **GSVAE (SD)** | [SD1.5 VAE](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | 84M | [gsvae_gobj265k_sd](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsvae_gobj265k_sd) | |
+| **GSVAE (SDXL)** | [SDXL fp16 VAE](https://huggingface.co/madebyollin/sdxl-vae-fp16-fix) | 84M | [gsvae_gobj265k_sdxl_fp16](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsvae_gobj265k_sdxl_fp16) | fp16-fixed SDXL VAE is more robust |
+| **GSVAE (SD3)** | [SD3 VAE](https://huggingface.co/stabilityai/stable-diffusion-3-medium) | 84M | [gsvae_gobj265k_sd3](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsvae_gobj265k_sd3) | |
+| **DiffSplat (SD1.5)** | [SD1.5](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | 0.86B | Text-cond: [gsdiff_gobj83k_sd15__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd15__render) Image-cond: [gsdiff_gobj83k_sd15_image__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd15_image__render) | Best efficiency |
+| **DiffSplat (PixArt-Sigma)** | [PixArt-Sigma](https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-512-MS) | 0.61B | Text-cond: [gsdiff_gobj83k_pas_fp16__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_pas_fp16__render) Image-cond: [gsdiff_gobj83k_pas_fp16_image__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_pas_fp16_image__render) | Best Trade-off |
+| **DiffSplat (SD3.5m)** | [SD3.5 median](https://huggingface.co/stabilityai/stable-diffusion-3.5-medium) | 2.24B | Text-cond: [gsdiff_gobj83k_sd35m__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd35m__render) Image-cond: [gsdiff_gobj83k_sd35m_image__render](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd35m_image__render) | Best performance |
+| **DiffSplat ControlNet (SD1.5)** | From scratch | 361M | Depth: [gsdiff_gobj83k_sd15__render__depth](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd15__render__depth) Normal: [gsdiff_gobj83k_sd15__render__normal](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd15__render__normal) Canny: [gsdiff_gobj83k_sd15__render__canny](https://huggingface.co/chenguolin/DiffSplat/tree/main/gsdiff_gobj83k_sd15__render__canny) | |
+| **(Optional) ElevEst** | [dinov2_vitb14_reg](https://github.com/facebookresearch/dinov2) | 86 M | [elevest_gobj265k_b_C25](https://huggingface.co/chenguolin/DiffSplat/tree/main/elevest_gobj265k_b_C25) | (Optional) Single-view image elevation estimation |
+
+
+### ⚡ Inference
+
+#### 0. Download Pretrained Models
+
+Note that:
+- Pretrained weights will download from HuggingFace and stored in `./out`.
+- Other pretrained models (such as CLIP, T5, image VAE, etc.) will be downloaded automatically and stored in your HuggingFace cache directory.
+- If you face problems in visiting HuggingFace Hub, you can try to set the environment variable `export HF_ENDPOINT=https://hf-mirror.com`.
+
+```bash
+python3 download_ckpt.py --model_type [MODEL_TYPE] [--image_cond]
+
+# `MODEL_TYPE`: choose from "sd15", "pas", "sd35m", "depth", "normal", "canny", "elevest".
+# `--image_cond`: add this flag for downloading image-conditioned models
+```
+
+For example, to download the `text-cond SD1.5-based DiffSplat`:
+```bash
+python3 download_ckpt.py --model_type sd15
+```
+To download the `image-cond PixArt-Sigma-based DiffSplat`:
+```bash
+python3 download_ckpt.py --model_type pas --image_cond
+```
+
+#### 1. Text-conditioned 3D Object Generation
+
+Note that:
+- Model differences may not be significant for simple text prompts. We recommend using `DiffSplat (SD1.5)` for better efficiency, `DiffSplat (SD3.5m)` for better performance, and `DiffSplat (PixArt-Sigma)` for a better trade-off.
+- By default, `export HF_HOME=~/.cache/huggingface`, `export TORCH_HOME=~/.cache/torch`. You can change theses paths in `scripts/infer.sh`. SD3-related models require HuggingFace token for downloading, which is expected to be stored in `HF_HOME`.
+- Outputs will be stored in `./out//inference`.
+- Prompt is specified by `--prompt` (e.g., `a_toy_robot`). Please seperate words by `_` and it will be replaced by space in the code automatically.
+- If `"gif"` is in `--output_video_type`, the output will be a `.gif` file. Otherwise, it will be a `.mp4` file. If `"fancy"` is in `--output_video_type`, the output video will be in a fancy style that 3DGS scales gradually increase while rotating.
+- `--seed` is used for random seed setting. `--gpu_id` is used for specifying the GPU device.
+- Use `--half_precision` for `BF16` half-precision inference. It will reduce the memory usage but may slightly affect the quality.
+
+```bash
+# DiffSplat (SD1.5)
+bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml gsdiff_gobj83k_sd15__render \
+--prompt a_toy_robot --output_video_type gif \
+--gpu_id 0 --seed 0 [--half_precision]
+
+# DiffSplat (PixArt-Sigma)
+bash scripts/infer.sh src/infer_gsdiff_pas.py configs/gsdiff_pas.yaml gsdiff_gobj83k_pas_fp16__render \
+--prompt a_toy_robot --output_video_type gif \
+--gpu_id 0 --seed 0 [--half_precision]
+
+# DiffSplat (SD3.5m)
+bash scripts/infer.sh src/infer_gsdiff_sd3.py configs/gsdiff_sd35m_80g.yaml gsdiff_gobj83k_sd35m__render \
+--prompt a_toy_robot --output_video_type gif \
+--gpu_id 0 --seed 0 [--half_precision]
+```
+
+You will get:
+| DiffSplat (SD1.5) | DiffSplat (PixArt-Sigma) | DiffSplat (SD3.5m) |
+|-------------------------|-------------------------------|-------------------------|
+|  |  |  |
+
+
+**More Advanced Arguments**:
+- `--prompt_file`: instead of using `--prompt`, `--prompt_file` will read prompts from a `.txt` file line by line.
+- Diffusion configurations:
+ - `--scheduler_type`: choose from `ddim`, `dpmsolver++`, `sde-dpmsolver++`, etc.
+ - `--num_inference_timesteps`: the number of diffusion steps.
+ - `--guidance_scale`: classifier-free guidance (CFG) scale; `1.0` means no CFG.
+ - `--eta`: specified for `DDIM` scheduler; the weight of noise for added noise in diffusion steps.
+- [Instant3D](https://instant-3d.github.io) tricks:
+ - `--init_std`, `--init_noise_strength`, `--init_bg`: initial noise settings, cf. [Instant3D Sec. 3.1](https://arxiv.org/pdf/2311.06214); NOT used by default, as we found it's not that helpful in our case.
+- Others:
+ - `--elevation`: elevation for viewing and rendering; not necessary for text-conditioned generation; set to `10` by default (from xz-plane (`0`) to +y axis (`90`)).
+ - `--negative_prompt`: empty prompt (`""`) by default; used with CFG for better visual quality (e.g., more vibrant colors), but we found it causes lower metric values (such as [ImageReward](https://github.com/THUDM/ImageReward)).
+ - `--save_ply`: save the generated 3DGS as a `.ply` file; used with `--opacity_threshold_ply` to filter out low-opacity splats for much smaller `.ply` file size.
+ - `--eval_text_cond`: evaluate text-conditioned generation automatically.
+ - ...
+
+Please refer to [infer_gsdiff_sd.py](./src/infer_gsdiff_sd.py), [infer_gsdiff_pas.py](./src/infer_gsdiff_pas.py), and [infer_gsdiff_sd3.py](./src/infer_gsdiff_sd3.py) for more argument details.
+
+#### 2. Image-conditioned 3D Object Generation
+
+Note that:
+- Most of the arguments are the same as text-conditioned generation. Our method support **text and image as conditions simultaneously**.
+- Elevation is necessary for image-conditioned generation. You can specify the elevation angle by `--elevation` for viewing and rendering (from xz-plane (`0`) to +y axis (`90`)) or estimate it from the input image by `--use_elevest` (download the pretrained `ElevEst` model by `python3 download_ckpt.py --model_type elevest`) first. But we found that the **estimated elevation is not always accurate**, so it's better to set it manually.
+- Text prompt is **optional** for image-conditioned generation. If you want to use text prompt, you can specify it by `--prompt` (e.g., `a_frog`), otherwise, empty prompt (`""`) will be used. Note that **DiffSplat (SD3.5m)** is sensitive to text prompts, and it may generate bad results without a proper prompt.
+- Remember to set a smaller `--guidance_scale` for image-conditioned generation, as the default value is set for text-conditioned generation. `2.0` is recommended for most cases.
+- `--triangle_cfg_scaling` is a trick that set larger CFG values for far-away views from the input image, while smaller CFG values for close-up views, cf. [SV3D Sec. 3](https://arxiv.org/pdf/2403.12008).
+- `--rembg_and_center` will remove the background and center the object in the image. It can be used with `--rembg_model_name` (by default `u2net`) and `--border_ratio` (by default `0.2`).
+- Image-conditioned generation is more sensitive to arguments, and you may need to tune them for better results.
+
+```bash
+# DiffSplat (SD1.5)
+bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml gsdiff_gobj83k_sd15_image__render \
+--rembg_and_center --triangle_cfg_scaling --output_video_type gif --guidance_scale 2 \
+--image_path assets/grm/frog.png --elevation 20 --prompt a_frog
+
+# DiffSplat (PixArt-Sigma)
+bash scripts/infer.sh src/infer_gsdiff_pas.py configs/gsdiff_pas.yaml gsdiff_gobj83k_pas_fp16_image__render \
+--rembg_and_center --triangle_cfg_scaling --output_video_type gif --guidance_scale 2 \
+--image_path assets/grm/frog.png --elevation 20 --prompt a_frog
+
+# DiffSplat (SD3.5m)
+bash scripts/infer.sh src/infer_gsdiff_sd3.py configs/gsdiff_sd35m_80g.yaml gsdiff_gobj83k_sd35m_image__render \
+--rembg_and_center --triangle_cfg_scaling --output_video_type gif --guidance_scale 2 \
+--image_path assets/grm/frog.png --elevation 20 --prompt a_frog
+```
+
+You will get
+| Arguments | DiffSplat (SD1.5) | DiffSplat (PixArt-Sigma) | DiffSplat (SD3.5m) |
+|---------|-------------------------|-------------------------------|-------------------------|
+| `--elevation 20 --prompt a_frog` |  |  |  |
+| `--use_elevest --prompt a_frog` (estimated elevation: -0.78 deg) |  |  |  |
+| `--elevation 20` (prompt is `""`) |  |  |  |
+
+**More Advanced Arguments**:
+- `--image_dir`: instead of using `--image_path`, `--image_dir` will read images from a directory.
+
+Please refer to [infer_gsdiff_sd.py](./src/infer_gsdiff_sd.py), [infer_gsdiff_pas.py](./src/infer_gsdiff_pas.py), and [infer_gsdiff_sd3.py](./src/infer_gsdiff_sd3.py) for more argument details.
+
+#### 3. ControlNet for 3D Object Generation
+
+Note that:
+- After downloading pretrained **DiffSplat (SD1.5)**, you shoule download the controlnet weights by `python3 download_ckpt.py --model_type [depth | normal | canny]`.
+- For **depth-controlnet**, values in depth maps are normalized to `[0, 1]` and larger values (white) mean closer to the camera (smaller depth). Please refer to [GObjaverse Dataset](./src/data/gobjaverse_parquet_dataset.py) for more details.
+- For **normal-controlnet**, input camera is normalized to locate at `(0, 0, 1.4)` and look at `(0, 0, 0)`, thus the input normal maps are transformed accordingly. Please refer to [GObjaverse Dataset](./src/data/gobjaverse_parquet_dataset.py) for more details.
+- For **canny-controlnet**, canny edges are extracted from the input RGB images automatically by `cv2.Canny`. Please refer to [GObjaverse Dataset](./src/data/gobjaverse_parquet_dataset.py) for more details.
+
+```bash
+# ControlNet (depth)
+bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml gsdiff_gobj83k_sd15__render \
+--load_pretrained_controlnet gsdiff_gobj83k_sd15__render__depth \
+--output_video_type gif --image_path assets/diffsplat/controlnet/toy_depth.png \
+--prompt teddy_bear --elevation 10
+
+# ControlNet (normal)
+bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml gsdiff_gobj83k_sd15__render \
+--load_pretrained_controlnet gsdiff_gobj83k_sd15__render__normal \
+--output_video_type gif --image_path assets/diffsplat/controlnet/robot_normal.png \
+--prompt iron_robot --elevation 10
+
+# ControlNet (canny)
+bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml gsdiff_gobj83k_sd15__render \
+--load_pretrained_controlnet gsdiff_gobj83k_sd15__render__canny \
+--output_video_type gif --image_path assets/diffsplat/controlnet/cookie_canny.png \
+--prompt book --elevation 10
+```
+
+You will get:
+| Original Image | Input Control | `--prompt teddy_bear` | `--prompt panda` |
+|----------------|---------------|-----------------------|--------------------|
+|  |  |  |  |
+
+| Original Image | Input Control | `--prompt iron_robot` | `--prompt plush_dog_toy` |
+|----------------|---------------|-----------------------|--------------------|
+|  |  |  |  |
+
+| Original Image | Input Control | `--prompt book` | `--prompt cookie` |
+|----------------|---------------|-----------------|---------------------|
+|  |  |  |  |
+
+**More Advanced Arguments**:
+- `--guess_mode`: ControlNet encoder tries to recognize the content of the input image even if you remove all prompts, cf. [the original ControlNet repo](https://github.com/lllyasviel/ControlNet#guess-mode--non-prompt-mode) and [HF ControlNet](https://huggingface.co/docs/diffusers/using-diffusers/controlnet#guess-mode).
+- `--controlnet_scale`: determines how much weight to assign to the conditioning inputs; outputs of the ControlNet are multiplied by `controlnet_scale` before they are added to the residual in the original UNet.
+
+Please refer to [infer_gsdiff_sd.py](./src/infer_gsdiff_sd.py) for more argument details.
+
+
+### 🦾 Training
+
+#### 1. GSRecon
+
+Please refer to [train_gsrecon.py](./src/train_gsrecon.py).
+
+Instructions for `GSRecon` training will be provided soon.
+
+#### 2. GSVAE
+
+Please refer to [train_gsvae.py](./src/train_gsvae.py).
+
+Instructions for `GSVAE` training will be provided soon.
+
+#### 3. DiffSplat
+
+Please refer to [train_gsdiff_sd.py](./src/train_gsdiff_sd.py), [train_gsdiff_pas.py](./src/train_gsdiff_pas.py), and [train_gsdiff_sd3.py](./src/train_gsdiff_sd3.py).
+
+Instructions for `DiffSplat` training will be provided soon.
+
+#### 4. ControlNet
+
+Please refer to [train_gsdiff_sd_controlnet.py](./src/train_gsdiff_sd_controlnet.py).
+
+Instructions for `ControlNet` training and inference will be provided soon.
+
+
+## 😊 Acknowledgement
+We would like to thank the authors of [LGM](https://me.kiui.moe/lgm), [GRM](https://justimyhxu.github.io/projects/grm), and [Wonder3D](https://www.xxlong.site/Wonder3D) for their great work and generously providing source codes, which inspired our work and helped us a lot in the implementation.
+
-Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
+## 📚 Citation
+If you find our work helpful, please consider citing:
+```bibtex
+@inproceedings{lin2025diffsplat,
+ title={DiffSplat: Repurposing Image Diffusion Models for Scalable 3D Gaussian Splat Generation},
+ author={Lin, Chenguo and Pan, Panwang and Yang, Bangbang and Li, Zeming and Mu, Yadong},
+ booktitle={International Conference on Learning Representations (ICLR)},
+ year={2025}
+}
+```
diff --git a/app.py b/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..a7866b950312a8e6042c82e0692fb82595792429
--- /dev/null
+++ b/app.py
@@ -0,0 +1,165 @@
+import os
+import shlex
+import subprocess
+import imageio
+import numpy as np
+
+import gradio as gr
+import spaces
+import sys
+from loguru import logger
+current_path = os.path.dirname(os.path.abspath(__file__))
+
+MAX_SEED = np.iinfo(np.int32).max
+TMP_DIR = os.path.join(current_path, 'out')
+os.makedirs(TMP_DIR, exist_ok=True)
+TAG = "gsdiff_gobj83k_sd15__render"
+
+# download checkpoints
+# subprocess.run(shlex.split("python3 download_ckpt.py --model_type pas")) # for txt condition
+# subprocess.run(shlex.split("python3 download_ckpt.py --model_type pas --image_cond")) # for img condition
+
+# img_commands = "PYTHONPATH=./ bash scripts/infer.sh src/infer_gsdiff_pas.py configs/gsdiff_pas.yaml {} \
+# --rembg_and_center --triangle_cfg_scaling --save_ply --output_video_type mp4 --guidance_scale {} \
+# --image_path {} --elevation {} --prompt {} --seed {}"
+
+# txt_commands = "PYTHONPATH=./ bash scripts/infer.sh src/infer_gsdiff_pas.py configs/gsdiff_pas.yaml \
+# --rembg_and_center --triangle_cfg_scaling --save_ply --output_video_type mp4 --guidance_scale {} \
+# --image_path {} --elevation {} --prompt {} --seed {}"
+
+# SD1.5
+subprocess.run(shlex.split("python3 download_ckpt.py --model_type sd15")) # for txt condition
+# subprocess.run(shlex.split("python3 download_ckpt.py --model_type sd15 --image_cond")) # for img condition
+img_commands = "PYTHONPATH=./ bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml \
+--rembg_and_center --triangle_cfg_scaling --save_ply --output_video_type mp4 --guidance_scale {} \
+--image_path {} --elevation {} --prompt {} --seed {}"
+
+txt_commands = "PYTHONPATH=./ bash scripts/infer.sh src/infer_gsdiff_sd.py configs/gsdiff_sd15.yaml {} \
+--rembg_and_center --save_ply --output_video_type mp4 --guidance_scale {} \
+ --elevation {} --prompt {} --seed {}"
+
+
+
+# process function
+@spaces.GPU
+def process(input_image, prompt='a_high_quality_3D_asset', prompt_neg='ugly, blurry, pixelated obscure, unnatural colors, poor lighting, dull, unclear, cropped, lowres, low quality, artifacts, duplicate', input_elevation=20, guidance_scale=2., input_seed=0):
+
+ if input_image is not None:
+ image_path = os.path.join(TMP_DIR, "input_image.png")
+ image_name = image_path.split('/')[-1].split('.')[0]
+ input_image.save(image_path)
+ full_command = img_commands.format(TAG, guidance_scale, image_path, input_elevation, prompt, input_seed)
+ else:
+ full_command = txt_commands.format(TAG, guidance_scale, input_elevation, prompt, input_seed)
+ image_name = ""
+
+ os.system(full_command)
+
+ # save video and ply files
+ ckpt_dir = os.path.join(TMP_DIR, TAG, "checkpoints")
+ infer_from_iter = int(sorted(os.listdir(ckpt_dir))[-1])
+ MAX_NAME_LEN = 20 # TODO: make `20` configurable
+ prompt = prompt.replace("_", " ")
+ prompt_name = prompt[:MAX_NAME_LEN] + "..." if prompt[:MAX_NAME_LEN] != "" else prompt
+ name = f"[{image_name}]_[{prompt_name}]_{infer_from_iter:06d}"
+ output_video_path = os.path.join(TMP_DIR, TAG, "inference", name + ".mp4")
+ output_ply_path = os.path.join(TMP_DIR, TAG, "inference", name + ".ply")
+ output_img_path = os.path.join(TMP_DIR, TAG, "inference", name + "_gs.png")
+
+ logger.info(full_command, output_video_path, output_ply_path)
+
+ output_image = imageio.imread(output_img_path)
+ return output_image, output_video_path, output_ply_path
+
+
+# gradio UI
+_TITLE = '''DiffSplat: Repurposing Image Diffusion Models for Scalable Gaussian Splat Generation'''
+
+_DESCRIPTION = '''
+### If you find our work helpful, please consider citing our paper 📚 or giving the repo a star 🌟
+
+
+* Input can be only text, only image, or both image and text.
+* If you find the generated 3D asset satisfactory, click "Extract GLB" to extract the GLB file and download it.
+* Upload an image and click "Generate" to create a 3D asset. If the image has alpha channel, it be used as the mask. Otherwise, we use `rembg` to remove the background.
+'''
+
+block = gr.Blocks(title=_TITLE).queue()
+with block:
+ with gr.Row():
+ with gr.Column(scale=1):
+ gr.Markdown('# ' + _TITLE)
+ gr.Markdown(_DESCRIPTION)
+
+ with gr.Row(variant='panel'):
+ with gr.Column(scale=1):
+ # input image
+ input_image = gr.Image(label="image", type='pil')
+
+ # input prompt
+ input_text = gr.Textbox(label="prompt",value="a_high_quality_3D_asset")
+
+ # negative prompt
+ input_neg_text = gr.Textbox(label="negative prompt", value="")
+
+ # guidance_scale
+ guidance_scale = gr.Slider(label="guidance scale", minimum=1., maximum=7.5, step=0.5, value=2.0)
+
+ # elevation
+ input_elevation = gr.Slider(label="elevation", minimum=-90, maximum=90, step=1, value=20)
+ # # inference steps
+ # input_num_steps = gr.Slider(label="inference steps", minimum=1, maximum=100, step=1, value=30)
+ # random seed
+ input_seed = gr.Slider(label="random seed", minimum=0, maximum=100000, step=1, value=0)
+ # gen button
+ button_gen = gr.Button("Generate")
+
+
+ with gr.Column(scale=1):
+ with gr.Tab("Video"):
+ # final video results
+ output_video = gr.Video(label="video")
+ # ply file
+ output_file = gr.File(label="3D Gaussians (ply format)")
+ with gr.Tab("Splatter Images"):
+ output_image = gr.Image(interactive=False, show_label=False)
+
+
+ button_gen.click(process, inputs=[input_image, input_text, input_neg_text, input_elevation, guidance_scale, input_seed], outputs=[output_image, output_video, output_file])
+
+ gr.Examples(
+ examples=[
+ f'assets/diffsplat/{image}'
+ for image in os.listdir("assets/diffsplat") if image.endswith('.png')
+ ],
+ inputs=[input_image],
+ outputs=[output_image, output_video, output_file],
+ fn=lambda x: process(input_image=x),
+ # cache_examples=True,
+ run_on_click=True,
+ label='Image-to-3D Examples'
+ )
+
+ gr.Examples(
+ examples=[
+ "a_toy_robot",
+ "a_cute_panda",
+ "a_book"
+ ],
+ inputs=[input_text],
+ outputs=[output_image, output_video, output_file],
+ fn=lambda x: process(input_image=None, prompt=x),
+ # cache_examples=True,
+ run_on_click=True,
+ label='Text-to-3D Examples'
+ )
+
+
+# Launch the Gradio app
+if __name__ == "__main__":
+ block.launch(share=True)
\ No newline at end of file
diff --git a/assets/_demo/1.gif b/assets/_demo/1.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2a19bd1cc53a07478075f560290014631e913874
--- /dev/null
+++ b/assets/_demo/1.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e5026f63c1c69ba4d31c34cc82ccef0ac75c24b947893376a4f227ff04fc00dc
+size 1867337
diff --git a/assets/_demo/10.gif b/assets/_demo/10.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d8870850132a2db0ae31653d0546258bb4c229ac
--- /dev/null
+++ b/assets/_demo/10.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e6d6191e04b32f0b74a299bb3cf35735fa329bec309165056128405e5a1e55ef
+size 1760409
diff --git a/assets/_demo/2.gif b/assets/_demo/2.gif
new file mode 100644
index 0000000000000000000000000000000000000000..833c7e89f0cb375c0046987d26f3a3ac27e4bb73
--- /dev/null
+++ b/assets/_demo/2.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f63f122c00335401c849c73e0bb71c12785d1754f506acb32c5fe324404cefd7
+size 4610065
diff --git a/assets/_demo/3.gif b/assets/_demo/3.gif
new file mode 100644
index 0000000000000000000000000000000000000000..dd7aadf49915bede8525f7507a77136ee73097f8
--- /dev/null
+++ b/assets/_demo/3.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:acf87ce7deebc7693fd6c72e25fc22deb3642b0cf5ff732a68bd330f3b5472af
+size 4955771
diff --git a/assets/_demo/4.gif b/assets/_demo/4.gif
new file mode 100644
index 0000000000000000000000000000000000000000..9ff8d8ccaf3f28ee65dce724ec2ca4085687a717
--- /dev/null
+++ b/assets/_demo/4.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2f88df29b6f2e06006df95d61a4be87d4c3774da455526b255dc7aacd4ec7ef6
+size 3224567
diff --git a/assets/_demo/5.gif b/assets/_demo/5.gif
new file mode 100644
index 0000000000000000000000000000000000000000..82be9a772e0a34f1f5ad6c6c9ad4630fb2e51c39
--- /dev/null
+++ b/assets/_demo/5.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:006f05b05d3630b7ebfe0cf067de203d55fa778472d7d038cbf87363e40c70a9
+size 4115396
diff --git a/assets/_demo/6.gif b/assets/_demo/6.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c27e4e95c1b0b18a64267b712db328bcef24b691
--- /dev/null
+++ b/assets/_demo/6.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c16ba28c12d40ea83d0cc705af89659c2e671bc93c254c49583d1d0fbca2ea56
+size 1969082
diff --git a/assets/_demo/7.gif b/assets/_demo/7.gif
new file mode 100644
index 0000000000000000000000000000000000000000..af6332c934e6ae5224d4e852c32dbe86bdb166be
--- /dev/null
+++ b/assets/_demo/7.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:79a27742114d96e0e767d8e722e70ea5f83b06e8fc44b3e782c2b7ce2f64a4bb
+size 1807555
diff --git a/assets/_demo/8.gif b/assets/_demo/8.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a09318d49c59852894617dd738a656b3fdb37139
--- /dev/null
+++ b/assets/_demo/8.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a99d281c8bc17a8c4655585cf4dbc1da51e3490229e55294582d35f26fba7a1
+size 2639139
diff --git a/assets/_demo/9.gif b/assets/_demo/9.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d6f0e994024ef340de973d0375a2df39d2e1fe7e
--- /dev/null
+++ b/assets/_demo/9.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aff03087a11381171ce700dffb0ffc194ff009ba36a486de01de8f2bb04f3069
+size 3313717
diff --git a/assets/_demo/a_frog/pas.gif b/assets/_demo/a_frog/pas.gif
new file mode 100644
index 0000000000000000000000000000000000000000..9480db2f5c99ce8c5864e27e6a52f7a2d5482b27
--- /dev/null
+++ b/assets/_demo/a_frog/pas.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:078c2374d80b8e3ecfdb0e54b024237708e06b6035ef750e16d05c39b97f4998
+size 3568369
diff --git a/assets/_demo/a_frog/sd15.gif b/assets/_demo/a_frog/sd15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..86ea80a06ca64a2c7475f230911091872d271ae0
--- /dev/null
+++ b/assets/_demo/a_frog/sd15.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cf8db71ca8962c9337fceabed510081ee5be63029c5194ec936e0809ef9c0814
+size 3529897
diff --git a/assets/_demo/a_frog/sd35m.gif b/assets/_demo/a_frog/sd35m.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c54fe628cb1a4ebefa24651002026ea738cc63c1
--- /dev/null
+++ b/assets/_demo/a_frog/sd35m.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ccbd8ced948c77606826e9baad190c82a97312cad3f73d875213c74480bba167
+size 4059015
diff --git a/assets/_demo/a_frog_elevest/pas.gif b/assets/_demo/a_frog_elevest/pas.gif
new file mode 100644
index 0000000000000000000000000000000000000000..00b6832b21aaf8d3090c7b497afc881a5bbf28a3
--- /dev/null
+++ b/assets/_demo/a_frog_elevest/pas.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2ba7e65d04231c4a686c2545925eb185e662633f99d8e62f46e4787f00a84cde
+size 3545826
diff --git a/assets/_demo/a_frog_elevest/sd15.gif b/assets/_demo/a_frog_elevest/sd15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..153f5865ffd8dd745e69dc92e8f50fa97ed5c463
--- /dev/null
+++ b/assets/_demo/a_frog_elevest/sd15.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a6054d11ee74288eee98bde90db223a40c79fa158f64b7cc6f27dac37d74dfbf
+size 3379021
diff --git a/assets/_demo/a_frog_elevest/sd35m.gif b/assets/_demo/a_frog_elevest/sd35m.gif
new file mode 100644
index 0000000000000000000000000000000000000000..425725186c1148a0051ce65eda238852d5c342ca
--- /dev/null
+++ b/assets/_demo/a_frog_elevest/sd35m.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a167109dfd1c1cd46f14648b3845d23b8d7f49e0cdaf089f78b356ff3300b34f
+size 3728729
diff --git a/assets/_demo/a_frog_empty/pas.gif b/assets/_demo/a_frog_empty/pas.gif
new file mode 100644
index 0000000000000000000000000000000000000000..17fbee7a6c72430bc64b3127f10ff93dd3bf79c9
--- /dev/null
+++ b/assets/_demo/a_frog_empty/pas.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18443bb88dcab653c41b2dcddfa8423d735fac1adf664cc374d45ef5ed9e5d53
+size 3485990
diff --git a/assets/_demo/a_frog_empty/sd15.gif b/assets/_demo/a_frog_empty/sd15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..bbf03c70d0d460d91cbfa1b9bc6077a17b07c1d0
--- /dev/null
+++ b/assets/_demo/a_frog_empty/sd15.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b0b550b17d9dc85af20324ad7bb310a37599f3d6502fc9969fda1d29897dacf9
+size 3425481
diff --git a/assets/_demo/a_frog_empty/sd35m.gif b/assets/_demo/a_frog_empty/sd35m.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6fd9a0b25d70d90b26c4de20ba685a7fd714a6f0
--- /dev/null
+++ b/assets/_demo/a_frog_empty/sd35m.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8ad473274b2cd9b2c7d4f7368a0bed22685ac8ca823e0984c7ca993c2b6898c
+size 3546525
diff --git a/assets/_demo/a_toy_robot/pas.gif b/assets/_demo/a_toy_robot/pas.gif
new file mode 100644
index 0000000000000000000000000000000000000000..4c53ed0b032e796201e19a5684f69974c4aa11f1
--- /dev/null
+++ b/assets/_demo/a_toy_robot/pas.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68d9b2d11a8129c5e1567664ab40d48da8123e283638bb2b5813d3461284b247
+size 2022257
diff --git a/assets/_demo/a_toy_robot/sd15.gif b/assets/_demo/a_toy_robot/sd15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2f349ee45a106843aa2ab46860921d13d3cb6bf3
--- /dev/null
+++ b/assets/_demo/a_toy_robot/sd15.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c213115602ac16f60cb3e877d5bfb57111ff1b7cfc2f47f3c188a096a421a658
+size 2136435
diff --git a/assets/_demo/a_toy_robot/sd35m.gif b/assets/_demo/a_toy_robot/sd35m.gif
new file mode 100644
index 0000000000000000000000000000000000000000..09b56a3da4dcfbc43e725c26b49bebb20024c7ec
--- /dev/null
+++ b/assets/_demo/a_toy_robot/sd35m.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:850dab4e311c96d23db7c4c2fe9b15598c695512a29b5643e7dcad220845bd9f
+size 2105324
diff --git a/assets/_demo/controlnet/book.gif b/assets/_demo/controlnet/book.gif
new file mode 100644
index 0000000000000000000000000000000000000000..47bdd307a03c03613ecd2b2e4c24baa50b857421
--- /dev/null
+++ b/assets/_demo/controlnet/book.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8d138dcba04ea3079a21b083416146a292a2b0f300bf3403aeb4c43918e29272
+size 2229948
diff --git a/assets/_demo/controlnet/cookie.gif b/assets/_demo/controlnet/cookie.gif
new file mode 100644
index 0000000000000000000000000000000000000000..59013976da2067eb2085b27944e93ebe1f16340e
--- /dev/null
+++ b/assets/_demo/controlnet/cookie.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0d842886ed5e13d2d03ded8d877cc6c25fbb09681fbcc1884e240a09e8cdbfd4
+size 2011807
diff --git a/assets/_demo/controlnet/iron_robot.gif b/assets/_demo/controlnet/iron_robot.gif
new file mode 100644
index 0000000000000000000000000000000000000000..980b02366871a16d4e306b7a435f829b9ca77d00
--- /dev/null
+++ b/assets/_demo/controlnet/iron_robot.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7d16871a73b989c0632dd722ab7134738ebf4d42e8953cec0dcc3eddc27d9c2
+size 2757336
diff --git a/assets/_demo/controlnet/panda.gif b/assets/_demo/controlnet/panda.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6359578f38708d180b369981f747067ccd2a9bac
--- /dev/null
+++ b/assets/_demo/controlnet/panda.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b7e53a7407d05617033fd9b7b90ff1e75c9e17983d60abd00499f48c0bc67ec4
+size 2773504
diff --git a/assets/_demo/controlnet/plush_dog_toy.gif b/assets/_demo/controlnet/plush_dog_toy.gif
new file mode 100644
index 0000000000000000000000000000000000000000..99a508e8c1c4fc943b240ece8f73d21d416d2378
--- /dev/null
+++ b/assets/_demo/controlnet/plush_dog_toy.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6c1e7731f8400beacf065db130f721789593f4c67a57473f5c5a1c935fa5c00a
+size 3178855
diff --git a/assets/_demo/controlnet/teddy_bear.gif b/assets/_demo/controlnet/teddy_bear.gif
new file mode 100644
index 0000000000000000000000000000000000000000..170ecba0e06f132cb72c195a7a954a65d9d31d45
--- /dev/null
+++ b/assets/_demo/controlnet/teddy_bear.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:32941570f92e60addec09091c0cac24ab28f85ceb2d732aa8f8e0bcb4a774493
+size 3119991
diff --git a/assets/_demo/overview.png b/assets/_demo/overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d02c09bd8fc604a5de893c1218528778b4fe5f3
--- /dev/null
+++ b/assets/_demo/overview.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f09b1aadf070bed1c9e4ca503b09c2ee0d6790951b4718f97ff2a24d4c3281dd
+size 236176
diff --git "a/assets/crm/3D\345\215\241\351\200\232\347\213\227.webp" "b/assets/crm/3D\345\215\241\351\200\232\347\213\227.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..47fdee13499f2669bd008433936edbe8ed4db0a7
Binary files /dev/null and "b/assets/crm/3D\345\215\241\351\200\232\347\213\227.webp" differ
diff --git a/assets/crm/astronaut.webp b/assets/crm/astronaut.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ed01d6dacbfa3c3ba279a50c682566d7302d4419
--- /dev/null
+++ b/assets/crm/astronaut.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c3e9157b31885c0fbccdba965f8ad1e27b51c41fbdb609ee8fc5728e6f4e4c3d
+size 101222
diff --git a/assets/crm/bulldog.webp b/assets/crm/bulldog.webp
new file mode 100644
index 0000000000000000000000000000000000000000..318fcf22cf756b31e25364f8fe28a3852c72fc9c
Binary files /dev/null and b/assets/crm/bulldog.webp differ
diff --git a/assets/crm/ghost-eating-burger.webp b/assets/crm/ghost-eating-burger.webp
new file mode 100644
index 0000000000000000000000000000000000000000..34d32f31dc8161d6eba92f9a33a4afc518abf669
Binary files /dev/null and b/assets/crm/ghost-eating-burger.webp differ
diff --git a/assets/crm/kunkun.webp b/assets/crm/kunkun.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a0c45d3c7091cdad8ef69374a9cbd065353e7982
Binary files /dev/null and b/assets/crm/kunkun.webp differ
diff --git "a/assets/crm/\344\270\207\345\234\243\345\215\227\347\223\234.webp" "b/assets/crm/\344\270\207\345\234\243\345\215\227\347\223\234.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..6ec4eb34c8387480ab66ecf205535750dea76f8a
Binary files /dev/null and "b/assets/crm/\344\270\207\345\234\243\345\215\227\347\223\234.webp" differ
diff --git "a/assets/crm/\344\272\272\347\211\251\351\252\221\351\251\254.webp" "b/assets/crm/\344\272\272\347\211\251\351\252\221\351\251\254.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..eec24ab04a9dec91f930513a6466e0fae9d67f5f
Binary files /dev/null and "b/assets/crm/\344\272\272\347\211\251\351\252\221\351\251\254.webp" differ
diff --git "a/assets/crm/\345\210\235\351\237\263\346\234\252\346\235\245\347\216\251\345\201\266.webp" "b/assets/crm/\345\210\235\351\237\263\346\234\252\346\235\245\347\216\251\345\201\266.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..793c6e07fd960e7ae710738151fea81f9d71d1ce
Binary files /dev/null and "b/assets/crm/\345\210\235\351\237\263\346\234\252\346\235\245\347\216\251\345\201\266.webp" differ
diff --git "a/assets/crm/\345\215\241\351\200\232\346\201\220\351\276\231.webp" "b/assets/crm/\345\215\241\351\200\232\346\201\220\351\276\231.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..2debdc5f7c546e8830ee6f79b7470edc43aff33a
Binary files /dev/null and "b/assets/crm/\345\215\241\351\200\232\346\201\220\351\276\231.webp" differ
diff --git "a/assets/crm/\345\215\241\351\200\232\346\211\213\346\236\252\346\210\252\345\233\276.webp" "b/assets/crm/\345\215\241\351\200\232\346\211\213\346\236\252\346\210\252\345\233\276.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..589c5391e53bb89c98673d5b2b2e0d76677bcb32
Binary files /dev/null and "b/assets/crm/\345\215\241\351\200\232\346\211\213\346\236\252\346\210\252\345\233\276.webp" differ
diff --git "a/assets/crm/\345\215\241\351\200\232\347\214\253.webp" "b/assets/crm/\345\215\241\351\200\232\347\214\253.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..bec01263d72e3f3e0e17cabd0e7a874f1bd04d55
Binary files /dev/null and "b/assets/crm/\345\215\241\351\200\232\347\214\253.webp" differ
diff --git "a/assets/crm/\345\215\241\351\200\232\350\230\221\350\217\207\345\245\227\350\243\205.webp" "b/assets/crm/\345\215\241\351\200\232\350\230\221\350\217\207\345\245\227\350\243\205.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..a8d2d485b8fcd46abad4b0caf7b52b84e77024bb
Binary files /dev/null and "b/assets/crm/\345\215\241\351\200\232\350\230\221\350\217\207\345\245\227\350\243\205.webp" differ
diff --git "a/assets/crm/\345\217\257\347\210\261\347\216\204\347\255\226.webp" "b/assets/crm/\345\217\257\347\210\261\347\216\204\347\255\226.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..ddffb99f48504aa5a890d676a48f39236a004631
Binary files /dev/null and "b/assets/crm/\345\217\257\347\210\261\347\216\204\347\255\226.webp" differ
diff --git "a/assets/crm/\345\244\247\345\244\264\346\263\241\346\263\241\351\251\254\347\211\271.webp" "b/assets/crm/\345\244\247\345\244\264\346\263\241\346\263\241\351\251\254\347\211\271.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..a37ca172ad2cf45fae3e9d09b5be7809ab0e10c0
--- /dev/null
+++ "b/assets/crm/\345\244\247\345\244\264\346\263\241\346\263\241\351\251\254\347\211\271.webp"
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7135922c38ef118eace0abe2a7fbf78574ebebcf973aeb8cf67ed6cfdde1fcdd
+size 354180
diff --git "a/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\207.webp" "b/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\207.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..bc41abe7d5113bb147a85fdb4f5b8f2d8e1e3851
Binary files /dev/null and "b/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\207.webp" differ
diff --git "a/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\2072.webp" "b/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\2072.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..08d870a503df6970534797730f7e429e57a84ab8
Binary files /dev/null and "b/assets/crm/\345\275\251\350\211\262\350\230\221\350\217\2072.webp" differ
diff --git "a/assets/crm/\346\201\220\351\276\231\345\245\227\350\243\205.webp" "b/assets/crm/\346\201\220\351\276\231\345\245\227\350\243\205.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..afd68e6205bba8dc5dd178ec8dcd0a6fd24287bb
Binary files /dev/null and "b/assets/crm/\346\201\220\351\276\231\345\245\227\350\243\205.webp" differ
diff --git "a/assets/crm/\346\211\213\345\212\236.webp" "b/assets/crm/\346\211\213\345\212\236.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..648206b5aa91124707cd5513bcc6ed8e866e1de6
Binary files /dev/null and "b/assets/crm/\346\211\213\345\212\236.webp" differ
diff --git "a/assets/crm/\346\234\272\346\242\260\347\213\227\350\243\201\345\210\207.webp" "b/assets/crm/\346\234\272\346\242\260\347\213\227\350\243\201\345\210\207.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..839c455378b356c5e76ebbc122291bd56e71d89d
Binary files /dev/null and "b/assets/crm/\346\234\272\346\242\260\347\213\227\350\243\201\345\210\207.webp" differ
diff --git "a/assets/crm/\346\236\227\345\205\213.webp" "b/assets/crm/\346\236\227\345\205\213.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..1b5bcfc99fd3e2e6d674b5c877f4128109355900
Binary files /dev/null and "b/assets/crm/\346\236\227\345\205\213.webp" differ
diff --git "a/assets/crm/\346\244\215\347\211\2511.webp" "b/assets/crm/\346\244\215\347\211\2511.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..73816008cc72abea18705e8f7c565f1fc57ccf1a
Binary files /dev/null and "b/assets/crm/\346\244\215\347\211\2511.webp" differ
diff --git "a/assets/crm/\346\255\246\345\231\250-\345\211\221.webp" "b/assets/crm/\346\255\246\345\231\250-\345\211\221.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..ed3404d64c648c75ab20a730afa46b2dba415f0a
--- /dev/null
+++ "b/assets/crm/\346\255\246\345\231\250-\345\211\221.webp"
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d3aad30d4f39bd4daf164a8cc7fb4af7a2e973c0e308a1d47940d9ae97033075
+size 110842
diff --git "a/assets/crm/\346\257\233\347\272\277\350\241\243.webp" "b/assets/crm/\346\257\233\347\272\277\350\241\243.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..406e7ab97959e88f63eee028d7696687df1cf253
--- /dev/null
+++ "b/assets/crm/\346\257\233\347\272\277\350\241\243.webp"
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:305350bc90ee39fcabb3422edabbfd2da9d14d9fbf2495accb0fa00b35310aa3
+size 118880
diff --git "a/assets/crm/\346\265\267\351\276\237.webp" "b/assets/crm/\346\265\267\351\276\237.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..0b1cb65946958b85d4ba977e277d46b96d3ad754
Binary files /dev/null and "b/assets/crm/\346\265\267\351\276\237.webp" differ
diff --git "a/assets/crm/\347\214\253\344\272\272.webp" "b/assets/crm/\347\214\253\344\272\272.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..5dd68d7308d4785f314e976561facc43e9d9e53a
Binary files /dev/null and "b/assets/crm/\347\214\253\344\272\272.webp" differ
diff --git "a/assets/crm/\347\214\253\345\244\264\351\271\260.webp" "b/assets/crm/\347\214\253\345\244\264\351\271\260.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..ea70b91fd162b1eed0d35b28314123a80e701a3b
Binary files /dev/null and "b/assets/crm/\347\214\253\345\244\264\351\271\260.webp" differ
diff --git "a/assets/crm/\347\216\251\345\205\267\345\205\224.webp" "b/assets/crm/\347\216\251\345\205\267\345\205\224.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..0c51b6e83ba928031967ae091c31b40efd9580ae
Binary files /dev/null and "b/assets/crm/\347\216\251\345\205\267\345\205\224.webp" differ
diff --git "a/assets/crm/\347\216\251\345\205\267\347\206\212.webp" "b/assets/crm/\347\216\251\345\205\267\347\206\212.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..7cfff09ab76ea5f0ea6ac6a180d349e593e05fee
Binary files /dev/null and "b/assets/crm/\347\216\251\345\205\267\347\206\212.webp" differ
diff --git "a/assets/crm/\347\216\251\345\205\267\347\214\252.webp" "b/assets/crm/\347\216\251\345\205\267\347\214\252.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..9e9d6aae6fa32807b734df2351a3d07e7e1ffa55
Binary files /dev/null and "b/assets/crm/\347\216\251\345\205\267\347\214\252.webp" differ
diff --git "a/assets/crm/\347\216\253\347\221\260.webp" "b/assets/crm/\347\216\253\347\221\260.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..d245944b32d29a5a7c56bf72b595fcc2b7de6650
Binary files /dev/null and "b/assets/crm/\347\216\253\347\221\260.webp" differ
diff --git "a/assets/crm/\347\232\256\345\215\241\344\270\230.webp" "b/assets/crm/\347\232\256\345\215\241\344\270\230.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..0c314f13f56e10968cfc67b194a51e48e934ed2d
Binary files /dev/null and "b/assets/crm/\347\232\256\345\215\241\344\270\230.webp" differ
diff --git "a/assets/crm/\347\232\256\351\236\213.webp" "b/assets/crm/\347\232\256\351\236\213.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..41bbb431f566663f3fb8ebd5dc32533cd4a2b990
Binary files /dev/null and "b/assets/crm/\347\232\256\351\236\213.webp" differ
diff --git "a/assets/crm/\347\237\263\345\244\264.webp" "b/assets/crm/\347\237\263\345\244\264.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..c462867d2f5d5a0f9ab7414b20af8b6adb46e2ae
Binary files /dev/null and "b/assets/crm/\347\237\263\345\244\264.webp" differ
diff --git "a/assets/crm/\347\237\263\345\244\264\345\223\206\345\225\246A\346\242\246.webp" "b/assets/crm/\347\237\263\345\244\264\345\223\206\345\225\246A\346\242\246.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..b5923198c1a6d3da835f9d9f6299ad8f3ad81732
Binary files /dev/null and "b/assets/crm/\347\237\263\345\244\264\345\223\206\345\225\246A\346\242\246.webp" differ
diff --git "a/assets/crm/\347\272\242\347\216\251\345\205\267\347\214\252.webp" "b/assets/crm/\347\272\242\347\216\251\345\205\267\347\214\252.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..600edfaea0c067f78d9db4c1e9af044b92437c91
Binary files /dev/null and "b/assets/crm/\347\272\242\347\216\251\345\205\267\347\214\252.webp" differ
diff --git "a/assets/crm/\347\277\205\350\206\200\351\201\223\345\205\267.webp" "b/assets/crm/\347\277\205\350\206\200\351\201\223\345\205\267.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..2180e08f64dea07f015c1a5c177b11b07f3f68ac
--- /dev/null
+++ "b/assets/crm/\347\277\205\350\206\200\351\201\223\345\205\267.webp"
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f63c33c5be0cc72053dc9c856191cd5a2390f7439d20b22c99c589c1c50a8d68
+size 102324
diff --git "a/assets/crm/\350\214\266\345\243\266.webp" "b/assets/crm/\350\214\266\345\243\266.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..a1e5809eeae47e05149c9f7b19d80810de58d19f
Binary files /dev/null and "b/assets/crm/\350\214\266\345\243\266.webp" differ
diff --git "a/assets/crm/\350\215\211\347\263\273\347\262\276\347\201\265.webp" "b/assets/crm/\350\215\211\347\263\273\347\262\276\347\201\265.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..ec483a7a23edec5d4c88ec7f49e6c76e5f257a24
Binary files /dev/null and "b/assets/crm/\350\215\211\347\263\273\347\262\276\347\201\265.webp" differ
diff --git "a/assets/crm/\350\223\235\350\211\262\345\260\217\346\200\252\347\211\251.webp" "b/assets/crm/\350\223\235\350\211\262\345\260\217\346\200\252\347\211\251.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..7204f5fa63d86843269210c306488444e0efafe1
Binary files /dev/null and "b/assets/crm/\350\223\235\350\211\262\345\260\217\346\200\252\347\211\251.webp" differ
diff --git "a/assets/crm/\350\223\235\350\211\262\346\263\241\346\263\241\351\251\254\347\211\271.webp" "b/assets/crm/\350\223\235\350\211\262\346\263\241\346\263\241\351\251\254\347\211\271.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..a2e1615efd6ca3f87aac3f43884666b85a804dc4
Binary files /dev/null and "b/assets/crm/\350\223\235\350\211\262\346\263\241\346\263\241\351\251\254\347\211\271.webp" differ
diff --git "a/assets/crm/\350\223\235\350\211\262\347\214\253.webp" "b/assets/crm/\350\223\235\350\211\262\347\214\253.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..8742e98a69f2441a4fab1094313fb30bf60d843d
Binary files /dev/null and "b/assets/crm/\350\223\235\350\211\262\347\214\253.webp" differ
diff --git "a/assets/crm/\350\265\233\345\215\232\346\234\213\345\205\213-\347\224\267.webp" "b/assets/crm/\350\265\233\345\215\232\346\234\213\345\205\213-\347\224\267.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..4c609f49d6dcfcb93d11c85b675fe1b0641300c9
Binary files /dev/null and "b/assets/crm/\350\265\233\345\215\232\346\234\213\345\205\213-\347\224\267.webp" differ
diff --git "a/assets/crm/\350\267\257\347\201\257.webp" "b/assets/crm/\350\267\257\347\201\257.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..909a3c906ca7ccafb49860be4aba73b827a627a4
Binary files /dev/null and "b/assets/crm/\350\267\257\347\201\257.webp" differ
diff --git "a/assets/crm/\350\277\220\345\212\250\347\263\273\346\211\213\345\212\236.webp" "b/assets/crm/\350\277\220\345\212\250\347\263\273\346\211\213\345\212\236.webp"
new file mode 100644
index 0000000000000000000000000000000000000000..15006e2e0608f602aa79d17ea0f24d94b9e62061
Binary files /dev/null and "b/assets/crm/\350\277\220\345\212\250\347\263\273\346\211\213\345\212\236.webp" differ
diff --git a/assets/diffsplat/1_wukong_avatar.png b/assets/diffsplat/1_wukong_avatar.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6cb5403e19a371b64e810772a9cc6fd007cfc67
--- /dev/null
+++ b/assets/diffsplat/1_wukong_avatar.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6d7699826d1ba35983bf9ef5af26106e50e2babdcb0141f535c6f0b46718511f
+size 158064
diff --git a/assets/diffsplat/2_wukong_sculpture.png b/assets/diffsplat/2_wukong_sculpture.png
new file mode 100644
index 0000000000000000000000000000000000000000..42450a2b0625fc8fb5017a207a82d19d3eafdeb5
--- /dev/null
+++ b/assets/diffsplat/2_wukong_sculpture.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1511ad5001f572f3a93fba1275536e7936af4f4d2232f71af23ac1c4ef784dc4
+size 219685
diff --git a/assets/diffsplat/3_wukong_toy.png b/assets/diffsplat/3_wukong_toy.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8b40974ec0d27a97c7c82fe1bc3bb37f5b32aae
--- /dev/null
+++ b/assets/diffsplat/3_wukong_toy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c176df9ead613543b896eddc1c002164ea729d61b4bc061d2d9a09ce61577c5
+size 182510
diff --git a/assets/diffsplat/4_mask.png b/assets/diffsplat/4_mask.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6974b9c32e26726eb8f045fe886983d96e5f642
--- /dev/null
+++ b/assets/diffsplat/4_mask.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:551816b16c210ccb2a7dc0cfc3700268cbc375d65047a20600b15eafd55b9323
+size 314414
diff --git a/assets/diffsplat/5_bajie.png b/assets/diffsplat/5_bajie.png
new file mode 100644
index 0000000000000000000000000000000000000000..635c12ec355a2fe9ffe3f37f5fbbfb156a62eead
--- /dev/null
+++ b/assets/diffsplat/5_bajie.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6f82ff89c16470a6d78f82010a67bbf178e33a6cd03fb076ac91367150b94111
+size 216800
diff --git a/assets/diffsplat/6_armor.png b/assets/diffsplat/6_armor.png
new file mode 100644
index 0000000000000000000000000000000000000000..2037f9b99e877765840290dbbf0710cdc8a91a34
--- /dev/null
+++ b/assets/diffsplat/6_armor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e2e0a0a6f8500e775cdada21a820d1b1e8b9f2a301ece3d3736b598f74f3ce95
+size 202132
diff --git a/assets/diffsplat/controlnet/cookie_canny.png b/assets/diffsplat/controlnet/cookie_canny.png
new file mode 100644
index 0000000000000000000000000000000000000000..847196abd6bd685520a9cf1a5b5a499b1e331a34
Binary files /dev/null and b/assets/diffsplat/controlnet/cookie_canny.png differ
diff --git a/assets/diffsplat/controlnet/cookie_image.png b/assets/diffsplat/controlnet/cookie_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ea0385e6a209c752f2a0621d6e6dd3f54d7962d
Binary files /dev/null and b/assets/diffsplat/controlnet/cookie_image.png differ
diff --git a/assets/diffsplat/controlnet/robot_image.png b/assets/diffsplat/controlnet/robot_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..68d73472c0bee8ec242cbe621ca6f2c42a4f47c6
Binary files /dev/null and b/assets/diffsplat/controlnet/robot_image.png differ
diff --git a/assets/diffsplat/controlnet/robot_normal.png b/assets/diffsplat/controlnet/robot_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..13cb61f2e6285ab9431aef0f182eceb1144369d2
Binary files /dev/null and b/assets/diffsplat/controlnet/robot_normal.png differ
diff --git a/assets/diffsplat/controlnet/toy_depth.png b/assets/diffsplat/controlnet/toy_depth.png
new file mode 100644
index 0000000000000000000000000000000000000000..076080654d0d8e55e06a6ab844bc7bf793c1bfb9
Binary files /dev/null and b/assets/diffsplat/controlnet/toy_depth.png differ
diff --git a/assets/diffsplat/controlnet/toy_image.png b/assets/diffsplat/controlnet/toy_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca11440dd440b979ec596e67ac80be504349fad8
Binary files /dev/null and b/assets/diffsplat/controlnet/toy_image.png differ
diff --git a/assets/grm/1.jpg b/assets/grm/1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0e74fe4572f9c6d22e57a45c8f9b88c75613849e
Binary files /dev/null and b/assets/grm/1.jpg differ
diff --git a/assets/grm/17_dalle3_rockingchair1.png b/assets/grm/17_dalle3_rockingchair1.png
new file mode 100644
index 0000000000000000000000000000000000000000..53fdc3299295f424d5ca1b9fba332cc3273c528f
--- /dev/null
+++ b/assets/grm/17_dalle3_rockingchair1.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6ad3eea0f2a98af1d5382787dda80c24b2061456ca8bde094cd9fc9308b178c3
+size 229625
diff --git a/assets/grm/19_dalle3_stump1.png b/assets/grm/19_dalle3_stump1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2adf9dbfa35aa3331fc370cafa0d0a230533300
--- /dev/null
+++ b/assets/grm/19_dalle3_stump1.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e64cbbc88f310487f5b2f3ed2eb7d1cd859adf4653e10173033ddee6562151e
+size 297214
diff --git a/assets/grm/astronaut.webp b/assets/grm/astronaut.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ed01d6dacbfa3c3ba279a50c682566d7302d4419
--- /dev/null
+++ b/assets/grm/astronaut.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c3e9157b31885c0fbccdba965f8ad1e27b51c41fbdb609ee8fc5728e6f4e4c3d
+size 101222
diff --git a/assets/grm/bag.jpg b/assets/grm/bag.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..56b537a5e5e0efcfb0f78a03de48d965d5e612f6
Binary files /dev/null and b/assets/grm/bag.jpg differ
diff --git a/assets/grm/bowl.png b/assets/grm/bowl.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d231ca9ab868b25201cd7459d815a7af8ad13ad
Binary files /dev/null and b/assets/grm/bowl.png differ
diff --git a/assets/grm/cdog.webp b/assets/grm/cdog.webp
new file mode 100644
index 0000000000000000000000000000000000000000..47fdee13499f2669bd008433936edbe8ed4db0a7
Binary files /dev/null and b/assets/grm/cdog.webp differ
diff --git a/assets/grm/coat.webp b/assets/grm/coat.webp
new file mode 100644
index 0000000000000000000000000000000000000000..406e7ab97959e88f63eee028d7696687df1cf253
--- /dev/null
+++ b/assets/grm/coat.webp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:305350bc90ee39fcabb3422edabbfd2da9d14d9fbf2495accb0fa00b35310aa3
+size 118880
diff --git a/assets/grm/david.jpg b/assets/grm/david.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d537863a4f8f239ed0d505299128db0524b75f52
Binary files /dev/null and b/assets/grm/david.jpg differ
diff --git a/assets/grm/david.png b/assets/grm/david.png
new file mode 100644
index 0000000000000000000000000000000000000000..01cd9c13d3e4bea75be97a8d819d7efde954b6bd
--- /dev/null
+++ b/assets/grm/david.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:80dd9a9c5338102f98ef8e49cf0ccadd9fbde280a707e667ffacfba82889aa08
+size 1055419
diff --git a/assets/grm/dragon2.png b/assets/grm/dragon2.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba7b2941c6aeae29ca94845f7de446df56e460f7
Binary files /dev/null and b/assets/grm/dragon2.png differ
diff --git a/assets/grm/dreamcraft3d_00.png b/assets/grm/dreamcraft3d_00.png
new file mode 100644
index 0000000000000000000000000000000000000000..cfcd54a1c6d180cfe2ab82ca8a8a657075b03a6e
--- /dev/null
+++ b/assets/grm/dreamcraft3d_00.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cc16c6845cc2c6c47da5fbe48c4c14f9f8e9fc8986689b1f2232b6d4c0a72a2c
+size 852221
diff --git a/assets/grm/dreamcraft3d_01.png b/assets/grm/dreamcraft3d_01.png
new file mode 100644
index 0000000000000000000000000000000000000000..24113f947faa06c50b1fc56288170d53bb61ec0c
--- /dev/null
+++ b/assets/grm/dreamcraft3d_01.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:227e21f29fe16d75fbac2c8588e97a7d082a721bdf4669ce317390ee551986fb
+size 427339
diff --git a/assets/grm/dreamcraft3d_02.png b/assets/grm/dreamcraft3d_02.png
new file mode 100644
index 0000000000000000000000000000000000000000..8176db1d0650d3b243c36ec0f3c23834b8411214
--- /dev/null
+++ b/assets/grm/dreamcraft3d_02.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0d0e5c9d9e144c316628d08f77bdb7e1c99cf7456af34fa624afbc9a8fabcc1
+size 571509
diff --git a/assets/grm/frog.png b/assets/grm/frog.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4061202780eebdf9edf394c42e96f894c52bd59
--- /dev/null
+++ b/assets/grm/frog.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:833c58c63c9a48af2b0b425fde42420ed1b76fa4e7ba1e1ce07e3424d2c278cf
+size 122763
diff --git a/assets/grm/girl.jpg b/assets/grm/girl.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d93c5a9a3831cb70c5376f58def7bbac1e0bc9f1
Binary files /dev/null and b/assets/grm/girl.jpg differ
diff --git a/assets/grm/girl1_padded.png b/assets/grm/girl1_padded.png
new file mode 100644
index 0000000000000000000000000000000000000000..22b6f0dd2aa7e9e0b6229137859c000b5e507924
--- /dev/null
+++ b/assets/grm/girl1_padded.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df527f5087938e806368768665327e68e7787ec606fe6683ba9e319c1e534620
+size 396238
diff --git a/assets/grm/girl2_copy.png b/assets/grm/girl2_copy.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bc78ca319608d1625ba23d6a30973ee7247c8ff
--- /dev/null
+++ b/assets/grm/girl2_copy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0454503f1ba2589f717e808e58efea47abd53b19a93bbf11d1ce863c021670c7
+size 975258
diff --git a/assets/grm/horse.jpg b/assets/grm/horse.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e42da5cb8cccad969d0d558f98be923b1749356c
Binary files /dev/null and b/assets/grm/horse.jpg differ
diff --git a/assets/grm/horsing.webp b/assets/grm/horsing.webp
new file mode 100644
index 0000000000000000000000000000000000000000..eec24ab04a9dec91f930513a6466e0fae9d67f5f
Binary files /dev/null and b/assets/grm/horsing.webp differ
diff --git a/assets/grm/image.png b/assets/grm/image.png
new file mode 100644
index 0000000000000000000000000000000000000000..3af5cc15493ca7c0412f3e9412ba661c39991ce9
--- /dev/null
+++ b/assets/grm/image.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:84774c4af538873ad544d6d392f5697e8d2f3601902d33fc7e7eebe7df8b6684
+size 141669
diff --git a/assets/grm/ironman_helmet.png b/assets/grm/ironman_helmet.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ee8b44c729f71e528394a7ee8a91a4a8e584b59
--- /dev/null
+++ b/assets/grm/ironman_helmet.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d39b19694548e9cbbeedf42fd51fb4709a5285d7435ffd231ac642898c019b97
+size 233244
diff --git a/assets/grm/kunkun.webp b/assets/grm/kunkun.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a0c45d3c7091cdad8ef69374a9cbd065353e7982
Binary files /dev/null and b/assets/grm/kunkun.webp differ
diff --git a/assets/grm/panda.png b/assets/grm/panda.png
new file mode 100644
index 0000000000000000000000000000000000000000..f283753d2a17fa46ac2b8dd76afe998284e1ba03
--- /dev/null
+++ b/assets/grm/panda.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c82fea6ac66b782b2aa1c6bd133447b5f54f688c7eb44998c4b00f190d47b2b7
+size 1517334
diff --git a/assets/grm/porsche.png b/assets/grm/porsche.png
new file mode 100644
index 0000000000000000000000000000000000000000..80c57aac57bd6aac8bac3ea288f43fcbeb575e28
Binary files /dev/null and b/assets/grm/porsche.png differ
diff --git a/assets/grm/pumpkin.png b/assets/grm/pumpkin.png
new file mode 100644
index 0000000000000000000000000000000000000000..495bd111ab789e7c673ef184d901e42ec54a5216
Binary files /dev/null and b/assets/grm/pumpkin.png differ
diff --git a/assets/grm/sculpture_0.png b/assets/grm/sculpture_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..674fc689802ff556c793dcf8dfacc3eeca01de70
--- /dev/null
+++ b/assets/grm/sculpture_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6ee7aeb4bb8314f0bd30d55a57693a785aaa9609286440cbb51fa4f2d35afe7c
+size 340977
diff --git a/assets/grm/sdog.webp b/assets/grm/sdog.webp
new file mode 100644
index 0000000000000000000000000000000000000000..839c455378b356c5e76ebbc122291bd56e71d89d
Binary files /dev/null and b/assets/grm/sdog.webp differ
diff --git a/assets/grm/turtle.png b/assets/grm/turtle.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c7091640694696833f8dd079ac9390135d240f1
--- /dev/null
+++ b/assets/grm/turtle.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:90be021b9add0ae22f25cadb9915934c4fc6df80da387b6c4aea0d44c6f39eda
+size 640466
diff --git a/assets/grm/unicorn.png b/assets/grm/unicorn.png
new file mode 100644
index 0000000000000000000000000000000000000000..0716e3cad3b4994390339bb2032cd179634d269b
--- /dev/null
+++ b/assets/grm/unicorn.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1211753fbc55a735dcf20724254e53542b12fe2bd247a43c46803ab258a7f8d7
+size 303939
diff --git a/assets/grm/yann-lecun.jpg b/assets/grm/yann-lecun.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4a15ae380e5e9224637c70f79cb72f37a91166b6
Binary files /dev/null and b/assets/grm/yann-lecun.jpg differ
diff --git a/assets/grm/zebra.png b/assets/grm/zebra.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d41aacb12dfcbb1836b2cab11d8366790718944
--- /dev/null
+++ b/assets/grm/zebra.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:233acdd71bd269dad96cbc8c82d67666dbec2cd164ac8c8886267d0d4acb04f6
+size 7852865
diff --git a/assets/instantmesh/bird.jpg b/assets/instantmesh/bird.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ac70a36ebefb87fb283f3bb95d07fe71700702a3
Binary files /dev/null and b/assets/instantmesh/bird.jpg differ
diff --git a/assets/instantmesh/blue_cat.png b/assets/instantmesh/blue_cat.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe7b00a6f8dfae195ae4644f5195d22bd8e3f997
--- /dev/null
+++ b/assets/instantmesh/blue_cat.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1da4904e53343ba03bf2c1e03e2de959a050080a45aff6da9673d04a44c02e60
+size 322226
diff --git a/assets/instantmesh/bubble_mart_blue.png b/assets/instantmesh/bubble_mart_blue.png
new file mode 100644
index 0000000000000000000000000000000000000000..7071ceaecd3e27af5296bc396ed5bedeec029b94
--- /dev/null
+++ b/assets/instantmesh/bubble_mart_blue.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e7c7e00de5fa8e59cc748345ecff9c712f887aaf07fd007b0aa9bc2933df50c
+size 211625
diff --git a/assets/instantmesh/bulldog.png b/assets/instantmesh/bulldog.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec0e12698dbd11138654cbbdbb39d975d34811a4
--- /dev/null
+++ b/assets/instantmesh/bulldog.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:422af31428e50ffb5a1c76479d0e13d30a16923660c3bbbd7117d5179c199443
+size 245711
diff --git a/assets/instantmesh/cake.jpg b/assets/instantmesh/cake.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..8dbebb6901e1230405be3451c0165e80458d5542
Binary files /dev/null and b/assets/instantmesh/cake.jpg differ
diff --git a/assets/instantmesh/cartoon_dinosaur.png b/assets/instantmesh/cartoon_dinosaur.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f6b4f976959a31f7816f75300ffc5fa069a647c
--- /dev/null
+++ b/assets/instantmesh/cartoon_dinosaur.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9c88289f72851efeb6dc8063b36ca3ea557257a9c78162ea1d37c0ec54cc1f1e
+size 727264
diff --git a/assets/instantmesh/cartoon_girl.jpg b/assets/instantmesh/cartoon_girl.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0664c7bb99a569faee449482ece59e3c32f06642
Binary files /dev/null and b/assets/instantmesh/cartoon_girl.jpg differ
diff --git a/assets/instantmesh/cartoon_panda.png b/assets/instantmesh/cartoon_panda.png
new file mode 100644
index 0000000000000000000000000000000000000000..f283753d2a17fa46ac2b8dd76afe998284e1ba03
--- /dev/null
+++ b/assets/instantmesh/cartoon_panda.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c82fea6ac66b782b2aa1c6bd133447b5f54f688c7eb44998c4b00f190d47b2b7
+size 1517334
diff --git a/assets/instantmesh/chair_armed.png b/assets/instantmesh/chair_armed.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5443525deed614e725e82f3cdf482ad5f3a1776
--- /dev/null
+++ b/assets/instantmesh/chair_armed.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7354b4e51dfcd903b93342b6b300a830c306c2ea8a6e2ed4183436f245b3a705
+size 183535
diff --git a/assets/instantmesh/chair_comfort.jpg b/assets/instantmesh/chair_comfort.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..918347fe51773d7ecaa7fb929274db8d7d5d3e19
Binary files /dev/null and b/assets/instantmesh/chair_comfort.jpg differ
diff --git a/assets/instantmesh/chair_watermelon.png b/assets/instantmesh/chair_watermelon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e663c998a1d47038efd2913a534c0c729599d7aa
--- /dev/null
+++ b/assets/instantmesh/chair_watermelon.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d6cb654c48e0219a9f3e01d57c853a481a3b2d5963cd8cc66da90ac0c8208be
+size 582996
diff --git a/assets/instantmesh/chair_wood.jpg b/assets/instantmesh/chair_wood.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bc60569896fb02a46185aabb85086890f0f400d7
Binary files /dev/null and b/assets/instantmesh/chair_wood.jpg differ
diff --git a/assets/instantmesh/cute_horse.jpg b/assets/instantmesh/cute_horse.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fe5ce2305d34070ac70facb1111fed59c9ae0757
--- /dev/null
+++ b/assets/instantmesh/cute_horse.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fafbc59862e6bbc00bd3180afccd98223730ec13fca0fef2e8278e4ab828271a
+size 149846
diff --git a/assets/instantmesh/cute_tiger.jpg b/assets/instantmesh/cute_tiger.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..82e873258d9f3fd6d569205ab75deb8a26918356
Binary files /dev/null and b/assets/instantmesh/cute_tiger.jpg differ
diff --git a/assets/instantmesh/earphone.jpg b/assets/instantmesh/earphone.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..498e4196b0d68f8809d049e7178b80592a31a0a2
Binary files /dev/null and b/assets/instantmesh/earphone.jpg differ
diff --git a/assets/instantmesh/extinguisher.png b/assets/instantmesh/extinguisher.png
new file mode 100644
index 0000000000000000000000000000000000000000..98f43a66718d49980e61d466b652bfca0a7ae9df
Binary files /dev/null and b/assets/instantmesh/extinguisher.png differ
diff --git a/assets/instantmesh/fox.jpg b/assets/instantmesh/fox.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1f2efc1c3a9c4ad8f36ad93082c124c91a6e9ef7
Binary files /dev/null and b/assets/instantmesh/fox.jpg differ
diff --git a/assets/instantmesh/fruit.jpg b/assets/instantmesh/fruit.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..07034ad3721de0e09c7509b22a7d3bc9679304d0
Binary files /dev/null and b/assets/instantmesh/fruit.jpg differ
diff --git a/assets/instantmesh/fruit_elephant.jpg b/assets/instantmesh/fruit_elephant.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ef8eaf3b88ae0a38272b34802fe40032055afa58
Binary files /dev/null and b/assets/instantmesh/fruit_elephant.jpg differ
diff --git a/assets/instantmesh/genshin_building.png b/assets/instantmesh/genshin_building.png
new file mode 100644
index 0000000000000000000000000000000000000000..00b6a949d01283e1ae30fac4bd6040e13f18a055
Binary files /dev/null and b/assets/instantmesh/genshin_building.png differ
diff --git a/assets/instantmesh/genshin_teapot.png b/assets/instantmesh/genshin_teapot.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f13a6edfe67ced810b4513117279067f0360fae
Binary files /dev/null and b/assets/instantmesh/genshin_teapot.png differ
diff --git a/assets/instantmesh/hatsune_miku.png b/assets/instantmesh/hatsune_miku.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fecf005fdd56a396c4894256fbb98fcc1c4dd8f
Binary files /dev/null and b/assets/instantmesh/hatsune_miku.png differ
diff --git a/assets/instantmesh/house2.jpg b/assets/instantmesh/house2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2eb8d63a6b91d5b16e729710c8b703aa5c11f9e5
Binary files /dev/null and b/assets/instantmesh/house2.jpg differ
diff --git a/assets/instantmesh/mushroom_teapot.jpg b/assets/instantmesh/mushroom_teapot.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a6c767354305f5467a4c0d5f199eee2a120f4501
Binary files /dev/null and b/assets/instantmesh/mushroom_teapot.jpg differ
diff --git a/assets/instantmesh/pikachu.png b/assets/instantmesh/pikachu.png
new file mode 100644
index 0000000000000000000000000000000000000000..a18101471aed868507411ca976db45ad6f85e5f7
--- /dev/null
+++ b/assets/instantmesh/pikachu.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4dc29a081919dd556c9aeae861ccdfd3e1fc3ffdfcd3339cc718998646dde75b
+size 350156
diff --git a/assets/instantmesh/plant.jpg b/assets/instantmesh/plant.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3519c1639c3f837d9f1147cba1172e6aaab25a23
Binary files /dev/null and b/assets/instantmesh/plant.jpg differ
diff --git a/assets/instantmesh/robot.jpg b/assets/instantmesh/robot.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..929450fba69a20389f39d46cb51d27facc1bba6d
Binary files /dev/null and b/assets/instantmesh/robot.jpg differ
diff --git a/assets/instantmesh/sea_turtle.png b/assets/instantmesh/sea_turtle.png
new file mode 100644
index 0000000000000000000000000000000000000000..c86f1ed5645e6d8df98f4077b0f798c565ad00e8
--- /dev/null
+++ b/assets/instantmesh/sea_turtle.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:173b443924f5477e7f99f3f38055938d242e7fb5e6361a2f86d0a4d6b2575990
+size 185287
diff --git a/assets/instantmesh/skating_shoe.jpg b/assets/instantmesh/skating_shoe.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5f21cb1d43e9d42d2836118963fc1d2874523748
Binary files /dev/null and b/assets/instantmesh/skating_shoe.jpg differ
diff --git a/assets/instantmesh/sorting_board.png b/assets/instantmesh/sorting_board.png
new file mode 100644
index 0000000000000000000000000000000000000000..a40fb8362afce0e323dd4517bba784cc652f5f6c
Binary files /dev/null and b/assets/instantmesh/sorting_board.png differ
diff --git a/assets/instantmesh/sword.png b/assets/instantmesh/sword.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5fbee429889baba665da47434b926267f6a3dd6
--- /dev/null
+++ b/assets/instantmesh/sword.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:65ea113b08fb3999fab034b92f8d8fd067315c3c0da487affbd7d71ccf61b4fa
+size 850199
diff --git a/assets/instantmesh/teasure_chest.jpg b/assets/instantmesh/teasure_chest.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..26ae0b145887e43b850d298b94fe54828e909492
Binary files /dev/null and b/assets/instantmesh/teasure_chest.jpg differ
diff --git a/assets/lgm/anya_rgba.png b/assets/lgm/anya_rgba.png
new file mode 100644
index 0000000000000000000000000000000000000000..089499e16e410207c890b45bc865627352df967d
Binary files /dev/null and b/assets/lgm/anya_rgba.png differ
diff --git a/assets/lgm/bird_rgba.png b/assets/lgm/bird_rgba.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1940a7320ed524b047475a46d446fc7704044e4
Binary files /dev/null and b/assets/lgm/bird_rgba.png differ
diff --git a/assets/lgm/catstatue_rgba.png b/assets/lgm/catstatue_rgba.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b44eb51645f4ecf9e288c53a46000c5a795af69
Binary files /dev/null and b/assets/lgm/catstatue_rgba.png differ
diff --git a/assets/prompts/df67.txt b/assets/prompts/df67.txt
new file mode 100644
index 0000000000000000000000000000000000000000..44c6663893861501b3b243a414664b0be34b3280
--- /dev/null
+++ b/assets/prompts/df67.txt
@@ -0,0 +1,67 @@
+A DMC Delorean car
+A DSLR photo of pyramid shaped burrito with a slice cut out of it
+Coffee cup with many holes
+Two locomotives playing tug of war
+Wedding dress made of tentacles
+a Space Shuttle
+a baby grand piano viewed from far away
+a bald eagle
+a bear dressed as a lumberjack
+a beautiful violin sitting flat on a table
+a blue tulip
+a brain in a jar
+a cake in the shape of a train
+a porcelain dragon
+a classic Packard car
+a colorful camping tent in a patch of grass
+a completely destroyed car
+a cute steampunk elephant
+a dachsund wearing a boater hat
+a dalmation wearing a fireman's hat
+a drum set made of cheese
+a ghost eating a hamburger
+a golden goblet, low poly
+a green monster truck
+a hotdog in a tutu skirt
+a human skull with a vine growing through one of the eye sockets
+a knight chopping wood
+a lion's mane jellyfish
+a lionfish
+a majestic sailboat
+a metal sculpture of a lion's head, highly detailed
+a model of a house in Tudor style
+a pair of tan cowboy boots, studio lighting, product photography
+a palm tree, low poly 3d model
+a pile of dice on a green tabletop
+a plate piled high with chocolate chip cookies
+a plush t-rex dinosaur toy, studio lighting, high resolution
+a pug made out of modeling clay
+a rabbit, animated movie character, high detail 3d model
+a recliner chair
+a red cardinal bird singing
+a red convertible car with the top down
+a red rotary telephone
+a ripe strawberry
+a roast turkey on a platter
+a robot tiger
+a rotary telephone carved out of wood
+a roulette wheel
+a shiny silver robot cat
+a small saguaro cactus planted in a clay pot
+a spanish galleon sailing on the open sea
+a stack of pancakes covered in maple syrup
+a steampunk space ship designed in the 18th century
+a teal moped
+a toy robot
+a tree stump with an axe buried in it
+a typewriter
+edible typewriter made out of vegetables
+a vintage record player
+a woolly mammoth standing on ice
+an expensive office chair
+an ice cream sundae
+an old vintage car
+an orchid flower planted in a clay pot
+an origami crane
+an origami motorcycle
+the Imperial State Crown of England
diff --git a/assets/prompts/gpteval3d.txt b/assets/prompts/gpteval3d.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c19f991e48e2ed053f9fb63d4bf3aa1a8bb2671a
--- /dev/null
+++ b/assets/prompts/gpteval3d.txt
@@ -0,0 +1,110 @@
+A torn hat
+A soft sofa
+A rusty boat
+A rough rock
+A thorny rose
+A brick house
+A crying sofa
+A sleeping cat
+A twisted tower
+A shouting leaf
+A rubbery cactus
+A wooden bicycle
+A dancing elephant
+A pen leaking blue ink
+A pair of worn-out shoes
+A lamp casting a warm glow
+A book with a leather cover
+A teddy bear with a red bow
+A book left on a park bench
+Four ripe apples in a basket
+A boat floating on calm water
+A chair made from polished oak
+A bicycle leaning against a wall
+An origami crane made from a map
+A mug filled with steaming coffee
+A book bound in mysterious symbols
+A dog creating sand art on a beach
+Three vibrant balloons tied together
+A cat with two different colored eyes
+An orange tabby cat shaped cookie jar
+A quartet of mugs that sing in harmony
+Floating bonsai tree, roots in mid-air
+Brown rabbit nibbling on a clover leaf
+An embroidered silk pillow with tassels
+A guitar resting against an old oak tree
+A pen sitting atop a pile of manuscripts
+A bicycle that leaves a trail of flowers
+A weathered hiking backpack with patches
+Sand hourglass, sand glitters like stars
+A velvet diary, locks with a fingerprint
+Spotted ladybug crawling on a green leaf
+Gray squirrel with an acorn in its mouth
+A teddy bear, fur matted, one eye missing
+A golden retriever plush toy, floppy-eare
+A carved wooden bear with a salmon in mouth
+A cat pondering the mysteries of the universe
+A lamp casting shadows on an old, forgotten map
+Orange monarch butterfly resting on a dandelion
+Clownfish peeking out from sea anemone tendrils
+Caterpillar with a keyboard pattern on its back
+A quill pen, feather shifts through rainbow hues
+Green tree frog clinging to a rain-soaked window
+An old-fashioned rotary phone with a tangled cord
+Tortoise with a shell that looks like stained glass
+A plush octopus whose arms are gently waving pencils
+An assortment of vintage, fragrant perfumes on display
+A group of vibrant, chattering parrots perched together
+Swan with feathers resembling soft, white origami folds
+A quaint, little house nestled at the end of a winding path
+Flamingo balancing on a sphere instead of standing in water
+A bright yellow rubber duck gently floats in a sudsy bathtub
+A collection of fresh vegetables arranged in a wicker basket
+An ancient, weathered statue, now covered in a blanket of moss
+A mesmerizing dance performed by a kaleidoscope of butterflies
+A lone, ancient tree stands tall in the middle of a quiet field
+A plush teddy bear, sitting alone with a slight tear in its seam
+A pair of hiking boots caked with mud at the doorstep of a cabin
+A worn leather recliner with a knitted throw draped over the back
+A small, intricately carved antique wooden box filled with mystery
+Frog with a translucent skin displaying a mechanical heart beating
+A small, rustic cabin sits alone in a peaceful, snow-covered forest
+Jellyfish with bioluminescent tentacles shaped like lightning bolts
+A floating teapot, pouring a stream of endless, steaming jasmine tea
+A smoldering campfire under a clear starry night, embers glowing softly
+A smartphone with a cracked screen lying on a coffee-stained office desk
+An ice cream scoop that serves up scoops of cloud fluff instead of ice cream
+A velvet-lined violin case, which opens to reveal a garden of miniature roses
+A hammock strung between two skyscrapers, swaying high above a neon cityscape
+A delicate porcelain teacup, painted with intricate flowers, rests on a saucer
+A sleek red sports car with chrome finishes parked by a bustling city sidewalk
+An ensemble of jellyfish-like hanging lamps, pulsing with soft bioluminescence
+A cluster of tents pitched near a forest, campfire smoke curling into the evening sky
+A colorful kite tangled in the branches of an oak tree, fabric fluttering in the wind
+A dragon-shaped kite, with scales that shimmer in the sunlight as it dances in the wind
+A stone bridge arching over a babbling brook, encrusted with moss and echoing with stories
+A sequence of street lamps, casting pools of light on cobblestone paths as twilight descends
+A bouquet of metallic flowers that bloom in response to moonlight, shimmering silver at night
+An array of small, solid, symmetrical, pastel-colored eggs, each revealing a miniature, enchanted forest scene when cracked open
+A heavy, layered, asymmetrical winter quilt, with a patchwork of plaid fabrics in reds and greens, folded at the foot of a well-made bed
+Various hollow, asymmetrical, textured seashells, collected in a sand-filled, clear glass jar with a twine-tied neck, displayed on a windowsill
+An old, solid, asymmetrical bronze bell, its contours irregular from centuries of use, with a green patina, sitting silent in an abandoned temple
+A small, hollow, asymmetrical birdhouse, painted in cheerful colors, with a round entrance and a tiny perch, swaying gently in a backyard apple tree
+An ensemble of hollow, irregularly shaped musical instruments, including a saxophone, a violin, and a drum, resting on a stage before a jazz concert
+An assortment of solid, symmetrical, smooth marbles, each one a different color with a unique swirl pattern, scattered playfully across a hardwood floor
+A medium-sized, layered, radially symmetrical conch shell, with a rough texture on the outside, fading from pink to cream, sitting alone on a sandy beach
+Several large, solid, symmetrical hay bales, with a rough, golden texture, scattered across a rural, open field, with the setting sun casting long shadows
+An old, layered, asymmetrical lantern, with a patina copper finish and translucent panes that flicker with bioluminescent light from cultured algae within
+A collection of solid, irregularly shaped hand tools, with wooden handles and metal ends, well-used and slightly rusty, hanging on a pegboard in a workshop
+Several solid, spherical, weathered cannonballs, with a rough cast-iron texture, lying beside a rusted cannon in a historical fort overlooking a serene bay
+A small, solid, geometrically spherical, metallic orb, with a glossy ruby finish, nestled in a nest of black velvet, untouched and gleaming under a spotlight
+An intricately carved, solid, wooden figurine, with jagged contours depicting an ancient deity, the wood grain visible under a matte finish, on a stone altar
+A large, multi-layered, symmetrical wedding cake, with smooth fondant, delicate piping, and lifelike sugar flowers in full bloom, displayed on a silver stand
+A large, hollow, asymmetrically shaped amphitheater, with jagged stone seating, nestled in a natural landscape, a classical play being performed as the sun sets
+A medium-sized, hollow, asymmetrical teapot, crafted to look like a slumbering dragon, with a scaly, rough texture and smoke gently wafting from its snout-spout
+A solid, smooth, symmetrical porcelain teapot, with a cobalt blue dragon design, steam rising from the spout, suggesting it's just been filled with boiling water
+A compact, cylindrical, vintage pepper mill, with a polished, ornate brass body, slightly worn from use, placed beside a porcelain plate on a checkered tablecloth
+Several large, solid, cube-shaped parcels, wrapped in brown paper and tied with string, each labeled with a different destination, awaiting dispatch in a post office
+An oversized, porous, sphere-shaped birdcage, made of woven golden wires, with a matte finish, housing a small, mechanical, singing bird that flutters in a lifelike manner
+A small, solid, radially symmetrical, iridescent abalone shell, with jagged contours, hosting a miniature, tranquil Zen garden complete with tiny, raked sand and micro bonsai
+A solid, symmetrical, smooth stone fountain, with water cascading over its edges into a clear, circular pond surrounded by blooming lilies, in the center of a sunlit courtyard
diff --git a/assets/prompts/instant3d.txt b/assets/prompts/instant3d.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e2812ee60d1012fee3e5c5baed16cf78c13f84b4
--- /dev/null
+++ b/assets/prompts/instant3d.txt
@@ -0,0 +1,112 @@
+a bear dancing ballet
+a woolly mammoth standing on ice
+a rotary telephone carved out of wood
+the titanic, aerial view
+a barbecue grill cooking sausages and burger patties
+a yorkie dog wearing extremely cool sneakers
+a yorkie dog eating a donut
+a beautiful rainbow fish
+a tiger waiter at a fancy restaurant
+an origami hippo in a river
+a frog wearing a sweater
+a covered wagon
+Michelangelo style statue of an astronaut
+a humanoid robot lying on a couch using a laptop
+a yorkie dog dressed as a maid
+a kangaroo sitting on a bench playing the accordion
+a red-eyed tree frog
+a robot tiger
+a blue jay standing on a large basket of rainbow macarons
+a shiba inu playing golf wearing tartan golf clothes and hat
+a dog made out of salad
+a cocker spaniel wearing a crown
+a vintage record player
+a chimpanzee dressed as a football player
+a baby dragon drinking boba
+a ghost eating a hamburger
+a hippo wearing a sweater
+a panda rowing a boat in a pond
+a plush dragon toy
+a squirrel dressed like Henry VIII King of England
+a tiger karate master
+a train engine made out of clay
+a mountain goat standing on a boulder
+two gummy bears playing dominoes
+a baby monkey riding on a pig
+an eggshell broken in two with an adorable chick standing next to it
+a train engine made out of clay
+an amigurumi bulldozer
+an old vintage car
+a cat wearing a lion costume
+a plate of delicious tacos
+a snail on a leaf
+an extravagant mansion, aerial view
+a drum set made of cheese
+a bulldozer clearing away a pile of snow
+an old car overgrown by vines and weeds
+a capybara wearing a top hat, low poly
+a ceramic upside down yellow octopus holding a blue green ceramic cup
+an opulent couch from the palace of Versailles
+a hippo biting through a watermelon
+a tiger karate master
+baby elephant jumping on a trampoline
+a colorful camping tent in a patch of grass
+a fox playing the cello
+an origami bulldozer sitting on the ground
+a group of squirrels rowing crew
+a squirrel gesturing in front of an easel showing colorful pie charts
+a chihuahua lying in a pool ring
+a lobster playing the saxophone
+a construction excavator
+a pig playing a drum set
+an orc forging a hammer on an anvil
+a marble bust of a fox head
+Michelangelo style statue of dog reading news on a cellphone
+a hippo wearing a sweater
+a porcelain dragon
+a baby dragon hatching out of a stone egg
+a human skeleton relaxing in a lounge chair
+a chimpanzee dressed like Napoleon Bonaparte
+a nest with a few white eggs and one golden egg
+a bald eagle
+a baby dragon drinking boba
+a ghost eating a hamburger
+a dachsund dressed up in a hotdog costume
+a robot made out of vegetables
+an octopus playing the piano
+a steaming basket full of dumplings
+a llama wearing a suit
+a chimpanzee dressed like Henry VIII king of England
+a panda rowing a boat in a pond
+a tiger dressed as a doctor
+a chihuahua wearing a tutu
+a plush toy of a corgi nurse
+a lionfish
+a panda wearing a necktie and sitting in an office chair
+an origami motorcycle
+a plush triceratops toy, studio lighting, high resolution
+two macaw parrots playing chess
+a teddy bear pushing a shopping cart full of fruits and vegetables
+a dachsund wearing a boater hat
+a pig playing the saxophone
+a lemur taking notes in a journal
+a group of dogs playing poker
+a blue motorcycle
+a pigeon reading a book
+a gummy bear playing the saxophone
+an amigurumi motorcycle
+a mouse holding a candlestick
+an ice cream sundae
+a bear dressed as a lumberjack
+a squirrel dressed like Henry VIII king of England
+a bumblebee sitting on a pink flower
+a pug wearing a bee costume
+a crab, low poly
+a wizard raccoon casting a spell
+two macaw parrots sharing a milkshake with two straws
+an orangutan making a clay bowl on a throwing wheel
+an orchid flower planted in a clay pot
+a tray of Sushi containing pugs
+an egg cracked open with a newborn chick hatching out of it
+a wide angle DSLR photo of a colorful rooster
+a pirate collie dog, high resolution
diff --git a/assets/prompts/instant3d_subset.txt b/assets/prompts/instant3d_subset.txt
new file mode 100644
index 0000000000000000000000000000000000000000..547c6ab7271cccdea64dc8b8e54214ace09038d5
--- /dev/null
+++ b/assets/prompts/instant3d_subset.txt
@@ -0,0 +1,16 @@
+a hippo wearing a sweater
+a plush dragon toy
+an old car overgrown by vines and weeds
+an origami bulldozer sitting on the ground
+a chimpanzee dressed as a football player
+a red-eye tree frog
+a ghost eating a hamburger
+a squirrel dressed like Henry VIII King of England
+a tiger karate master
+a train engine made out of clay
+a dog made out of salad
+baby dragon drinking boba
+a bear dancing ballet
+a robot tiger
+a yorkie dog wearing extremely cool sneakers
+a pigeon reading a book
diff --git a/assets/prompts/t3bench.txt b/assets/prompts/t3bench.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3f9baf2ded049a1600ae43f00306ebe7299c3baf
--- /dev/null
+++ b/assets/prompts/t3bench.txt
@@ -0,0 +1,300 @@
+A cactus with pink flowers
+A rainbow-colored umbrella
+An antique wooden rocking horse
+A golden retriever with a blue bowtie
+An ivory candlestick holder
+A pair of polka-dotted sneakers
+A steaming mug of hot chocolate with whipped cream
+A bright red fire hydrant
+A gleaming silver saxophone
+A leather-bound book with gold details
+A vibrant sunflower with green leaves
+A castle-shaped sandcastle
+A neon green skateboard with black wheels
+A pirate flag with skull and crossbones
+A plush teddy bear with a satin bow
+A ripe watermelon sliced in half
+A sparkling diamond ring in a velvet box
+A vintage porcelain doll with a frilly dress
+A chameleon perched on a tree branch
+A tarnished brass pocket watch
+A ceramic teapot with floral patterns
+An antique ruby-studded brooch
+A simple burgundy colored feather quill
+A vintage iron-cast typewriter
+A shiny emerald green beetle
+A crystal glass paperweight with abstract design
+A velvet cushion stitched with golden threads
+A small porcelain white rabbit figurine
+A left-handed electric guitar painted black
+A bright blue plastic swimming goggles
+A partly broken shell of a tortoise
+A long woolen scarf, striped red and black
+A tattered old explorer’s map
+A well-used black iron frying pan
+A crumpled silver aluminum soda can
+A thick, green-spined book with yellowed pages
+A shimmering emerald pendant necklace
+A well-worn straw sun hat
+A tarnished silver letter opener
+An antique glass perfume bottle
+A polished mahogany grand piano
+A dented brass trumpet
+A pristine white wedding gown
+A chipped porcelain teacup
+A rustic wrought-iron candle holder
+A vibrant, handmade patchwork quilt
+A plush velvet armchair
+A sleek, black top hat
+A paint-splattered easel
+A bent steel crowbar
+A crisp paper airplane
+A worn-out rubber tire swing
+An intricately-carved wooden chess set
+A bright red kite with a frayed tail
+A smooth, round opal stone
+A rusty, vintage metal key
+A delicate, handmade lace doily
+A sturdy mahogany walking cane
+A sparkling crystal chandelier
+A worn-out red flannel shirt
+A cracked porcelain doll's face
+A dusty classic typewriter
+A glossy grand black piano
+A faux-fur leopard print hat
+A futuristic, sleek electric car model
+A cherry red vintage lipstick tube
+A cobweb-covered old wooden chest
+A gold glittery carnival mask
+A tattered world map with stained edges
+A shiny red apple
+A worn-out leather briefcase
+An antique gold pocket watch
+A sleek, slim smartphone
+A wet, vibrant beach ball
+A rusty, abandoned bicycle
+A fluffy, orange cat
+Crisp, folded origami paper
+A shiny, new electric guitar
+A weather-beaten wooden bat
+A delicate crystal champagne flute
+An old, frayed straw hat
+A scuffed up soccer ball
+A pair of worn-in blue jeans
+A well-loved stuffed teddy bear
+A chipped, white coffee mug
+A bright, yellow rubber duck
+A sleek stainless steel teapot
+A water-streaked glass window pane
+An intricate ceramic vase with peonies painted on it
+A fuzzy pink flamingo lawn ornament
+A blooming potted orchid with purple flowers
+An old bronze ship's wheel
+A sparkling diamond tiara
+A vintage plaid woolen blanket
+A pair of shiny black patent leather shoes
+An elegant feather-quill ink pen
+A fragrant pine Christmas wreath
+A silver mirror with ornate detailing
+A green enameled watering can
+A classic leatherette radio with dials
+A white seashell on a sandy beach
+A vintage clock hanging on a brick wall
+A pair of glasses on an open notebook
+A green cactus in a clay pot
+A colorful kite flying in a clear sky
+A wooden rocking chair on a porch
+A silver spoon in a bowl of soup
+A black cat sleeping on a windowsill
+A bluebird perched on a tree branch
+A pair of sneakers hanging from a power line
+A yellow umbrella on a rainy day
+A pink bicycle leaning against a fence
+A snowman wearing a scarf in a winter landscape
+A leather-bound book on a wooden table
+A red rose in a crystal vase
+A jar of homemade jam on a kitchen counter
+A pair of ballet shoes on a dance floor
+A green turtle swimming in a clear pond
+A rainbow-colored kite soaring in the sky
+A chocolate cake on a white plate
+A pair of binoculars on a mountain peak
+A teddy bear on a child's bed
+A pair of blue jeans hanging on a clothesline
+A bright sunflower in a field
+A colorful parrot on a jungle tree
+A lighthouse on a rocky shore
+A pair of hiking boots on a trail
+A red and white lighthouse on a cliff
+A yellow school bus on a city street
+A pair of lovebirds in a golden cage
+A white sailboat on a calm sea
+A vintage typewriter on a desk
+A ripe watermelon on a picnic table
+A stack of pancakes on a breakfast table
+A green frog on a lily pad
+A pair of mittens on a snowy day
+A blue butterfly on a pink flower
+A red fire hydrant on a sidewalk
+A pair of cowboy boots in a barn
+A black and white photo in a silver frame
+A rainbow over a waterfall
+A white dove flying in a blue sky
+A pink piggy bank on a shelf
+A pair of scissors on a craft table
+A red barn in a green field
+A pair of flip flops on a beach
+A hot air balloon in a clear sky
+A green apple on a teacher's desk
+A yellow rubber duck in a bathtub
+A white swan on a tranquil lake
+A red cardinal on a snowy branch
+A black and white soccer ball on a field
+A silver teapot on a dining table
+A red and white candy cane on a Christmas tree
+A pair of red boxing gloves hanging on a wall
+A white wedding dress on a hanger
+A brown leather suitcase on a train platform
+A pink flamingo in a zoo
+A pair of green wellies in a puddle
+A black grand piano in a concert hall
+A white picket fence around a garden
+A blue whale in the deep ocean
+A brown horse in a green pasture
+A brown teddy bear in a toy shop
+A brown leather suitcase at an airport
+A green wellington boot in mud
+A blue and white china cup on a saucer
+A silver laptop sitting on a wooden desk
+A blue ceramic mug filled with steaming coffee
+A vintage pocket watch with a golden chain
+A green leather-bound book on an antique shelf
+A pair of white sneakers on a black mat
+A golden locket with a delicate chain
+A white porcelain teapot on a lace tablecloth
+A silver telescope pointing towards the starry sky
+A purple umbrella left on a park bench
+A wooden rocking horse in a child's playroom
+A red apple resting on a white ceramic plate
+A green paperback novel lying on a beige couch
+A white cotton t-shirt hanging on a wooden hanger
+A silver wristwatch ticking on a glass bedside table
+A pink ceramic vase filled with fresh white lilies
+A gold necklace with a diamond pendant displayed in a velvet box
+A black and white photograph framed in dark mahogany
+A pair of red high-heeled shoes sitting in a shoebox
+A blue denim jacket draped over a wooden chair
+A purple yoga mat rolled up in a gym bag
+A silver toaster with two slices of bread browning
+A red ceramic coffee mug sitting on a wooden table
+A green plastic watering can filled with fresh water
+A shiny gold pocket watch ticking away in a velvet box
+A blue denim jacket hanging on a metal coat rack
+A pair of brown leather boots standing at the front door
+A crystal chandelier sparkling in the grand foyer
+A fluffy white pillow resting on a red velvet couch
+A vibrant orange pumpkin sitting on a hay bale
+A striped beach umbrella standing tall on a sandy beach
+A stainless steel toaster sitting on a marble countertop
+A delicate china teacup resting on a lace doily
+A pair of neon running shoes waiting by the treadmill
+An artist is painting on a blank canvas
+A student is typing on his laptop
+A young gymnast trains with a balance beam
+A chef is making pizza dough in the kitchen
+A footballer is kicking a soccer ball
+A man is holding an umbrella against rain
+A girl is reading a hardcover book in her room
+A woman putting lipstick on in front of a mirror
+A worker is climbing a ladder to repair a roof
+A florist is making a bouquet with fresh flowers
+A boy is flying a colorful kite in the sky
+A gardener is watering plants with a hose
+A photographer is capturing a beautiful butterfly with his camera
+A scientist is examining a specimen under a microscope
+A drummer is beating the drumsticks on a drum
+A fisherman is throwing the fishing rod in the sea
+A baby is reaching for a teddy bear on the bed
+A candle burns beside an ancient, leather-bound book
+Colorful beads are scattered around a small, yellow sewing box
+A skateboard leans casually against a brightly-marked graffiti wall
+An apple lays nestled next to a vintage, brass pocket watch
+Two seashells gleam under the soft light of the moon
+A pair of worn ballet shoes rest next to a glossy violin
+A quill pen lies across a stack of unmarked parchment paper
+A baseball glove is forgotten next to a half-eaten hot dog
+A wine bottle and two empty glasses glisten under a chandelier
+A magnifying glass sits on top of a mysterious, printed map
+A black cat sleeps peacefully beside a carved pumpkin
+A weathered straw hat hangs beside a freshly picked sunflower
+An open diary lays flat, a single dried rose on its pages
+A twinkling star ornament hangs closely with a snow globe
+A chessboard is set up, the king and queen standing in opposition
+An elegant masquerade mask sits besides a velvet-handled brush
+A vintage typewriter shares space with a half-full bottle of whisky
+A teddy bear cuddles against a softly worn out children's book
+A sandy hourglass and a rugged compass lay side by side
+A pair of spectacles lies open on a dog-eared paperback
+A tarnished key lies next to a fading photograph
+Ripe apples cluster next to a gleaming knife
+An empty notebook rests beside a rustling quill
+An antique clock sits next to a fleeting hourglass
+Weathered boots stand next to a worn hiking stick
+A stack of vinyl records leans against an old gramophone
+A half-eaten sandwich sits next to a lukewarm thermos
+A flickering candle casts a dim light on a dusty mirror
+Luxurious perfume bottles sit next to a dainty jewelry box
+Burnt-out lightbulbs lie beside a discarded screwdriver
+Sandwiched between two hardbound novels lies a bookmark
+A broken tablespoon lies next to an empty sugar bowl
+A polished flute gleams next to hastily-scrawled sheet music
+A wine bottle rests besides a tall glass on a glossy surface
+A novel is sprawled open next to a pair of reading glasses
+An untouched slice of pizza is cooling beside a half-drunk can of soda
+A tangle of yarn rests beside a pair of silver knitting needles
+A violin reclines on a chair next to a music sheet filled with notes
+An exploded bottle of ink is smeared across a pile of papers
+A child's teddy bear is left abandoned near a frequently-read bedtime story book
+A brightly lit birthday cake is set near a closed, wrapped gift
+A dripping paintbrush stands poised above a half-finished canvas
+A silent alarm clock is glaring at a tousled pillow
+Two worn paddles rest next to an overturned canoe
+A crumpled sheet of paper lies beside a blue ink pen
+Two worn-out gym shoes are placed by the front door
+An abandoned teddy bear leans against a discarded toy car
+A bottle of red wine stands alongside an empty wine glass
+An old brass key sits next to an intricate, dust-covered lock
+Two silken, colorful scarves are knotted together
+A flickering candle stands beside a vintage photograph in a wooden frame
+A worn violin and a broken bow rest casually on a chair
+A chewed pencil rests alongside a frustration-filled sudoku puzzle
+A steaming teapot is standing next to a china teacup with roses
+A sprouting potted plant sits comfortably next to a watering can filled with water
+A camera with a telephoto lens rests atop a folded map of a city
+A novel rests atop a worn-out diary
+The golden trophy shines brightly next to a ruffled blue ribbon
+An antique clock and a retro radio compete for attention on the dusty shelf
+An artist's brush is soaked inwater, awaiting its turn beside a vibrant color palette
+A candle, half-burnt, emits an inviting scent near a generous plate of cookies
+Two wine glasses, one filled with red, the other white, touch in a graceful toast
+An old-fashioned typewriter aspires to outshine a sleek laptop
+A well-worn skateboard rests against a gleaming silver bike
+A ceramic elephant stands guard over an intricate puzzle yet to be completed
+The fragrance of an open perfume bottle mingles with the smell of a single red rose
+A pyramid of stacked poker chips dwarfs a pair of playing cards
+An oversharpened pencil argues with a ballpoint pen over a stash of blank paper
+A colorful array of spices in tiny jars sits next to an unused cooking book
+A warm, glowing lantern rests beside a well-read paperback book
+A treasure map, crumped and faded, cocooned beside an ornate compass
+Two vinyl records rest idly on the sputtering gramophone
+An envelope sealed with love stands demurely beside an ancient inkwell and a feather quill
+An open book sits beside a vintage brass spectacles
+Hot popcorn jump out from the red striped popcorn maker
+A rustic cowboy hat hangs on the rugged saddle
+A half-eaten slice of pizza forgotten beside a remote control
+A dripping paintbrush strokes a vibrant palette of colors
+A shimmering diamond necklace lays elegantly on a black velvet box
+A thick novel is accompanied by a steaming cup of cocoa
+A woolen knitted scarf is wrapped around a carved pumpkin
+A scratched surfboard lies in the sandy shadow of a worn-out straw hat
+An old brass key longs for the dusted antique chest it could unlock
diff --git a/assets/prompts/t3bench_multi.txt b/assets/prompts/t3bench_multi.txt
new file mode 100644
index 0000000000000000000000000000000000000000..aac03071ec49e3fe95e4f559ddcf4c9f51ea36b7
--- /dev/null
+++ b/assets/prompts/t3bench_multi.txt
@@ -0,0 +1,100 @@
+An artist is painting on a blank canvas
+A student is typing on his laptop
+A young gymnast trains with a balance beam
+A chef is making pizza dough in the kitchen
+A footballer is kicking a soccer ball
+A man is holding an umbrella against rain
+A girl is reading a hardcover book in her room
+A woman putting lipstick on in front of a mirror
+A worker is climbing a ladder to repair a roof
+A florist is making a bouquet with fresh flowers
+A boy is flying a colorful kite in the sky
+A gardener is watering plants with a hose
+A photographer is capturing a beautiful butterfly with his camera
+A scientist is examining a specimen under a microscope
+A drummer is beating the drumsticks on a drum
+A fisherman is throwing the fishing rod in the sea
+A baby is reaching for a teddy bear on the bed
+A candle burns beside an ancient, leather-bound book
+Colorful beads are scattered around a small, yellow sewing box
+A skateboard leans casually against a brightly-marked graffiti wall
+An apple lays nestled next to a vintage, brass pocket watch
+Two seashells gleam under the soft light of the moon
+A pair of worn ballet shoes rest next to a glossy violin
+A quill pen lies across a stack of unmarked parchment paper
+A baseball glove is forgotten next to a half-eaten hot dog
+A wine bottle and two empty glasses glisten under a chandelier
+A magnifying glass sits on top of a mysterious, printed map
+A black cat sleeps peacefully beside a carved pumpkin
+A weathered straw hat hangs beside a freshly picked sunflower
+An open diary lays flat, a single dried rose on its pages
+A twinkling star ornament hangs closely with a snow globe
+A chessboard is set up, the king and queen standing in opposition
+An elegant masquerade mask sits besides a velvet-handled brush
+A vintage typewriter shares space with a half-full bottle of whisky
+A teddy bear cuddles against a softly worn out children's book
+A sandy hourglass and a rugged compass lay side by side
+A pair of spectacles lies open on a dog-eared paperback
+A tarnished key lies next to a fading photograph
+Ripe apples cluster next to a gleaming knife
+An empty notebook rests beside a rustling quill
+An antique clock sits next to a fleeting hourglass
+Weathered boots stand next to a worn hiking stick
+A stack of vinyl records leans against an old gramophone
+A half-eaten sandwich sits next to a lukewarm thermos
+A flickering candle casts a dim light on a dusty mirror
+Luxurious perfume bottles sit next to a dainty jewelry box
+Burnt-out lightbulbs lie beside a discarded screwdriver
+Sandwiched between two hardbound novels lies a bookmark
+A broken tablespoon lies next to an empty sugar bowl
+A polished flute gleams next to hastily-scrawled sheet music
+A wine bottle rests besides a tall glass on a glossy surface
+A novel is sprawled open next to a pair of reading glasses
+An untouched slice of pizza is cooling beside a half-drunk can of soda
+A tangle of yarn rests beside a pair of silver knitting needles
+A violin reclines on a chair next to a music sheet filled with notes
+An exploded bottle of ink is smeared across a pile of papers
+A child's teddy bear is left abandoned near a frequently-read bedtime story book
+A brightly lit birthday cake is set near a closed, wrapped gift
+A dripping paintbrush stands poised above a half-finished canvas
+A silent alarm clock is glaring at a tousled pillow
+Two worn paddles rest next to an overturned canoe
+A crumpled sheet of paper lies beside a blue ink pen
+Two worn-out gym shoes are placed by the front door
+An abandoned teddy bear leans against a discarded toy car
+A bottle of red wine stands alongside an empty wine glass
+An old brass key sits next to an intricate, dust-covered lock
+Two silken, colorful scarves are knotted together
+A flickering candle stands beside a vintage photograph in a wooden frame
+A worn violin and a broken bow rest casually on a chair
+A chewed pencil rests alongside a frustration-filled sudoku puzzle
+A steaming teapot is standing next to a china teacup with roses
+A sprouting potted plant sits comfortably next to a watering can filled with water
+A camera with a telephoto lens rests atop a folded map of a city
+A novel rests atop a worn-out diary
+The golden trophy shines brightly next to a ruffled blue ribbon
+An antique clock and a retro radio compete for attention on the dusty shelf
+An artist's brush is soaked inwater, awaiting its turn beside a vibrant color palette
+A candle, half-burnt, emits an inviting scent near a generous plate of cookies
+Two wine glasses, one filled with red, the other white, touch in a graceful toast
+An old-fashioned typewriter aspires to outshine a sleek laptop
+A well-worn skateboard rests against a gleaming silver bike
+A ceramic elephant stands guard over an intricate puzzle yet to be completed
+The fragrance of an open perfume bottle mingles with the smell of a single red rose
+A pyramid of stacked poker chips dwarfs a pair of playing cards
+An oversharpened pencil argues with a ballpoint pen over a stash of blank paper
+A colorful array of spices in tiny jars sits next to an unused cooking book
+A warm, glowing lantern rests beside a well-read paperback book
+A treasure map, crumped and faded, cocooned beside an ornate compass
+Two vinyl records rest idly on the sputtering gramophone
+An envelope sealed with love stands demurely beside an ancient inkwell and a feather quill
+An open book sits beside a vintage brass spectacles
+Hot popcorn jump out from the red striped popcorn maker
+A rustic cowboy hat hangs on the rugged saddle
+A half-eaten slice of pizza forgotten beside a remote control
+A dripping paintbrush strokes a vibrant palette of colors
+A shimmering diamond necklace lays elegantly on a black velvet box
+A thick novel is accompanied by a steaming cup of cocoa
+A woolen knitted scarf is wrapped around a carved pumpkin
+A scratched surfboard lies in the sandy shadow of a worn-out straw hat
+An old brass key longs for the dusted antique chest it could unlock
diff --git a/assets/prompts/t3bench_single.txt b/assets/prompts/t3bench_single.txt
new file mode 100644
index 0000000000000000000000000000000000000000..00ee393d6334414d71d61e31d69ad5ac46b9b1f4
--- /dev/null
+++ b/assets/prompts/t3bench_single.txt
@@ -0,0 +1,100 @@
+A cactus with pink flowers
+A rainbow-colored umbrella
+An antique wooden rocking horse
+A golden retriever with a blue bowtie
+An ivory candlestick holder
+A pair of polka-dotted sneakers
+A steaming mug of hot chocolate with whipped cream
+A bright red fire hydrant
+A gleaming silver saxophone
+A leather-bound book with gold details
+A vibrant sunflower with green leaves
+A castle-shaped sandcastle
+A neon green skateboard with black wheels
+A pirate flag with skull and crossbones
+A plush teddy bear with a satin bow
+A ripe watermelon sliced in half
+A sparkling diamond ring in a velvet box
+A vintage porcelain doll with a frilly dress
+A chameleon perched on a tree branch
+A tarnished brass pocket watch
+A ceramic teapot with floral patterns
+An antique ruby-studded brooch
+A simple burgundy colored feather quill
+A vintage iron-cast typewriter
+A shiny emerald green beetle
+A crystal glass paperweight with abstract design
+A velvet cushion stitched with golden threads
+A small porcelain white rabbit figurine
+A left-handed electric guitar painted black
+A bright blue plastic swimming goggles
+A partly broken shell of a tortoise
+A long woolen scarf, striped red and black
+A tattered old explorer’s map
+A well-used black iron frying pan
+A crumpled silver aluminum soda can
+A thick, green-spined book with yellowed pages
+A shimmering emerald pendant necklace
+A well-worn straw sun hat
+A tarnished silver letter opener
+An antique glass perfume bottle
+A polished mahogany grand piano
+A dented brass trumpet
+A pristine white wedding gown
+A chipped porcelain teacup
+A rustic wrought-iron candle holder
+A vibrant, handmade patchwork quilt
+A plush velvet armchair
+A sleek, black top hat
+A paint-splattered easel
+A bent steel crowbar
+A crisp paper airplane
+A worn-out rubber tire swing
+An intricately-carved wooden chess set
+A bright red kite with a frayed tail
+A smooth, round opal stone
+A rusty, vintage metal key
+A delicate, handmade lace doily
+A sturdy mahogany walking cane
+A sparkling crystal chandelier
+A worn-out red flannel shirt
+A cracked porcelain doll's face
+A dusty classic typewriter
+A glossy grand black piano
+A faux-fur leopard print hat
+A futuristic, sleek electric car model
+A cherry red vintage lipstick tube
+A cobweb-covered old wooden chest
+A gold glittery carnival mask
+A tattered world map with stained edges
+A shiny red apple
+A worn-out leather briefcase
+An antique gold pocket watch
+A sleek, slim smartphone
+A wet, vibrant beach ball
+A rusty, abandoned bicycle
+A fluffy, orange cat
+Crisp, folded origami paper
+A shiny, new electric guitar
+A weather-beaten wooden bat
+A delicate crystal champagne flute
+An old, frayed straw hat
+A scuffed up soccer ball
+A pair of worn-in blue jeans
+A well-loved stuffed teddy bear
+A chipped, white coffee mug
+A bright, yellow rubber duck
+A sleek stainless steel teapot
+A water-streaked glass window pane
+An intricate ceramic vase with peonies painted on it
+A fuzzy pink flamingo lawn ornament
+A blooming potted orchid with purple flowers
+An old bronze ship's wheel
+A sparkling diamond tiara
+A vintage plaid woolen blanket
+A pair of shiny black patent leather shoes
+An elegant feather-quill ink pen
+A fragrant pine Christmas wreath
+A silver mirror with ornate detailing
+A green enameled watering can
+A classic leatherette radio with dials
diff --git a/assets/prompts/t3bench_surr.txt b/assets/prompts/t3bench_surr.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0163c022cdfcd665018b16f475da20d59316c6bb
--- /dev/null
+++ b/assets/prompts/t3bench_surr.txt
@@ -0,0 +1,100 @@
+A white seashell on a sandy beach
+A vintage clock hanging on a brick wall
+A pair of glasses on an open notebook
+A green cactus in a clay pot
+A colorful kite flying in a clear sky
+A wooden rocking chair on a porch
+A silver spoon in a bowl of soup
+A black cat sleeping on a windowsill
+A bluebird perched on a tree branch
+A pair of sneakers hanging from a power line
+A yellow umbrella on a rainy day
+A pink bicycle leaning against a fence
+A snowman wearing a scarf in a winter landscape
+A leather-bound book on a wooden table
+A red rose in a crystal vase
+A jar of homemade jam on a kitchen counter
+A pair of ballet shoes on a dance floor
+A green turtle swimming in a clear pond
+A rainbow-colored kite soaring in the sky
+A chocolate cake on a white plate
+A pair of binoculars on a mountain peak
+A teddy bear on a child's bed
+A pair of blue jeans hanging on a clothesline
+A bright sunflower in a field
+A colorful parrot on a jungle tree
+A lighthouse on a rocky shore
+A pair of hiking boots on a trail
+A red and white lighthouse on a cliff
+A yellow school bus on a city street
+A pair of lovebirds in a golden cage
+A white sailboat on a calm sea
+A vintage typewriter on a desk
+A ripe watermelon on a picnic table
+A stack of pancakes on a breakfast table
+A green frog on a lily pad
+A pair of mittens on a snowy day
+A blue butterfly on a pink flower
+A red fire hydrant on a sidewalk
+A pair of cowboy boots in a barn
+A black and white photo in a silver frame
+A rainbow over a waterfall
+A white dove flying in a blue sky
+A pink piggy bank on a shelf
+A pair of scissors on a craft table
+A red barn in a green field
+A pair of flip flops on a beach
+A hot air balloon in a clear sky
+A green apple on a teacher's desk
+A yellow rubber duck in a bathtub
+A white swan on a tranquil lake
+A red cardinal on a snowy branch
+A black and white soccer ball on a field
+A silver teapot on a dining table
+A red and white candy cane on a Christmas tree
+A pair of red boxing gloves hanging on a wall
+A white wedding dress on a hanger
+A brown leather suitcase on a train platform
+A pink flamingo in a zoo
+A pair of green wellies in a puddle
+A black grand piano in a concert hall
+A white picket fence around a garden
+A blue whale in the deep ocean
+A brown horse in a green pasture
+A brown teddy bear in a toy shop
+A brown leather suitcase at an airport
+A green wellington boot in mud
+A blue and white china cup on a saucer
+A silver laptop sitting on a wooden desk
+A blue ceramic mug filled with steaming coffee
+A vintage pocket watch with a golden chain
+A green leather-bound book on an antique shelf
+A pair of white sneakers on a black mat
+A golden locket with a delicate chain
+A white porcelain teapot on a lace tablecloth
+A silver telescope pointing towards the starry sky
+A purple umbrella left on a park bench
+A wooden rocking horse in a child's playroom
+A red apple resting on a white ceramic plate
+A green paperback novel lying on a beige couch
+A white cotton t-shirt hanging on a wooden hanger
+A silver wristwatch ticking on a glass bedside table
+A pink ceramic vase filled with fresh white lilies
+A gold necklace with a diamond pendant displayed in a velvet box
+A black and white photograph framed in dark mahogany
+A pair of red high-heeled shoes sitting in a shoebox
+A blue denim jacket draped over a wooden chair
+A purple yoga mat rolled up in a gym bag
+A silver toaster with two slices of bread browning
+A red ceramic coffee mug sitting on a wooden table
+A green plastic watering can filled with fresh water
+A shiny gold pocket watch ticking away in a velvet box
+A blue denim jacket hanging on a metal coat rack
+A pair of brown leather boots standing at the front door
+A crystal chandelier sparkling in the grand foyer
+A fluffy white pillow resting on a red velvet couch
+A vibrant orange pumpkin sitting on a hay bale
+A striped beach umbrella standing tall on a sandy beach
+A stainless steel toaster sitting on a marble countertop
+A delicate china teacup resting on a lace doily
+A pair of neon running shoes waiting by the treadmill
diff --git a/configs/elevest.yaml b/configs/elevest.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74893f7b0a88a30c38d93abad665d3d1109aaf45
--- /dev/null
+++ b/configs/elevest.yaml
@@ -0,0 +1,31 @@
+opt_type: "elevest"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.95
+ weight_decay: 0.05
+
+lr_scheduler:
+ name: "cosine_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 16
+ epochs: 30
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_paa.yaml b/configs/gsdiff_paa.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9aa996dcea85c21ebb7c1842218cec414c5b0bfc
--- /dev/null
+++ b/configs/gsdiff_paa.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_paa"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 8
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_pas.yaml b/configs/gsdiff_pas.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e477837cdfdcff1a7e25459374ccf9daa7565258
--- /dev/null
+++ b/configs/gsdiff_pas.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_pas"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 8
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_sd15.yaml b/configs/gsdiff_sd15.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8f8ef81e46d48bd9c1797336aa30dbff402d1c34
--- /dev/null
+++ b/configs/gsdiff_sd15.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_sd15"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 8
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_sd35m_80g.yaml b/configs/gsdiff_sd35m_80g.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8dbd8b1d6430ec823a68451039b7672acff19a52
--- /dev/null
+++ b/configs/gsdiff_sd35m_80g.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_sd35m"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 2
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_sd3m_80g.yaml b/configs/gsdiff_sd3m_80g.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9fbfa914489da5130550c6e93796e594fff34f35
--- /dev/null
+++ b/configs/gsdiff_sd3m_80g.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_sd3m"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 2
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsdiff_sdxl_80g.yaml b/configs/gsdiff_sdxl_80g.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..22ba7f5a641fabaf49a052044ed0ee5f232d2054
--- /dev/null
+++ b/configs/gsdiff_sdxl_80g.yaml
@@ -0,0 +1,32 @@
+opt_type: "gsdiff_sdxl"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0001
+ betas:
+ - 0.9
+ - 0.999
+ weight_decay: 0.01
+ eps: 1.e-8
+
+lr_scheduler:
+ name: "constant_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 2
+ epochs: 100
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsrecon.yaml b/configs/gsrecon.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..497905fd9a5dad8cfa9379e2ed0b039777c01f0c
--- /dev/null
+++ b/configs/gsrecon.yaml
@@ -0,0 +1,31 @@
+opt_type: "gsrecon"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0004
+ betas:
+ - 0.9
+ - 0.95
+ weight_decay: 0.05
+
+lr_scheduler:
+ name: "cosine_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 8
+ epochs: 30
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/configs/gsvae.yaml b/configs/gsvae.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cc3dfe38d498584c12b9e8854c41e76b88cc9f4d
--- /dev/null
+++ b/configs/gsvae.yaml
@@ -0,0 +1,31 @@
+opt_type: "gsvae"
+
+optimizer:
+ name: "adamw"
+ lr: 0.0004
+ betas:
+ - 0.9
+ - 0.95
+ weight_decay: 0.05
+
+lr_scheduler:
+ name: "cosine_warmup"
+ num_warmup_steps: 1000
+
+train:
+ batch_size_per_gpu: 2
+ epochs: 30
+ log_freq: 1
+ early_eval_freq: 100
+ eval_eval: 1000
+ save_freq: 2000
+ eval_freq_epoch: 5
+ save_freq_epoch: 10
+ ema_kwargs:
+ decay: 0.9999
+ use_ema_warmup: true
+ inv_gamma: 1.
+ power: 0.75
+
+val:
+ batch_size_per_gpu: 4
diff --git a/download_ckpt.py b/download_ckpt.py
new file mode 100644
index 0000000000000000000000000000000000000000..d6ad417c844ed52e0d8df265bde3dedc23a5d03d
--- /dev/null
+++ b/download_ckpt.py
@@ -0,0 +1,91 @@
+import os
+import argparse
+from huggingface_hub import snapshot_download
+
+
+def download_ckpt():
+ parser = argparse.ArgumentParser(description="Download checkpoints from HuggingFace Hub")
+ parser.add_argument(
+ "--local_dir",
+ type=str,
+ default="./out",
+ help="Local directory to save the checkpoints"
+ )
+ parser.add_argument(
+ "--model_type",
+ type=str,
+ default="sd15",
+ choices=["sd15", "pas", "sd35m", "depth", "normal", "canny", "elevest"],
+ help="Model type to download"
+ )
+ parser.add_argument(
+ "--image_cond",
+ action="store_true",
+ help="Whether to download image-conditioned models"
+ )
+
+ args = parser.parse_args()
+
+ repo_id, local_dir = "chenguolin/DiffSplat", args.local_dir
+ os.makedirs(local_dir, exist_ok=True)
+
+ model_type, image_cond = args.model_type, args.image_cond
+ suffix = "_image" if image_cond else ""
+
+ # DiffSplat (SD1.5)
+ if model_type == "sd15":
+ snapshot_download(
+ repo_id=repo_id,
+ local_dir=local_dir,
+ allow_patterns=[
+ "gsrecon_gobj265k_cnp_even4/*", # `GSRecon`
+ "gsvae_gobj265k_sd/*", # `GSVAE (SD)`
+ f"gsdiff_gobj83k_sd15{suffix}__render/*", # `DiffSplat (SD)`
+ ]
+ )
+ # DiffSplat (PixArt-Sigma)
+ elif model_type == "pas":
+ snapshot_download(
+ repo_id=repo_id,
+ local_dir=local_dir,
+ allow_patterns=[
+ "gsrecon_gobj265k_cnp_even4/*", # `GSRecon`
+ "gsvae_gobj265k_sdxl_fp16/*", # `GSVAE (SDXL)`
+ f"gsdiff_gobj83k_pas_fp16{suffix}__render/*", # `DiffSplat (PixArt-Sigma)`
+ ]
+ )
+ # DiffSplat (SD3.5m)
+ elif model_type == "sd35m":
+ snapshot_download(
+ repo_id=repo_id,
+ local_dir=local_dir,
+ allow_patterns=[
+ "gsrecon_gobj265k_cnp_even4/*", # `GSRecon`
+ "gsvae_gobj265k_sd3/*", # `GSVAE (SD3)`
+ f"gsdiff_gobj83k_sd35m{suffix}__render/*", # `DiffSplat (SD3.5m)`
+ ]
+ )
+ # DiffSplat ControlNet (SD1.5)
+ elif model_type in ["depth", "normal", "canny"]:
+ snapshot_download(
+ repo_id=repo_id,
+ local_dir=local_dir,
+ allow_patterns=[
+ f"gsdiff_gobj83k_sd15__render__{model_type}/*", # `DiffSplat ControlNet (SD1.5)`
+ ]
+ )
+ # Elevation Estimation
+ elif model_type == "elevest":
+ snapshot_download(
+ repo_id=repo_id,
+ local_dir=local_dir,
+ allow_patterns=[
+ "elevest_gobj265k_b_C25/*",
+ ]
+ )
+ else:
+ raise ValueError(f"Choose from ['sd15', 'pas', 'sd35m', 'depth', 'normal', 'canny', 'elevest'], but got [{model_type}]")
+
+
+if __name__ == "__main__":
+ download_ckpt()
diff --git a/extensions/RaDe-GS/.gitignore b/extensions/RaDe-GS/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..046f52ad7e7a6c9784971e0e42797d27b0f4cea0
--- /dev/null
+++ b/extensions/RaDe-GS/.gitignore
@@ -0,0 +1,19 @@
+*.pyc
+.vscode
+output*/
+build
+__pycache__
+tensorboard_3d
+screenshots
+debug/
+gaussian_renderer/__pycache__
+scene/__pycache__
+utils/__pycache__
+*.egg-info
+debug*
+dtu_eval/Offical_DTU_Dataset
+*.sh
+submodules/diff-gaussian-rasterization-org
+snapshot_fw.dump
+snapshot_bw.dump
+train_test_depth.py
\ No newline at end of file
diff --git a/extensions/RaDe-GS/.gitmodules b/extensions/RaDe-GS/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..ec0586f58c4961ad5079e2a26c83284590519d4e
--- /dev/null
+++ b/extensions/RaDe-GS/.gitmodules
@@ -0,0 +1,7 @@
+[submodule "submodules/simple-knn"]
+ path = submodules/simple-knn
+ url = https://gitlab.inria.fr/bkerbl/simple-knn.git
+
+[submodule "submodules/diff-gaussian-rasterization/third_party/glm"]
+ path = submodules/diff-gaussian-rasterization/third_party/glm
+ url = https://github.com/g-truc/glm.git
diff --git a/extensions/RaDe-GS/LICENSE.md b/extensions/RaDe-GS/LICENSE.md
new file mode 100644
index 0000000000000000000000000000000000000000..c869e695fa63bfde6f887d63a24a2a71f03480ac
--- /dev/null
+++ b/extensions/RaDe-GS/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/extensions/RaDe-GS/README.md b/extensions/RaDe-GS/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..31afd29bdf7390bfe2a70e9072cd213d531a3782
--- /dev/null
+++ b/extensions/RaDe-GS/README.md
@@ -0,0 +1,118 @@
+# RaDe-GS: Rasterizing Depth in Gaussian Splatting
+
+### RaDe-GS: Rasterizing Depth in Gaussian Splatting
+Baowen Zhang, Chuan Fang, Rakesh Shrestha, Yixun Liang, Xiaoxiao Long, Ping Tan
+
+[Project page](https://baowenz.github.io/radegs/)
+
+# News!
+### 1. We have updated the formluation of RaDe-GS (as shown in the 'Modifications'). It achieves better performance on TNT dataset.
+### 2. Now, we release the updated code of Marching Tetrahedra, based on [GOF](https://github.com/autonomousvision/gaussian-opacity-fields/blob/main/eval_tnt/run.py)'s orginal proposal. In our version, opacities are calculated in ray space, which better fits our needs.
+
+# Modifications
+
+1. We change to calculate depth using per-pixel cosine values (Eq. 14: $d=cos\theta\ t^*$). Additionally, an option is provided to directly render the camera space coordinate map. We utilize the inverse of affine approximation to transform intersections from ray space to camera space, and these transformed points are then used in computing normal consistency loss.
+2. The depth distortion loss has been eliminated from our training process. Currently, we rely solely on normal consistency loss for geometry regularization. We believe future techniques will enhance performance even further.
+
+
+# 1. Installation
+## Clone this repository.
+```
+git clone https://github.com/BaowenZ/RaDe-GS.git --recursive
+```
+
+## Install dependencies.
+1. create an environment
+```
+conda create -n radegs python=3.9
+conda activate radegs
+```
+
+2. install pytorch and other dependencies.
+```
+pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
+pip install -r requirements.txt
+```
+
+3. install submodules
+```
+pip install submodules/diff-gaussian-rasterization
+pip install submodules/simple-knn/
+
+# tetra-nerf for Marching Tetrahedra
+cd submodules/tetra_triangulation
+conda install cmake
+conda install conda-forge::gmp
+conda install conda-forge::cgal
+cmake .
+# you can specify your own cuda path
+# export CPATH=/usr/local/cuda-11.3/targets/x86_64-linux/include:$CPATH
+make
+pip install -e .
+```
+
+# 2. Preparation
+We use preprocessed DTU dataset from [2DGS](https://surfsplatting.github.io/) for training. And we follow GOF to evaluate the geometry. Point clouds from the [DTU dataset](https://roboimagedata.compute.dtu.dk/?page_id=36) need saved to dtu_eval/Offical_DTU_Dataset for the geometry evaluation.
+We use preprocessed Tanks and Temples dataset from [GOF](https://huggingface.co/datasets/ZehaoYu/gaussian-opacity-fields/tree/main). For evalution, please download ground truth point cloud, camera poses, alignments and cropfiles from [Tanks and Temples dataset](https://www.tanksandtemples.org/download/). The ground truth dataset should be organized as:
+```
+GT_TNT_dataset
+│
+└─── Barn
+│ │
+| └─── Barn.json
+│ │
+| └─── Barn.ply
+│ │
+| └─── Barn_COLMAP_SfM.log
+│ │
+| └─── Barn_trans.txt
+│
+└─── Caterpillar
+│ │
+......
+```
+
+# 3. Training and Evalution
+## DTU Dataset
+```
+# training
+python train.py -s -m -r 2 --use_decoupled_appearance
+# mesh extraction
+python mesh_extract.py -s -m -r 2
+# evaluation
+python evaluate_dtu_mesh.py -s -m
+```
+## TNT Dataset
+```
+# training
+python train.py -s -m -r 2 --eval --use_decoupled_appearance
+# mesh extraction
+python mesh_extract_tetrahedra.py -s -m -r 2 --eval
+# evaluation
+python eval_tnt/run.py --dataset-dir --traj-path --ply-path /recon.ply
+```
+## Novel View Synthesis
+```
+python train.py -s --eval
+python render.py -m -s
+python metrics.py -m # Compute error metrics on renderings
+```
+Our model can directly render coordinate map for training, without the need to first render a depth map and then convert it. This feature can be activated by including `--use_coord_map` in the argument list of 'train.py'.
+
+# 4. Viewer
+Current viewer in this repository is very similar to the original Gaussian Splatting viewer (with small modifications for 3D filters).
+You can build and use it in the same way as [Gaussian Splatting](https://github.com/graphdeco-inria/gaussian-splatting).
+
+
+# 5. Acknowledge
+We build this project based on [Gaussian Splatting](https://github.com/graphdeco-inria/gaussian-splatting).
+
+We incorporate the filters proposed in [Mip-Splatting](https://github.com/autonomousvision/mip-splatting).
+
+We incorporate the loss functions of [2D GS](https://github.com/hbb1/2d-gaussian-splatting) and use the preprocessed DTU dataset.
+
+We incorporate the densification strategy, evalution and decoupled appearance modeling form [GOF](https://github.com/autonomousvision/gaussian-opacity-fields/tree/main) and use the preprocessed TNT dataset.
+
+The evaluation scripts for the DTU and Tanks and Temples datasets are sourced from [DTUeval-python](https://github.com/jzhangbs/DTUeval-python) and [TanksAndTemples](https://github.com/isl-org/TanksAndTemples/tree/master/python_toolbox/evaluation), respectively.
+
+We thank the authors of Gaussian Splatting, Mip-Splatting, 2D GS, GOF, and the repos for their great works.
diff --git a/extensions/RaDe-GS/SIBR_viewers/.gitignore b/extensions/RaDe-GS/SIBR_viewers/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0c1464a204edd6f9c7cfe6084462c320876c7dde
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/.gitignore
@@ -0,0 +1,44 @@
+extlibs/
+build/
+install/
+cmake-gui.exe.stackdump
+__pycache__/
+
+# emacs garbage
+\#*
+.\#*
+
+# vim garbage
+*.swp
+*.swo
+*.idea/
+*.log
+*.sh
+*.tmp
+
+hs_err_*
+
+# re include common public projects
+!src/projects/ulr/
+!src/projects/dataset_tools/
+
+# more vim garbage
+# Swap
+[._]*.s[a-v][a-z]
+!*.svg # comment out if you don't need vector files
+[._]*.sw[a-p]
+[._]s[a-rt-v][a-z]
+[._]ss[a-gi-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+Sessionx.vim
+
+# Temporary
+.netrwhist
+*~
+# Auto-generated tag files
+tags
+# Persistent undo
+[._]*.un~
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/CMakeLists.txt b/extensions/RaDe-GS/SIBR_viewers/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bcbdc0946d3ae03b7702b49e744186a4e781294c
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/CMakeLists.txt
@@ -0,0 +1,213 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+CMAKE_MINIMUM_REQUIRED(VERSION 3.22)
+
+set (CMAKE_SYSTEM_VERSION 10.0.15063.0 CACHE INTERNAL "Cmake system version" FORCE)
+PROJECT(sibr_projects)
+
+set(REQUIRED_VERSION "3.22.0")
+set(CHECKED_VERSION "3.27.0")
+
+if (CMAKE_VERSION VERSION_LESS REQUIRED_VERSION)
+ message(WARNING "Deprecated version of cmake. Please update to at least ${REQUIRED_VERSION} (${CHECKED_VERSION} recommended).")
+elseif (CMAKE_VERSION VERSION_GREATER CHECKED_VERSION)
+ message(WARNING "Untested version of cmake. If you checked everything is working properly, please update ${CHECKED_VERSION} in the main CmakeLists.txt with the version you tested.")
+endif()
+
+## Include cmake stuff (functions/macros) : Modules files
+if(WIN32)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows/Modules)
+else()
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux/Modules)
+endif()
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+## To maintain cmake versions compatibilities
+include(cmake_policies)
+setPolicies()
+
+include(git_describe)
+git_describe(GIT_BRANCH SIBR_CORE_BRANCH GIT_COMMIT_HASH SIBR_CORE_COMMIT_HASH GIT_TAG SIBR_CORE_TAG GIT_VERSION SIBR_CORE_VERSION)
+
+message(STATUS "SIBR version :\n BRANCH ${SIBR_CORE_BRANCH}\n COMMIT_HASH ${SIBR_CORE_COMMIT_HASH}\n TAG ${SIBR_CORE_TAG}\n VERSION ${SIBR_CORE_VERSION}")
+
+if(NOT WIN32)
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+endif()
+
+
+if (WIN32)
+ ## Allow C++11 + other flags
+ include(CheckCXXCompilerFlag)
+ get_filename_component(currentBuildTool ${CMAKE_BUILD_TOOL} NAME_WE) # tool that can launch the native build system. returned value may be the full path
+ if(${currentBuildTool} MATCHES "(msdev|devenv|nmake|MSBuild)")
+
+ add_compile_options("$<$:/W3;/DNOMINMAX;/MP;-D_USE_MATH_DEFINES>")
+ #add_definitions(/W3 /DNOMINMAX /MP -D_USE_MATH_DEFINES)# /D_ITERATOR_DEBUG_LEVEL=1 because you need all external DLl to compile with this flag too
+ set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "" FORCE)
+ set(CMAKE_CXX_STANDARD 14)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ set(CMAKE_CXX_EXTENSIONS OFF)
+ elseif(${currentBuildTool} MATCHES "(make|gmake)")
+ add_definitions("-Wall -Wno-unknown-pragmas -Wno-sign-compare -g -std=c++14 -D__forceinline=\"inline\ __attribute__((always_inline))\"")
+ # CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
+ # CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_CXX0X)
+ # if(COMPILER_SUPPORTS_CXX11)
+ # add_definitions(-std=gnu++11)
+ # elseif(COMPILER_SUPPORTS_CXX0X)
+ # add_definitions(-std=gnu++0x)
+ # else()
+ # message(SEND_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
+ # endif()
+ elseif(APPLE) ## \todo TODO: do a better test and send error on unsupported c++14 compiler
+ add_definitions(-std=c++14 -stdlib=libc++)
+ endif()
+else()
+ ## Allow C++11 + other flags
+ include(CheckCXXCompilerFlag)
+ get_filename_component(currentBuildTool ${CMAKE_BUILD_TOOL} NAME_WE) # tool that can launch the native build system. returned value may be the full path
+ if(${currentBuildTool} MATCHES "(msdev|devenv|nmake|MSBuild)")
+
+ add_compile_options("$<$:/W3;/DNOMINMAX;/MP;-D_USE_MATH_DEFINES>")
+ #add_definitions(/W3 /DNOMINMAX /MP -D_USE_MATH_DEFINES)# /D_ITERATOR_DEBUG_LEVEL=1 because you need all external DLl to compile with this flag too
+ set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "" FORCE)
+ set(CMAKE_CXX_STANDARD 14)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ set(CMAKE_CXX_EXTENSIONS OFF)
+ elseif(${currentBuildTool} MATCHES "(make|gmake|ninja)")
+ add_definitions("-fpermissive -fPIC -Wall -Wno-unknown-pragmas -Wno-sign-compare -g -std=c++17 -D__forceinline=\"inline\ __attribute__((always_inline))\"")
+ elseif(APPLE) ## \todo TODO: do a better test and send error on unsupported c++14 compiler
+ add_definitions(-std=c++17 -stdlib=libc++)
+ endif()
+endif()
+
+set(INSTALL_STANDALONE ON)
+
+## Set default build output binaries (used also in sub CMakeLists.txt) :
+set(BIN_BUILT_DIR "bin")
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(ARCHI_BUILT_DIR "x64")
+ set(LIB_BUILT_DIR "lib64")
+else()
+ set(ARCHI_BUILT_DIR "x86")
+ set(LIB_BUILT_DIR "lib")
+endif()
+
+option(SEPARATE_CONFIGURATIONS "Clearer separation between configurations" OFF)
+SET(CMAKE_INSTALL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/install)
+SET(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_ROOT})
+
+if(DEFINED CMAKE_BUILD_TYPE) ## for mono config type (make/nmake/ninja based)
+ if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
+ set(CMAKE_DEBUG_POSTFIX "_d")
+ elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
+ set(CMAKE_RELWITHDEBINFO_POSTFIX "_rwdi")
+ elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
+ set(CMAKE_MINSIZEREL_POSTFIX "_msr")
+ elseif(${CMAKE_BUILD_TYPE} MATCHES "Release")
+ set(CMAKE_RELEASE_POSTFIX "")
+ endif()
+
+ if(SEPARATE_CONFIGURATIONS)
+ SET(CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE} ${CMAKE_INSTALL_ROOT}/${CMAKE_BUILD_TYPE})
+ else()
+ SET(CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE} ${CMAKE_INSTALL_ROOT})
+ endif()
+
+ MESSAGE(STATUS "Install path set to ${CMAKE_INSTALL_PREFIX}.")
+ SET(CMAKE_OUTPUT_LIB_${CMAKE_BUILD_TYPE} ${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/lib)
+ SET(CMAKE_OUTPUT_BIN_${CMAKE_BUILD_TYPE} ${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/bin)
+
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${CMAKE_OUTPUT_LIB_${CMAKE_BUILD_TYPE}})
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${CMAKE_OUTPUT_LIB_${CMAKE_BUILD_TYPE}})
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${CMAKE_OUTPUT_BIN_${CMAKE_BUILD_TYPE}})
+ set(CMAKE_PDB_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${CMAKE_OUTPUT_BIN_${CMAKE_BUILD_TYPE}})
+endif()
+foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ if(${CONFIG_TYPES} MATCHES "Debug")
+ set(CMAKE_DEBUG_POSTFIX "_d")
+ elseif(${CONFIG_TYPES} MATCHES "RelWithDebInfo")
+ set(CMAKE_RELWITHDEBINFO_POSTFIX "_rwdi")
+ elseif(${CONFIG_TYPES} MATCHES "MinSizeRel")
+ set(CMAKE_MINSIZEREL_POSTFIX "_msr")
+ elseif(${CMAKE_BUILD_TYPE} MATCHES "Release")
+ set(CMAKE_RELEASE_POSTFIX "")
+ endif()
+
+ if(SEPARATE_CONFIGURATIONS)
+ SET(CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC} ${CMAKE_INSTALL_ROOT}/${CONFIG_TYPES})
+ else()
+ SET(CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC} ${CMAKE_INSTALL_ROOT})
+ endif()
+
+ MESSAGE(STATUS "Install path for ${CONFIG_TYPES} set to ${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}.")
+ SET(CMAKE_OUTPUT_LIB_${CONFIG_TYPES_UC} ${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/lib)
+ SET(CMAKE_OUTPUT_BIN_${CONFIG_TYPES_UC} ${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/bin)
+
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC} ${CMAKE_OUTPUT_LIB_${CONFIG_TYPES_UC}})
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC} ${CMAKE_OUTPUT_LIB_${CONFIG_TYPES_UC}})
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC} ${CMAKE_OUTPUT_BIN_${CONFIG_TYPES_UC}})
+ set(CMAKE_PDB_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC} ${CMAKE_OUTPUT_BIN_${CONFIG_TYPES_UC}})
+endforeach()
+
+
+# Settings for RPATH
+if (NOT WIN32)
+ # Default config of Fedora at INRIA has no LD_LIBRARY_PATH (for security reasons I guess)
+ # So at least I had "./" in RPATH and found link paths
+ #set(CMAKE_SKIP_RPATH TRUE)
+ #SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+ SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+
+ SET(CMAKE_INSTALL_RPATH "$ORIGIN")
+ #SET(CMAKE_INSTALL_RPATH "./")
+ #SET(CMAKE_INSTALL_RPATH "./:/usr/lib64/:/usr/lib/:/usr/local/lib64/:/usr/local/lib/") # This one causes be a problem -> a "default" version of libGL (swrast) is located in /usr/lib64 and was selected instead of nvidia one (in /usr/lib64/nividia)
+
+ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+endif()
+
+
+set(SIBR_PROGRAMARGS "" CACHE STRING "Default program arguments used in Visual Studio target properties")
+if ("${SIBR_PROGRAMARGS}" STREQUAL "")
+ if (DEFINED ENV{SIBR_PROGRAMARGS})
+ set(SIBR_PROGRAMARGS "$ENV{SIBR_PROGRAMARGS}" CACHE STRING "Default program arguments used in Visual Studio target properties" FORCE)
+ message( STATUS "Using program options found in environment variable 'SIBR_PROGRAMARGS' => '${SIBR_PROGRAMARGS}'")
+ else()
+ message(
+ "Note you can provide default program options for Visual Studio target properties by either setting"
+ " a value for the cmake cached variable 'SIBR_PROGRAMARGS' or by setting a new environment "
+ "variable 'SIBR_PROGRAMARGS'")
+ endif()
+endif()
+
+add_custom_target(PREBUILD ALL)
+
+## Include all projects
+set(SIBR_PROJECTS_SAMPLES_SUBPAGE_REF "")
+set(SIBR_PROJECTS_OURS_SUBPAGE_REF "")
+set(SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF "")
+set(SIBR_PROJECTS_OTHERS_SUBPAGE_REF "")
+set(SIBR_PROJECTS_SAMPLES_REF_REF "")
+set(SIBR_PROJECTS_OURS_REF_REF "")
+set(SIBR_PROJECTS_TOOLBOX_REF_REF "")
+set(SIBR_PROJECTS_OTHERS_REF_REF "")
+set(DOXY_APP_SPECIFIC_IMG_PATH "")
+set(DOXY_DOC_EXCLUDE_PATTERNS_DIRS "")
+ADD_SUBDIRECTORY(src)
+
+
+## handle documentation
+if (WIN32)
+ADD_SUBDIRECTORY(docs)
+endif()
diff --git a/extensions/RaDe-GS/SIBR_viewers/LICENSE.md b/extensions/RaDe-GS/SIBR_viewers/LICENSE.md
new file mode 100644
index 0000000000000000000000000000000000000000..8385f92769bc60efca8b12ed616b0faabb033ae5
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/LICENSE.md
@@ -0,0 +1,83 @@
+SIBR License
+============
+
+**Inria** and **UCA** hold all the ownership rights on the *Software* named **sibr-core**.
+The *Software* has been registered with the Agence pour la Protection des
+Programmes (APP) under IDDN.FR.001.430020.000.S.P.2019.000.31235
+
+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 UCA
+
+*Software* means the original work of authorship made available under this
+License ie Sibr-core.
+
+*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/extensions/RaDe-GS/SIBR_viewers/README.md b/extensions/RaDe-GS/SIBR_viewers/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3a7c7fda944e4cce9462fb23c537dac017bb8c42
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/README.md
@@ -0,0 +1,142 @@
+# SIBR Core
+
+**SIBR** is a System for Image-Based Rendering.
+It is built around the *sibr-core* in this repo and several *Projects* implementing published research papers.
+For more complete documentation, see here: [SIBR Documentation](https://sibr.gitlabpages.inria.fr)
+
+This **SIBR core** repository provides :
+- a basic Image-Based Renderer
+- a per-pixel implementation of Unstructured Lumigraph (ULR)
+- several dataset tools & pipelines do process input images
+
+Details on how to run in the documentation and in the section below.
+If you use this code in a publication, please cite the system as follows:
+
+```
+@misc{sibr2020,
+ author = "Bonopera, Sebastien and Esnault, Jerome and Prakash, Siddhant and Rodriguez, Simon and Thonat, Theo and Benadel, Mehdi and Chaurasia, Gaurav and Philip, Julien and Drettakis, George",
+ title = "sibr: A System for Image Based Rendering",
+ year = "2020",
+ url = "https://gitlab.inria.fr/sibr/sibr_core"
+}
+```
+
+## Setup
+
+**Note**: The current release is for *Windows 10* only. We are planning a Linux release soon.
+
+#### Binary distribution
+
+The easiest way to use SIBR is to download the binary distribution. All steps described below, including all preprocessing for your datasets will work using this code.
+
+Download the distribution from the page: https://sibr.gitlabpages.inria.fr/download.html (Core, 57Mb); unzip the file and rename the directory "install".
+
+#### Install requirements
+
+- [**Visual Studio 2019**](https://visualstudio.microsoft.com/fr/downloads/)
+- [**Cmake 3.16+**](https://cmake.org/download)
+- [**7zip**](https://www.7-zip.org)
+- [**Python 3.8+**](https://www.python.org/downloads/) for shaders installation scripts and dataset preprocess scripts
+- [**Doxygen 1.8.17+**](https://www.doxygen.nl/download.html#srcbin) for documentation
+- [**CUDA 10.1+**](https://developer.nvidia.com/cuda-downloads) and [**CUDnn**](https://developer.nvidia.com/cudnn) if projects requires it
+
+Make sure Python, CUDA and Doxygen are in the PATH
+
+If you have Chocolatey, you can grab most of these with this command:
+
+```sh
+choco install cmake 7zip python3 doxygen.install cuda
+
+## Visual Studio is available on Chocolatey,
+## though we do advise to set it from Visual Studio Installer and to choose your licensing accordingly
+choco install visualstudio2019community
+```
+
+#### Generation of the solution
+
+- Checkout this repository's master branch:
+
+ ```sh
+ ## through HTTPS
+ git clone https://gitlab.inria.fr/sibr/sibr_core.git -b master
+ ## through SSH
+ git clone git@gitlab.inria.fr:sibr/sibr_core.git -b master
+ ```
+- Run Cmake-gui once, select the repo root as a source directory, `build/` as the build directory. Configure, select the Visual Studio C++ Win64 compiler
+- Select the projects you want to generate among the BUILD elements in the list (you can group Cmake flags by categories to access those faster)
+- Generate
+
+#### Compilation
+
+- Open the generated Visual Studio solution (`build/sibr_projects.sln`)
+- Build the `ALL_BUILD` target, and then the `INSTALL` target
+- The compiled executables will be put in `install/bin`
+- TODO: are the DLLs properly installed?
+
+#### Compilation of the documentation
+
+- Open the generated Visual Studio solution (`build/sibr_projects.sln`)
+- Build the `DOCUMENTATION` target
+- Run `install/docs/index.html` in a browser
+
+
+## Scripts
+
+Some scripts will require you to install `PIL`, and `convert` from `ImageMagick`.
+
+```sh
+## To install pillow
+python -m pip install pillow
+
+## If you have Chocolatey, you can install imagemagick from this command
+choco install imagemagick
+```
+
+## Troubleshooting
+
+#### Bugs and Issues
+
+We will track bugs and issues through the Issues interface on gitlab. Inria gitlab does not allow creation of external accounts, so if you have an issue/bug please email sibr@inria.fr
and we will either create a guest account or create the issue on our side.
+
+#### Cmake complaining about the version
+
+if you are the first to use a very recent Cmake version, you will have to update `CHECKED_VERSION` in the root `CmakeLists.txt`.
+
+#### Weird OpenCV error
+
+you probably selected the 32-bits compiler in Cmake-gui.
+
+#### `Cmd.exe failed with error 009` or similar
+
+make sure Python is installed and in the path.
+
+#### `BUILD_ALL` or `INSTALL` fail because of a project you don't really need
+
+build and install each project separately by selecting the proper targets.
+
+#### Error in CUDA headers under Visual Studio 2019
+
+make sure CUDA >= 10.1 (first version to support VS2019) is installed.
+
+## To run an example
+
+For more details, please see the documentation: http://sibr.gitlabpages.inria.fr
+
+Download a dataset from: https://repo-sam.inria.fr/fungraph/sibr-datasets/
+
+e.g., the *sibr-museum-front* dataset in the *DATASETS_PATH* directory.
+
+```
+wget https://repo-sam.inria.fr/fungraph/sibr-datasets/museum_front27_ulr.zip
+```
+
+Once you have built the system or downloaded the binaries (see above), go to *install/bin* and you can run:
+```
+ sibr_ulrv2_app.exe --path DATASETS_PATH/sibr-museum-front
+```
+
+You will have an interactive viewer and you can navigate freely in the captured scene.
+Our default interactive viewer has a main view running the algorithm and a top view to visualize the position of the calibrated cameras. By default you are in WASD mode, and can toggle to trackball using the "y" key. Please see the page [Interface](https://sibr.gitlabpages.inria.fr/docs/nightly/howto_sibr_useful_objects.html) for more details on the interface.
+
+Please see the documentation on how to create a dataset from your own scene, and the various other IBR algorithms available.
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/MSVCsetUserCommand.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/MSVCsetUserCommand.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29dcdbcada5c6e30471358d2fe0d143be9af2534
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/MSVCsetUserCommand.cmake
@@ -0,0 +1,149 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+if(__MSVCsetUserCommand_cmake_INCLUDED__)
+ return()
+else()
+ set(__MSVCsetUserCommand_cmake_INCLUDED__ ON)
+endif()
+
+## Allow to configure the Debugger settings of visual studio
+## Note: Using this command under linux doesn't affect anything
+## On run Debug Windows local : visual will try to load a specific COMMAND with ARGS in the provided WORKING_DIR
+##
+## usage:
+## MSVCsetUserCommand(
+## [COMMAND | [ PATH [FILE ] ] ]
+## ARGS
+## WORKING_DIR
+## )
+##
+## Warning 1 : All arugments () must be passed under quotes
+## Warning 2 : WORKING_DIR path arg have to finish with remain slah '/'
+## Warning 3 : use COMMAND for external app OR PATH (optionaly with FILE) option(s) to set your built/installed/moved target
+##
+## Example 1:
+## include(MSVCsetUserCommand)
+## MSVCsetUserCommand( UnityRenderingPlugin
+## COMMAND "C:/Program Files (x86)/Unity/Editor/Unity.exe"
+## ARGS "-force-opengl -projectPath \"${CMAKE_HOME_DIRECTORY}/UnityPlugins/RenderingPluginExample/UnityProject\""
+## WORKING_DIR "${CMAKE_HOME_DIRECTORY}/UnityPlugins/RenderingPluginExample/UnityProject"
+## VERBOSE
+## )
+##
+## Example 2:
+## include(MSVCsetUserCommand)
+## MSVCsetUserCommand( ibrApp
+## PATH "C:/Program Files (x86)/workspace/IBR/install"
+## FILE "ibrApp${CMAKE_EXECUTABLE_SUFFIX}" ## this option line is optional since the target name didn't change between build and install step
+## ARGS "-path \"${CMAKE_HOME_DIRECTORY}/dataset\""
+## WORKING_DIR "${CMAKE_HOME_DIRECTORY}"
+## VERBOSE
+## )
+##
+function(MSVCsetUserCommand targetName)
+ cmake_parse_arguments(MSVCsuc "VERBOSE" "PATH;FILE;COMMAND;ARGS;WORKING_DIR" "" ${ARGN} )
+
+ ## If no arguments are given, do not create an unecessary .vcxproj.user file
+ set(MSVCsuc_DEFAULT OFF)
+
+ if(MSVCsuc_PATH AND MSVCsuc_DEFAULT)
+ set(MSVCsuc_DEFAULT OFF)
+ endif()
+
+ if(MSVCsuc_FILE AND MSVCsuc_DEFAULT)
+ set(MSVCsuc_DEFAULT OFF)
+ endif()
+
+ if(NOT MSVCsuc_COMMAND)
+ if(MSVCsuc_PATH AND MSVCsuc_FILE)
+ set(MSVCsuc_COMMAND "${MSVCsuc_PATH}\\${MSVCsuc_FILE}")
+ elseif(MSVCsuc_PATH)
+ set(MSVCsuc_COMMAND "${MSVCsuc_PATH}\\$(TargetFileName)")
+ else()
+ set(MSVCsuc_COMMAND "$(TargetPath)") ## => $(TargetDir)\$(TargetName)$(TargetExt)
+ endif()
+ elseif(MSVCsuc_DEFAULT)
+ set(MSVCsuc_DEFAULT OFF)
+ endif()
+
+ # NOTE: there was a typo here. there is an else if written after else statement
+ # changing the order of the else if statement
+ if(MSVCsuc_WORKING_DIR)
+ file(TO_NATIVE_PATH ${MSVCsuc_WORKING_DIR} MSVCsuc_WORKING_DIR)
+ elseif(MSVCsuc_DEFAULT)
+ set(MSVCsuc_DEFAULT OFF)
+ else()
+ set(MSVCsuc_WORKING_DIR "$(ProjectDir)")
+ endif()
+
+ if(NOT MSVCsuc_ARGS)
+ set(MSVCsuc_ARGS "")
+ elseif(MSVCsuc_DEFAULT)
+ set(MSVCsuc_DEFAULT OFF)
+ endif()
+
+ if(MSVC10 OR (MSVC AND MSVC_VERSION GREATER 1600)) # 2010 or newer
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(PLATEFORM_BITS x64)
+ else()
+ set(PLATEFORM_BITS Win32)
+ endif()
+
+ if(NOT MSVCsuc_DEFAULT AND PLATEFORM_BITS)
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${targetName}.vcxproj.user"
+ "
+
+
+ ${MSVCsuc_COMMAND}
+ ${MSVCsuc_ARGS}
+ WindowsLocalDebugger
+ ${MSVCsuc_WORKING_DIR}
+
+
+ ${MSVCsuc_COMMAND}
+ ${MSVCsuc_ARGS}
+ WindowsLocalDebugger
+ ${MSVCsuc_WORKING_DIR}
+
+
+ ${MSVCsuc_COMMAND}
+ ${MSVCsuc_ARGS}
+ WindowsLocalDebugger
+ ${MSVCsuc_WORKING_DIR}
+
+
+ ${MSVCsuc_COMMAND}
+ ${MSVCsuc_ARGS}
+ WindowsLocalDebugger
+ ${MSVCsuc_WORKING_DIR}
+
+ "
+ )
+ if(MSVCsuc_VERBOSE)
+ message(STATUS "[MSVCsetUserCommand] Write ${CMAKE_CURRENT_BINARY_DIR}/${targetName}.vcxproj.user file")
+ message(STATUS " to execute ${MSVCsuc_COMMAND} ${MSVCsuc_ARGS}")
+ message(STATUS " from derectory ${MSVCsuc_WORKING_DIR}")
+ message(STATUS " on visual studio run debugger button")
+ endif()
+
+ else()
+ message(WARNING "PLATEFORM_BITS is undefined...")
+ endif()
+
+ else()
+ if(MSVCsuc_VERBOSE)
+ message(WARNING "MSVCsetUserCommand is disable because too old MSVC is used (need MSVC10 2010 or newer)")
+ endif()
+ endif()
+
+endfunction()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindASSIMP.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindASSIMP.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..8bc50f410caef0ae7fc3cdeecb0fa3742c3ccfc5
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindASSIMP.cmake
@@ -0,0 +1,114 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## Try to find the ASSIMP library
+## Once done this will define
+##
+## ASSIMP_FOUND - system has ASSIMP
+## ASSIMP_INCLUDE_DIR - The ASSIMP include directory
+## ASSIMP_LIBRARIES - The libraries needed to use ASSIMP
+## ASSIMP_CMD - the full path of ASSIMP executable
+## ASSIMP_DYNAMIC_LIB - the Assimp dynamic lib (available only on windows as .dll file for the moment)
+##
+## Edited for using a bugfixed version of Assimp
+
+if(NOT ASSIMP_DIR)
+ set(ASSIMP_DIR "$ENV{ASSIMP_DIR}" CACHE PATH "ASSIMP root directory")
+ message("NO ASSIMP DIR " ASSIMP_DIR )
+ file(TO_CMAKE_PATH "/data/graphdeco/share/usr/local" ASSIMP_DIR)
+ set(ASSIMP_DIR "/data/graphdeco/share/usr/local" )
+ message("SETTING ASSIMP DIR " ASSIMP_DIR )
+endif()
+if(ASSIMP_DIR)
+ file(TO_CMAKE_PATH ${ASSIMP_DIR} ASSIMP_DIR)
+ file(TO_CMAKE_PATH "/data/graphdeco/share/usr/local" ASSIMP_DIR)
+ message("ASSIMP DIR " ASSIMP_DIR )
+endif()
+
+
+## set the LIB POSTFIX to find in a right directory according to what kind of compiler we use (32/64bits)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(ASSIMP_SEARCH_LIB "lib64")
+ set(ASSIMP_SEARCH_BIN "bin64")
+ set(ASSIMP_SEARCH_LIB_PATHSUFFIXE "x64")
+else()
+ set(ASSIMP_SEARCH_LIB "lib32")
+ set(ASSIMP_SEARCH_BIN "bin32")
+ set(ASSIMP_SEARCH_LIB_PATHSUFFIXE "x86")
+endif()
+
+set(PROGRAMFILESx86 "PROGRAMFILES(x86)")
+
+
+FIND_PATH(ASSIMP_INCLUDE_DIR
+ NAMES assimp/config.h
+ PATHS
+ ${ASSIMP_DIR}
+ ## linux
+ /usr
+ /usr/include
+ /usr/local
+ /opt/local
+ ## windows
+ "$ENV{PROGRAMFILES}/Assimp"
+ "$ENV{${PROGRAMFILESx86}}/Assimp"
+ "$ENV{ProgramW6432}/Assimp"
+ PATH_SUFFIXES include
+)
+
+
+FIND_LIBRARY(ASSIMP_LIBRARY
+ NAMES assimp-vc140-mt assimp
+ PATHS
+ ${ASSIMP_DIR}/${ASSIMP_SEARCH_LIB}
+ ${ASSIMP_DIR}/lib
+ ${ASSIMP_DIR}/lib64
+ ## linux
+ /usr/${ASSIMP_SEARCH_LIB}
+ /usr/local/${ASSIMP_SEARCH_LIB}
+ /opt/local/${ASSIMP_SEARCH_LIB}
+ /usr/lib
+ /usr/lib64
+ /usr/local/lib
+ /opt/local/lib
+ ## windows
+ "$ENV{PROGRAMFILES}/Assimp/${ASSIMP_SEARCH_LIB}"
+ "$ENV{${PROGRAMFILESx86}}/Assimp/${ASSIMP_SEARCH_LIB}"
+ "$ENV{ProgramW6432}/Assimp/${ASSIMP_SEARCH_LIB}"
+ "$ENV{PROGRAMFILES}/Assimp/lib"
+ "$ENV{${PROGRAMFILESx86}}/Assimp/lib"
+ "$ENV{ProgramW6432}/Assimp/lib"
+ PATH_SUFFIXES ${ASSIMP_SEARCH_LIB_PATHSUFFIXE}
+)
+set(ASSIMP_LIBRARIES ${ASSIMP_LIBRARY})
+
+
+if(ASSIMP_LIBRARY)
+ get_filename_component(ASSIMP_LIBRARY_DIR ${ASSIMP_LIBRARY} PATH)
+ if(WIN32)
+ file(GLOB ASSIMP_DYNAMIC_LIB "${ASSIMP_LIBRARY_DIR}/assimp*.dll")
+ if(NOT ASSIMP_DYNAMIC_LIB)
+ message("ASSIMP_DYNAMIC_LIB is missing... at ${ASSIMP_LIBRARY_DIR}")
+ endif()
+ endif()
+ set(ASSIMP_DYNAMIC_LIB ${ASSIMP_DYNAMIC_LIB} CACHE PATH "Windows dll location")
+endif()
+
+MARK_AS_ADVANCED(ASSIMP_DYNAMIC_LIB ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ASSIMP
+ REQUIRED_VARS ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES
+ FAIL_MESSAGE "ASSIMP wasn't found correctly. Set ASSIMP_DIR to the root SDK installation directory."
+)
+
+if(NOT ASSIMP_FOUND)
+ set(ASSIMP_DIR "" CACHE STRING "Path to ASSIMP install directory")
+endif()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEGL.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEGL.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9f2a2506203a5e68e8e920e8ae0c6f8f750ee42c
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEGL.cmake
@@ -0,0 +1,161 @@
+#.rst:
+# FindEGL
+# -------
+#
+# Try to find EGL.
+#
+# This will define the following variables:
+#
+# ``EGL_FOUND``
+# True if (the requested version of) EGL is available
+# ``EGL_VERSION``
+# The version of EGL; note that this is the API version defined in the
+# headers, rather than the version of the implementation (eg: Mesa)
+# ``EGL_LIBRARIES``
+# This can be passed to target_link_libraries() instead of the ``EGL::EGL``
+# target
+# ``EGL_INCLUDE_DIRS``
+# This should be passed to target_include_directories() if the target is not
+# used for linking
+# ``EGL_DEFINITIONS``
+# This should be passed to target_compile_options() if the target is not
+# used for linking
+#
+# If ``EGL_FOUND`` is TRUE, it will also define the following imported target:
+#
+# ``EGL::EGL``
+# The EGL library
+#
+# In general we recommend using the imported target, as it is easier to use.
+# Bear in mind, however, that if the target is in the link interface of an
+# exported library, it must be made available by the package config file.
+#
+# Since pre-1.0.0.
+
+#=============================================================================
+# Copyright 2014 Alex Merry
+# Copyright 2014 Martin Gräßlin
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL 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 IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#=============================================================================
+
+include(CheckCXXSourceCompiles)
+include(CMakePushCheckState)
+
+# Use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig)
+pkg_check_modules(PKG_EGL QUIET egl)
+
+set(EGL_DEFINITIONS ${PKG_EGL_CFLAGS_OTHER})
+
+find_path(EGL_INCLUDE_DIR
+ NAMES
+ EGL/egl.h
+ HINTS
+ ${PKG_EGL_INCLUDE_DIRS}
+)
+find_library(EGL_LIBRARY
+ NAMES
+ EGL
+ HINTS
+ ${PKG_EGL_LIBRARY_DIRS}
+)
+
+# NB: We do *not* use the version information from pkg-config, as that
+# is the implementation version (eg: the Mesa version)
+if(EGL_INCLUDE_DIR)
+ # egl.h has defines of the form EGL_VERSION_x_y for each supported
+ # version; so the header for EGL 1.1 will define EGL_VERSION_1_0 and
+ # EGL_VERSION_1_1. Finding the highest supported version involves
+ # finding all these defines and selecting the highest numbered.
+ file(READ "${EGL_INCLUDE_DIR}/EGL/egl.h" _EGL_header_contents)
+ string(REGEX MATCHALL
+ "[ \t]EGL_VERSION_[0-9_]+"
+ _EGL_version_lines
+ "${_EGL_header_contents}"
+ )
+ unset(_EGL_header_contents)
+ foreach(_EGL_version_line ${_EGL_version_lines})
+ string(REGEX REPLACE
+ "[ \t]EGL_VERSION_([0-9_]+)"
+ "\\1"
+ _version_candidate
+ "${_EGL_version_line}"
+ )
+ string(REPLACE "_" "." _version_candidate "${_version_candidate}")
+ if(NOT DEFINED EGL_VERSION OR EGL_VERSION VERSION_LESS _version_candidate)
+ set(EGL_VERSION "${_version_candidate}")
+ endif()
+ endforeach()
+ unset(_EGL_version_lines)
+endif()
+
+cmake_push_check_state(RESET)
+list(APPEND CMAKE_REQUIRED_LIBRARIES "${EGL_LIBRARY}")
+list(APPEND CMAKE_REQUIRED_INCLUDES "${EGL_INCLUDE_DIR}")
+
+check_cxx_source_compiles("
+#include
+
+int main(int argc, char *argv[]) {
+ EGLint x = 0; EGLDisplay dpy = 0; EGLContext ctx = 0;
+ eglDestroyContext(dpy, ctx);
+}" HAVE_EGL)
+
+cmake_pop_check_state()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(EGL
+ FOUND_VAR
+ EGL_FOUND
+ REQUIRED_VARS
+ EGL_LIBRARY
+ EGL_INCLUDE_DIR
+ HAVE_EGL
+ VERSION_VAR
+ EGL_VERSION
+)
+
+if(EGL_FOUND AND NOT TARGET EGL::EGL)
+ add_library(EGL::EGL UNKNOWN IMPORTED)
+ set_target_properties(EGL::EGL PROPERTIES
+ IMPORTED_LOCATION "${EGL_LIBRARY}"
+ INTERFACE_COMPILE_OPTIONS "${EGL_DEFINITIONS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${EGL_INCLUDE_DIR}"
+ )
+endif()
+
+mark_as_advanced(EGL_LIBRARY EGL_INCLUDE_DIR HAVE_EGL)
+
+# compatibility variables
+set(EGL_LIBRARIES ${EGL_LIBRARY})
+set(EGL_INCLUDE_DIRS ${EGL_INCLUDE_DIR})
+set(EGL_VERSION_STRING ${EGL_VERSION})
+
+include(FeatureSummary)
+set_package_properties(EGL PROPERTIES
+ URL "https://www.khronos.org/egl/"
+ DESCRIPTION "A platform-agnostic mechanism for creating rendering surfaces for use with other graphics libraries, such as OpenGL|ES and OpenVG."
+)
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c6cf1db96d98f75e72bf9d7cd1d9a6937d07cb65
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake
@@ -0,0 +1,94 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+## Important Note:
+## This is not an official Find*cmake. It has been written for searching through
+## a custom path (EMBREE_DIR) before checking elsewhere.
+##
+## FindEMBREE.cmake
+## Find EMBREE's includes and library
+##
+## This module defines :
+## [in] EMBREE_DIR, The base directory to search for EMBREE (as cmake var or env var)
+## [out] EMBREE_INCLUDE_DIR where to find EMBREE.h
+## [out] EMBREE_LIBRARIES, EMBREE_LIBRARY, libraries to link against to use EMBREE
+## [out] EMBREE_FOUND, If false, do not try to use EMBREE.
+##
+
+
+if(NOT EMBREE_DIR)
+ set(EMBREE_DIR "$ENV{EMBREE_DIR}" CACHE PATH "EMBREE root directory")
+endif()
+if(EMBREE_DIR)
+ file(TO_CMAKE_PATH ${EMBREE_DIR} EMBREE_DIR)
+endif()
+
+
+## set the LIB POSTFIX to find in a right directory according to what kind of compiler we use (32/64bits)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(EMBREE_SEARCH_LIB "lib64")
+ set(EMBREE_SEARCH_BIN "bin64")
+ set(EMBREE_SEARCH_LIB_PATHSUFFIXE "x64")
+else()
+ set(EMBREE_SEARCH_LIB "lib32")
+ set(EMBREE_SEARCH_BIN "bin32")
+ set(EMBREE_SEARCH_LIB_PATHSUFFIXE "x86")
+endif()
+
+set(PROGRAMFILESx86 "PROGRAMFILES(x86)")
+
+FIND_PATH(EMBREE_INCLUDE_DIR
+ NAMES embree3/rtcore_geometry.h
+ PATHS
+ ${EMBREE_DIR}
+ ## linux
+ /usr
+ /usr/local
+ /opt/local
+ ## windows
+ "$ENV{PROGRAMFILES}/EMBREE"
+ "$ENV{${PROGRAMFILESx86}}/EMBREE"
+ "$ENV{ProgramW6432}/EMBREE"
+ PATH_SUFFIXES include
+)
+
+FIND_LIBRARY(EMBREE_LIBRARY
+ NAMES embree3
+ PATHS
+ ${EMBREE_DIR}/${EMBREE_SEARCH_LIB}
+ ${EMBREE_DIR}/lib
+ ## linux
+ /usr/${EMBREE_SEARCH_LIB}
+ /usr/local/${EMBREE_SEARCH_LIB}
+ /opt/local/${EMBREE_SEARCH_LIB}
+ /usr/lib
+ /usr/local/lib
+ /opt/local/lib
+ ## windows
+ "$ENV{PROGRAMFILES}/EMBREE/${EMBREE_SEARCH_LIB}"
+ "$ENV{${PROGRAMFILESx86}}/EMBREE/${EMBREE_SEARCH_LIB}"
+ "$ENV{ProgramW6432}/EMBREE/${EMBREE_SEARCH_LIB}"
+ "$ENV{PROGRAMFILES}/EMBREE/lib"
+ "$ENV{${PROGRAMFILESx86}}/EMBREE/lib"
+ "$ENV{ProgramW6432}/EMBREE/lib"
+ PATH_SUFFIXES ${EMBREE_SEARCH_LIB_PATHSUFFIXE}
+)
+set(EMBREE_LIBRARIES ${EMBREE_LIBRARY})
+
+MARK_AS_ADVANCED(EMBREE_INCLUDE_DIR EMBREE_LIBRARIES)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(EMBREE
+ REQUIRED_VARS EMBREE_INCLUDE_DIR EMBREE_LIBRARIES
+ FAIL_MESSAGE "EMBREE wasn't found correctly. Set EMBREE_DIR to the root SDK installation directory."
+)
+
+if(NOT EMBREE_FOUND)
+ set(EMBREE_DIR "" CACHE STRING "Path to EMBREE install directory")
+endif()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindFFMPEG.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindFFMPEG.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..671f0d18d237cd1079ddf8f7947c99250f4d5953
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindFFMPEG.cmake
@@ -0,0 +1,110 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## Try to find the FFMPEG library
+## Once done this will define
+##
+## FFMPEG_FOUND - system has FFmpeg
+## FFMPEG_INCLUDE_DIR - The FFmpeg include directory
+## FFMPEG_LIBRARIES - The libraries needed to use FFmpeg
+## FFMPEG_DYNAMIC_LIBS - DLLs for windows
+
+
+if(NOT FFMPEG_DIR)
+ set(FFMPEG_DIR "$ENV{FFMPEG_DIR}" CACHE PATH "FFMPEG_DIR root directory")
+endif()
+
+if(FFMPEG_DIR)
+ file(TO_CMAKE_PATH ${FFMPEG_DIR} FFMPEG_DIR)
+endif()
+
+MACRO(FFMPEG_FIND varname shortname headername)
+
+ # Path to include dirs
+ FIND_PATH(FFMPEG_${varname}_INCLUDE_DIRS
+ NAMES "lib${shortname}/${headername}"
+ PATHS
+ "${FFMPEG_DIR}/include" # modify this to adapt according to OS/compiler
+ "/usr/include"
+ "/usr/include/ffmpeg"
+ )
+
+ #Add libraries
+ IF(${FFMPEG_${varname}_INCLUDE_DIRS} STREQUAL "FFMPEG_${varname}_INCLUDE_DIR-NOTFOUND")
+ MESSAGE(STATUS "Can't find includes for ${shortname}...")
+ ELSE()
+ FIND_LIBRARY(FFMPEG_${varname}_LIBRARIES
+ NAMES ${shortname}
+ PATHS
+ ${FFMPEG_DIR}/lib
+ "/usr/lib"
+ "/usr/lib64"
+ "/usr/local/lib"
+ "/usr/local/lib64"
+ )
+
+ # set libraries and other variables
+ SET(FFMPEG_${varname}_FOUND 1)
+ SET(FFMPEG_${varname}_INCLUDE_DIRS ${FFMPEG_${varname}_INCLUDE_DIR})
+ SET(FFMPEG_${varname}_LIBS ${FFMPEG_${varname}_LIBRARIES})
+ ENDIF()
+ ENDMACRO(FFMPEG_FIND)
+
+#Calls to ffmpeg_find to get librarires ------------------------------
+FFMPEG_FIND(LIBAVFORMAT avformat avformat.h)
+FFMPEG_FIND(LIBAVDEVICE avdevice avdevice.h)
+FFMPEG_FIND(LIBAVCODEC avcodec avcodec.h)
+FFMPEG_FIND(LIBAVUTIL avutil avutil.h)
+FFMPEG_FIND(LIBSWSCALE swscale swscale.h)
+
+# check if libs are found and set FFMPEG related variables
+#SET(FFMPEG_FOUND "NO")
+IF(FFMPEG_LIBAVFORMAT_FOUND
+ AND FFMPEG_LIBAVDEVICE_FOUND
+ AND FFMPEG_LIBAVCODEC_FOUND
+ AND FFMPEG_LIBAVUTIL_FOUND
+ AND FFMPEG_LIBSWSCALE_FOUND)
+
+ # All ffmpeg libs are here
+ SET(FFMPEG_FOUND "YES")
+ SET(FFMPEG_INCLUDE_DIR ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS})
+ SET(FFMPEG_LIBRARY_DIRS ${FFMPEG_LIBAVFORMAT_LIBRARY_DIRS})
+ SET(FFMPEG_LIBRARIES
+ ${FFMPEG_LIBAVFORMAT_LIBS}
+ ${FFMPEG_LIBAVDEVICE_LIBS}
+ ${FFMPEG_LIBAVCODEC_LIBS}
+ ${FFMPEG_LIBAVUTIL_LIBS}
+ ${FFMPEG_LIBSWSCALE_LIBS} )
+
+ # add dynamic libraries
+ if(WIN32)
+ file(GLOB FFMPEG_DYNAMIC_LIBS "${FFMPEG_DIR}/bin/*.dll")
+ if(NOT FFMPEG_DYNAMIC_LIBS)
+ message("FFMPEG_DYNAMIC_LIBS is missing...")
+ endif()
+ set(FFMPEG_DYNAMIC_LIBS ${FFMPEG_DYNAMIC_LIBS} CACHE PATH "Windows dll location")
+endif()
+
+ mark_as_advanced(FFMPEG_INCLUDE_DIR FFMPEG_LIBRARY_DIRS FFMPEG_LIBRARIES FFMPEG_DYNAMIC_LIBS)
+ELSE ()
+ MESSAGE(STATUS "Could not find FFMPEG")
+ENDIF()
+
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFMPEG
+ REQUIRED_VARS FFMPEG_INCLUDE_DIR FFMPEG_LIBRARIES
+ FAIL_MESSAGE "FFmpeg wasn't found correctly. Set FFMPEG_DIR to the root SDK installation directory."
+)
+
+if(NOT FFMPEG_FOUND)
+ set(FFMPEG_DIR "" CACHE STRING "Path to FFmpeg install directory")
+endif()
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindGLFW.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindGLFW.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..462c76c1eca6f384d25adfee9c15df8e02094d01
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Modules/FindGLFW.cmake
@@ -0,0 +1,109 @@
+##=============================================================================
+##
+## Copyright (c) Kitware, Inc.
+## All rights reserved.
+## See LICENSE.txt for details.
+##
+## This software is distributed WITHOUT ANY WARRANTY; without even
+## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE. See the above copyright notice for more information.
+##
+## Copyright 2016 Sandia Corporation.
+## Copyright 2016 UT-Battelle, LLC.
+## Copyright 2016 Los Alamos National Security.
+##
+## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+## the U.S. Government retains certain rights in this software.
+## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
+## Laboratory (LANL), the U.S. Government retains certain rights in
+## this software.
+##
+##=============================================================================
+# Try to find EGL library and include dir.
+# Once done this will define
+#
+# GLFW_FOUND
+# GLFW_INCLUDE_DIR
+# GLFW_LIBRARY
+#
+
+include(FindPackageHandleStandardArgs)
+
+if (WIN32)
+ find_path( GLFW_INCLUDE_DIR
+ NAMES
+ GLFW/glfw3.h
+ PATHS
+ ${PROJECT_SOURCE_DIR}/shared_external/glfw/include
+ ${PROJECT_SOURCE_DIR}/../shared_external/glfw/include
+ ${GLFW_LOCATION}/include
+ $ENV{GLFW_LOCATION}/include
+ $ENV{PROGRAMFILES}/GLFW/include
+ ${GLFW_LOCATION}
+ $ENV{GLFW_LOCATION}
+ DOC "The directory where GLFW/glfw3.h resides" )
+ if(ARCH STREQUAL "x86")
+ find_library( GLFW_LIBRARY
+ NAMES
+ glfw3
+ PATHS
+ ${GLFW_LOCATION}/lib
+ $ENV{GLFW_LOCATION}/lib
+ $ENV{PROGRAMFILES}/GLFW/lib
+ DOC "The GLFW library")
+ else()
+ find_library( GLFW_LIBRARY
+ NAMES
+ glfw3
+ PATHS
+ ${GLFW_LOCATION}/lib
+ $ENV{GLFW_LOCATION}/lib
+ $ENV{PROGRAMFILES}/GLFW/lib
+ DOC "The GLFW library")
+ endif()
+endif ()
+
+if (${CMAKE_HOST_UNIX})
+ message("GFLW LOCATION " $ENV{GLFW_LOCATION} )
+ find_path( GLFW_INCLUDE_DIR
+ NAMES
+ GLFW/glfw3.h
+ PATHS
+# ${GLFW_LOCATION}/include
+ $ENV{GLFW_LOCATION}/include
+# /usr/include
+# /usr/local/include
+# /sw/include
+# /opt/local/include
+# NO_DEFAULT_PATH
+ DOC "The directory where GLFW/glfw3.h resides"
+ )
+ find_library( GLFW_LIBRARY
+ NAMES
+ glfw3 glfw
+ PATHS
+# ${GLFW_LOCATION}/lib
+ $ENV{GLFW_LOCATION}/lib
+ $ENV{GLFW_LOCATION}/lib64
+# /usr/lib64
+# /usr/lib
+# /usr/local/lib64
+# /usr/local/lib
+# /sw/lib
+# /opt/local/lib
+# /usr/lib/x86_64-linux-gnu
+# NO_DEFAULT_PATH
+ DOC "The GLFW library")
+
+ set( GLFW_INCLUDE_DIR $ENV{GLFW_LOCATION}/include )
+ set( GLFW_LIBRARY $ENV{GLFW_LOCATION}/lib64/libglfw3.a )
+ message("*************==========> FindGLFW .cmake " ${GLFW_INCLUDE_DIR} " LIB " ${GLFW_LIBRARY} )
+endif ()
+
+find_package_handle_standard_args(GLFW DEFAULT_MSG
+ GLFW_INCLUDE_DIR
+ GLFW_LIBRARY
+)
+
+mark_as_advanced( GLFW_FOUND )
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Win3rdParty.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Win3rdParty.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..e42ab8c89fd46c0c2ccbe12aa88006a57751689f
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/Win3rdParty.cmake
@@ -0,0 +1,337 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## This file should be include and use only on WIN32 OS and once
+## It allow to auto check/download and use a preconfigured 3rdParty binaries for cmake usage
+## It use the downloadAndExtractZipFile cmake module to work.
+##
+if(__Win3rdParty_cmake_INCLUDED__)
+ return()
+else()
+ set(__Win3rdParty_cmake_INCLUDED__ ON)
+endif()
+
+
+##
+## To be sure to reset an empty cached variable but keep any other kind of variables
+##
+## Usage:
+## check_cached_var( [FORCE])
+##
+## is the cached cmake variable you need to reset
+## is the new default value of the reseted cached cmake variable
+## is the kind of GUI cache input can be : FILEPATH; PATH; STRING or BOOL
+## is the associated GUI cache input documentation display in the GUI
+## FORCE option could be use to reset a cached variable even if it is not empty.
+##
+macro(check_cached_var var resetedCachedValue cacheType cacheDoc)
+ # message(STATUS "inside check_cached_var macro. argn=${ARGN}")
+ cmake_parse_arguments(ccv "FORCE" "" "" ${ARGN})
+
+ if(ccv_FORCE)
+ set(FORCE FORCE)
+ else()
+ set(FORCE )
+ endif()
+
+ if(NOT ${var} OR ccv_FORCE)
+ unset(${var} CACHE)
+ # message(STATUS "setting new cache value. var ${var} = ${resetedCachedValue}")
+ set(${var} "${resetedCachedValue}" CACHE ${cacheType} "${cacheDoc}" ${FORCE})
+ endif()
+endmacro()
+
+
+##
+## Win3rdParty function allow to specify a directory which contain all necessary windows dependenties.
+## By uploading 3rdParty directory (which contain dependencies, *.lib, *.dll... for a specific version of compiler) onto Gforge file tab,
+## you get back an URL of download you can give to this function with a directory name. So you can provide multiple 3rdParty version of same dependencies (MSVC11, MSVC12...).
+## By providing a prefix to this function, you allow to use different kind of 3rdParty which can be handled by CMAKE OPTIONS depending on what your framework need for example.
+##
+## Usage 1:
+## Win3rdParty( MSVC
+## [MSVC ] [...]
+## [VCID] [DEFAULT_USE] [VERBOSE] )
+##
+## * allow to identify which 3rdParty you process (prefix name)
+## * MSVC flag could be MSVC11 or MSVC12 (any element of the MSVC_VERSIONS_LIST) and refer to a 3rdParty compiler with :
+## * which will be the local pathName of the downloaded 3rdParty : relative to CMAKE_BINARY_DIR
+## * which is the link location of the 3rdParty zip
+## * VCID flag will make available a cache variable ${prefix}_WIN3RDPARTY_VCID
+## * DEFAULT_USE flag [ON|OFF] may be used to set default value of cmake cached variable : _WIN3RDPARTY_USE [default to ON]
+##
+## WARNING:
+## This function define CACHE variables you can use after :
+## * ${prefix}_WIN3RDPARTY_USE : allow to check/downloaded win3rdParty dir (it will force the cached variables for this dependency folder generally _DIR>)
+## * ${prefix}_WIN3RDPARTY_DIR : where is your local win3rdParty dir (the PATH)
+## * ${prefix}_WIN3RDPARTY_VCID : [if VCID flag is used] the MSVC id (commonly used to prefix/suffix library name, see boost or CGAL)
+##
+## If you want to add a win3rdParty version, please:
+## 1- build dependencies on your local side with the compiler you want
+## 2- build your own zip with your built dependencies
+## 3- upload it (onto the forge where the project is stored) and copy the link location in order to use it for this function
+## 4- if you just introduced a new MSVC version, add it to the MSVC_VERSIONS_LIST bellow
+##
+## In a second pass, you can also use this function to set necessary cmake cached variables in order to let cmake find packages of these 3rdParty.
+##
+## Usage 2:
+## win3rdParty( [VERBOSE] MULTI_SET|SET
+## CHECK_CACHED_VAR [LIST] [DOC ]
+## [ CHECK_CACHED_VAR [LIST] [DOC ] ] [...]
+##
+## * MULTI_SET or SET flags are used to tell cmake that all next arguments will use repeated flags with differents entries (SET mean we will provide only one set of arguments, without repetition)
+## * CHECK_CACHED_VAR are the repeated flag which contain differents entries
+## * is the cmake variable you want to be cached for the project
+## * is the kind of cmake variable (couble be: FILEPATH; PATH; STRING or BOOL) => see check_cached_var.
+## * LIST optional flag could be used with CHECK_CACHED_VAR when = STRING. It allow to handle multiple STRINGS value list.
+## * is the value of the variable (if FILEPATH, PATH or STRING: use quotes, if BOOL : use ON/OFF)
+## * DOC optional flag is used to have a tooltips info about this new cmake variable entry into the GUI (use quotes).
+##
+## Full example 1 :
+## win3rdParty(COMMON MSVC11 "win3rdParty-MSVC11" "https://path.to/an.archive.7z"
+## SET CHECK_CACHED_VAR SuiteSparse_DIR PATH "SuiteSparse-4.2.1" DOC "default empty doc"
+## )
+##
+## WARNING:
+## For the 2nd usage (with MULTI_SET), if you planned to set some CACHED_VAR using/composed by ${prefix}_WIN3RDPARTY_* just set in this macro (usage 1),
+## then (due to the not yet existing var) you will need to call this function 2 times :
+## One for the 1st usage (downloading of the current compiler 3rdParty).
+## One for the MLUTI_SET flag which will use existsing ${prefix}_WIN3RDPARTY_* cached var.
+##
+## Full example 2 :
+## win3rdParty(COMMON MSVC11 "win3rdParty-MSVC11" "https://path.to/an.archive.7z")
+## win3rdParty(COMMON MULTI_SET
+## CHECK_CACHED_VAR CGAL_INCLUDE_DIR PATH "CGAL-4.3/include" DOC "default empty doc"
+## CHECK_CACHED_VAR CGAL_LIBRARIES STRING LIST "debug;CGAL-4.3/lib${LIB_POSTFIX}/CGAL-${WIN3RDPARTY_COMMON_VCID}-mt-gd-4.3.lib;optimized;CGAL-4.3/lib${LIB_POSTFIX}/CGAL-${WIN3RDPARTY_COMMON_VCID}-mt-4.3.lib"
+##
+##
+## WARNING: This function use internaly :
+## * downloadAndExtractZipFile.cmake
+## * parse_arguments_multi.cmake
+## * check_cached_var macro
+##
+function(win3rdParty prefix )
+
+ # ARGV: list of all arguments given to the macro/function
+ # ARGN: list of remaining arguments
+
+ if(NOT WIN32)
+ return()
+ endif()
+
+ ## set the handled version of MSVC
+ ## if you plan to add a win3rdParty dir to download with a new MSVC version: build the win3rdParty dir and add the MSCV entry here.
+ set(MSVC_VERSIONS_LIST "MSVC17;MSVC11;MSVC12;MSVC14")
+
+ #include(CMakeParseArguments) # CMakeParseArguments is obsolete since cmake 3.5
+ # cmake_parse_arguments ( args)
+ # : options (flags) pass to the macro
+ # : options that neeed a value
+ # : options that neeed more than one value
+ cmake_parse_arguments(w3p "VCID" "VERBOSE;TIMEOUT;DEFAULT_USE" "${MSVC_VERSIONS_LIST};MULTI_SET;SET" ${ARGN})
+
+ # message(STATUS "value of w3p_VCID = ${w3p_VCID}")
+ # message(STATUS "value of w3p_VERBOSE = ${w3p_VERBOSE}")
+ # message(STATUS "value of w3p_TIMEOUT = ${w3p_TIMEOUT}")
+ # message(STATUS "value of w3p_DEFAULT_USE = ${w3p_DEFAULT_USE}")
+
+ # foreach (loop_var ${MSVC_VERSIONS_LIST})
+ # message(STATUS "value of w3p_${loop_var} = ${w3p_${loop_var}}")
+ # endforeach(loop_var)
+
+ # message(STATUS "value of w3p_MULTI_SET = ${w3p_MULTI_SET}")
+ # message(STATUS "value of w3p_SET = ${w3p_SET}")
+
+ # message("values for MSVC = ${w3p_MSVC14}")
+
+ if(NOT w3p_TIMEOUT)
+ set(w3p_TIMEOUT 300)
+ endif()
+
+ if(NOT DEFINED w3p_DEFAULT_USE)
+ set(w3p_DEFAULT_USE ON)
+ endif()
+
+
+ ## 1st use (check/update|download) :
+ set(${prefix}_WIN3RDPARTY_USE ${w3p_DEFAULT_USE} CACHE BOOL "Use required 3rdParty binaries from ${prefix}_WIN3RDPARTY_DIR or download it if not exist")
+
+
+ ## We want to test if each version of MSVC was filled by the function (see associated parameters)
+ ## As CMake is running only for one version of MSVC, if that MSVC version was filled, we get back associated parameters,
+ ## otherwise we can't use the downloadAndExtractZipFile with win3rdParty.
+ set(enableWin3rdParty OFF)
+
+ foreach(MSVC_VER ${MSVC_VERSIONS_LIST})
+ if(${MSVC_VER} AND w3p_${MSVC_VER} OR ${MSVC_TOOLSET_VERSION} EQUAL 143 AND ${MSVC_VER} STREQUAL "MSVC17")
+ list(LENGTH w3p_${MSVC_VER} count)
+ if("${count}" LESS "2")
+ #message(WARNING "You are using ${MSVC_VER} with ${prefix}_WIN3RDPARTY_USE=${${prefix}_WIN3RDPARTY_USE}, but win3rdParty function isn't filled for ${MSVC_VER}!")
+ else()
+ list(GET w3p_${MSVC_VER} 0 Win3rdPartyName)
+ list(GET w3p_${MSVC_VER} 1 Win3rdPartyUrl)
+ if(w3p_VCID)
+ ## try to get the VcId of MSVC. See also MSVC_VERSION cmake var in the doc.
+ string(REGEX REPLACE "MS([A-Za-z_0-9-]+)" "\\1" vcId ${MSVC_VER})
+ string(TOLOWER ${vcId} vcId)
+ set(${prefix}_WIN3RDPARTY_VCID "${vcId}0" CACHE STRING "the MSVC id (commonly used to prefix/suffix library name, see boost or CGAL)")
+ mark_as_advanced(${prefix}_WIN3RDPARTY_VCID)
+ endif()
+ set(enableWin3rdParty ON)
+ set(suffixCompilerID ${MSVC_VER})
+ break()
+ endif()
+ endif()
+ endforeach()
+ ## If previous step succeed to get MSVC dirname and URL of the current MSVC version, use it to auto download/update the win3rdParty dir
+ if(enableWin3rdParty AND ${prefix}_WIN3RDPARTY_USE)
+
+ if(IS_ABSOLUTE "${Win3rdPartyName}")
+ else()
+ set(Win3rdPartyName "${CMAKE_BINARY_DIR}/${Win3rdPartyName}")
+ endif()
+
+ if(NOT EXISTS "${Win3rdPartyName}")
+ file(MAKE_DIRECTORY ${Win3rdPartyName})
+ endif()
+
+ include(downloadAndExtractZipFile)
+ downloadAndExtractZipFile( "${Win3rdPartyUrl}" ## URL link location
+ "Win3rdParty-${prefix}-${suffixCompilerID}.7z" ## where download it: relative path, so default to CMAKE_BINARY_DIR
+ "${Win3rdPartyName}" ## where extract it : fullPath (default relative to CMAKE_BINARY_DIR)
+ CHECK_DIRTY_URL "${Win3rdPartyName}/Win3rdPartyUrl" ## last downloaded url file : fullPath (default relative to CMAKE_BINARY_DIR)
+ TIMEOUT ${w3p_TIMEOUT}
+ VERBOSE ${w3p_VERBOSE}
+ )
+ file(GLOB checkDl "${Win3rdPartyName}/*")
+ list(LENGTH checkDl checkDlCount)
+ if("${checkDlCount}" GREATER "1")
+ else()
+ message("The downloadAndExtractZipFile didn't work...?")
+ set(enableWin3rdParty OFF)
+ endif()
+ endif()
+
+ ## Try to auto set ${prefix}_WIN3RDPARTY_DIR or let user set it manually
+ set(${prefix}_WIN3RDPARTY_DIR "" CACHE PATH "windows ${Win3rdPartyName} dir to ${prefix} dependencies of the project")
+
+ if(NOT ${prefix}_WIN3RDPARTY_DIR AND ${prefix}_WIN3RDPARTY_USE)
+ if(EXISTS "${Win3rdPartyName}")
+ unset(${prefix}_WIN3RDPARTY_DIR CACHE)
+ set(${prefix}_WIN3RDPARTY_DIR "${Win3rdPartyName}" CACHE PATH "dir to ${prefix} dependencies of the project")
+ endif()
+ endif()
+
+ if(EXISTS ${${prefix}_WIN3RDPARTY_DIR})
+ message(STATUS "Found a 3rdParty ${prefix} dir : ${${prefix}_WIN3RDPARTY_DIR}.")
+ set(enableWin3rdParty ON)
+ elseif(${prefix}_WIN3RDPARTY_USE)
+ message(WARNING "${prefix}_WIN3RDPARTY_USE=${${prefix}_WIN3RDPARTY_USE} but ${prefix}_WIN3RDPARTY_DIR=${${prefix}_WIN3RDPARTY_DIR}.")
+ set(enableWin3rdParty OFF)
+ endif()
+
+ ## Final check
+ if(NOT enableWin3rdParty)
+ message("Disable ${prefix}_WIN3RDPARTY_USE (cmake cached var will be not set), due to a win3rdParty problem.")
+ message("You still can set ${prefix}_WIN3RDPARTY_DIR to an already downloaded Win3rdParty directory location.")
+ set(${prefix}_WIN3RDPARTY_USE OFF CACHE BOOL "Use required 3rdParty binaries from ${prefix}_WIN3RDPARTY_DIR or download it if not exist" FORCE)
+ endif()
+
+ ## 2nd use : handle multi values args to set cached cmake variables in order to ease the next find_package call
+ if(${prefix}_WIN3RDPARTY_USE AND ${prefix}_WIN3RDPARTY_DIR)
+ if(w3p_VERBOSE)
+ message(STATUS "Try to set cmake cached variables for ${prefix} required libraries directly from : ${${prefix}_WIN3RDPARTY_DIR}.")
+ endif()
+
+ include(parse_arguments_multi)
+ # message (STATUS "before defining an override of parse_arguments_multi_function")
+ function(parse_arguments_multi_function ) ## overloaded function to handle all CHECK_CACHED_VAR values list (see: parse_arguments_multi)
+ # message(STATUS "inside overloaded parse_arguments_multi_function defined in Win3rdParty.cmake")
+ # message(STATUS ${ARGN})
+ ## we know the function take 3 args : var cacheType resetedCachedValue (see check_cached_var)
+ cmake_parse_arguments(pamf "" "DOC" "LIST" ${ARGN})
+
+ ## var and cacheType are mandatory (with the resetedCachedValue)
+ set(var ${ARGV0})
+ set(cacheType ${ARGV1})
+ # message(STATUS "var=${var} and cacheType=${cacheType} list=${pamf_LIST}")
+ if(pamf_DOC)
+ set(cacheDoc ${pamf_DOC})
+ else()
+ set(cacheDoc "")
+ endif()
+ if(pamf_LIST)
+ set(value ${pamf_LIST})
+ else()
+ # message("USING ARGV2 with value ${ARGV2}")
+ set(value ${ARGV2})
+ endif()
+ # message("inside override function in Win3rdparty.cmake value+ ${value}")
+ if("${cacheType}" MATCHES "PATH" AND EXISTS "${${prefix}_WIN3RDPARTY_DIR}/${value}")
+ # message("math with path")
+ set(resetedCachedValue "${${prefix}_WIN3RDPARTY_DIR}/${value}") ## path relative to ${prefix}_WIN3RDPARTY_DIR
+ elseif ("${cacheType}" MATCHES "PATH" AND EXISTS "${${prefix}_WIN3RDPARTY_DIR}")
+ set(resetedCachedValue "${${prefix}_WIN3RDPARTY_DIR}") ## path relative to ${prefix}_WIN3RDPARTY_DIR
+ elseif("${cacheType}" MATCHES "STRING")
+ foreach(var IN LISTS value)
+ if(EXISTS "${${prefix}_WIN3RDPARTY_DIR}/${var}")
+ list(APPEND resetedCachedValue "${${prefix}_WIN3RDPARTY_DIR}/${var}") ## string item of the string list is a path => make relative to ${prefix}_WIN3RDPARTY_DIR
+ else()
+ list(APPEND resetedCachedValue ${var}) ## string item of the string list is not an existing path => simply use the item
+ endif()
+ endforeach()
+ else()
+ set(resetedCachedValue "${value}") ## could be a BOOL or a STRING
+ endif()
+
+ ## call our macro to reset cmake cache variable if empty
+ check_cached_var(${var} "${resetedCachedValue}" ${cacheType} "${cacheDoc}" FORCE)
+
+ endfunction()
+ # message (STATUS "after defining an override of parse_arguments_multi_function")
+
+ if(w3p_MULTI_SET)
+ parse_arguments_multi(CHECK_CACHED_VAR w3p_MULTI_SET ${w3p_MULTI_SET}) ## internaly will call our overloaded parse_arguments_multi_function
+ elseif(w3p_SET)
+ # message("calling set version of parse_arguments_multi with w3p_set = ${w3p_SET}")
+ parse_arguments_multi(CHECK_CACHED_VAR w3p_SET ${w3p_SET})
+ endif()
+
+ endif()
+
+endfunction()
+
+## cmake variables introspection to globally activate/deactivate ${prefix}_WIN3RDPARTY_USE
+## This "one shot" call (only one for the next cmake configure) will automatically then reset the global variable WIN3RDPARTY_USE to UserDefined (do nothing).
+## use (call it) before and after the call of all your win3rdParty functions
+function(Win3rdPartyGlobalCacheAction )
+ set(WIN3RDPARTY_USE "UserDefined" CACHE STRING "Choose how to handle all cmake cached *_WIN3RDPARTY_USE for the next configure.\nCould be:\nUserDefined [default]\nActivateAll\nDesactivateAll" )
+ set_property(CACHE WIN3RDPARTY_USE PROPERTY STRINGS "UserDefined;ActivateAll;DesactivateAll" )
+ if(${WIN3RDPARTY_USE} MATCHES "UserDefined")
+ else()
+ if(${WIN3RDPARTY_USE} MATCHES "ActivateAll")
+ set(win3rdPvalue ON)
+ elseif(${WIN3RDPARTY_USE} MATCHES "DesactivateAll")
+ set(win3rdPvalue OFF)
+ endif()
+ get_cmake_property(_variableNames CACHE_VARIABLES)
+ foreach (_variableName ${_variableNames})
+ string(REGEX MATCH "[A-Za-z_0-9-]+_WIN3RDPARTY_USE" win3rdpartyUseCacheVar ${_variableName})
+ if(win3rdpartyUseCacheVar)
+ string(REGEX REPLACE "([A-Za-z_0-9-]+_WIN3RDPARTY_USE)" "\\1" win3rdpartyUseCacheVar ${_variableName})
+ set(${win3rdpartyUseCacheVar} ${win3rdPvalue} CACHE BOOL "Use required 3rdParty binaries from ${prefix}_WIN3RDPARTY_DIR or download it if not exist" FORCE)
+ message(STATUS "${win3rdpartyUseCacheVar} cached variable set to ${win3rdPvalue}.")
+ endif()
+ endforeach()
+ set(WIN3RDPARTY_USE "UserDefined" CACHE STRING "Choose how to handle all cmake cached *_WIN3RDPARTY_USE for the next configure.\nCould be:\nUserDefined [default]\nActivateAll\nDesactivateAll" FORCE)
+ message(STATUS "reset WIN3RDPARTY_USE to UserDefined.")
+ endif()
+ mark_as_advanced(WIN3RDPARTY_USE)
+endfunction()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/cmake_policies.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/cmake_policies.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4f660d857e375fa5d807ed33a18dce27bd61d40e
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/cmake_policies.cmake
@@ -0,0 +1,19 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+if(__set_policies_INCLUDED__)
+ return()
+else()
+ set(__set_policies_INCLUDED__ ON)
+endif()
+
+macro(setPolicies)
+ # No more policies to enforce
+endmacro()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/dependencies.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/dependencies.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fd24de99bbe0e0dd16238da6623f9e7a177c49d7
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/dependencies.cmake
@@ -0,0 +1,324 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## Included once for all sub project.
+## It contain the whole cmake instructions to find necessary common dependencies.
+## 3rdParty (provided by sibr_addlibrary win3rdParty or from external packages) are then available in cmake sub projects.
+##
+## Do not include this file more than once but you can modify it to fit to your own project.
+## So please, read it carefully because you can use on of these dependencies for your project or appen new one.
+##
+## As it is included after camke options, you can use conditional if()/endif() to encapsulate your 3rdParty.
+##
+
+## win3rdParty function allowing to auto check/download/update binaries dependencies for current windows compiler
+## Please open this file in order to get more documentation and usage examples.
+include(Win3rdParty)
+
+include(sibr_library)
+
+Win3rdPartyGlobalCacheAction()
+
+find_package(OpenGL REQUIRED)
+
+set(OpenGL_GL_PREFERENCE "GLVND")
+
+############
+## Find GLEW
+############
+##for headless rendering
+find_package(EGL QUIET)
+
+if(EGL_FOUND)
+ add_definitions(-DGLEW_EGL)
+ message("Activating EGL support for headless GLFW/GLEW")
+else()
+ message("EGL not found : EGL support for headless GLFW/GLEW is disabled")
+endif()
+
+if (MSVC11 OR MSVC12)
+ set(glew_multiset_arguments
+ CHECK_CACHED_VAR GLEW_INCLUDE_DIR PATH "glew-1.10.0/include" DOC "default empty doc"
+ CHECK_CACHED_VAR GLEW_LIBRARIES STRING LIST "debug;glew-1.10.0/${LIB_BUILT_DIR}/glew32d.lib;optimized;glew-1.10.0/${LIB_BUILT_DIR}/glew32.lib" DOC "default empty doc"
+ )
+elseif (MSVC14)
+ set(glew_multiset_arguments
+ CHECK_CACHED_VAR GLEW_INCLUDE_DIR PATH "glew-2.0.0/include" DOC "default empty doc"
+ CHECK_CACHED_VAR GLEW_SHARED_LIBRARY_RELEASE PATH "glew-2.0.0/${LIB_BUILT_DIR}/glew32.lib"
+ CHECK_CACHED_VAR GLEW_STATIC_LIBRARY_RELEASE PATH "glew-2.0.0/${LIB_BUILT_DIR}/glew32s.lib"
+ CHECK_CACHED_VAR GLEW_SHARED_LIBRARY_DEBUG PATH "glew-2.0.0/${LIB_BUILT_DIR}/glew32d.lib"
+ CHECK_CACHED_VAR GLEW_STATIC_LIBRARY_DEBUG PATH "glew-2.0.0/${LIB_BUILT_DIR}/glew32sd.lib"
+ )
+else ()
+ message("There is no provided GLEW library for your compiler, relying on find_package to find it")
+endif()
+sibr_addlibrary(NAME GLEW #VERBOSE ON
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/glew-1.10.0.7z"
+ MSVC12 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/glew-1.10.0.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/glew-2.0.0.7z" # using recompiled version of glew
+ MULTI_SET ${glew_multiset_arguments}
+)
+set(GLEW_VERBOSE ON)
+FIND_PACKAGE(GLEW REQUIRED)
+IF(GLEW_FOUND)
+ INCLUDE_DIRECTORIES(${GLEW_INCLUDE_DIR})
+ELSE(GLEW_FOUND)
+ MESSAGE("GLEW not found. Set GLEW_DIR to base directory of GLEW.")
+ENDIF(GLEW_FOUND)
+
+
+##############
+## Find ASSIMP
+##############
+if (MSVC11 OR MSVC12)
+ set(assimp_set_arguments
+ CHECK_CACHED_VAR ASSIMP_DIR PATH "Assimp_3.1_fix"
+ )
+elseif (MSVC14)
+ set(assimp_set_arguments
+ CHECK_CACHED_VAR ASSIMP_DIR PATH "Assimp-4.1.0"
+ )
+else ()
+ message("There is no provided ASSIMP library for your compiler, relying on find_package to find it")
+endif()
+
+sibr_addlibrary(NAME ASSIMP #VERBOSE ON
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/Assimp_3.1_fix.7z"
+ MSVC12 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/Assimp_3.1_fix.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/Assimp-4.1.0.7z"
+ MULTI_SET
+ ${assimp_set_arguments}
+)
+
+find_package(ASSIMP REQUIRED)
+include_directories(${ASSIMP_INCLUDE_DIR})
+
+################
+## Find FFMPEG
+################
+sibr_addlibrary(NAME FFMPEG
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/ffmpeg.zip"
+ MSVC12 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/ffmpeg.zip"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/ffmpeg-4.0.2-win64-win3rdParty.7z"
+ SET CHECK_CACHED_VAR FFMPEG_DIR PATH ${FFMPEG_WIN3RDPARTY_DIR}
+)
+find_package(FFMPEG)
+include_directories(${FFMPEG_INCLUDE_DIR})
+## COMMENT OUT ALL FFMPEG FOR CLUSTER
+
+###################
+## Find embree3
+###################
+sibr_addlibrary(
+ NAME embree3
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/embree2.7.0.x64.windows.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/embree-3.6.1.x64.vc14.windows.7z" # TODO SV: provide a valid version if required
+)
+
+# CLUSTER
+#find_package(embree 3.0 REQUIRED PATHS "/data/graphdeco/share/embree/usr/local/lib64/cmake/" )
+find_package(embree 3.0 )
+
+###################
+## Find eigen3
+###################
+sibr_addlibrary(
+ NAME eigen3
+ #MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/eigen-eigen-dc6cfdf9bcec.7z"
+ #MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/eigen-eigen-dc6cfdf9bcec.7z" # TODO SV: provide a valid version if required
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/eigen3.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/eigen3.7z"
+ SET CHECK_CACHED_VAR eigen3_DIR PATH "eigen/share/eigen3/cmake"
+)
+include_directories(/usr/include/eigen3)
+add_definitions(-DEIGEN_INITIALIZE_MATRICES_BY_ZERO)
+
+#############
+## Find Boost
+#############
+set(Boost_REQUIRED_COMPONENTS "system;chrono;filesystem;date_time" CACHE INTERNAL "Boost Required Components")
+
+if (WIN32)
+ # boost multiset arguments
+ if (MSVC11 OR MSVC12)
+ set(boost_multiset_arguments
+ CHECK_CACHED_VAR BOOST_ROOT PATH "boost_1_55_0"
+ CHECK_CACHED_VAR BOOST_INCLUDEDIR PATH "boost_1_55_0"
+ CHECK_CACHED_VAR BOOST_LIBRARYDIR PATH "boost_1_55_0/${LIB_BUILT_DIR}"
+ #CHECK_CACHED_VAR Boost_COMPILER STRING "-${Boost_WIN3RDPARTY_VCID}" DOC "vcid (eg: -vc110 for MSVC11)"
+ CHECK_CACHED_VAR Boost_COMPILER STRING "-vc110" DOC "vcid (eg: -vc110 for MSVC11)" # NOTE: if it doesnt work, uncomment this option and set the right value for VisualC id
+ )
+ elseif (MSVC14)
+ set(boost_multiset_arguments
+ CHECK_CACHED_VAR BOOST_ROOT PATH "boost-1.71"
+ CHECK_CACHED_VAR BOOST_INCLUDEDIR PATH "boost-1.71"
+ CHECK_CACHED_VAR BOOST_LIBRARYDIR PATH "boost-1.71/${LIB_BUILT_DIR}"
+ CHECK_CACHED_VAR Boost_COMPILER STRING "-vc141" DOC "vcid (eg: -vc110 for MSVC11)" # NOTE: if it doesnt work, uncomment this option and set the right value for VisualC id
+ )
+
+ option(BOOST_MINIMAL_VERSION "Only get minimal Boost dependencies" ON)
+
+ if(${BOOST_MINIMAL_VERSION})
+ set(BOOST_MSVC14_ZIP "boost-1.71-ibr-minimal.7z")
+ else()
+ set(BOOST_MSVC14_ZIP "boost-1.71.7z")
+ endif()
+ else ()
+ message("There is no provided Boost library for your compiler, relying on find_package to find it")
+ endif()
+
+ sibr_addlibrary(NAME Boost VCID TIMEOUT 600 #VERBOSE ON
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/boost_1_55_0.7z"
+ MSVC12 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC11-splitted%20version/boost_1_55_0.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/${BOOST_MSVC14_ZIP}" # boost compatible with msvc14
+ MULTI_SET ${boost_multiset_arguments}
+ CHECK_CACHED_VAR Boost_NO_SYSTEM_PATHS BOOL ON DOC "Set to ON to disable searching in locations not specified by these boost cached hint variables"
+ CHECK_CACHED_VAR Boost_NO_BOOST_CMAKE BOOL ON DOC "Set to ON to disable the search for boost-cmake (package cmake config file if boost was built with cmake)"
+ )
+ if(NOT Boost_COMPILER AND Boost_WIN3RDPARTY_USE)
+ message(WARNING "Boost_COMPILER is not set and it's needed.")
+ endif()
+endif()
+
+find_package(Boost 1.65.0 REQUIRED COMPONENTS ${Boost_REQUIRED_COMPONENTS})
+# for CLUSTER
+##find_package(Boost 1.58.0 REQUIRED COMPONENTS ${Boost_REQUIRED_COMPONENTS})
+
+
+if(WIN32)
+ add_compile_options("$<$:/EHsc>")
+ #add_definitions(/EHsc)
+endif()
+
+if(Boost_LIB_DIAGNOSTIC_DEFINITIONS)
+ add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
+endif()
+
+#if(WIN32)
+ add_definitions(-DBOOST_ALL_DYN_LINK -DBOOST_ALL_NO_LIB)
+#endif()
+
+include_directories(${BOOST_INCLUDEDIR} ${Boost_INCLUDE_DIRS})
+link_directories(${BOOST_LIBRARYDIR} ${Boost_LIBRARY_DIRS})
+
+
+##############
+## Find OpenMP
+##############
+find_package(OpenMP)
+
+##############
+## Find OpenCV
+##############
+if (WIN32)
+ if (${MSVC_TOOLSET_VERSION} EQUAL 143)
+ MESSAGE("SPECIAL OPENCV HANDLING")
+ set(opencv_set_arguments
+ CHECK_CACHED_VAR OpenCV_DIR PATH "install" ## see OpenCVConfig.cmake
+ )
+ elseif (MSVC11 OR MSVC12)
+ set(opencv_set_arguments
+ CHECK_CACHED_VAR OpenCV_DIR PATH "opencv/build" ## see OpenCVConfig.cmake
+ )
+ elseif (MSVC14)
+ set(opencv_set_arguments
+ CHECK_CACHED_VAR OpenCV_DIR PATH "opencv-4.5.0/build" ## see OpenCVConfig.cmake
+ )
+ else ()
+ message("There is no provided OpenCV library for your compiler, relying on find_package to find it")
+ endif()
+else()
+ message("There is no provided OpenCV library for your compiler, relying on find_package to find it")
+endif()
+
+sibr_addlibrary(NAME OpenCV #VERBOSE ON
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/sibr/~0.9/opencv.7z"
+ MSVC12 "https://repo-sam.inria.fr/fungraph/dependencies/sibr/~0.9/opencv.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/sibr/~0.9/opencv-4.5.0.7z" # opencv compatible with msvc14 and with contribs
+ MSVC17 "https://repo-sam.inria.fr/fungraph/dependencies/sibr/~0.9/opencv4-8.7z"
+ SET ${opencv_set_arguments}
+ )
+find_package(OpenCV 4.5 REQUIRED) ## Use directly the OpenCVConfig.cmake provided
+## FOR CLUSTER
+###find_package(OpenCV 4.5 REQUIRED PATHS "/data/graphdeco/share/opencv/usr/local/lib64/cmake/opencv4/" ) ## Use directly the OpenCVConfig.cmake provided
+
+ ##https://stackoverflow.com/questions/24262081/cmake-relwithdebinfo-links-to-debug-libs
+set_target_properties(${OpenCV_LIBS} PROPERTIES MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE)
+
+add_definitions(-DOPENCV_TRAITS_ENABLE_DEPRECATED)
+
+if(OpenCV_INCLUDE_DIRS)
+ foreach(inc ${OpenCV_INCLUDE_DIRS})
+ if(NOT EXISTS ${inc})
+ set(OpenCV_INCLUDE_DIR "" CACHE PATH "additional custom include DIR (in case of trouble to find it (fedora 17 opencv package))")
+ endif()
+ endforeach()
+ if(OpenCV_INCLUDE_DIR)
+ list(APPEND OpenCV_INCLUDE_DIRS ${OpenCV_INCLUDE_DIR})
+ include_directories(${OpenCV_INCLUDE_DIRS})
+ endif()
+endif()
+
+###################
+## Find GLFW
+###################
+sibr_addlibrary(
+ NAME glfw3
+ MSVC11 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/glfw-3.2.1.7z"
+ MSVC14 "https://repo-sam.inria.fr/fungraph/dependencies/ibr-common/win3rdParty-MSVC15-splitted%20version/glfw-3.2.1.7z" # TODO SV: provide a valid version if required
+ SET CHECK_CACHED_VAR glfw3_DIR PATH "glfw-3.2.1"
+)
+
+### FOR CLUSTER COMMENT OUT lines above, uncomment lines below
+##find_package(GLFW REQUIRED 3.3 )
+##message("***********=============> GLFW IS " ${GLFW_LIBRARY})
+##message("***********=============> GLFW IS " ${GLFW_LIBRARIES})
+
+find_package(glfw3 REQUIRED)
+
+sibr_gitlibrary(TARGET imgui
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/imgui.git"
+ GIT_TAG "741fb3ab6c7e1f7cef23ad0501a06b7c2b354944"
+)
+
+## FOR CLUSTER COMMENT OUT nativefiledialog
+sibr_gitlibrary(TARGET nativefiledialog
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/nativefiledialog.git"
+ GIT_TAG "ae2fab73cf44bebdc08d997e307c8df30bb9acec"
+)
+
+
+sibr_gitlibrary(TARGET mrf
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/mrf.git"
+ GIT_TAG "30c3c9494a00b6346d72a9e37761824c6f2b7207"
+)
+
+sibr_gitlibrary(TARGET nanoflann
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/nanoflann.git"
+ GIT_TAG "7a20a9ac0a1d34850fc3a9e398fc4a7618e8a69a"
+)
+
+sibr_gitlibrary(TARGET picojson
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/picojson.git"
+ GIT_TAG "7cf8feee93c8383dddbcb6b64cf40b04e007c49f"
+)
+
+sibr_gitlibrary(TARGET rapidxml
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/rapidxml.git"
+ GIT_TAG "069e87f5ec5ce1745253bd64d89644d6b894e516"
+)
+
+sibr_gitlibrary(TARGET xatlas
+ GIT_REPOSITORY "https://gitlab.inria.fr/sibr/libs/xatlas.git"
+ GIT_TAG "0fbe06a5368da13fcdc3ee48d4bdb2919ed2a249"
+ INCLUDE_DIRS "source/xatlas"
+)
+
+Win3rdPartyGlobalCacheAction()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/downloadAndExtractZipFile.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/downloadAndExtractZipFile.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b5fe99bac086c6c0fd7d12dafa16b1e7cf697777
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/downloadAndExtractZipFile.cmake
@@ -0,0 +1,243 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## downloadAndExtractZipFile cmake function
+## Provide a way to download zip file from public internet ZIP_URL host
+## and to extract it in a specific EXCTRATED_ZIP_PATH destination.
+## This function use 7-Zip external tool to maximize the compatibles formats.
+## This will be not download again if the EXCTRATED_ZIP_PATH already exist and DL_FORCE is set to OFF.
+## This will try to unzip file if already exist in the ZIP_DL_PATH.
+##
+## If EXCTRATED_ZIP_PATH and/or ZIP_DL_PATH are not full path,
+## it will be interpreted relative to CMAKE_BINARY_DIR
+##
+## Usage example :
+## include(downloadAndExtractZipFile)
+## downloadAndExtractZipFile(
+## http://www.cs.cornell.edu/~snavely/bundler/distr/bundler-v0.4-source.zip
+## ${CMAKE_BINARY_DIR}/Bundler/bundler-v0.4-source.zip
+## ${CMAKE_BINARY_DIR}/Bundler
+## [DL_FORCE ON|OFF]
+## [TIMEOUT]
+## [CHECK_DIRTY_URL]
+## )
+##
+## option DL_FORCE will redownload the zip file [deafult to OFF]
+## option TIMEOUT will end the unzip process after this period of time [default to 600s]
+## option CHECK_DIRTY_URL will write into the given file the downloaded URL and then,
+## next time, if the URL was updated, it detect it with this file
+## and will download the last version. This prevent to alway set manually DL_FORCE to ON...
+##
+if(__downloadAndExtractZipFile_cmake_INCLUDED__)
+ return()
+else()
+ set(__downloadAndExtractZipFile_cmake_INCLUDED__ ON)
+endif()
+
+function(downloadAndExtractZipFile ZIP_URL ZIP_DL_PATH EXCTRATED_ZIP_PATH)
+
+ # message(STATUS "zipUrl=${ZIP_URL} zipDlPath=${ZIP_DL_PATH} extractedZipPath=${EXCTRATED_ZIP_PATH}")
+ cmake_parse_arguments(dwnlezf "" "VERBOSE;DL_FORCE;TIMEOUT;CHECK_DIRTY_URL" "" ${ARGN})
+
+ set(PROGRAMFILESx86 "PROGRAMFILES(x86)")
+
+ ## Check entries mandatory args
+ if(IS_ABSOLUTE "${ZIP_DL_PATH}")
+ else()
+ set(ZIP_DL_PATH "${CMAKE_BINARY_DIR}/${ZIP_DL_PATH}")
+ endif()
+ if(IS_ABSOLUTE "${EXCTRATED_ZIP_PATH}")
+ else()
+ set(EXCTRATED_ZIP_PATH "${CMAKE_BINARY_DIR}/${EXCTRATED_ZIP_PATH}")
+ endif()
+ if(NOT EXISTS "${EXCTRATED_ZIP_PATH}")
+ file(MAKE_DIRECTORY ${EXCTRATED_ZIP_PATH})
+ endif()
+
+ # SB: Once, one of downloaded zip was corrupted by an error message coming from the server.
+ if(EXISTS "${ZIP_DL_PATH}")
+ # So I check for removing such corrupted files
+ message("Removing previous ${ZIP_DL_PATH} (might be corrupted)")
+ file(REMOVE "${ZIP_DL_PATH}")
+ if(EXISTS "${dwnlezf_CHECK_DIRTY_URL}")
+ # and remove the previous (corrupted) made 'Win3rdPartyUrl' file
+ file(REMOVE "${dwnlezf_CHECK_DIRTY_URL}")
+ endif()
+ endif()
+
+ ## Check entries optional args
+ macro(readDirtyUrl )
+ if(dwnlezf_CHECK_DIRTY_URL)
+ if(IS_ABSOLUTE "${dwnlezf_CHECK_DIRTY_URL}")
+ else()
+ set(dwnlezf_CHECK_DIRTY_URL "${CMAKE_BINARY_DIR}/${dwnlezf_CHECK_DIRTY_URL}")
+ endif()
+ get_filename_component(unzipDir ${EXCTRATED_ZIP_PATH} NAME)
+ get_filename_component(unzipPath ${EXCTRATED_ZIP_PATH} PATH)
+ message(STATUS "Checking ${unzipDir} [from ${unzipPath}]...")
+ if(EXISTS "${dwnlezf_CHECK_DIRTY_URL}")
+ get_filename_component(CHECK_DIRTY_URL_FILENAME ${dwnlezf_CHECK_DIRTY_URL} NAME)
+ file(STRINGS "${dwnlezf_CHECK_DIRTY_URL}" contents)
+ list(GET contents 0 downloadURL)
+ list(REMOVE_AT contents 0)
+ if("${downloadURL}" MATCHES "${ZIP_URL}")
+ if(dwnlezf_VERBOSE)
+ message(STATUS "Your downloaded version (URL) seems to be up to date. Let me check if nothing is missing... (see ${dwnlezf_CHECK_DIRTY_URL}).")
+ endif()
+ file(GLOB PATHNAME_PATTERN_LIST "${EXCTRATED_ZIP_PATH}/*") ## is there something inside the downloaded destination ?
+ unset(NAME_PATTERN_LIST)
+ foreach(realPathPattern ${PATHNAME_PATTERN_LIST})
+ get_filename_component(itemName ${realPathPattern} NAME)
+ list(APPEND NAME_PATTERN_LIST ${itemName})
+ endforeach()
+ if(NAME_PATTERN_LIST)
+ foreach(item ${contents})
+ list(FIND NAME_PATTERN_LIST ${item} id)
+ if(${id} MATCHES "-1")
+ message(STATUS "${item} is missing, your downloaded version content changed, need to redownload it.")
+ set(ZIP_DL_FORCE ON)
+ break()
+ else()
+ list(REMOVE_AT NAME_PATTERN_LIST ${id})
+ set(ZIP_DL_FORCE OFF)
+ endif()
+ endforeach()
+ if(NOT ZIP_DL_FORCE AND NAME_PATTERN_LIST)
+ message("Yours seems to be up to date (regarding to ${CHECK_DIRTY_URL_FILENAME})!\nBut there are additional files/folders into your downloaded destination (feel free to clean it if you want).")
+ foreach(item ${NAME_PATTERN_LIST})
+ if(item)
+ message("${item}")
+ endif()
+ endforeach()
+ endif()
+ endif()
+ else()
+ set(ZIP_DL_FORCE ON)
+ message(STATUS "Your downloaded version is dirty (too old).")
+ endif()
+ else()
+ file(GLOB PATHNAME_PATTERN_LIST "${EXCTRATED_ZIP_PATH}/*") ## is there something inside the downloaded destination ?
+ if(NOT PATHNAME_PATTERN_LIST)
+ message("We found nothing into ${EXCTRATED_ZIP_PATH}, we will try to download it for you now.")
+ endif()
+ set(ZIP_DL_FORCE ON)
+ endif()
+ endif()
+ endmacro()
+ readDirtyUrl()
+ if(NOT ZIP_DL_FORCE)
+ return() ## do not need to further (as we are up to date, just exit the function
+ endif()
+
+ macro(writeDirtyUrl )
+ if(dwnlezf_CHECK_DIRTY_URL)
+ file(WRITE "${dwnlezf_CHECK_DIRTY_URL}" "${ZIP_URL}\n")
+ file(GLOB PATHNAME_PATTERN_LIST "${EXCTRATED_ZIP_PATH}/*") ## is there something inside the downloaded destination ?
+ unset(NAME_PATTERN_LIST)
+ foreach(realPathPattern ${PATHNAME_PATTERN_LIST})
+ get_filename_component(itemName ${realPathPattern} NAME)
+ list(APPEND NAME_PATTERN_LIST ${itemName})
+ endforeach()
+ if(NAME_PATTERN_LIST)
+ foreach(item ${NAME_PATTERN_LIST})
+ file(APPEND "${dwnlezf_CHECK_DIRTY_URL}" "${item}\n")
+ endforeach()
+ endif()
+ endif()
+ endmacro()
+
+ if(dwnlezf_DL_FORCE)
+ set(ZIP_DL_FORCE ON)
+ endif()
+
+ if(NOT dwnlezf_TIMEOUT)
+ set(dwnlezf_TIMEOUT 600)
+ endif()
+ math(EXPR dwnlezf_TIMEOUT_MIN "${dwnlezf_TIMEOUT}/60")
+
+ macro(unzip whichZipFile)
+ if(NOT SEVEN_ZIP_CMD)
+ find_program(SEVEN_ZIP_CMD NAMES 7z 7za p7zip DOC "7-zip executable" PATHS "$ENV{PROGRAMFILES}/7-Zip" "$ENV{${PROGRAMFILESx86}}/7-Zip" "$ENV{ProgramW6432}/7-Zip")
+ endif()
+ if(SEVEN_ZIP_CMD)
+ if(dwnlezf_VERBOSE)
+ message(STATUS "UNZIP: please, WAIT UNTIL ${SEVEN_ZIP_CMD} finished...\n(no more than ${dwnlezf_TIMEOUT_MIN} min)")
+ else()
+ message(STATUS "UNZIP...wait...")
+ endif()
+ execute_process( COMMAND ${SEVEN_ZIP_CMD} x ${whichZipFile} -y
+ WORKING_DIRECTORY ${EXCTRATED_ZIP_PATH} TIMEOUT ${dwnlezf_TIMEOUT}
+ RESULT_VARIABLE resVar OUTPUT_VARIABLE outVar ERROR_VARIABLE errVar
+ )
+ if(${resVar} MATCHES "0")
+ if(dwnlezf_VERBOSE)
+ message(STATUS "SUCESS to unzip in ${EXCTRATED_ZIP_PATH}. Now we can remove the downloaded zip file.")
+ endif()
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${whichZipFile})
+ mark_as_advanced(SEVEN_ZIP_CMD)
+ else()
+ message(WARNING "something wrong in ${EXCTRATED_ZIP_PATH}\n with \"${SEVEN_ZIP_CMD} x ${whichZipFile} -y\", redo or try to unzip by yourself...")
+ message("unzip: resVar=${resVar}")
+ message("unzip: outVar=${outVar}")
+ message("unzip: errVar=${errVar}")
+ message("unzip: failed or canceled or timeout")
+ endif()
+ else()
+ message(WARNING "You need 7zip (http://www.7-zip.org/download.html) to unzip the downloaded dir.")
+ set(SEVEN_ZIP_CMD "" CACHE FILEPATH "7-zip executable")
+ mark_as_advanced(CLEAR SEVEN_ZIP_CMD)
+ endif()
+ endmacro()
+
+ if(dwnlezf_VERBOSE)
+ message(STATUS "Trying to look ${ZIP_DL_PATH} if a zip file exist...")
+ endif()
+ if(EXISTS "${ZIP_DL_PATH}")
+
+ ## already downloaded, so just unzip it
+ unzip(${ZIP_DL_PATH})
+ writeDirtyUrl()
+
+ elseif(ZIP_DL_FORCE)
+
+ ## the download part (+ unzip)
+ message(STATUS "Let me try to download package for you : ${ZIP_URL}")
+ if(dwnlezf_VERBOSE)
+ message(STATUS "Downloading...\n SRC=${ZIP_URL}\n DEST=${ZIP_DL_PATH}.tmp\n INACTIVITY_TIMEOUT=180s")
+ endif()
+ file(DOWNLOAD ${ZIP_URL} ${ZIP_DL_PATH}.tmp INACTIVITY_TIMEOUT 360 STATUS status SHOW_PROGRESS)
+
+ list(GET status 0 numResult)
+ if(${numResult} MATCHES "0")
+
+ if(dwnlezf_VERBOSE)
+ message(STATUS "Download succeed, so let me rename the tmp file to unzip it")
+ endif()
+ execute_process(COMMAND ${CMAKE_COMMAND} -E rename ${ZIP_DL_PATH}.tmp ${ZIP_DL_PATH})
+ unzip(${ZIP_DL_PATH})
+ writeDirtyUrl()
+
+ else()
+
+ list(GET status 1 errMsg)
+ message(WARNING "DOWNLOAD ${ZIP_URL} to ${ZIP_DL_PATH} failed\n:${errMsg}")
+ message(WARNING "OK, you need to download the ${ZIP_URL} manually and put it into ${ZIP_DL_PATH}")
+ message("Take a look at the project website page to check available URL.")
+
+ endif()
+
+ endif()
+
+ ## clean up the tmp downloaded file
+ if(EXISTS "${ZIP_DL_PATH}.tmp")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${ZIP_DL_PATH}.tmp)
+ endif()
+
+endfunction()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/git_describe.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/git_describe.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2d2a1a46451497eb8e9f21204beb7223a54db915
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/git_describe.cmake
@@ -0,0 +1,114 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+if(__git_describe_INCLUDED__)
+ return()
+else()
+ set(__git_describe_INCLUDED__ ON)
+endif()
+
+find_package(Git)
+if(Git_FOUND)
+ message(STATUS "Git found: ${GIT_EXECUTABLE}")
+else()
+ message(FATAL_ERROR "Git not found. Aborting")
+endif()
+
+macro(git_describe)
+ cmake_parse_arguments(GIT_DESCRIBE "" "GIT_URL;GIT_BRANCH;GIT_COMMIT_HASH;GIT_TAG;GIT_VERSION;PATH" "" ${ARGN})
+
+ if(NOT GIT_DESCRIBE_PATH)
+ set(GIT_DESCRIBE_PATH ${CMAKE_SOURCE_DIR})
+ endif()
+
+ if(GIT_DESCRIBE_GIT_URL)
+ # Get the current remote
+ execute_process(
+ COMMAND git remote
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE GIT_DESCRIBE_GIT_REMOTE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+
+ # Get the current remote
+ execute_process(
+ COMMAND git remote get-url ${GIT_DESCRIBE_GIT_REMOTE}
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE ${GIT_DESCRIBE_GIT_URL}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ endif()
+
+ if(GIT_DESCRIBE_GIT_BRANCH)
+ # Get the current working branch
+ execute_process(
+ COMMAND git rev-parse --abbrev-ref HEAD
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE ${GIT_DESCRIBE_GIT_BRANCH}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ endif()
+
+ if(GIT_DESCRIBE_GIT_COMMIT_HASH)
+ # Get the latest abbreviated commit hash of the working branch
+ execute_process(
+ COMMAND git rev-parse HEAD
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE ${GIT_DESCRIBE_GIT_COMMIT_HASH}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ endif()
+
+ if(GIT_DESCRIBE_GIT_TAG)
+ # Get the tag
+ execute_process(
+ COMMAND git describe --tags --exact-match
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE ${GIT_DESCRIBE_GIT_TAG}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ endif()
+
+ if(GIT_DESCRIBE_GIT_VERSION)
+ # Get the version from git describe
+ execute_process(
+ COMMAND git describe
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE ${GIT_DESCRIBE_GIT_VERSION}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+
+ if(${GIT_DESCRIBE_GIT_VERSION} STREQUAL "")
+ execute_process(
+ COMMAND git rev-parse --abbrev-ref HEAD
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE GIT_DESCRIBE_GIT_VERSION_BRANCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ execute_process(
+ COMMAND git log -1 --format=%h
+ WORKING_DIRECTORY ${GIT_DESCRIBE_PATH}
+ OUTPUT_VARIABLE GIT_DESCRIBE_GIT_VERSION_COMMIT
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+
+ set(${GIT_DESCRIBE_GIT_VERSION} "${GIT_DESCRIBE_GIT_VERSION_BRANCH}-${GIT_DESCRIBE_GIT_VERSION_COMMIT}")
+ endif()
+ endif()
+
+endmacro()
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/include_once.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/include_once.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4a285fecd8c9ba942097dab4b1dbd43b627339de
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/include_once.cmake
@@ -0,0 +1,22 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+macro(include_once file)
+ get_filename_component(INCLUDE_ONCE_FILEPATH ${file} REALPATH)
+ string(REGEX REPLACE "(\\.|\\/+|\\:|\\\\+)" "_" INCLUDE_ONCE_FILEPATH ${INCLUDE_ONCE_FILEPATH})
+ get_property(INCLUDED_${INCLUDE_ONCE_FILEPATH}_LOCAL GLOBAL PROPERTY INCLUDED_${INCLUDE_ONCE_FILEPATH})
+ if (INCLUDED_${INCLUDE_ONCE_FILEPATH}_LOCAL)
+ return()
+ else()
+ set_property(GLOBAL PROPERTY INCLUDED_${INCLUDE_ONCE_FILEPATH} true)
+
+ include(${file})
+ endif()
+endmacro()
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/install_runtime.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/install_runtime.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..8e31487a8a5da4b46a368d4f92cf97891fbe2ffb
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/install_runtime.cmake
@@ -0,0 +1,887 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+## This file is mainly used to allow runtime installation
+## There are some utilities cmake functions to ease the generic deployement (abstract common usage of cmake)...
+##
+## You cannot run your programm automaticaly from your CNAKE_BINARY_DIR when you build
+## as it will miss all dependencies and ressources files...
+## You have to run install target in order to test your programm.
+##
+## The only one function/macros you may use inside your sub-CMakeLists.txt (sub-project) is :
+## ******************
+## ibr_install_target macro => see documentation at the end of this file
+## ******************
+## It use these utilities cmake functions to abstract the installation in an uniform way for all sub-projects.
+##
+if(__install_runtime_cmake_INCLUDED__)
+ return()
+else()
+ set(__install_runtime_cmake_INCLUDED__ ON)
+endif()
+
+
+##
+## Allow to write a resource config file which contain additional ressource paths
+## (used by IBR_Common Resource system to load shaders and potentialy images, plugins and so on)
+##
+## ADD option list all the paths to add in the file (relative paths are interpreted relative to working dir of the executable)
+## INSTALL option to specify where we want to install this file
+##
+## Example usage:
+## resourceFile(ADD "shaders" "${PROJECT_NAME}_rsc" INSTALL bin)
+##
+macro(resourceFile)
+ cmake_parse_arguments(rsc "" "INSTALL;FILE_PATH;CONFIG_TYPE" "ADD" ${ARGN}) ## both args are directory path
+
+ if(rsc_ADD)
+ unset(IBR_RSC_FILE_CONTENT_LIST)
+ if(EXISTS "${rsc_FILE_PATH}")
+ file(READ "${rsc_FILE_PATH}" IBR_RSC_FILE_CONTENT)
+ string(REGEX REPLACE "\n" ";" IBR_RSC_FILE_CONTENT_LIST "${IBR_RSC_FILE_CONTENT}")
+ endif()
+ list(APPEND IBR_RSC_FILE_CONTENT_LIST "${rsc_ADD}")
+ list(REMOVE_DUPLICATES IBR_RSC_FILE_CONTENT_LIST)
+ file(WRITE "${rsc_FILE_PATH}" "")
+ foreach(rscDir ${IBR_RSC_FILE_CONTENT_LIST})
+ file(APPEND "${rsc_FILE_PATH}" "${rscDir}\n")
+ endforeach()
+ unset(rsc_ADD)
+ endif()
+
+ if(rsc_INSTALL)
+ install(FILES ${rsc_FILE_PATH} CONFIGURATIONS ${rsc_CONFIG_TYPE} DESTINATION ${rsc_INSTALL})
+ unset(rsc_INSTALL)
+ endif()
+endmacro()
+
+
+##
+## Install *.pdb generated file for the current cmake project
+## assuming the output target name is the cmake project name.
+## This macro is useful for crossplateform multi config mode.
+##
+## Usage Example:
+##
+## if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+## installPDB(${PROJECT_NAME} ${CMAKE_BUILD_TYPE} RUNTIME_DEST bin ARCHIVE_DEST lib LIBRARY_DEST lib)
+## endif()
+## foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+## installPDB(${PROJECT_NAME} ${CONFIG_TYPES} RUNTIME_DEST bin ARCHIVE_DEST lib LIBRARY_DEST lib)
+## endforeach()
+##
+macro(installPDB targetName configType)
+ cmake_parse_arguments(instpdb "" "COMPONENT" "ARCHIVE_DEST;LIBRARY_DEST;RUNTIME_DEST" ${ARGN}) ## both args are directory path
+
+ if(NOT MSVC)
+ return()
+ endif()
+
+ ## Check if DESTINATION are provided according to the TYPE of the given target (see install command doc to see correspodances)
+ get_target_property(type ${targetName} TYPE)
+ if(${type} MATCHES "EXECUTABLE" AND instpdb_RUNTIME_DEST)
+ set(pdb_DESTINATION ${instpdb_RUNTIME_DEST})
+ elseif(${type} MATCHES "STATIC_LIBRARY" AND instpdb_ARCHIVE_DEST)
+ set(pdb_DESTINATION ${instpdb_ARCHIVE_DEST})
+ elseif(${type} MATCHES "MODULE_LIBRARY" AND instpdb_LIBRARY_DEST)
+ set(pdb_DESTINATION ${instpdb_LIBRARY_DEST})
+ elseif(${type} MATCHES "SHARED_LIBRARY")
+ if(WIN32 AND instpdb_RUNTIME_DEST)
+ set(pdb_DESTINATION ${instpdb_RUNTIME_DEST})
+ else()
+ set(pdb_DESTINATION ${instpdb_LIBRARY_DEST})
+ endif()
+ endif()
+
+ if(NOT pdb_DESTINATION)
+ set(pdb_DESTINATION bin) ## default destination of the pdb file
+ endif()
+
+ if(NOT instpdb_COMPONENT)
+ set(instpdb_COMPONENT )
+ else()
+ set(instpdb_COMPONENT COMPONENT ${instpdb_COMPONENT})
+ endif()
+
+ string(TOUPPER ${configType} CONFIG_TYPES_UC)
+ get_target_property(PDB_PATH ${targetName} PDB_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC})
+
+ get_target_property(confModePostfix ${targetName} ${CONFIG_TYPES_UC}_POSTFIX)
+ if(NOT confModePostfix)
+ set(confModePostfix "")
+ endif()
+ set_target_properties(${targetName} PROPERTIES PDB_NAME_${CONFIG_TYPES_UC} ${targetName}${confModePostfix})
+ get_target_property(PDB_NAME ${targetName} PDB_NAME_${CONFIG_TYPES_UC})# if not set, this is empty
+
+ if(EXISTS "${PDB_PATH}/${PDB_NAME}.pdb")
+ install(FILES "${PDB_PATH}/${PDB_NAME}.pdb" CONFIGURATIONS ${configType} DESTINATION ${pdb_DESTINATION} ${instpdb_COMPONENT} OPTIONAL)
+ endif()
+endmacro()
+
+
+##
+## Add additional target to install a project independently and based on its component
+## configMode is used to prevent default Release installation (we want also to install in other build/config type)
+##
+macro(installTargetProject targetOfProject targetOfInstallProject)
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ set(configMode ${CMAKE_BUILD_TYPE})
+ elseif(MSVC)
+ ## $(Configuration) will be one of the following : Debug, Release, MinSizeRel, RelWithDebInfo
+ set(configMode $(Configuration))
+ endif()
+ if(configMode)
+ get_target_property(srcFiles ${targetOfProject} SOURCES)
+ add_custom_target( ${targetOfInstallProject} #ALL
+ ${CMAKE_COMMAND} -DBUILD_TYPE=${configMode} -DCOMPONENT=${targetOfInstallProject} -P ${CMAKE_BINARY_DIR}/cmake_install.cmake
+ DEPENDS ${srcFiles}
+ COMMENT "run the installation only for ${targetOfProject}" VERBATIM
+ )
+ add_dependencies(${targetOfInstallProject} ${targetOfProject})
+
+ get_target_property(INSTALL_BUILD_FOLDER ${targetOfProject} FOLDER)
+ set_target_properties(${targetOfInstallProject} PROPERTIES FOLDER ${INSTALL_BUILD_FOLDER})
+ endif()
+endmacro()
+
+# Collect all currently added targets in all subdirectories
+#
+# Parameters:
+# - _result the list containing all found targets
+# - _dir root directory to start looking from
+function(get_all_targets _result _dir)
+ get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
+ foreach(_subdir IN LISTS _subdirs)
+ get_all_targets(${_result} "${_subdir}")
+ endforeach()
+
+ get_directory_property(_sub_targets DIRECTORY "${_dir}" BUILDSYSTEM_TARGETS)
+ set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
+endfunction()
+
+##
+## Add targets for building and installing subdirectories
+macro(subdirectory_target target directory build_folder)
+ add_custom_target(${target}
+ COMMENT "run build for all projects in this directory" VERBATIM
+ )
+ get_all_targets(ALL_TARGETS ${directory})
+ add_dependencies(${target} ${ALL_TARGETS})
+ add_custom_target(${target}_install
+ ${CMAKE_COMMAND} -DBUILD_TYPE=$ -DCOMPONENT=${target}_install -P ${CMAKE_BINARY_DIR}/cmake_install.cmake
+ COMMENT "run install for all projects in this directory" VERBATIM
+ )
+ add_dependencies(${target}_install ${target})
+
+ set_target_properties(${target} PROPERTIES FOLDER ${build_folder})
+ set_target_properties(${target}_install PROPERTIES FOLDER ${build_folder})
+endmacro()
+
+
+## CMAKE install all required dependencies for an application (included system OS files like msvc*.dll for example)
+##
+## install_runtime(
+## [TARGET name]
+## [PLUGINS name [nameN ...] [PLUGIN_PATH_NAME currentPathName [FROM_REL_PATH matchDirFromCurrentPathName] [PLUGIN_PATH_DEST installDir] ]
+## [PLUGINS ...]
+## [DIRS path [pathN ...] ]
+## [TARGET_LIBRARIES filePath [filePathN ...] ]
+## [TARGET_PACKAGES packageName [packageNameN ...] ]
+## [COMPONENT installComponentName]
+## [PLAUSIBLES_POSTFIX Debug_postfix [MinSizeRel_postfix relWithDebInfo_postfix ...] ]
+## [VERBOSE]
+## )
+##
+## installedFilePathTargetAppToResolve : the final installed targetApp absolute full file path name you want to resolve
+##
+## TARGET : The target app we want to install. If given, it's used to look for link libraries paths (best choice to use, strongly advised to use it)
+##
+## PLUGINS : Some application built use/load some plugins which can't be detect inside its binary,
+## so, here you can specify which plugins the application use/load in order to install them
+## and resolve also there dependencies.
+## With PLUGINS multi FLAGS :
+## PLUGIN_PATH_NAME : The current plugin full file path we want to install
+## FROM_REL_PATH : [optional: default only the file is kept] From which matching dir of the plugin path we want to install (keep the directories structure)
+## PLUGIN_PATH_DEST : [optional: default relative to executable directory] Where (full path to the install directory) we will install the plugin file (or file path)
+##
+## DIRS : A list of directories to looking for dependencies
+## TARGET_LIBRARIES : DEPRECATED (use TARGET flag instead) : The cmake content variables used for the target_link_libraries( ...)
+## TARGET_PACKAGES : DEPRECATED (use TARGET flag instead) : The cmake package names used for the findPackage(...) for your targetApp
+## ADVICE: This flag add entries in cache (like: _DIR), it could be useful to fill these variable!
+## COMPONENT : (default to runtime) Is the component name associated to the installation
+## It is used when you want to install separatly some part of your projets (see install cmake doc)
+## VERBOSE : For debug or to get more informations in the output console
+##
+## Usage:
+## install_runtime(${CMAKE_INSTALL_PREFIX}/${EXECUTABLE_NAME}${CMAKE_EXECUTABLE_SUFFIX}
+## VERBOSE
+## TARGET ${PROJECT_NAME}
+## PLAUSIBLES_POSTFIX _d
+## PLUGINS
+## PLUGIN_PATH_NAME ${PLUGIN_PATH_NAME}${CMAKE_SHARED_MODULE_SUFFIX} ## will be installed (default exec path if no PLUGINS_DEST) and then will be resolved
+## FROM_REL_PATH plugins ## optional, used especially for keeping qt plugins tree structure
+## PLUGIN_PATH_DEST ${CMAKE_INSTALL_PREFIX}/plugins ## (or relative path 'plugins' will be interpreted relative to installed executable)
+## DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}
+## TARGET_LIBRARIES ${OPENGL_LIBRARIES} ## DEPRECATED (use TARGET flag instead)
+## ${GLEW_LIBRARIES}
+## ${GLUT_LIBRARIES}
+## ${Boost_LIBRARIES}
+## ${SuiteSparse_LIBRARIES}
+## ${CGAL_LIBRARIES}
+## TARGET_PACKAGES OPENGL ## DEPRECATED (use TARGET flag instead)
+## GLEW
+## GLUT
+## CGAL
+## Boost
+## SuiteSparse
+## )
+##
+## For plugins part, it use our internal parse_arguments_multi.cmake
+##
+function(install_runtime installedFilePathTargetAppToResolve)
+ set(optionsArgs "VERBOSE")
+ set(oneValueArgs "COMPONENT;INSTALL_FOLDER;CONFIG_TYPE")
+ set(multiValueArgs "DIRS;PLUGINS;TARGET_LIBRARIES;TARGET_PACKAGES;TARGET;PLAUSIBLES_POSTFIX")
+ cmake_parse_arguments(inst_run "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ if(IS_ABSOLUTE ${installedFilePathTargetAppToResolve})
+ else()
+ set(installedFilePathTargetAppToResolve ${inst_run_INSTALL_FOLDER}/${installedFilePathTargetAppToResolve})
+ endif()
+
+ get_filename_component(EXEC_NAME ${installedFilePathTargetAppToResolve} NAME_WE)
+ get_filename_component(EXEC_PATH ${installedFilePathTargetAppToResolve} PATH)
+
+ if(NOT inst_run_COMPONENT)
+ set(inst_run_COMPONENT runtime)
+ endif()
+
+
+ ## Try to append as more possible as possible paths to find dependencies (deprecated since we can use target_properties to get back paths)
+ set(libPaths )
+ foreach(libraryFileName ${inst_run_TARGET_LIBRARIES})
+ if(IS_DIRECTORY "${libraryFileName}")
+ list(APPEND libPaths "${libraryFileName}")
+ else()
+ get_filename_component(libpath "${libraryFileName}" PATH)
+ if(EXISTS "${libpath}")
+ list(APPEND libPaths "${libpath}")
+ endif()
+ endif()
+ endforeach()
+
+ ## This macro is used internaly here to recursilvely get path of LINK_LIBRARIES of each non imported target
+ ## Typically if you have 2 internal dependencies between cmake targets, we want cmake to be able to get back path where are these dependencies
+ macro(recurseDepList target)
+ get_target_property(linkLibs ${target} LINK_LIBRARIES)
+ foreach(lib ${linkLibs})
+ string(FIND ${lib} ">" strId) ## cmake is using generator-expression?
+ if(TARGET ${lib})
+ ## Skipping interface libraries as they're system ones
+ get_target_property(type ${lib} TYPE)
+ get_target_property(imported ${lib} IMPORTED)
+ if(type STREQUAL "INTERFACE_LIBRARY")
+ get_target_property(imp_loc ${lib} INTERFACE_IMPORTED_LOCATION)
+ if(imp_loc)
+ get_filename_component(imp_loc ${imp_loc} PATH)
+ list(APPEND targetLibPath ${imp_loc})
+ endif()
+ get_target_property(loc ${lib} INTERFACE_LOCATION)
+ if(loc)
+ get_filename_component(loc ${loc} PATH)
+ list(APPEND targetLibPath ${loc})
+ endif()
+ ## it's not a path but a single target name
+ ## for build-target which are part of the current cmake configuration : nothing to do as cmake already know the output path
+ ## for imported target, we need to look for theire imported location
+ elseif(imported)
+ get_target_property(imp_loc ${lib} IMPORTED_LOCATION)
+ if(imp_loc)
+ get_filename_component(imp_loc ${imp_loc} PATH)
+ list(APPEND targetLibPath ${imp_loc})
+ endif()
+ get_target_property(loc ${lib} LOCATION)
+ if(loc)
+ get_filename_component(loc ${loc} PATH)
+ list(APPEND targetLibPath ${loc})
+ endif()
+ else()
+ recurseDepList(${lib})
+ endif()
+ elseif(NOT ${strId} MATCHES -1) ## mean cmake use generator-expression (CMAKE VERSION > 3.0)
+ string(REGEX MATCH ">:[@A-Za-z_:/.0-9-]+" targetLibPath ${lib})
+ string(REGEX REPLACE ">:([@A-Za-z_:/.0-9-]+)" "\\1" targetLibPath ${targetLibPath})
+ get_filename_component(targetLibPath ${targetLibPath} PATH)
+ elseif(EXISTS ${lib})
+ set(targetLibPath ${lib})
+ get_filename_component(targetLibPath ${targetLibPath} PATH)
+ else()
+ #message(STATUS "[install_runtime] skip link library : ${lib} , of target ${target}")
+ endif()
+ if(targetLibPath)
+ list(APPEND targetLinkLibsPathList ${targetLibPath})
+ endif()
+ endforeach()
+ if(targetLinkLibsPathList)
+ list(REMOVE_DUPLICATES targetLinkLibsPathList)
+ endif()
+ endmacro()
+ if(inst_run_TARGET)
+ recurseDepList(${inst_run_TARGET})
+ if(targetLinkLibsPathList)
+ list(APPEND libPaths ${targetLinkLibsPathList})
+ endif()
+ endif()
+
+ if(libPaths)
+ list(REMOVE_DUPLICATES libPaths)
+ foreach(libPath ${libPaths})
+ get_filename_component(path ${libPath} PATH)
+ list(APPEND libPaths ${path})
+ endforeach()
+ endif()
+
+
+ ## possible speciale dir(s) according to the build system and OS
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(BUILD_TYPES_FOR_DLL "x64")
+ if(WIN32)
+ list(APPEND BUILD_TYPES_FOR_DLL "Win64")
+ endif()
+ else()
+ set(BUILD_TYPES_FOR_DLL "x86")
+ if(WIN32)
+ list(APPEND BUILD_TYPES_FOR_DLL "Win32")
+ endif()
+ endif()
+
+
+ ## Try to append as more as possible paths to find dependencies (here, mainly for *.dll)
+ foreach(dir ${inst_run_DIRS} ${libPaths})
+ if(EXISTS "${dir}/bin")
+ list(APPEND inst_run_DIRS "${dir}/bin")
+ elseif(EXISTS "${dir}")
+ list(APPEND inst_run_DIRS "${dir}")
+ endif()
+ endforeach()
+ list(REMOVE_DUPLICATES inst_run_DIRS)
+ foreach(dir ${inst_run_DIRS})
+ if(EXISTS "${dir}")
+ list(APPEND argDirs ${dir})
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${dir}/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND argDirs "${dir}/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) ## for windows multi-generator (MSVC)
+ if(EXISTS "${dir}/${BUILD_TYPE_FOR_DLL}/${OUTPUTCONFIG}")
+ list(APPEND argDirs "${dir}/${BUILD_TYPE_FOR_DLL}/${OUTPUTCONFIG}")
+ endif()
+ endforeach()
+ if(CMAKE_BUILD_TYPE) ## for single generator (makefiles)
+ if(EXISTS "${dir}/${BUILD_TYPE_FOR_DLL}/${CMAKE_BUILD_TYPE}")
+ list(APPEND argDirs "${dir}/${BUILD_TYPE_FOR_DLL}/${CMAKE_BUILD_TYPE}")
+ endif()
+ endif()
+ endforeach()
+ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) ## for windows multi-generator (MSVC)
+ if(EXISTS "${dir}/${OUTPUTCONFIG}")
+ list(APPEND argDirs "${dir}/${OUTPUTCONFIG}")
+ endif()
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${dir}/${OUTPUTCONFIG}/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND argDirs "${dir}/${OUTPUTCONFIG}/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ endforeach()
+ endforeach()
+ if(CMAKE_BUILD_TYPE) ## for single generator (makefiles)
+ if(EXISTS "${dir}/${CMAKE_BUILD_TYPE}")
+ list(APPEND argDirs "${dir}/${CMAKE_BUILD_TYPE}")
+ endif()
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${dir}/${CMAKE_BUILD_TYPE}/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND argDirs "${dir}/${CMAKE_BUILD_TYPE}/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ endforeach()
+ endif()
+ endif()
+ endforeach()
+ if(argDirs)
+ list(REMOVE_DUPLICATES argDirs)
+ endif()
+
+
+ ## Try to append as more possible paths to find dependencies (here, mainly for *.dll)
+ foreach(packageName ${inst_run_TARGET_PACKAGES})
+ if(EXISTS "${${packageName}_DIR}")
+ list(APPEND packageDirs ${${packageName}_DIR})
+ list(APPEND packageDirs ${${packageName}_DIR}/bin)
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) ## for windows multi-generator (MSVC)
+ if(EXISTS "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}/${OUTPUTCONFIG}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}/${OUTPUTCONFIG}")
+ endif()
+ endforeach()
+ if(CMAKE_BUILD_TYPE) ## for single generator (makefiles)
+ if(EXISTS "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}/${CMAKE_BUILD_TYPE}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${BUILD_TYPE_FOR_DLL}/${CMAKE_BUILD_TYPE}")
+ endif()
+ endif()
+ endforeach()
+ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) ## for windows multi-generator (MSVC)
+ if(EXISTS "${${packageName}_DIR}/bin/${OUTPUTCONFIG}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${OUTPUTCONFIG}")
+ endif()
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${${packageName}_DIR}/bin/${OUTPUTCONFIG}/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${OUTPUTCONFIG}/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ endforeach()
+ endforeach()
+ if(CMAKE_BUILD_TYPE) ## for single generator (makefiles)
+ if(EXISTS "${${packageName}_DIR}/bin/${CMAKE_BUILD_TYPE}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${CMAKE_BUILD_TYPE}")
+ endif()
+ foreach(BUILD_TYPE_FOR_DLL ${BUILD_TYPES_FOR_DLL})
+ if(EXISTS "${${packageName}_DIR}/bin/${CMAKE_BUILD_TYPE}/${BUILD_TYPE_FOR_DLL}")
+ list(APPEND packageDirs "${${packageName}_DIR}/bin/${CMAKE_BUILD_TYPE}/${BUILD_TYPE_FOR_DLL}")
+ endif()
+ endforeach()
+ endif()
+ else()
+ set(${packageName}_DIR "$ENV{${packageName}_DIR}" CACHE PATH "${packageName}_DIR root directory for looking for dirs containning *.dll")
+ endif()
+ endforeach()
+ if(packageDirs)
+ list(REMOVE_DUPLICATES packageDirs)
+ endif()
+
+
+ set(dirsToLookFor "${EXEC_PATH}")
+ if(packageDirs)
+ list(APPEND dirsToLookFor ${packageDirs})
+ endif()
+ if(argDirs)
+ list(APPEND dirsToLookFor ${argDirs})
+ endif()
+ get_property(used_LINK_DIRECTORIES DIRECTORY PROPERTY LINK_DIRECTORIES)
+ if (used_LINK_DIRECTORIES)
+ list(APPEND dirsToLookFor ${used_LINK_DIRECTORIES})
+ list(REMOVE_DUPLICATES dirsToLookFor)
+ endif()
+
+
+ ## handle plugins
+ set(pluginsList "")
+ include(parse_arguments_multi) ## this function will process recursively items of the sub-list [default print messages]
+ function(parse_arguments_multi_function results)
+ cmake_parse_arguments(pamf "VERBOSE" "PLUGIN_PATH_DEST;FROM_REL_PATH;EXEC_PATH;COMPONENT" "" ${ARGN}) ## EXEC_PATH and COMPONENT are for exclusive internal use
+ list(REMOVE_DUPLICATES pamf_UNPARSED_ARGUMENTS)
+ foreach(PLUGIN_PATH_NAME ${pamf_UNPARSED_ARGUMENTS})
+ if(EXISTS ${PLUGIN_PATH_NAME})
+ if(IS_DIRECTORY ${PLUGIN_PATH_NAME})
+ if(pamf_VERBOSE)
+ message(WARNING "${PLUGIN_PATH_NAME} IS_DIRECTORY, cannot installed a directory, please give a path filename")
+ endif()
+ else()
+ if(NOT pamf_PLUGIN_PATH_DEST)
+ set(PLUGIN_PATH_DEST ${pamf_EXEC_PATH}) ## the default dest value
+ else()
+ set(PLUGIN_PATH_DEST ${pamf_PLUGIN_PATH_DEST})
+ endif()
+
+ if(pamf_FROM_REL_PATH)
+ file(TO_CMAKE_PATH ${PLUGIN_PATH_NAME} PLUGIN_PATH_NAME)
+ get_filename_component(PLUGIN_PATH ${PLUGIN_PATH_NAME} PATH)
+ unset(PLUGIN_PATH_LIST)
+ unset(PLUGIN_PATH_LIST_COUNT)
+ unset(PLUGIN_REL_PATH_LIST)
+ unset(PLUGIN_REL_PATH)
+ string(REPLACE "/" ";" PLUGIN_PATH_LIST ${PLUGIN_PATH}) ## create a list of dir
+ list(FIND PLUGIN_PATH_LIST ${pamf_FROM_REL_PATH} id)
+ list(LENGTH PLUGIN_PATH_LIST PLUGIN_PATH_LIST_COUNT)
+ if(${id} GREATER 0)
+ math(EXPR id "${id}+1") ## matches relative path not include
+ math(EXPR PLUGIN_PATH_LIST_COUNT "${PLUGIN_PATH_LIST_COUNT}-1") ## the end of the list
+ foreach(i RANGE ${id} ${PLUGIN_PATH_LIST_COUNT})
+ list(GET PLUGIN_PATH_LIST ${i} out)
+ list(APPEND PLUGIN_REL_PATH_LIST ${out})
+ endforeach()
+ foreach(dir ${PLUGIN_REL_PATH_LIST})
+ set(PLUGIN_REL_PATH "${PLUGIN_REL_PATH}/${dir}")
+ endforeach()
+ endif()
+ set(PLUGIN_PATH_DEST ${PLUGIN_PATH_DEST}${PLUGIN_REL_PATH})
+ endif()
+
+ install(FILES ${PLUGIN_PATH_NAME} CONFIGURATIONS ${inst_run_CONFIG_TYPE} DESTINATION ${PLUGIN_PATH_DEST} COMPONENT ${pamf_COMPONENT})
+ get_filename_component(pluginName ${PLUGIN_PATH_NAME} NAME)
+ if(IS_ABSOLUTE ${PLUGIN_PATH_DEST})
+ else()
+ set(PLUGIN_PATH_DEST ${inst_run_INSTALL_FOLDER}/${PLUGIN_PATH_DEST})
+ endif()
+ list(APPEND pluginsList ${PLUGIN_PATH_DEST}/${pluginName})
+ endif()
+ else()
+ message(WARNING "You need to provide a valid PLUGIN_PATH_NAME")
+ set(pluginsList )
+ endif()
+ endforeach()
+ set(${results} ${pluginsList} PARENT_SCOPE)
+ endfunction()
+
+ if(inst_run_VERBOSE)
+ list(APPEND extra_flags_to_add VERBOSE)
+ endif()
+ list(APPEND extra_flags_to_add EXEC_PATH ${EXEC_PATH} COMPONENT ${inst_run_COMPONENT}) ## for internal use inside overloaded function
+ list(LENGTH inst_run_PLUGINS inst_run_PLUGINS_count)
+ if(${inst_run_PLUGINS_count} GREATER 0)
+ parse_arguments_multi(PLUGIN_PATH_NAME inst_run_PLUGINS ${inst_run_PLUGINS} ## see internal overload parse_arguments_multi_function for processing each sub-list
+ NEED_RESULTS ${inst_run_PLUGINS_count} ## this is used to check when we are in the first loop (in order to reset parse_arguments_multi_results)
+ EXTRAS_FLAGS ${extra_flags_to_add} ## this is used to allow catching additional internal flags of our overloaded function
+ )
+ endif()
+
+ #message(parse_arguments_multi_results = ${parse_arguments_multi_results})
+ list(APPEND pluginsList ${parse_arguments_multi_results})
+
+
+
+ ## Install rules for required system runtimes such as MSVCRxx.dll
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP ON)
+ include(InstallRequiredSystemLibraries)
+ if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
+ install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
+ CONFIGURATIONS ${inst_run_CONFIG_TYPE}
+ DESTINATION ${EXEC_PATH}
+ COMPONENT ${inst_run_COMPONENT}
+ )
+ endif()
+
+ ## print what we are doing to do
+ if(inst_run_VERBOSE)
+ message(STATUS "[install_runtime] On install target call, cmake will try to resolve dependencies for given app:\n ${installedFilePathTargetAppToResolve} (with plausible postfix: ${inst_run_PLAUSIBLES_POSTFIX})")
+ if(pluginsList)
+ message(STATUS " and also for plugins :")
+ foreach(plugin ${pluginsList})
+ message(STATUS " ${plugin}")
+ endforeach()
+ endif()
+ message(STATUS " Looking for dependencies into:")
+ foreach(dir ${dirsToLookFor})
+ message(STATUS " ${dir}")
+ endforeach()
+ endif()
+
+ ## Install rules for required dependencies libs/plugins for the target app
+ ## will resolve all installed target files with config modes postfixes
+ string(TOUPPER ${inst_run_CONFIG_TYPE} inst_run_CONFIG_TYPE_UC)
+ get_target_property(postfix ${inst_run_TARGET} "${inst_run_CONFIG_TYPE_UC}_POSTFIX")
+ install(CODE "set(target \"${inst_run_TARGET}\")" COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE})
+ install(CODE "set(inst_run_CONFIG_TYPE \"${inst_run_CONFIG_TYPE}\")" COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE})
+ install(CODE "set(inst_run_INSTALL_FOLDER \"${inst_run_INSTALL_FOLDER}\")" COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE})
+ install(CODE "set(app \"${EXEC_PATH}/${EXEC_NAME}${postfix}${CMAKE_EXECUTABLE_SUFFIX}\")" COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE})
+ install(CODE "set(dirsToLookFor \"${dirsToLookFor}\")" COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE})
+ install(CODE
+ [[
+ if("${CMAKE_INSTALL_CONFIG_NAME}" STREQUAL "${inst_run_CONFIG_TYPE}")
+ message(STATUS "Installing ${target} dependencies...")
+
+ file(GET_RUNTIME_DEPENDENCIES
+ EXECUTABLES ${app}
+ RESOLVED_DEPENDENCIES_VAR _r_deps
+ UNRESOLVED_DEPENDENCIES_VAR _u_deps
+ CONFLICTING_DEPENDENCIES_PREFIX _c_deps
+ DIRECTORIES ${dirsToLookFor}
+ PRE_EXCLUDE_REGEXES "api-ms-*"
+ POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" ".*SysWOW64/.*\\.dll"
+ )
+
+ if(_u_deps)
+ message(WARNING "There were unresolved dependencies for executable ${EXEC_FILE}: \"${_u_deps}\"!")
+ endif()
+ if(_c_deps_FILENAMES)
+ message(WARNING "There were conflicting dependencies for executable ${EXEC_FILE}: \"${_c_deps_FILENAMES}\"!")
+ endif()
+
+ foreach(_file ${_r_deps})
+ file(INSTALL
+ DESTINATION "${inst_run_INSTALL_FOLDER}/bin"
+ TYPE SHARED_LIBRARY
+ FOLLOW_SYMLINK_CHAIN
+ FILES "${_file}"
+ )
+ endforeach()
+ endif()
+ ]]
+ COMPONENT ${inst_run_COMPONENT} CONFIGURATIONS ${CONFIG_TYPE}
+ )
+
+endfunction()
+
+## High level macro to install resources in the correct folder
+##
+## EXECUTABLE: [opt] option to copy files as programs
+## RELATIVE : [opt] copy files relatively to current folder
+## TYPE : [opt] type and folder where to store the files
+## FOLDER : [opt] subfolder to use
+## FILES : [opt] contains a list of resources files to copy to install folder
+macro(ibr_install_rsc target)
+ cmake_parse_arguments(install_rsc_${target} "EXECUTABLE;RELATIVE" "TYPE;FOLDER" "FILES" ${ARGN})
+ set(rsc_target "${target}_${install_rsc_${target}_TYPE}")
+
+ if(install_rsc_${target}_FOLDER)
+ set(rsc_folder "${install_rsc_${target}_TYPE}/${install_rsc_${target}_FOLDER}")
+ else()
+ set(rsc_folder "${install_rsc_${target}_TYPE}")
+ endif()
+
+ add_custom_target(${rsc_target}
+ COMMENT "run the ${install_rsc_${target}_TYPE} installation only for ${target} (component ${rsc_target})"
+ VERBATIM)
+ foreach(scriptFile ${install_rsc_${target}_FILES})
+ if(install_rsc_${target}_RELATIVE)
+ file(RELATIVE_PATH relativeFilename ${CMAKE_CURRENT_SOURCE_DIR} ${scriptFile})
+ else()
+ get_filename_component(relativeFilename ${scriptFile} NAME)
+ endif()
+
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ add_custom_command(TARGET ${rsc_target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E
+ copy_if_different ${scriptFile} ${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/${rsc_folder}/${relativeFilename})
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ add_custom_command(TARGET ${rsc_target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E
+ copy_if_different ${scriptFile} ${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/${rsc_folder}/${relativeFilename})
+ endforeach()
+ endforeach()
+
+ get_target_property(INSTALL_RSC_BUILD_FOLDER ${target} FOLDER)
+ set_target_properties(${rsc_target} PROPERTIES FOLDER ${INSTALL_RSC_BUILD_FOLDER})
+
+ add_dependencies(${target} ${rsc_target})
+ add_dependencies(PREBUILD ${rsc_target})
+
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ resourceFile(ADD ${rsc_folder} CONFIG_TYPE ${CMAKE_BUILD_TYPE} FILE_PATH "${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/ibr_resources.ini")
+
+ if(install_rsc_${target}_EXECUTABLE)
+ install(
+ PROGRAMS ${install_rsc_${target}_FILES}
+ CONFIGURATIONS ${CMAKE_BUILD_TYPE}
+ DESTINATION "${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/${rsc_folder}"
+ )
+ else()
+ install(
+ FILES ${install_rsc_${target}_FILES}
+ CONFIGURATIONS ${CMAKE_BUILD_TYPE}
+ DESTINATION "${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}/${rsc_folder}"
+ )
+ endif()
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ resourceFile(ADD ${rsc_folder} CONFIG_TYPE ${CONFIG_TYPES} FILE_PATH "${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/ibr_resources.ini")
+
+ if(install_rsc_${target}_EXECUTABLE)
+ install(
+ PROGRAMS ${install_rsc_${target}_FILES}
+ CONFIGURATIONS ${CONFIG_TYPES}
+ DESTINATION "${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/${rsc_folder}"
+ )
+ else()
+ install(
+ FILES ${install_rsc_${target}_FILES}
+ CONFIGURATIONS ${CONFIG_TYPES}
+ DESTINATION "${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}/${rsc_folder}"
+ )
+ endif()
+ endforeach()
+endmacro()
+
+
+## High level macro to install in an homogen way all our ibr targets (it use some functions inside this file)
+##
+## RSC_FILE_ADD : [opt] is used to auto write/append relative paths of target resources into a common file
+## INSTALL_PDB : [opt] is used to auto install PDB file (when using MSVC according to the target type)
+## STANDALONE : [opt] bool ON/OFF var to call install_runtime or not (for bundle resolution)
+## DIRS : [opt] used if STANDALONE set to ON, see install_runtime doc
+## PLUGINS: [opt] used if STANDALONE set to ON, see install_runtime doc
+## MSVC_CMD : [opt] used to specify an absolute filePathName application to launch with the MSVC IDE Debugger associated to this target (project file)
+## MSVC_ARGS : [opt] load the MSVC debugger with correct settings (app path, args, working dir)
+##
+macro(ibr_install_target target)
+ cmake_parse_arguments(ibrInst${target} "VERBOSE;INSTALL_PDB" "COMPONENT;MSVC_ARGS;STANDALONE;RSC_FOLDER" "SHADERS;RESOURCES;SCRIPTS;DIRS;PLUGINS" ${ARGN})
+
+ if(ibrInst${target}_RSC_FOLDER)
+ set(rsc_folder "${ibrInst${target}_RSC_FOLDER}")
+ else()
+ set(rsc_folder "${target}")
+ endif()
+
+ if(ibrInst${target}_SHADERS)
+ ibr_install_rsc(${target} EXECUTABLE TYPE "shaders" FOLDER ${rsc_folder} FILES "${ibrInst${target}_SHADERS}")
+ endif()
+
+ if(ibrInst${target}_RESOURCES)
+ ibr_install_rsc(${target} TYPE "resources" FOLDER ${rsc_folder} FILES "${ibrInst${target}_RESOURCES}")
+ endif()
+
+ if(ibrInst${target}_SCRIPTS)
+ ibr_install_rsc(${target} EXECUTABLE TYPE "scripts" FOLDER ${rsc_folder} FILES "${ibrInst${target}_SCRIPTS}")
+ endif()
+
+ if(ibrInst${target}_COMPONENT)
+ set(installCompArg COMPONENT ${ibrInst${target}_COMPONENT})
+ ## Create a custom install target based on COMPONENT
+ installTargetProject(${target} ${ibrInst${target}_COMPONENT})
+ endif()
+
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ set_target_properties(${target} PROPERTIES ${CMAKE_BUILD_TYPE}_POSTFIX "${CMAKE_${CMAKE_BUILD_TYPE}_POSTFIX}")
+ get_target_property(CURRENT_TARGET_BUILD_TYPE_POSTFIX ${target} ${CMAKE_BUILD_TYPE}_POSTFIX)
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ set_target_properties(${target} PROPERTIES ${CONFIG_TYPES_UC}_POSTFIX "${CMAKE_${CONFIG_TYPES_UC}_POSTFIX}")
+ get_target_property(CURRENT_TARGET_BUILD_TYPE_POSTFIX ${target} ${CONFIG_TYPES_UC}_POSTFIX)
+ endforeach()
+
+ ## Specify default installation rules
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ install(TARGETS ${target}
+ CONFIGURATIONS ${CMAKE_BUILD_TYPE}
+ LIBRARY DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}} ${installCompArg}
+ ARCHIVE DESTINATION ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}} ${installCompArg}
+ RUNTIME DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}} ${installCompArg}
+ )
+ install(TARGETS ${target}
+ CONFIGURATIONS ${CMAKE_BUILD_TYPE}
+ LIBRARY DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}} ${installCompArg}
+ ARCHIVE DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}} ${installCompArg}
+ )
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ install(TARGETS ${target}
+ CONFIGURATIONS ${CONFIG_TYPES}
+ LIBRARY DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}} ${installCompArg}
+ ARCHIVE DESTINATION ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}} ${installCompArg}
+ RUNTIME DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}} ${installCompArg}
+ )
+ install(TARGETS ${target}
+ CONFIGURATIONS ${CONFIG_TYPES}
+ LIBRARY DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}} ${installCompArg}
+ ARCHIVE DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}} ${installCompArg}
+ )
+ endforeach()
+
+ if(ibrInst${target}_INSTALL_PDB)
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ installPDB(${target} ${CMAKE_BUILD_TYPE}
+ LIBRARY_DEST ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}}
+ ARCHIVE_DEST ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}}
+ RUNTIME_DEST ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}}
+ )
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ installPDB(${target} ${CONFIG_TYPES}
+ LIBRARY_DEST ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}}
+ ARCHIVE_DEST ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}}
+ RUNTIME_DEST ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}}
+ )
+ endforeach()
+ endif()
+
+ ## install dynamic necessary dependencies
+ if(ibrInst${target}_STANDALONE)
+ get_target_property(type ${target} TYPE)
+ if(${type} MATCHES "EXECUTABLE")
+
+ if(ibrInst${target}_VERBOSE)
+ set(VERBOSE VERBOSE)
+ else()
+ set(VERBOSE )
+ endif()
+
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ install_runtime(bin/${target}${CMAKE_EXECUTABLE_SUFFIX} ## default relative to CMAKE_INSTALL_PREFIX
+ INSTALL_FOLDER "${CMAKE_INSTALL_PREFIX_${CMAKE_BUILD_TYPE}}"
+ CONFIG_TYPE ${CMAKE_BUILD_TYPE}
+ ${VERBOSE}
+ TARGET ${target}
+ ${installCompArg}
+ PLUGINS ## will be installed
+ ${ibrInst${target}_PLUGINS}
+ DIRS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE}}
+ ${ibrInst${target}_DIRS}
+ )
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ install_runtime(bin/${target}${CMAKE_EXECUTABLE_SUFFIX} ## default relative to CMAKE_INSTALL_PREFIX
+ INSTALL_FOLDER "${CMAKE_INSTALL_PREFIX_${CONFIG_TYPES_UC}}"
+ CONFIG_TYPE ${CONFIG_TYPES}
+ ${VERBOSE}
+ TARGET ${target}
+ ${installCompArg}
+ PLUGINS ## will be installed
+ ${ibrInst${target}_PLUGINS}
+ DIRS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPES_UC}}
+ ${ibrInst${target}_DIRS}
+ )
+ endforeach()
+ else()
+ message(WARNING "STANDALONE option is only compatible with EXECUTABLES target type. Skip the STANDALONE installation process.")
+ endif()
+ endif()
+
+ ## Provide a way to directly load the MSVC debugger with correct settings
+ if(MSVC)
+ if(ibrInst${target}_MSVC_CMD) ## command absolute filePathName is optional as the default is to use the installed target file application
+ set(msvcCmdArg COMMAND ${ibrInst${target}_MSVC_CMD}) ## flag following by the value (both to pass to the MSVCsetUserCommand function)
+ endif()
+ if(ibrInst${target}_MSVC_ARGS) ## args (between quotes) are optional
+ set(msvcArgsArg ARGS ${ibrInst${target}_MSVC_ARGS}) ## flag following by the value (both to pass to the MSVCsetUserCommand function)
+ endif()
+ get_target_property(type ${target} TYPE)
+ if( (ibrInst${target}_MSVC_CMD OR ibrInst${target}_MSVC_ARGS) OR (${type} MATCHES "EXECUTABLE") )
+ include(MSVCsetUserCommand)
+ if(DEFINED CMAKE_BUILD_TYPE) ## for make/nmake based
+ MSVCsetUserCommand( ${target}
+ PATH ${CMAKE_OUTPUT_BIN_${CMAKE_BUILD_TYPE}} ##FILE option not necessary since it deduced from targetName
+ ARGS "${SIBR_PROGRAMARGS}"
+ ${msvcCmdArg}
+ #${msvcArgsArg}
+ WORKING_DIR ${CMAKE_OUTPUT_BIN_${CMAKE_BUILD_TYPE}}
+ )
+ endif()
+ foreach(CONFIG_TYPES ${CMAKE_CONFIGURATION_TYPES}) ## for multi config types (MSVC based)
+ string(TOUPPER ${CONFIG_TYPES} CONFIG_TYPES_UC)
+ MSVCsetUserCommand( ${target}
+ PATH ${CMAKE_OUTPUT_BIN_${CONFIG_TYPES_UC}} ##FILE option not necessary since it deduced from targetName
+ ARGS "${SIBR_PROGRAMARGS}"
+ ${msvcCmdArg}
+ #${msvcArgsArg}
+ WORKING_DIR ${CMAKE_OUTPUT_BIN_${CONFIG_TYPES_UC}}
+ )
+ endforeach()
+ elseif(NOT ${type} MATCHES "EXECUTABLE")
+ #message("Cannot set MSVCsetUserCommand with target ${target} without COMMAND parameter as it is not an executable (skip it)")
+ endif()
+ endif()
+
+endmacro()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/parse_arguments_multi.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/parse_arguments_multi.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4edf4601a7494409a7bd3222bb09063177b415e8
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/parse_arguments_multi.cmake
@@ -0,0 +1,304 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+if(NOT WIN32 OR __parse_arguments_multi_cmake_INCLUDED__)
+ return()
+else()
+ set(__parse_arguments_multi_cmake_INCLUDED__ ON)
+endif()
+
+## This macro allow to process repeating multi value args from a given function which use cmake_parse_arguments module.
+##
+## cmake_parse_arguments multi args standard behavior:
+## function(foo)
+## cmake_parse_arguments(arg "" "" "MULTI" ${ARGN})
+## foreach(item IN LISTS arg_MULTI)
+## message(STATUS "${item}")
+## endforeach()
+## endfunction()
+## foo(MULTI x y MULTI z w)
+## The above code outputs 'z' and 'w'. It originally expected it to output all of 'x' 'y' 'z' 'w'.
+##
+## Using this macro inside a function which want to handle repeating multi args values
+## will recursively iterate onto the multi tags list to process each sub list.
+## It take as 1st argument the subTag flag to separate sub list from the main multi list.
+## It take as 2nd argument the nameList of the main multi list (the multiValuesArgs from cmake_parse_arguments: here it is MULTI in the example)
+## and that's why it is important that it should be a macro and not a function (to get access to external variable).
+## Then you give the content of this list allowing to be processed by the macro.
+##
+## parse_arguments_multi macro call a parse_arguments_multi_function which do actually the process from the given sub-list.
+## By default this function only print infos about what variables you are trying to pass/process (only verbose messages),
+## but, by overloading this cmake function, you will be able to externalize the process of your multi argument list.
+##
+## Usage (into a function) :
+## parse_arguments_multi(
+## [NEED_RESULTS ] [EXTRAS_FLAGS <...> <...> ...]
+## )
+##
+## Simple usage example [user point of view]:
+## foo(MULTI
+## SUB_MULTI x y
+## SUB_MULTI z w
+## )
+##
+## Simple usage example [inside a function]:
+## function(foo)
+## cmake_parse_arguments(arg "" "" "MULTI" ${ARGN})
+## include(parse_arguments_multi)
+## function(parse_arguments_multi_function )
+## #message("I'm an overloaded cmake function used by parse_arguments_multi")
+## #message("I'm processing first part of my sub list: ${ARGN}")
+## message("ARGV0=${ARGV0}")
+## message("ARGV1=${ARGV1}")
+## endfunction()
+## parse_arguments_multi(SUB_MULTI arg_MULTI ${arg_MULTI}) ## this function will process recusively items of the sub-list [default print messages]
+## endfunction()
+##
+## Will print:
+## ARGV0=z
+## ARGV1=w
+## ARGV0=x
+## ARGV1=y
+##
+## WARNING : DO NEVER ADD EXTRA THINGS TO parse_arguments_multi MACRO :
+## parse_arguments_multi(SUB_MULTI arg_MULTI ${arg_MULTI} EXTRAS foo bar SOMTHING) => will failed !!
+## use EXTRAS_FLAGS instead !!
+##
+## Advanced usage example [user point of view]:
+## bar(C:/prout/test.exe VERBOSE
+## PLUGINS
+## PLUGIN_PATH_NAME x PLUGIN_PATH_DEST w
+## PLUGIN_PATH_NAME a b PLUGIN_PATH_DEST y
+## PLUGIN_PATH_NAME c
+## )
+##
+## Advanced usage example [inside a function]:
+## function(bar execFilePathName)
+## cmake_parse_arguments(arg "VERBOSE" "" "PLUGINS" ${ARGN})
+##
+## include(parse_arguments_multi)
+## function(parse_arguments_multi_function results)
+## cmake_parse_arguments(pamf "VERBOSE" "PLUGIN_PATH_DEST;EXEC_PATH" "" ${ARGN}) ## EXEC_PATH is for internal use
+## message("")
+## message("I'm an overloaded cmake function used by parse_arguments_multi from install_runtime function")
+## message("I'm processing first part of my sub list: ${ARGN}")
+## message("PLUGIN_PATH_NAME = ${pamf_UNPARSED_ARGUMENTS}")
+## message(pamf_VERBOSE = ${pamf_VERBOSE})
+## message("pamf_PLUGIN_PATH_DEST = ${pamf_PLUGIN_PATH_DEST}")
+## message(pamf_EXEC_PATH = ${pamf_EXEC_PATH})
+## if(NOT ${pamf_PLUGIN_PATH_DEST})
+## set(pamf_PLUGIN_PATH_DEST ${pamf_EXEC_PATH})
+## endif()
+## foreach(plugin ${pamf_UNPARSED_ARGUMENTS})
+## get_filename_component(pluginName ${plugin} NAME)
+## list(APPEND pluginsList ${pamf_PLUGIN_PATH_DEST}/${pluginName})
+## endforeach()
+## set(${results} ${pluginsList} PARENT_SCOPE)
+## endfunction()
+##
+## if(arg_VERBOSE)
+## list(APPEND extra_flags_to_add VERBOSE) ## here we transmit the VERNOSE flag
+## endif()
+## get_filename_component(EXEC_PATH ${execFilePathName} PATH) ## will be the default value if PLUGIN_PATH_DEST option is not provided
+## list(APPEND extra_flags_to_add EXEC_PATH ${EXEC_PATH})
+## list(LENGTH arg_PLUGINS arg_PLUGINS_count)
+## parse_arguments_multi(PLUGIN_PATH_NAME arg_PLUGINS ${arg_PLUGINS}
+## NEED_RESULTS ${arg_PLUGINS_count} ## this is used to check when we are in the first loop (in order to reset parse_arguments_multi_results)
+## EXTRAS_FLAGS ${extra_flags_to_add} ## this is used to allow catching VERBOSE and PLUGIN_PATH_DEST flags of our overloaded function
+## )
+## endfunction()
+## message(parse_arguments_multi_results = ${parse_arguments_multi_results}) ## list of the whole pluginsList
+## #Will print w/x;a/y;b/y;C:/prout/c
+##
+## NOTE that here, since our overloaded function need to provide a result list, we use the other parse_arguments_multi_function signature (the which one with a results arg)
+##
+
+function(parse_arguments_multi_function_default) ## used in case of you want to reset the default behavior of this function process
+ message("[default function] parse_arguments_multi_function(ARGC=${ARGC} ARGV=${ARGV} ARGN=${ARGN})")
+ message("This function is used by parse_arguments_multi and have to be overloaded to process sub list of multi values args")
+endfunction()
+
+function(parse_arguments_multi_function ) ## => the function to overload
+ parse_arguments_multi_function_default(${ARGN})
+endfunction()
+
+## first default signature above
+##------------------------------
+## second results signature behind
+
+function(parse_arguments_multi_function_default result) ## used in case of you want to reset the default behavior of this function process
+ message("[default function] parse_arguments_multi_function(ARGC=${ARGC} ARGV=${ARGV} ARGN=${ARGN})")
+ message("This function is used by parse_arguments_multi and have to be overloaded to process sub list of muluti values args")
+endfunction()
+
+function(parse_arguments_multi_function result) ## => the function to overload
+ parse_arguments_multi_function_default(result ${ARGN})
+endfunction()
+
+## => the macro to use inside your function which use cmake_parse_arguments
+# NOTE: entry point of parse_arguments_multi, which is called from win3rdPart)
+macro(parse_arguments_multi multiArgsSubTag multiArgsList #<${multiArgsList}> the content of the list
+)
+ # message (STATUS "")
+ # message(STATUS "calling parse_arguemnts_multi defined in parse_arguments_multi.cmake:141")
+ # message(STATUS "multiArgsSubTag = ${multiArgsSubTag}") # CHECK_CACHED_VAR
+ # message(STATUS "multiArgsList = ${multiArgsList}") # it contains the name of the variable which is holding the list i.e w3p_MULTI_SET
+ # message(STATUS "value of ${multiArgsList} = ${${multiArgsList}}") # a semicolon separated list of values passed to SET or MULTISET keyword in win3rdParty
+ # message(STATUS "actual values ARGN = ${ARGN}") # the same as ${${multiArgsList}}
+
+ ## INFO
+ ## starting from CMake 3.5 cmake_parse_arguments is not a module anymore and now is a native CMake command.
+ ## the behaviour is different though
+ ## In CMake 3.4, if you pass multiple times a multi_value_keyword, CMake returns the values of the LAST match
+ ## In CMake 3.5 and above, CMake returns the whole list of values that were following that multi_value_keyword
+ ## example:
+ ## cmake_parse_arguments(
+ ##
+ ## "" # options
+ ## "" # one value keywords
+ ## "MY_MULTI_VALUE_TAG"
+ ## MY_MULTI_VALUE_TAG value1 value2
+ ## MY_MULTI_VALUE_TAG value3 value4
+ ## MY_MULTI_VALUE_TAG value5 value6
+ ## )
+ ## result in CMake 3.4
+ ## _MY_MULTI_VALUE_TAG = "value5;value6"
+ ##
+ ## result in CMake 3.8
+ ## _MY_MULTI_VALUE_TAG = "value5;value6"
+
+ #include(CMakeParseArguments) #module CMakeParseArguments is obsolete since cmake 3.5
+ # cmake_parse_arguments ( args)
+ # : options (flags) pass to the macro
+ # : options that neeed a value
+ # : options that neeed more than one value
+ cmake_parse_arguments(_pam "" "NEED_RESULTS" "${multiArgsSubTag};EXTRAS_FLAGS" ${ARGN})
+
+ ## multiArgsList is the name of the list used by the multiValuesOption flag from the cmake_parse_arguments of the user function
+ ## that's why we absolutly need to use MACRO here (and also for passing parse_arguments_multi_results when NEED_RESULTS flag is set)
+
+ ## for debugging
+ #message("")
+ #message("[parse_arguments_multi] => ARGN = ${ARGN}")
+ #message("_pam_NEED_RESULTS=${_pam_NEED_RESULTS}")
+ #message("_pam_EXTRAS_FLAGS=${_pam_EXTRAS_FLAGS}")
+ # foreach(var ${_pam_${multiArgsSubTag}})
+ # message("arg=${var}")
+ # endforeach()
+
+ if (${CMAKE_VERSION} VERSION_GREATER "3.5")
+ # lets make ${_pam_${multiArgsSubTag}} behave as it is in version 3.4
+ # that means, cmake_parse_arguments should have only the last values of a multi set for a given keyword
+
+ # message("")
+ # message("values in multiArgsList")
+ # foreach(val ${${multiArgsList}})
+ # message(STATUS ${val})
+ # endforeach()
+ # message("end values in multiArgsList")
+
+
+ set(lastIndexFound OFF)
+ list(LENGTH ${multiArgsList} argnLength)
+ # message(${argnLength})
+ math(EXPR argnLength "${argnLength}-1") # make last index a valid one
+ set(recordIndex 0)
+ set(records "") # clear records list
+ set(record0 "") # clear first record list
+ foreach(iter RANGE ${argnLength})
+ list(GET ${multiArgsList} ${iter} value)
+ # message(STATUS "index=${iter} value=${value}")
+ if (${value} STREQUAL ${multiArgsSubTag})
+ if (lastIndexFound)
+ list(APPEND records ${recordIndex}) # records store the list NAMES
+ math(EXPR recordIndex "${recordIndex}+1")
+ set(record${recordIndex} "") # clear record list
+ else ()
+ set(lastIndexFound ON)
+ endif()
+
+ set(lastIndex ${iter})
+ else ()
+ if (lastIndexFound)
+ # message(${value})
+ list(APPEND record${recordIndex} ${value})
+ endif()
+ endif()
+ endforeach()
+
+ # save the last list of values
+ if (lastIndexFound)
+ list(APPEND records ${recordIndex}) # records store the list NAMES
+ endif()
+
+ # set multiArgsList to make it behave like CMake 3.4
+ # message("")
+ # message("using my records")
+ foreach(recordName ${records})
+ # message(${recordName})
+ # foreach(value ${record${recordName}})
+ # message(${value})
+ # endforeach()
+ # message("")
+ set(_pam_${multiArgsSubTag} ${record${recordName}})
+ endforeach()
+ # message(${_pam_${multiArgsSubTag}})
+
+ # message("")
+ # message("using argn")
+ # foreach(value ${ARGN})
+ # message(${value})
+ # endforeach()
+ endif() # end if cmake > 3.5
+
+ # message("values with pam ${_pam_${multiArgsSubTag}}")
+
+ ## check and init
+ list(LENGTH ${multiArgsList} globalListCount) # GLUT_TRACE: globalListCound=16 in CMake3.4 and CMake3.8
+ # message(STATUS "nr items in multiArgsList: ${globalListCount}")
+ math(EXPR globalListCount "${globalListCount}-1") ## because it will contain [multiArgsSubTag + ${multiArgsList}]
+ if(_pam_NEED_RESULTS)
+ if(${globalListCount} EQUAL ${_pam_NEED_RESULTS})
+ ## first time we enter into this macro (because we call it recursively)
+ unset(parse_arguments_multi_results)
+ endif()
+ endif()
+
+ ## process the part of the multi agrs list
+ ## ${ARGN} shouldn't be passed to the function in order to avoid missmatch size list ${multiArgsList} and _pam_${multiArgsSubTag}
+ ## if you want to pass extra internal flags from your function to this callback, use EXTRAS_FLAGS
+ if(_pam_NEED_RESULTS)
+ parse_arguments_multi_function(parse_arguments_multi_function_result ${_pam_${multiArgsSubTag}} ${_pam_EXTRAS_FLAGS})
+ list(APPEND parse_arguments_multi_results ${parse_arguments_multi_function_result})
+ else()
+ # message(STATUS "about to call parse_arguments_multi_function in parse_arguments_multi.cmake:177 ${_pam_${multiArgsSubTag}} and extra flags ${_pam_EXTRAS_FLAGS}")
+ parse_arguments_multi_function(${_pam_${multiArgsSubTag}} ${_pam_EXTRAS_FLAGS})
+ endif()
+
+ ## remove just processed items from the main list to process (multiArgsList)
+ list(REVERSE ${multiArgsList})
+ list(LENGTH _pam_${multiArgsSubTag} subTagListCount)
+ unset(ids)
+ foreach(id RANGE ${subTagListCount})
+ list(APPEND ids ${id})
+ endforeach()
+ list(REMOVE_AT ${multiArgsList} ${ids})
+ list(REVERSE ${multiArgsList})
+
+ ## test if remain sub multi list to process (recursive call) or finish the process
+ list(LENGTH ${multiArgsList} mainTagListCount)
+ if(${mainTagListCount} GREATER 1)
+ ## do not pass ${ARGN} just because it will re pass the initial 2 inputs args and we wont as they was consumed (in order to avoir conflicts)
+ # message(STATUS "about to call a parse_arguments_multi but without knowing where the definition is going to be taken from")
+ parse_arguments_multi(${multiArgsSubTag} ${multiArgsList} ${${multiArgsList}}
+ NEED_RESULTS ${_pam_NEED_RESULTS} EXTRAS_FLAGS ${_pam_EXTRAS_FLAGS}
+ )
+ endif()
+endmacro()
diff --git a/extensions/RaDe-GS/SIBR_viewers/cmake/linux/sibr_library.cmake b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/sibr_library.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..e7c2065348de272781de250d6f0fdd9ba0840018
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/cmake/linux/sibr_library.cmake
@@ -0,0 +1,174 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+# NOTE
+# This feature is used to easily download, store and link external dependencies. This
+# requires to prepare pre-compiled libraries (to download). For now, packages have
+# only be prepare for Windows 64-bit with Visual Studio 2012. (You should re-build
+# everything if you want to use another version of Visual Studio/ another compiler).
+
+# NOTE ABOUT UNIX SYSTEMS
+# There is no need for "searching mechanism". This function is discard and your
+# libraries should be installed is the standard folders that are:
+#
+# /usr/include/
+# /usr/lib/
+# /usr/lib64/
+# for packages downloaded using apt-get/yum
+#
+# /usr/local/include/
+# /usr/local/lib/
+# /usr/local/lib64/
+# for packages manually installed ("make install")
+#
+# if you encounter problems when linking (e.g. lib not found even if it is installed),
+# please check these folders are in your search PATH environment variables.
+
+set(EXTLIBS_PACKAGE_FOLDER "${CMAKE_SOURCE_DIR}/extlibs")
+
+function(sibr_addlibrary)
+ if(NOT WIN32)
+ return()
+ endif()
+
+ file(MAKE_DIRECTORY ${EXTLIBS_PACKAGE_FOLDER})
+ cmake_parse_arguments(args "VCID" "VERBOSE;TIMEOUT;DEFAULT_USE;NAME;VERSION;MSVC11;MSVC12;MSVC14;MSVC17" "MULTI_SET;SET" ${ARGN})
+
+
+ if (NOT "${args_VERSION}" MATCHES "")
+ message(WARNING "VERSION is not implemented yet")
+ endif()
+
+ set(lcname "")
+ set(ucname "")
+ string(TOLOWER "${args_NAME}" lcname)
+ string(TOUPPER "${args_NAME}" ucname)
+
+ set(LIB_PACKAGE_FOLDER "${EXTLIBS_PACKAGE_FOLDER}/${lcname}")
+ win3rdParty(${ucname}
+ $
+ VERBOSE ${args_VERBOSE}
+ TIMEOUT ${args_TIMEOUT}
+ DEFAULT_USE ${args_DEFAULT_USE}
+ MSVC11 "${LIB_PACKAGE_FOLDER}" "${args_MSVC11}"
+ MSVC12 "${LIB_PACKAGE_FOLDER}" "${args_MSVC12}"
+ MSVC14 "${LIB_PACKAGE_FOLDER}" "${args_MSVC14}" # TODO SV: make sure to build this library if required
+ MSVC17 "${LIB_PACKAGE_FOLDER}" "${args_MSVC17}"
+ SET ${args_SET}
+ MULTI_SET ${args_MULTI_SET}
+ )
+
+ # Add include/ directory
+ # and lib/ directories
+
+ # TODO SV: paths not matching with current hierarchy. example: libraw/libraw-0.17.1/include
+ # SR: The link directories will also be used to lookup for dependency DLLs to copy in the install directory.
+ # Some libraries put the DLLs in the bin/ directory, so we include those.
+ file(GLOB subdirs RELATIVE ${LIB_PACKAGE_FOLDER} ${LIB_PACKAGE_FOLDER}/*)
+ set(dirlist "")
+ foreach(dir ${subdirs})
+ if(IS_DIRECTORY ${LIB_PACKAGE_FOLDER}/${dir})
+ # message("adding ${LIB_PACKAGE_FOLDER}/${dir}/include/ to the include directories")
+ include_directories("${LIB_PACKAGE_FOLDER}/${dir}/include/")
+ # message("adding ${LIB_PACKAGE_FOLDER}/${dir}/lib[64] to the link directories")
+ link_directories("${LIB_PACKAGE_FOLDER}/${dir}/")
+ link_directories("${LIB_PACKAGE_FOLDER}/${dir}/lib/")
+ link_directories("${LIB_PACKAGE_FOLDER}/${dir}/lib64/")
+ link_directories("${LIB_PACKAGE_FOLDER}/${dir}/bin/")
+ endif()
+ endforeach()
+
+endfunction()
+
+include(FetchContent)
+include(git_describe)
+include(install_runtime)
+
+function(sibr_gitlibrary)
+ cmake_parse_arguments(args "" "TARGET;GIT_REPOSITORY;GIT_TAG;ROOT_DIR;SOURCE_DIR" "INCLUDE_DIRS" ${ARGN})
+ if(NOT args_TARGET)
+ message(FATAL "Error on sibr_gitlibrary : please define your target name.")
+ return()
+ endif()
+
+ if(NOT args_ROOT_DIR)
+ set(args_ROOT_DIR ${args_TARGET})
+ endif()
+
+ if(NOT args_SOURCE_DIR)
+ set(args_SOURCE_DIR ${args_TARGET})
+ endif()
+
+ if(args_GIT_REPOSITORY AND args_GIT_TAG)
+ if(EXISTS ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/${args_SOURCE_DIR}/.git)
+ git_describe(
+ PATH ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/${args_SOURCE_DIR}
+ GIT_URL SIBR_GITLIBRARY_URL
+ GIT_BRANCH SIBR_GITLIBRARY_BRANCH
+ GIT_COMMIT_HASH SIBR_GITLIBRARY_COMMIT_HASH
+ GIT_TAG SIBR_GITLIBRARY_TAG
+ )
+
+ if((SIBR_GITLIBRARY_URL STREQUAL args_GIT_REPOSITORY) AND
+ ((SIBR_GITLIBRARY_BRANCH STREQUAL args_GIT_TAG) OR
+ (SIBR_GITLIBRARY_TAG STREQUAL args_GIT_TAG) OR
+ (SIBR_GITLIBRARY_COMMIT_HASH STREQUAL args_GIT_TAG)))
+ message(STATUS "Library ${args_TARGET} already available, skipping.")
+ set(SIBR_GITLIBRARY_DECLARED ON)
+ else()
+ message(STATUS "Adding library ${args_TARGET} from git...")
+ endif()
+ endif()
+
+ FetchContent_Declare(${args_TARGET}
+ GIT_REPOSITORY ${args_GIT_REPOSITORY}
+ GIT_TAG ${args_GIT_TAG}
+ GIT_SHALLOW ON
+ SOURCE_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/${args_SOURCE_DIR}
+ SUBBUILD_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/subbuild
+ BINARY_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/build
+ )
+ FetchContent_GetProperties(${args_TARGET})
+ string(TOLOWER "" lcTargetName)
+
+ if((NOT SIBR_GITLIBRARY_DECLARED) AND (NOT ${lcTargetName}_POPULATED))
+ message(STATUS "Populating library ${args_TARGET}...")
+ FetchContent_Populate(${args_TARGET} QUIET
+ GIT_REPOSITORY ${args_GIT_REPOSITORY}
+ GIT_TAG ${args_GIT_TAG}
+ SOURCE_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/${args_SOURCE_DIR}
+ SUBBUILD_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/subbuild
+ BINARY_DIR ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/build
+ )
+ endif()
+
+ add_subdirectory(${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/${args_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/extlibs/${args_ROOT_DIR}/build)
+
+ get_target_property(type ${args_TARGET} TYPE)
+ if(NOT (type STREQUAL "INTERFACE_LIBRARY"))
+ set_target_properties(${args_TARGET} PROPERTIES FOLDER "extlibs")
+
+ ibr_install_target(${args_TARGET}
+ COMPONENT ${args_TARGET}_install ## will create custom target to install only this project
+ )
+ endif()
+
+ list(APPEND ${args_TARGET}_INCLUDE_DIRS ${EXTLIBS_PACKAGE_FOLDER}/${args_ROOT_DIR})
+ list(APPEND ${args_TARGET}_INCLUDE_DIRS ${EXTLIBS_PACKAGE_FOLDER}/${args_ROOT_DIR}/${args_SOURCE_DIR})
+
+ foreach(args_INCLUDE_DIR ${args_INCLUDE_DIRS})
+ list(APPEND ${args_TARGET}_INCLUDE_DIRS ${EXTLIBS_PACKAGE_FOLDER}/${args_ROOT_DIR}/${args_SOURCE_DIR}/${args_INCLUDE_DIR})
+ endforeach()
+
+ include_directories(${${args_TARGET}_INCLUDE_DIRS})
+ else()
+ message(FATAL "Error on sibr_gitlibrary for target ${args_TARGET}: missing git tag or git url.")
+ endif()
+endfunction()
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/CMakeLists.txt b/extensions/RaDe-GS/SIBR_viewers/docs/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1493804fddc1a542206901d23a1d33278565c0ae
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+#########################################################
+# Include doxygen documentation target
+#########################################################
+option(BUILD_DOCUMENTATION "build doxygen documentation ('Build' DOCUMENTATION target, and find the compiled docs in install/docs/index.html)" OFF)
+if(BUILD_DOCUMENTATION)
+ set(DOXYGEN_REQUIRED_VERSION "1.8.17")
+ find_package(Doxygen)
+ if(NOT DOXYGEN_FOUND)
+ message(FATAL_ERROR "Doxygen not found, unable to generate documentation.")
+ elseif(DOXYGEN_VERSION VERSION_LESS DOXYGEN_REQUIRED_VERSION)
+ message(FATAL_ERROR "Doxygen version is less than ${DOXYGEN_REQUIRED_VERSION} (Current version is ${DOXYGEN_VERSION}).")
+ else()
+ set(DOXY_DOC_DEST_DIR ${CMAKE_INSTALL_ROOT}/docs) ## used in the doxyfile.in
+
+ set(DOXY_DOC_INPUT_ROOT_DIRS "${CMAKE_HOME_DIRECTORY}/src ${CMAKE_HOME_DIRECTORY}/docs ${CMAKE_CURRENT_BINARY_DIR}/generated") ## used in the doxyfile.in
+ set(DOXY_DOC_EXCLUDE_PATTERNS_DIRS "${DOXY_DOC_EXCLUDE_PATTERNS_DIRS}") ## used in the doxyfile.in
+ set(DOXY_DOC_COMMON_IMG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/img ${CMAKE_HOME_DIRECTORY}/src/projects")
+ set(DOXY_DOC_PAGES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pages")
+ set(DOXY_DOC_GENERATED_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
+
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_SAMPLES_SUBPAGE_REF "${SIBR_PROJECTS_SAMPLES_SUBPAGE_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_OURS_SUBPAGE_REF "${SIBR_PROJECTS_OURS_SUBPAGE_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF "${SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_OTHERS_SUBPAGE_REF "${SIBR_PROJECTS_OTHERS_SUBPAGE_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_SAMPLES_REF_REF "${SIBR_PROJECTS_SAMPLES_REF_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_OURS_REF_REF "${SIBR_PROJECTS_OURS_REF_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_TOOLBOX_REF_REF "${SIBR_PROJECTS_TOOLBOX_REF_REF}")
+ string(REPLACE "\\" "\\\\" SIBR_PROJECTS_OTHERS_REF_REF "${SIBR_PROJECTS_OTHERS_REF_REF}")
+
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_SAMPLES_SUBPAGE_REF "${SIBR_PROJECTS_SAMPLES_SUBPAGE_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_OURS_SUBPAGE_REF "${SIBR_PROJECTS_OURS_SUBPAGE_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF "${SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_OTHERS_SUBPAGE_REF "${SIBR_PROJECTS_OTHERS_SUBPAGE_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_SAMPLES_REF_REF "${SIBR_PROJECTS_SAMPLES_REF_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_OURS_REF_REF "${SIBR_PROJECTS_OURS_REF_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_TOOLBOX_REF_REF "${SIBR_PROJECTS_TOOLBOX_REF_REF}")
+ string(REPLACE "\n" "\\n" SIBR_PROJECTS_OTHERS_REF_REF "${SIBR_PROJECTS_OTHERS_REF_REF}")
+
+ file(GLOB doxygen_config_files "*.in")
+ foreach(filename ${doxygen_config_files})
+ message(STATUS "Generating ${filename}...")
+ get_filename_component(output_filename ${filename} NAME_WLE)
+ message(STATUS "Output in ${CMAKE_CURRENT_BINARY_DIR}/${output_filename}...")
+ configure_file(${filename} ${CMAKE_CURRENT_BINARY_DIR}/${output_filename} @ONLY)
+ endforeach()
+
+ add_custom_target(DOCUMENTATION ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/doxygen_prebuild.cmake
+ COMMAND ${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/doxyfile"
+ WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}
+ COMMENT "Building user's documentation into ${DOXY_DOC_DEST_DIR} dir..."
+ )
+ endif()
+endif()
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/doxyfile.in b/extensions/RaDe-GS/SIBR_viewers/docs/doxyfile.in
new file mode 100644
index 0000000000000000000000000000000000000000..86d08abb25435b66b47a279a8c70f6a813aa9588
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/doxyfile.in
@@ -0,0 +1,2571 @@
+# Doxyfile 1.8.20
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = SIBR
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = @SIBR_CORE_VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = @DOXY_DOC_DEST_DIR@
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION = None
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
+# such as
+# /***************
+# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
+# Javadoc-style will behave just like regular comments and it will not be
+# interpreted by doxygen.
+# The default value is: NO.
+
+JAVADOC_BANNER = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# By default Python docstrings are displayed as preformatted text and doxygen's
+# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
+# doxygen's special commands can be used and the contents of the docstring
+# documentation blocks is shown as doxygen documentation.
+# The default value is: YES.
+
+PYTHON_DOCSTRING = YES
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files). For instance to make doxygen treat .inc files
+# as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 5.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
+# during processing. When set to 0 doxygen will based this on the number of
+# cores available in the system. You can set it explicitly to a value larger
+# than 0 to get more control over the balance between CPU load and processing
+# speed. At this moment only the input processing can be done using multiple
+# threads. Since this is still an experimental feature the default is set to 1,
+# which efficively disables parallel processing. Please report any issues you
+# encounter. Generating dot graphs in parallel is controlled by the
+# DOT_NUM_THREADS setting.
+# Minimum value: 0, maximum value: 32, default value: 1.
+
+NUM_PROC_THREADS = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
+# methods of a class will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIV_VIRTUAL = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = YES
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# declarations. If set to NO, these declarations will be included in the
+# documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = YES
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# (including Cygwin) and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = YES
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if ... \endif and \cond
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE = @CMAKE_CURRENT_BINARY_DIR@/layout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = @DOXY_DOC_INPUT_ROOT_DIRS@
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
+# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
+# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
+# *.vhdl, *.ucf, *.qsf and *.ice.
+
+FILE_PATTERNS = *.h \
+ *.hh \
+ *.hpp \
+ *.hxx \
+ *.cpp \
+ *.cxx \
+ *.cc \
+ *.fp \
+ *.vp \
+ *.gp \
+ *.vs \
+ *.fs \
+ *.gs \
+ *.vert \
+ *.frag \
+ *.geom \
+ *.md \
+ *.dox \
+ *.py
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = @DOXY_DOC_EXCLUDE_PATTERNS_DIRS@
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH = @DOXY_DOC_COMMON_IMG_PATH@ \
+ @DOXY_APP_SPECIFIC_IMG_PATH@
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+#
+#
+# where is the value of the INPUT_FILTER tag, and is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# entity all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see https://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+# If clang assisted parsing is enabled you can provide the clang parser with the
+# path to the directory containing a file called compile_commands.json. This
+# file is the compilation database (see:
+# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
+# options used when the source files were built. This is equivalent to
+# specifying the "-p" option to a clang tool, such as clang-check. These options
+# will then be passed to the parser. Any options specified with CLANG_OPTIONS
+# will be added as well.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+
+CLANG_DATABASE_PATH =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = NO
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = .
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via JavaScript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have JavaScript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: https://developer.apple.com/xcode/), introduced with OSX
+# 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the main .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
+# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
+# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
+# the HTML output. These images will generally look nicer at scaled resolutions.
+# Possible values are: png (the default) and svg (looks nicer but requires the
+# pdf2svg or inkscape tool).
+# The default value is: png.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FORMULA_FORMAT = png
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
+# to create new LaTeX commands to be used in formulas as building blocks. See
+# the section "Including formulas" for details.
+
+FORMULA_MACROFILE =
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# https://www.mathjax.org) which uses client side JavaScript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use + S
+# (what the is depends on the OS and browser, but it is typically
+# , /, or both). Inside the search box use the to jump into the search results window, the results can be navigated
+# using the . Press to select an item or to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing +. Also here use the
+# to select a filter and or to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using JavaScript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when not enabling USE_PDFLATEX the default is latex when enabling
+# USE_PDFLATEX the default is pdflatex and when in the later case latex is
+# chosen this is overwritten by pdflatex. For specific output languages the
+# default can have been set differently, this depends on the implementation of
+# the output language.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# Note: This tag is used in the Makefile / make.bat.
+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
+# (.tex).
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
+# generate index for LaTeX. In case there is no backslash (\) as first character
+# it will be automatically added in the LaTeX code.
+# Note: This tag is used in the generated output file (.tex).
+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
+# The default value is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_MAKEINDEX_CMD = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
+# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
+# files. Set this option to YES, to get a higher quality PDF documentation.
+#
+# See also section LATEX_CMD_NAME for selecting the engine.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
+# path from which the emoji images will be read. If a relative path is entered,
+# it will be relative to the LATEX_OUTPUT directory. If left blank the
+# LATEX_OUTPUT directory will be used.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EMOJI_DIRECTORY =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# configuration file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's configuration file. A template extensions file can be
+# generated using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
+# namespace members in file scope as well, matching the HTML output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_NS_MEMB_FILE_SCOPE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME =
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = NO
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/doxygen_prebuild.cmake.in b/extensions/RaDe-GS/SIBR_viewers/docs/doxygen_prebuild.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..07799dc60ca770c13a07f4eb23a0f8a4bc52072a
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/doxygen_prebuild.cmake.in
@@ -0,0 +1,24 @@
+set(SIBR_PROJECTS_SAMPLES_SUBPAGE_REF "@SIBR_PROJECTS_SAMPLES_SUBPAGE_REF@")
+set(SIBR_PROJECTS_OURS_SUBPAGE_REF "@SIBR_PROJECTS_OURS_SUBPAGE_REF@")
+set(SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF "@SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF@")
+set(SIBR_PROJECTS_OTHERS_SUBPAGE_REF "@SIBR_PROJECTS_OTHERS_SUBPAGE_REF@")
+set(SIBR_PROJECTS_SAMPLES_REF_REF "@SIBR_PROJECTS_SAMPLES_REF_REF@")
+set(SIBR_PROJECTS_OURS_REF_REF "@SIBR_PROJECTS_OURS_REF_REF@")
+set(SIBR_PROJECTS_TOOLBOX_REF_REF "@SIBR_PROJECTS_TOOLBOX_REF_REF@")
+set(SIBR_PROJECTS_OTHERS_REF_REF "@SIBR_PROJECTS_OTHERS_REF_REF@")
+set(DOXY_DOC_DEST_DIR "@DOXY_DOC_DEST_DIR@")
+set(DOXY_DOC_GENERATED_DOC_DIR "@DOXY_DOC_GENERATED_DOC_DIR@")
+set(DOXY_DOC_PAGES_DIR "@DOXY_DOC_PAGES_DIR@")
+
+## Cleaning documentation folders
+file(REMOVE_RECURSE "${DOXY_DOC_GENERATED_DOC_DIR}")
+file(REMOVE_RECURSE "${DOXY_DOC_DEST_DIR}")
+
+## Generating documentation pages with variables
+file(GLOB_RECURSE doc_files "${DOXY_DOC_PAGES_DIR}/*.in")
+foreach(filename ${doc_files})
+ message(STATUS "Generating ${filename}...")
+ get_filename_component(output_filename ${filename} NAME_WLE)
+ message(STATUS "Output in ${DOXY_DOC_GENERATED_DOC_DIR}/${output_filename}...")
+ configure_file(${filename} ${DOXY_DOC_GENERATED_DOC_DIR}/${output_filename} @ONLY)
+endforeach()
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealaddinputs.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealaddinputs.png
new file mode 100644
index 0000000000000000000000000000000000000000..88d45fbb96aa0ae2dab4c07a5e019b3becc99660
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealaddinputs.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealalignimages.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealalignimages.png
new file mode 100644
index 0000000000000000000000000000000000000000..05b57387daadeef78f6808d15e9ad035cc98e305
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealalignimages.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealcolorizesimplify.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealcolorizesimplify.png
new file mode 100644
index 0000000000000000000000000000000000000000..34460e50be88f5ca6fc79699e72382b1d4f03742
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealcolorizesimplify.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealexportmodel.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealexportmodel.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7f584079ae613104c84a556dde1964e906adba5
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealexportmodel.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealinputsonly.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealinputsonly.png
new file mode 100644
index 0000000000000000000000000000000000000000..723cf71addeb44e032b698a7a35aa072f60a8086
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealinputsonly.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:64dae1bade3362d70ce42d31f448adfd97dacb685118ad692454de55316e10c5
+size 117923
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmesh.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmesh.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ce14c7e74e0a041772adace43e2a50322946f4d
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmesh.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3f9ea27918492696717875cdadfa1854c591456b3bfdfd10ae41fc9419151888
+size 370831
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmeshreconstruction.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmeshreconstruction.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8177acf18cc6c32daecb5a2f32a60b9a46f2099
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealmeshreconstruction.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealnew.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealnew.png
new file mode 100644
index 0000000000000000000000000000000000000000..f9f05d997db4fc7b48006cf63a6362421d5e44b8
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealnew.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealpointcloud.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealpointcloud.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a57cfbe019ab2c45bd2acb60eb724758dfbee36
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/caprealpointcloud.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e0673db0bcf142b50dba501cf9126620704a876ff383b3284fca8f0d792b938
+size 275587
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/meshlab.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/meshlab.png
new file mode 100644
index 0000000000000000000000000000000000000000..da424bd5079a6846a6deed924dba82691ba96bdc
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/capreal/meshlab.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dbfff276c63cb65d5fa64e477c413f5863c46b6b531aaf1ff4c09c3cdec5bf14
+size 682709
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/cmake.gif b/extensions/RaDe-GS/SIBR_viewers/docs/img/cmake.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b11ddda3d9ddbfb33f47880389378487f0f72982
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/cmake.gif differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/sibr_classes_v2.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/sibr_classes_v2.png
new file mode 100644
index 0000000000000000000000000000000000000000..03e194e9674c687e5efe4be9feb20e2d276226e0
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/sibr_classes_v2.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e3fed9ccdb41e7aa2ef20bece935985d1e94489bfdfdf41979aa74912892c543
+size 212803
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/unity_ulr.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/unity_ulr.png
new file mode 100644
index 0000000000000000000000000000000000000000..9fc66456a9abd62a434cbcaaff79103fbbbbd9c3
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/class/unity_ulr.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/AssetStreamer/seq_assetStreamer.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/AssetStreamer/seq_assetStreamer.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..9104ac0274ebaa6c58a25698d25b23f2c8e5268e
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/AssetStreamer/seq_assetStreamer.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cba8a727a6028223026b5540d74610b8cfd9ef9eb99cc303cddf3958184aec4a
+size 914729
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_insideOut.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_insideOut.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..663c74805c43f4ed1dd63a2c27851a837e5b0a00
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_insideOut.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f871e91b74ed592240b6330218b8f674d9de4ffba204da38ca0c1b6aa58c2791
+size 856701
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_stream.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_stream.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..50f4d42a1a67095ab50c60f9764315b4d6bb644b
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_stream.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cf5b12e2796f7655e2ed5bc6e1bfc34a6eb1a79c9f2e04ea82b2ecbd89c037a8
+size 1439169
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_v3_landscape.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_v3_landscape.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..cdc4892ac9ca609073a66707c97cba38fcc0b98f
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Renderers/seq_ulr_v3_landscape.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1477a75e03e317eac929b7eb8b16688d753faf77dc7fac8186fd855accbfc9fc
+size 834246
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_rendering.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_rendering.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..7bac7f666428195eaf25746a671a75d326727c2f
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_rendering.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c9c99577b35f2af1a00b0347b525809655f2b6112f47d5fcceafcb2a2d15fad4
+size 434045
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_texture_upload.pdf b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_texture_upload.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..bfc121e2493f595274940b8e3b8ca9783fabd5c9
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/diagramas/sequence/Unity/seq_unity_ulr_texture_upload.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bd5461bc3615db885c923bbaad9c9525243d40d2b524e022fd51991343e4b47d
+size 636136
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_cmake.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_cmake.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2fe8d67c7b2ff62678da37e12dd9557e1c375ec
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_cmake.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5fb3247d422df23b2e0b5e41f2ec42d18f4f279d26e2a5f3b1f595bf73ec977d
+size 117471
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_globale.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_globale.png
new file mode 100644
index 0000000000000000000000000000000000000000..217d47d0ea649fcf28179ffde59fab7831ef988d
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_globale.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_principle.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_principle.png
new file mode 100644
index 0000000000000000000000000000000000000000..d270ac29f326db8273c2866407748f7d222be1e1
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/ibr_common_principle.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/jesnault_git_cheat_sheet.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/jesnault_git_cheat_sheet.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f1b651dd27a5d4ba7312638b7fe3c2d30225201
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/jesnault_git_cheat_sheet.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:998cdfebcadd09dc376f9c102da8009921481c58b47a5e6018d07b1f64ebd958
+size 403423
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/multimeshmanager.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/multimeshmanager.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4d48dc3fca78d7d04440113bc0ba59a0d8ef4de
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/multimeshmanager.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:08ace970e97deef0c6dd03e1778a2a1ab272bee7a653b127ca8ce301e0b5b1fd
+size 569810
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/multiviewmanager.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/multiviewmanager.png
new file mode 100644
index 0000000000000000000000000000000000000000..af57a3d3633e80378389c5c3f38a01da25ca2d2d
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/multiviewmanager.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4eadf28a5618287d4db8267ccae2ae50cb445d715fd1fd828ab32eac2ff796ae
+size 1008864
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_dataset.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_dataset.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef0a8abb40a23c3f9e487ab24df178ef72fc5515
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_dataset.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_diagram_lvl2.svg b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_diagram_lvl2.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8f0e12ce778b2aa1c77738b6d124eaedc735bcab
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_diagram_lvl2.svg
@@ -0,0 +1,2 @@
+
+Renderer Libs Utilities sibr_system sibr_assets sibr_graphics sibr_spixelwarp<br> SWARP<br>Renderer Utils sibr_renderer (common)<br> sibr_url<br> ... Boost Property Config (Log) ProgramArgs Loading<br>Progress ByteStream Array2d<br> C++ Standard Library<br> CopyRenderer BlurRenderer RenderView ImageRGB/<br>ImageRGBA<br> Vector3 Matrix4 Quaternion Vector2 PixelMask PixelSpixelssss PixelNormal Transform3d RenderTarget Texture Mesh Image Viewport Window Camera RenderUtility(additional functions)
[Not supported by viewer] Renderer (OpenGL States/Functions)
[Not supported by viewer] [Not supported by viewer] Property Keys<br> MVSFile ActiveCamFile SDepthFile QualityFile PlaneFile ImageListFile sibr_view RenderView:<br>TopView<br> RenderView:<br>SceneView<br> RenderView:<br>ShowRTView<br> RenderView:<br>DebugView<br> RenderingMode:<br>Mono<br> UIBehavior RenderingMode: StereoQuadBuffer
[Not supported by viewer] RenderingMode: Stereo Anaglyph
[Not supported by viewer] CameraDolly IBRArgs Trackball PathRecorder PatchFile [Not supported by viewer] SpixelFile [Not supported by viewer] GLEW<br> OpenCV Eigen (might be moved in IBR System)
[Not supported by viewer] OpenGL<br> img_normal.exe maskpatch.exe color_harmoni.exe qualityEstim.exe planeEstim.exe<br> scene2patch.exe depthSynthesis.exe superpixel.exe undistort.exe depth.exe [Not supported by viewer] Renderer Apps sibr_fplan_app.exe sibr_selection_app.exe sibr_ulr_app.exe sibr_proxy_app.exe <span>sibr_compare_app.exe</span> sibr_spixelwarp_app.exe SpixelImage ... TODO: sibr_view should be higher (always) than sibr_assets in the hierarchy
TODO: sibr_view should be higher (always) than sibr_assets in the hierarchy<br> sibr_mixed_model.exe sibr_plan_app.exe <span>sibr_compare_app.exe</span> InputCamera SpixelGraph [Not supported by viewer] [Not supported by viewer] [Not supported by viewer] [Not supported by viewer] ... PoissonRenderer
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_new_architecture.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_new_architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..b20b733a14ccd283ea8450b3710f2bd6b0f1bd9a
Binary files /dev/null and b/extensions/RaDe-GS/SIBR_viewers/docs/img/sibr_new_architecture.png differ
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/img/ulr_screenshot.png b/extensions/RaDe-GS/SIBR_viewers/docs/img/ulr_screenshot.png
new file mode 100644
index 0000000000000000000000000000000000000000..00b5fe99b8c39cecfc5bd83e0a99153f45a618f1
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/img/ulr_screenshot.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9198b88594e4c7fb3aa51905b0834a99ebbc0aac0dcf768c930c6ce0c18072c2
+size 1442097
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/layout.xml.in b/extensions/RaDe-GS/SIBR_viewers/docs/layout.xml.in
new file mode 100644
index 0000000000000000000000000000000000000000..0c2088f80cfa0e60b0de781e17f200b053b2e460
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/layout.xml.in
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/1_Getting_Started.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/1_Getting_Started.dox
new file mode 100644
index 0000000000000000000000000000000000000000..5d58acde27feb6c74e2129da9d6974e0d86b48b0
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/1_Getting_Started.dox
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@mainpage Getting Started
+
+@section intro_sec Introduction
+The System for Image-Based Rendering or **SIBR**, is a specialized collection of libraries and toolkits for quickly implementing Image-Based Rendering (IBR) algorithms, and includes implementations of several published IBR papers, mainly from Inria and UCL, but also (re-implementations) of projects from other research groups. Most of **SIBR** was developed over the years (since 2011) at Inria Sophia-Antipolis for the various IBR research projects in the group, but the codebase includes a significant part of code from the *fribr* codebase of P. Hedman from UCL. The codebase has a long history; see @ref sibr_history section.
+
+In this first release, we are providing reference source code implementations and datasets for the following \ref sibr_projects_available.
+
+We will be progressively releasing more implementations of past and future projects (please see the @ref sibr_roadmap). For the first few releases, the main intended usage of the codebase is comparisons with previous algorithms. In the medium-term future, we hope that the codebase will be useful to others for the development of their own IBR algorithms.
+
+The codebase contains three main components: the main *core* library, various utility/helper libraries and what we call *Projects* (see @ref sibr_projects_about), that are the implementations of Inria, UCL (and other) research projects.
+The core library has support for multi-view (MV) datasets, processed with Structure-from-Motion (SfM) and Multi-view Stereo (MVS) software. We support data from various SfM/MVS sources, such as *colmap* and the (commercial) *RealityCapture* package (see @ref howto_generate_dataset), and a some interactive viewing utilities for developing and debugging IBR algorithms (e.g., ``top view'' shown below).
+
+@image HTML ulr_screenshot.png An example view of SIBR width=700px
+
+The utilities include various MV dataset (pre-)processing utilities that are used by various *Projects* and can be of general use, and various utilities for different API interfaces (e.g., tensorflow and pytorch, OptiX) and the core *fribr* framework from UCL that is used in some *Projects*.
+
+Each *Project* provided in **SIBR** has (more or less) similar documentation and code structure: a binary release for easy use, how to checkout the code, configure, build and install the solution, and run the basic renderer; a set if fully-processed datasets are provided for each project. The *Project* has *apps*, typically including a *rendering app* that is usually enough to run the method to compare with a new algorithm on one of our datasets.
+Most projects also have a *preprocessing* step. The code for preprocessing allows processing of your own data with the corresponding algorithm; the datasets provided have been processed with these tools.
+Please see the section on comparisons (@ref comparisons_sec) below.
+
+The first *Project* is bundled in the *core* library, and has implementations of per-pixel variants of the Unstructured Lumigraph \[Buehler 2001\] (see the @ref ulrPage page). This implementation has been used as a baseline comparison in many of our projects, and is always a useful baseline for any new IBR algorithm.
+
+The licensing of the *core* is free for non-commercial, research and evaluation purposes, by academic or industrial labs, as defined in the LICENSE.md file. For commercial usage in a for-profit product, a paid license is required; please contact George.Drettakis@inria.fr if you are interested.
+
+The rest of this page explains how to download binaries, compile, configure and install the basic system and its documentation.
+
+If you use this code in a publication, please cite the system as follows in your publications:
+
+```
+@misc{sibr2020,
+ author = "Bonopera, Sebastien and Hedman, Peter and Esnault, Jerome and Prakash, Siddhant and Rodriguez, Simon and Thonat, Theo and Benadel, Mehdi and Chaurasia, Gaurav and Philip, Julien and Drettakis, George",
+ title = "sibr: A System for Image Based Rendering",
+ year = "2020",
+ url = "https://sibr.gitlabpages.inria.fr/"
+}
+```
+
+@section comparison_sec Comparisons
+
+A major goal of this code release is to allow comparisons. Most renderers in the *Projects* are interactive, allowing free-viewpoint navigation in the corresponding scenes. For comparisons, most renderers take a --pathFile
argument that is a path of cameras in the scene. These are written to the directory requested, or by default in the pathOutput
directory at the root of the dataset. For more details on cameras and paths, see the tutorial page @ref howto_cameras_paths .
+
+@section install_sec Installation
+
+**Note**: The current release is for *Windows 10* only. We are planning a Linux release soon.
+
+@subsection sibr_binaries Binary distribution
+
+The easiest way to use *SIBR* is to download the binary distribution. All steps described below, including all preprocessing for your datasets will work using this code.
+A binary distribution (200Mb) of the core is available here:
+
+```
+wget https://repo-sam.inria.fr/fungraph/sibr-release/sibr-core/install.zip
+```
+
+unzip to create the ``install'' directory. All instructions below on running the code can be performed using this binary distribution.
+
+@subsection sibr_example To run an example
+
+Download a dataset from: https://repo-sam.inria.fr/fungraph/sibr-datasets/
+
+e.g., the *sibr-museum-front* dataset in the *DATASETS_PATH* directory.
+
+```
+wget https://repo-sam.inria.fr/fungraph/sibr-datasets/museum_front27_ulr.zip
+```
+
+Once you have built the system or downloaded the binaries (see above), go to *install/bin* and you can run:
+```
+ sibr_ulrv2_app.exe --path DATASETS_PATH/sibr-museum-front
+```
+
+You will have an interactive viewer and you can navigate freely in the captured scene.
+Our default interactive viewer has a main view running the algorithm and a top view to visualize the position of the calibrated cameras. By default you are in WASD mode, and can toggle to trackball using the "y" key. Please see the page [Interface](https://sibr.gitlabpages.inria.fr/docs/nightly/howto_sibr_useful_objects.html) for more details on the interface.
+
+
+@subsection sibr_prerequisite Prerequisites
+
+- git
+- Visual Studio 2019 (https://visualstudio.microsoft.com/).
+- Cmake 3.16+,(https://cmake.org/).
+- 7zip should be installed (https://www.7-zip.org/download.html).
+- Python 3.8+ should be installed and configured in the PATH (https://www.python.org/downloads/).
+- PIL (pip install pillow, in an admin command if needed: https://pypi.org/project/Pillow/) might be needed for some preprocess scripts.
+- ImageMagick (https://imagemagick.org/script/download.php).
+- Doxygen 1.8.17+ should be installed and configured in the PATH for generating the documentation (http://www.doxygen.nl/download.html).
+- If needed (Optix, Tensorflow, Pytorch,... integration), CUDA 10.1+ (https://developer.nvidia.com/cuda-downloads) and cuDNN.
+- An internet connection, as external dependencies will be downloaded from our servers during the CMake configuration.
+
+@subsection sibr_checkout Checkout the code
+
+- Clone sibr_core repository (https://gitlab.inria.fr/sibr/sibr_core). We recommend that you checkout master branch, but you can also work with the develop branch (unstable).
+@code
+## through HTTPS
+git clone https://gitlab.inria.fr/sibr/sibr_core.git -b master
+## through SSH
+git clone git@gitlab.inria.fr:sibr/sibr_core.git -b master
+@endcode
+- You can add the projects' source code you would like to compile with SIBR, for this see @ref sibr_projects_add)
+@subsection sibr_configure_cmake Configuring the solution
+
+- Run Cmake, select SIBR root folder as a source directory and \/build/ as the build directory.
+- Configure, select the Visual Studio C++ Win64 compiler.
+- Select the projects you want to generate among the BUILD_* variables in the list.
+- Generate.
+
+@subsection sibr_compile Compiling
+
+- Configure the solution & Generate like we did in @ref sibr_configure_cmake.
+- Open the generated Visual Studio solution (sibr_root/build/sibr_projects.sln).
+- Build the BUILD_ALL target, and then the INSTALL target.
+- The compiled executables will be put in install/bin.
+@note If install fails, you will have to copy the required .dll files which are not copied automatically in the install/bin directory.
+ In general make sure these .dll files are in the bin directory : boost_system-vc141-mt-1_64.dll, boost_filesystem-vc141-mt-1_64.dll, glew32.dll, assimp-vc140-mt.dll, embree.dll.
+ Alternatively, you can selectively execute some of the install targets for specific projects.
+
+@subsection sibr_generate_documentation Generating the documentation
+
+- Configure the solution like we did in @ref sibr_configure_cmake and choose BUILD_DOCUMENTATION along with the projects you want in the documentation. Then generate the solution.
+- Open the generated Visual Studio solution (sibr_root/build/sibr_projects.sln).
+- Build the DOCUMENTATION target.
+- The generated documentation will be put in docs and can be accessed through install/docs/index.html.
+
+@subsection sibr_troubleshooting Troubleshoot
+
+- Cmake can't find GLU, GLEW or another library: use an up-to-date CMake, check that you are connected to the Internet.
+- Weird OpenCV error: you probably selected the 32-bits compiler in cmake-gui.
+- 'Cmd.exe failed wither error 009' or similar: make sure Python is installed and in the PATH.
+- BUILD_ALL or INSTALL fail because of a project you don't really need: build and install each project separately by selecting the proper targets.
+- Some projects may depend on other projects. Make sure you have checked all the required projects before generating the solution.
+- Error in CUDA headers under Visual Studio 2019: make sure CUDA >= 10.1 is installed.
+
+@subsection sibr_bugs Bugs and Issues
+
+We will track bugs and issues through the Issues interface on gitlab. Inria gitlab does not allow creation of external accounts, so if you have an issue/bug please email sibr@inria.fr
and we will either create a guest account or create the issue on our side.
+
+@subsection sibr_main_authors Authors
+
+The authors of **SIBR** *core* are Gaurav Chaurasia (Ph.D. Inria, 2011-2013), Rodrigo Ortiz-Cayon (Ph.D. Inria 2013-2016), Jerome Esnault (Software Engineer, Inria, DATES), Sebastien Bonopera (Software Engineer, Inria, DATES), Theo Thonat (Ph.D. Inria 2015-2019), Simon Rodriguez (Ph.D. Inria, 2017-2020), Julien Philip (Ph.D. Inria, 2017-2020), Siddhant Prakash (Soft. Engineer & currently Ph.D. Inria). Mehdi Benadel (Soft. Engineer, Inria) is currently in charge of **SIBR**. George Drettakis had the overall supervision of the project throughout. See also @ref sibr_history.
+
+
+Each *Project* has different authors, who are listed in the corresponding project pages. A special mention is due to Peter Hedman (at UCL) who wrote the *fribr* framework used in several projects.
+
+@subsection sibr_funding Funding
+
+The various projects in **SIBR** were funded by Inria, French national and European research funds. These include French Ministry of Education and University of Nice Sophia-Antipolis (now Universite Cote d'Azur) funds (G. Chaurasia, S. Rodriguez), the ANR SEMAPOLIS project (https://project.inria.fr/semapolis/) and the Region Provence Alpes Cote d'Azur (T. Thonat), the EU projects VERVE (https://gv2.scss.tcd.ie/VERVE/) G. Chaurasia; CR-PLAY (http://www.cr-play.eu/) R. Ortiz-Cayon, J. Esnault, S. Bonopera; EMOTIVE (https://emotiveproject.eu/) S. Duchene, J. Philip and the ERC FUNGRAPH project (http://fungraph.inria.fr), J. Philip, S. Rodriguez, S. Prakash, S. Morgenthaler, M. Benadel. The FRIBR code was funded by the Rabin Ezra scholarship fund for P. Hedman at UCL.
+
+@section sibr_history History of SIBR
+
+The oldest code in SIBR was written by G. Chaurasia for his Ph.D. in 2011-2013 at what was then the REVES (LINK) research group at Inria Sophia-Antipolis. The initial ULR implementation, and parts of the code in the Superpixel Warp project [Chaurasia 2013] are from this work. Gaurav re-factored the code to allow it work first with Qt and then with OpenSceneGraph, in a code base called *ibr_collection*, used for the EU project VERVE (https://gv2.scss.tcd.ie/VERVE/). In the followup CR-PLAY (http://www.cr-play.eu/) project, the code was refactored by S. Bonopera, and as part of the ERC FUNGRAPH S. Prakash was in charge of designing the current core/projects structure. M. Benadel has been in charge of cleanup for the release. The overall development of the entire project was managed by G. Drettakis.
+
+@section sibr_roadmap SIBR Release Roadmap
+
+After the first release (see \ref sibr_projects_available ), we plan to release code for the deep learning solution for outdoor relighting [Philip 19] (Jan 21), and potentially for other recent IBR projects from the GRAPHDECO group.
+We will be releasing a Linux version of the core, and for some of the *Projects* soon. Stay tuned.
+
+@subsection sibr_main_authors Authors
+
+The authors of **SIBR** *core* are Gaurav Chaurasia (Ph.D. Inria, 2011-2013), Rodrigo Ortiz-Cayon (Ph.D. Inria 2013-2016), Jerome Esnault (Software Engineer, Inria, DATES), Sebastien Bonopera (Software Engineer, Inria, DATES), Theo Thonat (Ph.D. Inria 2015-2019), Simon Rodriguez (Ph.D. Inria, 2017-2020), Julien Philip (Ph.D. Inria, 2017-2020), Siddhant Prakash (Soft. Engineer & currently Ph.D. Inria). Mehdi Benadel (Soft. Engineer, Inria) is currently in charge of **SIBR**. George Drettakis had the overall supervision of the project throughout. See also @ref sibr_history.
+
+
+Each *Project* has different authors, who are listed in the corresponding project pages. A special mention is due to Peter Hedman (at UCL) who wrote the *fribr* framework used in several projects.
+
+@subsection sibr_funding Funding
+
+The various projects in **SIBR** were funded by Inria, French national and European research funds. These include French Ministry of Education and University of Nice Sophia-Antipolis (now Universite Cote d'Azur) funds (G. Chaurasia, S. Rodriguez), the ANR SEMAPOLIS project (https://project.inria.fr/semapolis/) and the Region Provence Alpes Cote d'Azur (T. Thonat), the EU projects VERVE (https://gv2.scss.tcd.ie/VERVE/) G. Chaurasia; CR-PLAY (http://www.cr-play.eu/) R. Ortiz-Cayon, J. Esnault, S. Bonopera; EMOTIVE (https://emotiveproject.eu/) S. Duchene, J. Philip and the ERC FUNGRAPH project (http://fungraph.inria.fr), J. Philip, S. Rodriguez, S. Prakash, S. Morgenthaler, M. Benadel. The FRIBR code was funded by the Rabin Ezra scholarship fund for P. Hedman at UCL.
+
+@section sibr_references References
+[Chaurasia 13] G. Chaurasia, S. Duchene, O. Sorkine-Hornung, & G. Drettakis. (2013). Depth synthesis and local warps for plausible image-based navigation. ACM Transactions on Graphics (TOG), 32(3), 30. http://www-sop.inria.fr/reves/Basilic/2013/CDSD13/
+
+[Philip 19] J. Philip, M. Gharbi, T. Zhou, A. Efros, G. Drettakis (2019), Multi-view Relighting Using a Geometry-Aware Network Multi-view-Relighting.pdf ACM Transactions on Graphics (SIGGRAPH Conference Proceedings), Volume 38, Number 4 - July 2019 http://www-sop.inria.fr/reves/Basilic/2019/PGZED19/
+
+
+ */
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox
new file mode 100644
index 0000000000000000000000000000000000000000..a6b53d9612810b3bbebbcaf5f183cd7b8007b23c
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page projects Projects
+*/
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox.in b/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox.in
new file mode 100644
index 0000000000000000000000000000000000000000..d08c50c48b67395ac685f841a2857c5149b2160a
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/2_Projects.dox.in
@@ -0,0 +1,77 @@
+/*!
+@page projects Projects
+
+@section sibr_projects_about What are projects ?
+
+Research algorithms and toolboxes have been implemented for SIBR as plugins named "Projects".\n
+Unstructured Lumigraph Rendering (ULR) application is provided by default with SIBR to help users get started.\n
+Some projects called toolboxes might also be used by other projects to bring additional functionalities (for instance the SIBR/Optix integration).\n
+
+@subsection sibr_projects_available Available Projects
+
+The list of projects that have been added to this generated version of SIBR's documentation is given below.\n
+For projects corresponding to publications, the link to the paper is provided.\n
+Most of other projects are helper libraries that can be used to augment SIBR with new functionalities.
+
+- @subpage sibr_projects_samples
+@SIBR_PROJECTS_SAMPLES_REF_REF@
+- @subpage sibr_projects_ours
+@SIBR_PROJECTS_OURS_REF_REF@
+- @subpage sibr_projects_others
+@SIBR_PROJECTS_OTHERS_REF_REF@
+- @subpage sibr_projects_toolbox
+@SIBR_PROJECTS_TOOLBOX_REF_REF@
+
+@subsection sibr_projects_documentation Access projects documentation
+
+Each project documentation is compilable through SIBR.\n
+To access the projects documentation, first :\n
+- Add the project to SIBR like explained in @ref sibr_projects_add
+- Compile the documentation
+
+@subsection sibr_projects_add Adding projects to SIBR
+
+Existing projects can be added as subdirectories in the src/projects directory.\n
+For this, you need to access to the project's source code (most of them are in https://gitlab.inria.fr/sibr/projects) to clone it, build it with SIBR and use it.\n
+If you want to create your own project, see @ref howto_setup_project .\n
+You can follow the given steps to add a project once access is given.\n
+- You will need to checkout SIBR Core source code (see @ref sibr_checkout).
+- Go to src/projects
+- Clone/Copy the project source code in the correct project folder (it should be the same as the project repository, or check the README for more information).
+- You can then resume with @ref sibr_generate_documentation or @ref sibr_compile
+
+@subsection sibr_project_structure Project structure
+
+See @ref project_structure
+
+@subsection sibr_your_project Creating your own project
+
+See @ref howto_setup_project
+
+*/
+
+/*!
+@page sibr_projects_samples Sample algorithms & toolboxes
+
+@SIBR_PROJECTS_SAMPLES_SUBPAGE_REF@
+*/
+
+/*!
+@page sibr_projects_ours Our algorithms
+
+@SIBR_PROJECTS_OURS_SUBPAGE_REF@
+*/
+
+/*!
+@page sibr_projects_others Other algorithms
+
+@SIBR_PROJECTS_OTHERS_SUBPAGE_REF@
+*/
+
+/*!
+@page sibr_projects_toolbox Integrated toolboxes
+
+@SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF@
+*/
+
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/3_Tutorials.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/3_Tutorials.dox
new file mode 100644
index 0000000000000000000000000000000000000000..e5904897c05690bbedd1d278fad191aef449225a
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/3_Tutorials.dox
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page tutorials Dataset Documentation & Tutorials
+
+- @subpage howto_generate_dataset
+- @subpage howto_sibr_useful_objects
+- @subpage howto_setup_project
+- @subpage howto_cameras_paths
+
+ */
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/4_Architecture.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/4_Architecture.dox
new file mode 100644
index 0000000000000000000000000000000000000000..cb928c4c12d2cef2a6f2ef60d12e8e2dc1610171
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/4_Architecture.dox
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page architecture Architecture
+
+This is a diagram describing the overall SIBR architecture:
+@image html sibr_new_architecture.png "Architecture Diagram" width=700px
+
+SIBR is built using layers.
+
+@section Core
+
+SIBR core module exposes internal libraries (system, graphics, assets, scene, raycaster, imgproc, view, renderer, video) which can be used to implement multiple IBR algorithms.
+
+@subsection system
+At the very low level, we have **core/system** that contains OS tools (e.g. filesystems), mathematical tools (e.g. vector operations), and standard tools (e.g. string operations). It also contains a configuration file (Config.hpp) that defines many useful macros/const.
+
+In short:
+- we use STL and C++11 (std::shared_ptr are heavily used)
+- we use Boost Libraries to manage filesystems.
+- we use Eigen for math tools. (Dev tips: Please use sibr::Vector (e.g. sibr::Vector3f), because they define important flags.)
+
+@subsection graphics
+Next we expose **core/graphics** which contains graphics tools, such as images, meshes, textures, rendertargets, shaders,... We use OpenCV for managing images and image operations. Note that we wrapped OpenCV's cv::Mat in sibr::Image to control/check types statically. See sibr::Image class for details.
+
+@subsection assets
+The classes contained in **core/assets** represent basic resource files present in IBR datasets. These classes are useful for loading and reading different types of files found in a typical dataset.
+
+@subsection scene
+**core/scene** contains a full IBR dataset representation and storage, based on multiple components that form a "scene". A good example is sibr::BasicIBRScene, containing a default set of assets (cameras, images, proxies etc.) which can be initialized by means of a scene metadata file.
+
+@subsection raycaster
+The **core/raycaster** library provides raycasting and intersection test utilities, wrapping Intel Embree for fast ray/triangle tests.
+
+@subsection imgproc
+Basic image processing utilities cam be found in **core/imgproc**. For more complex tasks, you can use OpenCV algorithms as our Images are backed by OpenCV matrices.
+
+@subsection video
+You can load and save videos using the **core/video** module. It internally relies on ffmpeg.
+
+@subsection view
+The **core/view** library exposes tools for making viewer apps for live rendering and debugging of the algorithms. It define a basic view interface along with interactive camera modes, a multi-window management system,...
+
+@subsection renderer
+The classes in **core/renderer** library implements general rendering passes and functionalities required for many IBR applications. usually, when designing a View for a custom rendering algorithm, you will use multiple renderers, some customs and some out-of-the-box.
+
+ */
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_colmap.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_colmap.dox
new file mode 100644
index 0000000000000000000000000000000000000000..7ab850529fef34dfcd0c2e00673475e826b442c9
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_colmap.dox
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page HowToColmap How to create a dataset from Colmap
+
+We provide a python script that runs the entire Colmap pipeline, see here: @ref sibr_projects_dataset_tools_preprocess_tools_fullColmapProcess
+
+@note The previous link might not be available if you did not build the doc with `BUILD_IBR_DATASET_TOOLS` on
+
+However, you can also run your own Colmap reconstruction by yourself, and use `ColmapToSIBR` to create an SIBR project (i.e., images without borders, of the same size) from colmap data. In the install\scripts directory run:
+
+@code
+python colmap2sibr PATH_TO_DATASET
+@endcode
+
+This will create a *sibr_cm* subdirectory containing the modified scene.
+
+\section HowToColmap_example_datasets Example Datasets
+
+Example datasets processed with *fullColmapProcess* and *colmap2Sibr* are here:
+\n
+ https://repo-sam.inria.fr/fungraph/sibr-datasets/
+\n
+
+
+*/
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_realitycapture.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_realitycapture.dox
new file mode 100644
index 0000000000000000000000000000000000000000..8169eedb73c079d8e2c04ef7ff9317f12dc3eb97
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to generate your dataset/How_to_create_dataset_from_realitycapture.dox
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page HowToCapreal How to create a dataset from Reality Capture
+
+\tableofcontents
+
+@section capreal_usage How to use
+
+We use Reality Capture to generate a reconstruction of a mesh from several images gererated with multiple point of view. The program can open a group of images and determinate the position of the initial cameras.
+Please be aware that RealityCapture does not let you export the results without a license (which you might need to pay for).
+Here is a detailed explanation of all the steps:
+
+@subsection capreal_usage_layout Choose your layout
+
+Before anything, you'll have to choose your layout.
+You can modify them with the icons on the top of the screen.
+The interface can be a bit wonky, especially the 3D view. If you want to avoid possible display issues, you can choose `1 + 1 + 1 Layout`.
+
+@image html caprealnew.png Layout
+
+@subsection capreal_usage_input_images Select input images
+
+For reconstruction, you will need to provide a set of images of your scene. You can do so by clicking on `Inputs` or `Folder` buttons in the `Workflow` tab.
+
+@image html caprealaddinputs.png Add input images
+
+@image html caprealinputsonly.png Now the input images are set
+
+@subsection capreal_usage_align_images Align images
+
+When the image set is properly provided, you can align them with the `Align Images` option, in the `Alignment` tab.
+
+@image html caprealalignimages.png Align images option
+
+Now, you can see a point cloud in the 3D view.
+
+@image html caprealpointcloud.png The point cloud you get when you align images
+
+@subsection capreal_usage_mesh_reconstruction Mesh reconstruction
+
+Now you'd want to have a mesh from the images. For this, you need to select one of the `Calculate Model` options in the `Reconstruction` tab. We'll go for the `Normal Detail` option.
+
+@image html caprealmeshreconstruction.png The mesh reconstruction options
+
+Now you should be able to see the reconstruction.
+
+You can click on `Colorize` to colorize the mesh (or `Texture` if you want to texturize it : colorization only apprixomate vertices color, while texturing gives you an approximated texture).
+
+The generated mesh is likely to be pretty complex in terms of triangle count.
+You can decreased the number of triangles by doing : `Tools > Simplify Tools`
+You can take 1 or 2 For teh render optionmillion of triangle for the simplification
+
+You now have calibrated cameras and a reconstructed 3D mesh that are ready for use by **SIBR**. The next two sections explain whow to create a set of directories that will be useful for dataset managements, then save the data required from RealityCapture.
+
+@image html caprealcolorizesimplify.png Colorize and Simplify Tools options
+
+@section capreal_DirStruc Suggested directory structure
+(Note: This directory structure is only suggested for user accessibility. You can store/create the dataset in separate directories as you like, as long as you provide correct input to the scripts to generate SIBR datasets.)
+
+@li dataset\\raw
+\n Contains the original images from the cameras.
+\n
+@li dataset\\rcprojs
+\n Contains the .rcproj files and the data directories (these are big after reconstruction, since they contain the mesh and texture).
+\n
+@li dataset\\sfm_mvs_rc
+\n Contains the exported undistorted images with black borders, the file bundle.out, pmvs_recon.ply and optionally textured.obj, textured.mtl and textured_u1_v1.png (see what to save below)
+\n
+@li dataset\\sibr_rc
+\n Contains the extracted data to create scene(s) using SIBR, containing bundle file, reconstructed mesh, list of images, scene metadata etc. in proper directory structure.
+\n
+
+@section capreal_WhatToSave What to save from RealityCapture
+
+In the selected directory (*sfm_mvs_rc*) save the following:
+
+@li After alignment and reconstruction, save Registration (choose optionsbundler v0.3 Negative-Z format, jpg image type, fit=Inner_region), and save to file *bundle.out*
+@li After reconstruction -> Mesh -> save to the file *recon.ply*
+@li After texturing -> Mesh -> save textured.obj (which will save textured.mtl and textured_u1_v1.png containing the texture);
+@todo Textures verify
+
+@subsection Restore
+
+@todo Does this exist ?
+@li If something goes wrong, use python restore_dataset.py to restore all original files (bundle, ply, obj) as exported from RealityCapture
+*/
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Configuring_your_project.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Configuring_your_project.dox
new file mode 100644
index 0000000000000000000000000000000000000000..2402608c45cc23bc15edaf5abafbded5ae8ed9c2
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Configuring_your_project.dox
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page configure_project Configuring your project
+
+@ingroup setup_project
+
+@section gen_setup_config General setup
+
+- Create a repository in `src/projects/my_project` (name your project at your convenience)
+- Setup your project structure as stated in @ref project_structure
+- Use the following sample files (form the following sections) for your `CMakeLists.txt` files and `Config.hpp` structure
+- Re-run configure for the main SIBR `CMakeLists.txt`.
+- The project should be automatically detected; If so, check `BUILD_IBR_MY_PROJECT` (`MY_PROJECT` being your project name folder) in CMake and re-generate.
+
+@section all_sec Main project configuration
+
+This `CMakeLists.txt` is the one in the root of your project. It is registering the subdirectories of your project against the main CMake.\n
+It will also provide you with an additional project wide install target.\n
+
+@code
+set(SIBR_PROJECT "my_project") # Please replace my_project with your project folder name
+project(sibr_${SIBR_PROJECT}_all)
+
+# Update this with the folders included in your project
+add_subdirectory(apps)
+add_subdirectory(preprocess)
+add_subdirectory(renderer)
+
+include(install_runtime)
+subdirectory_target(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR} "projects/${SIBR_PROJECT}")
+@endcode
+
+@section listing_sec Listing app & preprocesses projects
+
+This `CMakeLists.txt` is registering the CMake projects in subdirectories against the main CMake of your SIBR project, putting them together in a custom named group.\n
+They will appear as multiple solutions in a subdirectory in Visual Studio for instance.\n
+Useful to group the `apps/` or `preprocess/` executables of a project.\n
+\n
+You can use it as sample structure for `apps/CMakeLists.txt` and `preprocess/CMakeLists.txt`.
+
+@code
+project(sibr_my_apps_group) # Please rename this project at your convenience
+add_subdirectory(my_app_1/)
+add_subdirectory(my_app_2/)
+#...
+@endcode
+
+
+@section exe_sec App and preprocess projects
+
+This example can be used for application and preprocess executables.\n
+The parts to modify are the project name, the linked libraries and the folder property.\n
+Put the `CMakeLists.txt` in your application project directory.
+
+@code
+set(SIBR_PROJECT "my_project") # Please replace my_project with your project folder name
+project(sibr_${SIBR_PROJECT}_app) # Please rename this project at your convenience
+
+file(GLOB SOURCES "*.cpp" "*.h" "*.hpp")
+source_group("Source Files" FILES ${SOURCES})
+
+# Define build output for project
+add_executable(${PROJECT_NAME} ${SOURCES})
+
+# Define dependencies
+target_link_libraries(${PROJECT_NAME}
+ ${Boost_LIBRARIES}
+ ${ASSIMP_LIBRARIES}
+ ${GLEW_LIBRARIES}
+ ${OPENGL_LIBRARIES}
+ ${OpenCV_LIBRARIES}
+ sibr_system
+
+ # you can add your internal or external dependencies here (sibr_renderer, sibr_view, sibr_graphics, sibr_assets,...)
+)
+
+# Define location in solution.
+set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "projects/${SIBR_PROJECT}/apps")
+
+## High level macro to install in an homogen way all our ibr targets
+include(install_runtime)
+ibr_install_target(${PROJECT_NAME}
+ INSTALL_PDB ## mean install also MSVC IDE *.pdb file (DEST according to target type)
+ STANDALONE ${INSTALL_STANDALONE} ## mean call install_runtime with bundle dependencies resolution
+ COMPONENT ${PROJECT_NAME}_install ## will create custom target to install only this project
+)
+@endcode
+
+@section scripts_sec Scripts projects
+
+You can also add scripts projects. Scripts are bundled in the install/scripts folder, which ensures you have access to utility functions and SIBR binaries.\n
+
+@code
+set(SIBR_PROJECT "my_project") # Please replace my_project with your project folder name
+project(sibr_${SIBR_PROJECT}_scripts)
+
+file(GLOB_RECURSE SCRIPTS "*.py") #add any scripts files / wildcards here
+
+add_custom_target(${PROJECT_NAME} ALL)
+
+include(install_runtime)
+set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "projects/${SIBR_PROJECT}/preprocess")
+ibr_install_rsc(${PROJECT_NAME} TYPE "scripts" FILES ${SCRIPTS} RELATIVE) # you can use FOLDER option if you want the scripts to be stored in a specific folder
+@endcode
+
+@section lib_sec Library project
+
+This example can be used for libraries, in `renderer\CMakeLists.txt`.\n
+The parts to modify are the project name, the linked libraries, the export/import flag for Windows libraries, and the folder property. \n
+Put the `CMakeLists.txt` in your library project directory.\n
+This example also supports displaying shaders and copying them to the bin/resources common directory.
+
+@code
+set(SIBR_PROJECT "my_project")
+project(sibr_${SIBR_PROJECT}) # Please rename this project at your convenience
+
+file(GLOB SOURCES "*.cpp" "*.h" "*.hpp")
+source_group("Source Files" FILES ${SOURCES})
+
+file(GLOB SHADERS "shaders/*.frag" "shaders/*.vert" "shaders/*.geom" "shaders/*.fp" "shaders/*.vp" "shaders/*.gp")
+source_group("Source Files\\shaders" FILES ${SHADERS})
+
+# Redefine sources and all the files to display in the IDE.
+file(GLOB SOURCES "*.cpp" "*.h" "*.hpp" "shaders/*.frag" "shaders/*.vert" "shaders/*.geom" "shaders/*.fp" "shaders/*.vp" "shaders/*.gp")
+
+# Declare library.
+add_library(${PROJECT_NAME} SHARED ${SOURCES})
+
+# Define dependencies.
+include_directories(${Boost_INCLUDE_DIRS} .)
+target_link_libraries(${PROJECT_NAME}
+ ${Boost_LIBRARIES}
+ ${ASSIMP_LIBRARIES}
+ ${GLEW_LIBRARIES}
+ ${OPENGL_LIBRARIES}
+ ${OpenCV_LIBRARIES}
+ glfw3
+ sibr_system
+
+ # you can add your internal or external dependencies here (sibr_renderer, sibr_view, sibr_graphics, sibr_assets,...)
+)
+
+# Define export/import flag.
+add_definitions( -DSIBR_MY_LIBRARY_EXPORTS -DBOOST_ALL_DYN_LINK ) # Please refactor it with your library export/import flag from Config.hpp
+
+# Define location in solution.
+set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "projects/${SIBR_PROJECT}/renderer")
+
+## High level macro to install in an homogen way all our ibr targets
+include(install_runtime)
+ibr_install_target(${PROJECT_NAME}
+ INSTALL_PDB ## mean install also MSVC IDE *.pdb file (DEST according to target type)
+ SHADERS "${SHADERS}" ## You can also add scripts and resources with the corresponding keyword (SCRIPTS, RESOURCES)
+ RSC_FOLDER "${SIBR_PROJECT}" ## Resources will be stored in this subfolder in their respective resource folder (scripts, shaders, resources)
+ COMPONENT ${PROJECT_NAME}_install ## will create custom target to install only this project
+)
+@endcode
+
+To handle export/import of library methods properly on Windows, you also need a `Config.hpp` file in your library directory.
+
+@code
+#ifndef __SIBR_MY_LIBRARY_CONFIG_HPP__ // Please refactor it with your library name
+# define __SIBR_MY_LIBRARY_CONFIG_HPP__ // Please refactor it with your library name
+
+# include
+
+# ifdef SIBR_OS_WINDOWS
+# ifdef SIBR_STATIC_DEFINE
+# define SIBR_EXPORT
+# define SIBR_NO_EXPORT
+# else
+# ifndef SIBR_MY_LIBRARY_EXPORT // Please refactor it with your library name
+# ifdef SIBR_MY_LIBRARY_EXPORTS // Please refactor it with your library name
+/* We are building this library */
+# define SIBR_MY_LIBRARY_EXPORT __declspec(dllexport) // Please refactor it with your library name
+# else
+/* We are using this library */
+# define SIBR_MY_LIBRARY_EXPORT __declspec(dllimport) // Please refactor it with your library name
+# endif
+# endif
+# ifndef SIBR_NO_EXPORT
+# define SIBR_NO_EXPORT
+# endif
+# endif
+# else
+# define SIBR_MY_LIBRARY_EXPORT // Please refactor it with your library name
+# endif
+
+#endif //__SIBR_MY_LIBRARY_CONFIG_HPP__ // Please refactor it with your library name
+
+@endcode
+ */
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Creating_your_library.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Creating_your_library.dox
new file mode 100644
index 0000000000000000000000000000000000000000..19b7d11faf8bd77e538fd6a3cf1814ed05473a23
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Creating_your_library.dox
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page create_library Creating your library
+
+@ingroup setup_project
+
+@section ge_setup_library General setup
+
+The content of your library would basically be up to what you will need in this specific project.\n
+However, we do implement core patterns that could be useful to create your view and handle the rendering of your scene.
+
+@section library_views Views
+
+basic example of a View:
+
+see:
+- https://gitlab.inria.fr/mbenadel/sibr_simple/-/blob/master/renderer/SimpleView.hpp
+- https://gitlab.inria.fr/mbenadel/sibr_simple/-/blob/master/renderer/SimpleView.cpp
+
+@section library_renderers Renderers
+
+basic example of a Renderer:
+
+see:
+- https://gitlab.inria.fr/mbenadel/sibr_simple/-/blob/master/renderer/SimpleRenderer.hpp
+- https://gitlab.inria.fr/mbenadel/sibr_simple/-/blob/master/renderer/SimpleRenderer.cpp
+
+@section library_shaders Shaders
+
+Shaders copy to binary folder is handled by the library CMake.\n
+You can put your shaders files in `renderer/shaders` with the following extensions:
+
+- `.vert`
+- `.frag`
+- `.geom`
+- `.vp`
+- `.fp`
+- `.gp`
+
+If unchanged, those shaders should be copied to `install/bin/shaders_rsc`.\n
+To extend this behavior, please update `renderer/CMakeLists.txt`.
+
+ */
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Documenting_a_project.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Documenting_a_project.dox
new file mode 100644
index 0000000000000000000000000000000000000000..e9d974bc860eb7f8d31ec32329e58ef4e43e9308
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Documenting_a_project.dox
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+ /*!
+@page document_project Documenting projects
+
+@ingroup setup_project
+
+@section gendoc Writing
+Each class created in one of the core SIBR modules (system, assets,...) should be properly documented.
+Please try to document as many methods as possible (especially public ones). Don't forget to add each class to its module .
+You will find below an example of a commented class.
+
+@verbatim
+ /* Represents a general view.
+ @ingroup sibr_view
+ */
+ class SIBR_MY_LIBRARY_EXPORT MyView {
+ public:
+
+ /* Loads everything.
+ @param flags the options to use.
+ @return a boolean denoting the success of the operation.
+ */
+ bool load(const int flags);
+
+ MyView();
+ ~MyView();
+
+ private:
+
+ /* Performs complex operations.
+ @param val the value to use.
+ */
+ void performComplexOps(const float val);
+
+ int _flags; ///< configuration flags
+ sibr::Vector2i _size; ///< The size of the view.
+ }
+@endverbatim
+
+
+If you need to create a new module and want it to appear in the Modules doxygen listing, you will need to create a `sibr_mymodule.dox` file in your module directory, with the following content:
+
+@verbatim
+/*!
+ @defgroup sibr_mymodule
+
+ @brief This is my module.
+
+ This is a longer description of my module. It's mine.
+*/
+@endverbatim
+
+You can also write general .dox pages to give more details on a process or a project.\n
+Please add them to your project `documentation/` folder.\n
+Here is an example of a dox file content:\n
+
+@verbatim
+/*!
+@page yourPageReference Your Page Name
+
+This is a Page.\n
+
+You can add ref to pages like this : @ref anotherPage\n
+Or add a link to a subpage like this : @subpage yetAnotherPage\n
+*/
+@endverbatim
+
+You can automatically link them as subpages in docs/pages/Projects.dox by providing a `_doc.cmake` file in your project `documentation/` folder.\n
+Here you can see an example:\n
+
+@verbatim
+/*!
+set(PROJECT_PAGE "yourPageReference")
+set(PROJECT_LINK "https://the.link.to.your.source.code.for.instance")
+set(PROJECT_DESCRIPTION "A short description")
+set(PROJECT_TYPE "OTHER") # this could be either SAMPLES, TOOLBOX, OURS or OTHERS. If not affiliated to SIBR, you might want to use OTHERS or TOOLBOX
+*/
+@endverbatim
+
+@section compileDoc Generating
+
+To generate the documentation, enable the BUILD_DOCUMENTATION flag in cmake and build the DOCUMENTATION target in Visual Studio. The generated output html pages will be accessible from intall/docs/index.html .
+
+*/
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Project_structure.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Project_structure.dox
new file mode 100644
index 0000000000000000000000000000000000000000..905fb2a9c148a8e3751c4d422c11e702cec96688
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How to setup your own project/Project_structure.dox
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page project_structure Project Structure
+
+@ingroup setup_project
+
+@section gen_struct General structure
+
+- Projects should follow the following hierarchy:
+
+@verbatim
+ apps/
+ CMakeLists.txt # for listing apps to compile
+ my_app_1/ # one of your apps, named at your convenience
+ CMakeLists.txt
+ main.cpp
+ my_app_2/
+ CMakeLists.txt
+ main.cpp
+ preprocess/
+ CMakeLists.txt # for listing preprocesses to compile
+ my_preprocess_1/ # one of your preprocesses, named at your convenience
+ CMakeLists.txt
+ main.cpp
+ my_preprocess_2/
+ CMakeLists.txt
+ main.cpp
+ renderer/
+ CMakeLists.txt # for compiling your library
+ my_library_code.cpp
+ documentation/ # you can add optional documentation pages in this folder
+ my_doc.dox
+ CMakeLists.txt # project-wide configuration
+@endverbatim
+
+- `renderer/`: contains your library code and configuration
+- `preprocess/`: contains your preprocesses listed by directory, and the configuration CMake file to list them
+- `apps/`: contains your apps listed by directory, and the configuration CMake file to list them
+- `documentation/`: contains additional doxygen documentation
+
+*/
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_generate_your_dataset.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_generate_your_dataset.dox
new file mode 100644
index 0000000000000000000000000000000000000000..131a9714dfea36dc1c0e9c6f3c074a8914545999
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_generate_your_dataset.dox
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page howto_generate_dataset Dataset Structure and Generation
+
+Most *Projects* take as input a *multi-view dataset*, i.e., a set of images taken using a camera (phone, DSLR, videocamera such as GoPro etc). In almost all cases we assume that a Structure-from-Motion (SfM) algorithm has been run on the input images to generate *calibrated cameras*, and most often a second Multi-View Stereo (MVS) step has been run, to generate a reconstructed 3D mesh. Optionally, we may also use dense depth maps that come from MVS.
+
+In **SIBR** we have a ``native'' dataset format, described below, which was used traditionally for some of the original *Projects*. For most recent projects we have used the commercial tool RealityCapture for SfM/MVS, since it tends to produce the best overall reconstruction quality. In some recent projects (e.g., DeepBlending, or SemanticCars, see @ref projects), we have used *Colmap*, since the dense per-view depth maps are very useful.
+
+As a result, **SIBR** supports two types of dataset natively:
+
+ @li Native **SIBR** datasets, created using the tools described below, from RealityCapture or Colmap.
+We provide pre-processing documentation following which you can create SIBR compatible datasets from output of these two SfM/MVS systems:
+ - @subpage HowToCapreal
+ - @subpage HowToColmap
+
+ @li Native Colmap datasets: we simply create a metadata file the first time the dataset is read.
+
+Different *Projects* often add additional information to their datasets, typically via multiple pre-processing utilities, some general, some specific to the *Project*.
+Python scripts designed to process and prepare datasets are provided with each project along with instructions on how to use them in the corresponding documentation.
+
+@section howto_generate_dataset_sibr_format Basic SIBR Dataset Structure and Generation
+
+There are two main ways to generate a dataset for **SIBR**. The first is to use *colmap* (see @ref HowToColmap) to to SfM/MVS, and the second is using the commercial RealityCapture package (see @ref HowToCapreal).
+
+After running colmap
**SIBR** can read the dataset natively. In this case the dataset will just contain the colmap
directory:
+```
+\dataset\
+\dataset\colmap\
+\dataset\colmap\sparse
+\dataset\colmap\dataset.db
+\dataset\colmap\stereo
+\dataset\colmap\stereo\images
+\dataset\colmap\stereo\sparse
+
+```
+SIBR expects camera calibration to be in colmap\stereo\sparse
, and the MVS mesh in colmap\stereo\meshed-delaunay.ply
.
+Note that in this case, the images *do not have the same size*. Some IBR algorithms (e.g., ULR) can handle this, but others require that the input images all have the same size; this was historically the case for [Chaurasia 13], and **SIBR** handles this natively.
+
+Specifically, we run the colmap2sibr
script to generate an **SIBR** dataset.
+The basic structure of this **SIBR** dataset is shown below, generated from colmap with texture:
+\n
+
+```
+\dataset\
+\dataset\colmap\
+\dataset\sibr_cm\scene_metadata.txt
+\dataset\sibr_cm\cameras
+\dataset\sibr_cm\meshes
+\dataset\sibr_cm\images
+\dataset\sibr_cm\cameras\bundle.out
+\dataset\sibr_cm\cameras\list_images.txt
+\dataset\sibr_cm\images\{img00000000.jpg,...,img000000NN.jpg}
+\dataset\sibr_cm\meshes\recon.{ply,obj}
+\dataset\capreal\
+\dataset\capreal\mesh.ply
+\dataset\capreal\texture.png
+```
+
+\n
+
+The native **SIBR** directory structure in sibr_cm
is as follows.
+The colmap
directory contains the colmap reconstruction, with the calibration, depthmap and mesh data.
+
+The capreal
directory contains the textured mesh generated by the conversion pipeline.
+
+In the sibr_cm
subdirectory:
+
+@li The *cameras* directory contains the calibrated cameras, using the *Bundler* format by default (\ref subsecDataSetFormatsBundle).
+
+@li The *images* directory that contains the undistorted images from the reconstruction and the list images file (\ref subsecDataSetFormatsListImg)
+
+@li The *meshes* directory that contains a *recon.ply* file that is the 3D reconstruction of the scene
+\n
+
+
+To generate a dataset after following the procedure for RealityCapture (@ref HowToCapreal), you need to perform the following steps:
+
+@li Generate and build the solution to generate executables for preprocessing applications (unless you already have the binary distribution).
+@li Go to `install\scripts`
+@li Run the python script using
+```
+python ibr_preprocess_rc_to_sibr.py -i original_dataset_path -o original_dataset_path\sibr_rc --bin path_to_sibr_bin
+```
+@li Specifying the binaries directory is optional. While compiling cmake automatically generates settings file which is parsed by the script to set bin directory.
+@li The script calls the distordCrop, cropFromCenter, and clipping_planes app executables; make sure they are up to date.
+ - They crop the images to remove the black borders; the --ratio parameter to distordCrop (currently 0.2 (/.5)) sets the percentage of border which can be removed. Images that have larger black borders are removed from the dataset.
+ - They also copy the meshes (ply and obj if available) and modifies the bundle.out and list_images.txt to the new values of resolution, and removes the images excluded (the numbers can be found in Dataset\\SibrData\\raw\\excluded_images.txt)
+ - Next they compute the clipping planes for each camera corresponding to input images and stores them in a clipping_planes.txt file.
+ - Finally, they parse all data to create a scene_metadata.txt file which holds information of the images, clipping planes etc. and is used to create the scene. This file can be manually extended.
+@li *[Recommended]* If you do not want to create a copy of the dataset, you can only specify the input directory with -i option. The dataset will be generated within the input directory itself.
+\n
+
+The **SIBR** dataset will have the following structure, similar to the case above, but with sibr_rc
instead of sibr_cm
.
+
+```
+\dataset\
+\dataset\sibr_rc\scene_metadata.txt
+\dataset\sibr_rc\cameras
+\dataset\sibr_rc\meshes
+\dataset\sibr_rc\images
+\dataset\sibr_rc\cameras\bundle.out
+\dataset\sibr_rc\cameras\list_images.txt
+\dataset\sibr_rc\images\{img000.jpg,...,img0NN.jpg}
+\dataset\sibr_rc\meshes\recon.ply
+\dataset\sibr_rc\meshes\recon.ply
+\dataset\capreal\
+\dataset\capreal\textured.obj
+\dataset\capreal\textured.mtl
+\dataset\capreal\textured_u1_v1.png
+```
+\n
+ \subsection subsecInputDatasetFilesFormats Dataset Files and Formats
+\n
+ The following sections contain documentation of the various files used in the dataset. Some are inherited from other SfM/MVS solutions.
+\subsection subsecMetadataFile The scene_metadata.txt file
+
+Contains the list of images and their resolution as well as the near and far planes for each images.
+\n
+ \subsection subsecDataSetFormatsBundle The bundle.out file
+\n
+ Content: [the bundler documentation](http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html) explain all what it contain \n
+ Description: [the output of the bundler](http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html#S6) \n
+ Bundle file format is in plain text :\n
+ ~~~~~~~~~~~~~{.txt}
+ # Bundle file v0.3
+ [two integers]
+
+
+ ...
+
+
+
+ ...
+
+ ~~~~~~~~~~~~~
+ Where \ contain :
+ ~~~~~~~~~~~~~{.txt}
+ [the focal length, followed by two radial distortion coeffs]
+ [a 3x3 matrix representing the camera rotation]
+ [a 3-vector describing the camera translation]
+ ~~~~~~~~~~~~~
+ And where \ contain :
+ ~~~~~~~~~~~~~{.txt}
+ [a 3-vector describing the 3D position of the point]
+ [a 3-vector describing the RGB color of the point]
+ [a list of views the point is visible in]
+ ~~~~~~~~~~~~~
+
+
+ \subsection subsecDataSetFormatsListImg The list_images.txt file
+ Content: It a list of all input images sorted by order it was taken (renamed) with their resolution \n
+ Description: If you have [ImageMagick](http://www.imagemagick.org/script/command-line-options.php#format_identify_) you can do : `identify -format "%f %w %h\n" *.jpg` \n
+ ~~~~~~~~~~~~~{.txt}
+ <%8d.jpg>
+ ~~~~~~~~~~~~~
+ Example:
+ ~~~~~~~~~~~~~{.txt}
+ 00000000.jpg 2256 1504
+ 00000001.jpg 2256 1504
+ 00000002.jpg 2256 1504
+ ...
+ 00000026.jpg 2256 1504
+ 00000027.jpg 2256 1504
+ ~~~~~~~~~~~~~
+ */
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_setup_your_own_project.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_setup_your_own_project.dox
new file mode 100644
index 0000000000000000000000000000000000000000..375ae4b0eeab68f5eba78990f7209416fba62858
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/How_to_setup_your_own_project.dox
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page howto_setup_project How to setup your own project
+
+- @subpage project_structure
+- @subpage configure_project
+- @subpage create_library
+- @subpage document_project
+
+ */
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Paths_and_cameras.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Paths_and_cameras.dox
new file mode 100644
index 0000000000000000000000000000000000000000..399438d3b1dbda04036ee9c473103327b4f65332
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Paths_and_cameras.dox
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+/*!
+@page howto_cameras_paths Cameras, Paths and Dataset Alignment
+
+@section cameras_section Cameras
+
+Calibrated cameras come from the SfM method used. We support bundler .out
(http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html), Blender .lookat
, Colmap cameras.txt/images.txt
and to a certain extent VisualSFM .nvm
files.
+Each format has different constraints, and they are not always compatible. Internally, we convert to an sibr::InputCamera
data structure.
+
+
+@section paths_section Paths
+
+We can read paths, i.e., a sequence of cameras, in any of the above formats in the interactive viewers for most renderers, typically in the main "View" panel, and the "Load path" button. The path can be played either by interpolated between the views ("Play" button), or just playing the exact cameras ("Play (No Interp)"). We also have an internal .path
binary path format.
+You can define key cameras in the same menu using the "Add key" button.
+
+Paths can be played by most renderers by running the renderer in offscreen mode:
+```
+SIBR_renderer_app.exe --offscreen --pathFile path.(out|lookat|tst|path) [--outPath optionalOutputPath --noExit]
+```
+
+By default, the application exits when this operation is performed. Rendering the same path is the easiest way to compare different algorithms, and works for most of the *Projects* provided.
+
+
+@section align_section Aligning datasets and transforming paths
+
+We provide the alignMeshes
tools to align two different reconstructions of the same multi-view dataset, see also the dataset tools page (@ref sibr_projects_dataset_tools).
+If you need to align your dataset dataset2Align
(e.g., a colmap reconstruction) to a reference dataset refDataset
(e.g., a RealityCapture reconstruction) you can use the alignMeshes command (in install\bin
).
+*Important note: both datasets must have the same (or a subset of the same) images, calibrated cameras and a fully reconstructed mesh*
+```
+alignMeshes_rwdi.exe --path2Align dataset2Align --pathRef refDataset --out outputPath
+alignMeshes.exe --path2Align dataset2Align --pathRef refDataset --out outputPath
+```
+This will align the two datasets, and write the aligned mesh in outputPath
as well as the file transform.txt
that contains the transformation matrix of the dataset2Align
to refDataset
.
+
+Please note that alignMeshes may not manage to completely align meshes: please lalways compare the aligned mesh with the target (e.g., using meshlab). If alignmeshes fails, an alternative is to use a manual tool such as CloudCompare or meshlab.
+
+You can then transform a camera path defined in the first dataset to the a path in the reference dataset:
+
+```
+cameraConverter_rwdi.exe --input inputPath.(out|lookat|path|tst) --output outputPath.(out|lookat|path|tst)
+cameraConverter.exe --input inputPath.(out|lookat|path|tst) --output outputPath.(out|lookat|path|tst)
+```
+
+ */
diff --git a/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Useful_sibr_elements.dox b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Useful_sibr_elements.dox
new file mode 100644
index 0000000000000000000000000000000000000000..ca8bb85c25501a408505cfa84cae3a51eb78a49e
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/docs/pages/Tutorials/Useful_sibr_elements.dox
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+/*!
+@page howto_sibr_useful_objects Useful systems in SIBR
+
+@section multiviewmanager Using the windowing system
+
+SIBR provides tools to display multiple rendering algorithms in different subviews that can be resized and hidden on screen. This is handled by the `MultiViewManager`. once instantiated and tied to a system window, the multi view manager can keep track of multiple views, ensuring that their content is updated and that they receive the correct user inputs. Views can be hidden, resized, their content captured as a screenshot.
+
+Two modes can be used, mainly for legacy reasons:
+
+- IBR subviews, that have to implement onRenderIBR() (which was used to support anaglyph rendering previously)
+- basic subviews, that have to implement onRender()
+
+It is possible to associate an interactive user camera to a view, so that the user can move around in the displayed content. Two views can use the same handler, for synchronized motion.
+
+Basic example:
+
+@code
+Window window(PROGRAM_NAME, sibr::Vector2i(50, 50), myArgs);
+MultiViewManager manager(window, false);
+
+// Register a first view, with an interactive user camera
+MyView::Ptr myView(new MyView());
+InteractiveCameraHandler::Ptr userCam(new InteractiveCameraHandler());
+manager.addIBRSubView("My view", myView);
+manager.addCameraForView("My view", userCam);
+
+// Register another view, which already handles the user motions by itself
+DebugView::Ptr dbgView(new DebugView());
+manager.addSubView("Debug view", dbgView, usedResolution);
+
+while (window.isOpened()) {
+
+ Input::poll();
+ window.makeContextCurrent();
+ if (Input::global().key().isPressed(Key::Escape)) {
+ window.close();
+ }
+
+ manager.onUpdate(Input::global());
+ manager.onRender(window);
+
+ window.swapBuffer();
+}
+@endcode
+
+@image html multiviewmanager.png
+
+@section interactiveHandler Interactive user camera
+
+User interaction in a view are handled by an `InteractiveCameraHandler`, that supports many interaction modes such as a FPS camera or a trackball.
+It can also snaps to predefined viewpoints or interpolate between them. You can adjust the field of view and frustum planes.
+You can toggle between modes in the GUI or by pressing Y.
+
+- FPS : move around with WASD, down/up with Q/E, rotate with IJKL and roll with U/O.
+- Trackball : rotate around a central point with the left click in the center of the view, roll with left click towards the view edges. Pan with righ click in the center region, move forward/backward with right click towards the view edges, or by scrolling. Ctrl+left click redefines the center of the trackball, this is very useful to focus on a specific region of the scene and zoom in.
+- Orbit: rotate around using the numeric keypad.
+
+@subsection recordPaths Recording and replaying camera paths
+
+The handler can also records and playback paths. Once the `Record` button is pressed, all user camera motions are recorded. When pressing `Save path`, they will be saved to a file on disk. Types such as `.lookat`, `.path` and `.bundle` are supported, which is useful for comparison with other frameworks. A `.path` can be reloaded using the `Load path` button, and will start playing automatically.
+
+@subsection recordVideos Generating videos
+
+It is possible to record videos and dump images following a path in a view. In the camera handler GUI, you can check if you want to record videos or frames. If checked, the next start a path starts playing, each frame will be recorded and saved on disk.
+
+- for video recording, check the corresponding box, start playing the path. At the end, in the view manager, select "Capture > Export video" and select the output destination (supported export format: h264 with `.mp4` extension).
+- for frames recording, hen checking the box you will have to select an output directory. once the path starts to play, frames are going to be saved in the directory.
+
+@section debugview Visualizing debug geometry
+
+It can be useful to visualize information such as the scene geometry, location of the cameras, rays, voxel-like structures in a view with an interactive camera. SIBR provides the `MultiMeshManager` for this prupose. It can be used to display multiple meshes, vertices, lines,... At runtime, a list of all elements is displayed and many attributes can be toggled. The same attributes can be edited from the code using chaining. Everything can be updated on the fly based on the objects names.
+For instance:
+
+@code
+debugView.addMeshAsLines("BBox", bbox).setColor({1.0f, 0.0f, 1.0f}).setDepthTest(false).setColormode(USER_DEFINED);
+// Later in the code
+debugView.addMeshAsLines("BBox", anotherBbox); // will replace the previous mesh
+// Later again
+debugView.getMeshData("BBox").setAlpha(0.5f); // dim the box
+@endcode
+
+Because the MultiMeshManager conforms to the ViewBase interface, it can be added to the view manager as any other view. It comes with its own interactive camera.
+
+@note The `SceneDebugView` that can be used to visualize an IBR dataset including the geometry, cameras and images, is built on top of `MultiMeshManager`, with extra code generating geometry for the frusta and the image quads.
+
+@image html multimeshmanager.png
+
+@section commandlineargs Command line arguments
+
+To simplify the definition and parsing of arguments, SIBR provide tools to easily define and populate arguments. The system is based on `Arg` and `RequiredArg`, that can be used to define arguments anywhere. It is recommended to group them in a structure, especially as some existing structures can be reused to define command arguments (windowing options, dataset path, etc., see for instance `WindowAppArgs` or `BasicDatasetArgs`).
+
+Before anything, you have to make sure the raw input arguments have been parsed by calling `CommandLineArgs::parseMainArgs(argc, argv);` in your main. Any argument instantiated afterwards will then be able to fetch its user-provided value (if it exists). Default values and help messages can be provided when declaring arguments. Required arguments will raise an error when used if the user did not provide a value.
+
+Arguments will convert to their contained type when using them, it is also possible to access their value using `get()`. Arguments values can also be set directly in the code.
+
+@code
+struct MyArgs : virtual WindowAppArgs, BasicDatasetArgs {
+ RequiredArg iterations = {"itcount", 5, "Number of smoothing iterations"};
+ Arg logPath = {"log", "", "Path to log file"};
+ Arg showResult = {"show", "Display results in a popup window"};
+}
+
+int main(int argc, char** argv){
+ CommandLineArgs::parseMainArgs(argc, argv);
+ MyArgs args;
+ const std::string logFile = args.logPath.get() + "_test.log";
+ Thing(args.iterations, logFile);
+ if(args.showResult){
+ //...
+ }
+}
+@endcode
+
+
+@section uniformsystem The uniform system
+
+When using OpenGL shaders, values are often passed from the CPU using uniforms. In the past, SIBR required the developer to maintain both a GLParameter object and the corresponding variable on the CPU to store the value and expose it. It is now recommended to use GLUniform, that wraps a CPU value while allowing you to update the GPU uniform easily. The GLUniform will automatically converts to its contained type in most cases ; if a reference to the CPU value is needed, you can use get().
+
+@code
+// In the header, as members of a renderer for instance
+GLShader _shader;
+GLuniform _val = 0.5;
+
+// At construction
+_shader.init("My Shader", "vertex shader content", "fragment shader content");
+_val.init(_shader, "alpha"); // link the uniform to the shader, specify the name in the shader code
+
+// At some point in the code
+_val += 0.3f; // Mofidy the CPU value
+
+// In the render loop
+_shader.begin();
+_val.send(); // Send to the GPU
+...
+@endcode
+
+
+ */
\ No newline at end of file
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/CMakeLists.txt b/extensions/RaDe-GS/SIBR_viewers/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bc80ee304e3a4bb11eff633d94994b871d3e089b
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/CMakeLists.txt
@@ -0,0 +1,176 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+################################################################################
+# This CMakeLists.txt manages which projects should be built and add their #
+# dependencies. #
+################################################################################
+set(SIBR_FOLDER "core")
+set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "")
+
+option(BUILD_SIBR "Build core libs of SIBR (sibr_system, sibr_graphics, sibr_view, sibr_assets, ...)" ON)
+
+#https://stackoverflow.com/questions/7787823/cmake-how-to-get-the-name-of-all-subdirectories-of-a-directory
+MACRO(SUBDIRLIST result curdir)
+ FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
+ SET(dirlist "")
+ foreach(child ${children})
+ IF(IS_DIRECTORY ${curdir}/${child})
+ LIST(APPEND dirlist ${child})
+ ENDIF()
+ endforeach()
+ SET(${result} ${dirlist})
+ENDMACRO()
+
+set(SIBR_PROJECTS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/projects")
+SUBDIRLIST(SUBDIRS ${SIBR_PROJECTS_FOLDER})
+
+list(APPEND PROJECT_SUBFOLDERS "apps" "preprocess" "renderer" "scripts" "library")
+
+# Moving ulr to the top of the list
+list(PREPEND SUBDIRS "dataset_tools" "ulr" "basic")
+list(REMOVE_DUPLICATES SUBDIRS)
+
+## DEPS ##
+include(include_once)
+
+message(STATUS "\n\n****************** Handling core dependencies ******************")
+
+include_once(dependencies) ## Map/bind 3rdParty/external dependencies packages to cmake
+
+message(STATUS "****************************************************************\n\n")
+
+foreach(subdir ${SUBDIRS})
+ set(${subdir}_ROOT_DIR "${SIBR_PROJECTS_FOLDER}/${subdir}")
+ set(PROJECT_NAME "BUILD_IBR_${subdir}")
+ string(TOUPPER ${PROJECT_NAME} PROJECT_NAME)
+ if(${${PROJECT_NAME}})
+ foreach(PROJECT_SUBFOLDER ${PROJECT_SUBFOLDERS})
+ if(EXISTS "${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/cmake/Modules")
+ list(APPEND CMAKE_MODULE_PATH ${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/cmake/Modules)
+ endif()
+
+ if(EXISTS "${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/cmake/dependencies.cmake")
+ message(STATUS "********* Handling ${subdir} ${PROJECT_SUBFOLDER} dependencies *********")
+ include_once("${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/cmake/dependencies.cmake")
+
+ message(STATUS "****************************************************************\n\n")
+ endif()
+ endforeach()
+ endif()
+endforeach()
+
+Win3rdPartyGlobalCacheAction()
+
+include_directories(.)
+
+if (BUILD_SIBR)
+ add_subdirectory(core/system)
+ add_subdirectory(core/graphics)
+ add_subdirectory(core/renderer)
+ add_subdirectory(core/raycaster)
+ add_subdirectory(core/view)
+ add_subdirectory(core/scene)
+ add_subdirectory(core/assets)
+ add_subdirectory(core/imgproc)
+ add_subdirectory(core/video)
+endif()
+
+set(PROJECTS_ON_AT_FIRST_BUILD "basic" "gaussianviewer" "remote")
+
+foreach(subdir ${SUBDIRS})
+ message(STATUS "Adding ${subdir} project")
+ set(PROJECT_NAME "BUILD_IBR_${subdir}")
+ string(TOUPPER ${PROJECT_NAME} PROJECT_NAME)
+
+ if(NOT (DEFINED ${PROJECT_NAME}))
+ foreach(PROJECT_SUBFOLDER ${PROJECT_SUBFOLDERS})
+ if(EXISTS "${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/CMakeLists.txt")
+ if(subdir IN_LIST PROJECTS_ON_AT_FIRST_BUILD)
+ option(${PROJECT_NAME} "Build project \"${subdir}\"" ON)
+ else()
+ option(${PROJECT_NAME} "Build project \"${subdir}\"" OFF)
+ endif()
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ message(STATUS "${PROJECT_NAME} is ${${PROJECT_NAME}}")
+
+ if(${${PROJECT_NAME}})
+ if(EXISTS "${${subdir}_ROOT_DIR}/CMakeLists.txt")
+ add_subdirectory("${${subdir}_ROOT_DIR}")
+ else()
+ foreach(PROJECT_SUBFOLDER ${PROJECT_SUBFOLDERS})
+ if(EXISTS "${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}/CMakeLists.txt")
+ add_subdirectory("${${subdir}_ROOT_DIR}/${PROJECT_SUBFOLDER}")
+ endif()
+ endforeach()
+ endif()
+
+ if(EXISTS "${${subdir}_ROOT_DIR}/documentation/" AND BUILD_DOCUMENTATION)
+ unset(PROJECT_PAGE)
+ unset(PROJECT_LINK)
+ unset(PROJECT_DESCRIPTION)
+ unset(PROJECT_TYPE)
+ include("${${subdir}_ROOT_DIR}/documentation/${subdir}_doc.cmake" OPTIONAL)
+
+ if(NOT DEFINED PROJECT_PAGE)
+ set(PROJECT_PAGE "${subdir}Page")
+ endif()
+
+ if(NOT DEFINED PROJECT_TYPE)
+ set(PROJECT_TYPE "OTHERS")
+ endif()
+
+ set(PROJECT_SUBPAGE_REF " - @subpage ${PROJECT_PAGE}")
+ set(PROJECT_REF_REF " - @ref ${PROJECT_PAGE}")
+
+ if(DEFINED PROJECT_LINK)
+ string(APPEND PROJECT_SUBPAGE_REF " (${PROJECT_LINK})")
+ string(APPEND PROJECT_REF_REF " (${PROJECT_LINK})")
+ endif()
+
+ if(DEFINED PROJECT_DESCRIPTION)
+ string(APPEND PROJECT_SUBPAGE_REF ": ${PROJECT_DESCRIPTION}")
+ string(APPEND PROJECT_REF_REF " (${PROJECT_DESCRIPTION})")
+ endif()
+
+ string(APPEND SIBR_PROJECTS_${PROJECT_TYPE}_SUBPAGE_REF_LOCAL "${PROJECT_SUBPAGE_REF}\n")
+ string(APPEND SIBR_PROJECTS_${PROJECT_TYPE}_REF_REF_LOCAL "${PROJECT_REF_REF}\n")
+
+ if(EXISTS "${${subdir}_ROOT_DIR}/documentation/img")
+ set(DOXY_APP_SPECIFIC_IMG_PATH_LOCAL "${DOXY_APP_SPECIFIC_IMG_PATH_LOCAL} ${${subdir}_ROOT_DIR}/documentation/img")
+ endif()
+
+ if(EXISTS "${${subdir}_ROOT_DIR}/LICENSE.md")
+ set(DOXY_DOC_EXCLUDE_PATTERNS_DIRS_LOCAL "${DOXY_DOC_EXCLUDE_PATTERNS_DIRS_LOCAL} ${${subdir}_ROOT_DIR}/LICENSE.md")
+ endif()
+ endif()
+ else()
+ set(DOXY_DOC_EXCLUDE_PATTERNS_DIRS_LOCAL "${DOXY_DOC_EXCLUDE_PATTERNS_DIRS_LOCAL} ${${subdir}_ROOT_DIR}")
+ endif()
+endforeach()
+
+set(SIBR_PROJECTS_SAMPLES_SUBPAGE_REF "${SIBR_PROJECTS_SAMPLES_SUBPAGE_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_OURS_SUBPAGE_REF "${SIBR_PROJECTS_OURS_SUBPAGE_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF "${SIBR_PROJECTS_TOOLBOX_SUBPAGE_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_OTHERS_SUBPAGE_REF "${SIBR_PROJECTS_OTHERS_SUBPAGE_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_SAMPLES_REF_REF "${SIBR_PROJECTS_SAMPLES_REF_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_OURS_REF_REF "${SIBR_PROJECTS_OURS_REF_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_TOOLBOX_REF_REF "${SIBR_PROJECTS_TOOLBOX_REF_REF_LOCAL}" PARENT_SCOPE)
+set(SIBR_PROJECTS_OTHERS_REF_REF "${SIBR_PROJECTS_OTHERS_REF_REF_LOCAL}" PARENT_SCOPE)
+set(DOXY_APP_SPECIFIC_IMG_PATH "${DOXY_APP_SPECIFIC_IMG_PATH_LOCAL}" PARENT_SCOPE)
+set(DOXY_DOC_EXCLUDE_PATTERNS_DIRS "${DOXY_DOC_EXCLUDE_PATTERNS_DIRS_LOCAL}" PARENT_SCOPE)
+
+if (BUILD_IBR_TFGL_INTEROP)
+ add_subdirectory(projects/tfgl_interop/renderer/custom_ops)
+endif()
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ActiveImageFile.cpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ActiveImageFile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..18fa9e826729f29849162b39365d85f3fee056ec
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ActiveImageFile.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+# include
+# include
+# include "core/assets/ActiveImageFile.hpp"
+
+namespace sibr
+{
+ bool ActiveImageFile::load( const std::string& filename, bool verbose )
+ {
+
+ std::fstream file(filename, std::ios::in);
+ if(_numImages == 0 )
+ SIBR_WRG << "No Images Loaded while loading '"<> imageId;
+ _active[imageId] = true;
+ }
+
+ if( verbose )
+ SIBR_FLOG << "'"<< filename <<"' successfully loaded." << std::endl;
+ else
+ std::cerr<< "." ;
+ return true;
+ }
+ else {
+ for(int i=0; i < _numImages; i++)
+ _active[i]=true;
+ if( verbose )
+ SIBR_WRG << "file not found: '"<& active( void ) const { return _active; }
+
+
+ private:
+ std::vector _active; ///< Flags denoting which images are active.
+ int _numImages = 0; ///< Number of images.
+
+ };
+
+
+} // namespace sibr
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CMakeLists.txt b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e68317caab93bc0366ce0a25702a764c05cb3d91
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+
+
+project(sibr_assets)
+
+file(GLOB SOURCES "*.cpp" "*.h" "*.hpp" )
+source_group("Source Files" FILES ${SOURCES})
+
+file(GLOB SOURCES "*.cpp" "*.h" "*.hpp")
+
+
+## Specify target rules
+add_library(${PROJECT_NAME} SHARED ${SOURCES})
+
+include_directories(
+ ${Boost_INCLUDE_DIRS}
+ ${xatlas_INCLUDE_DIRS}
+)
+target_link_libraries(${PROJECT_NAME}
+ ${Boost_LIBRARIES}
+ ${ASSIMP_LIBRARIES}
+ ${GLEW_LIBRARIES}
+ ${OPENGL_LIBRARIES}
+ ${OpenCV_LIBRARIES}
+ OpenMP::OpenMP_CXX
+ sibr_graphics
+ xatlas
+)
+
+add_definitions(-DSIBR_ASSETS_EXPORTS -DBOOST_ALL_DYN_LINK)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER ${SIBR_FOLDER})
+
+## High level macro to install in an homogen way all our ibr targets
+include(install_runtime)
+ibr_install_target(${PROJECT_NAME}
+ INSTALL_PDB ## mean install also MSVC IDE *.pdb file (DEST according to target type)
+)
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.cpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..598dcd91210adda85f548fe2f760e597dd580a8f
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+#include
+#include "core/assets/CameraRecorder.hpp"
+#include "core/assets/InputCamera.hpp"
+#include
+
+namespace sibr
+{
+ void CameraRecorder::use(Camera& cam)
+ {
+ if (_recording) {
+ _cameras.push_back(cam);
+ }
+ else if (_playing && _pos < _cameras.size() ) {
+ const float znear = cam.znear();
+ const float zfar = cam.zfar();
+
+ if( !_playNoInterp ) {
+ //std::cout << _playing << std::endl;
+ // If we reach the last frame of the interpolation b/w two cameras, skip to next camera.
+ if (_interp > (1.0f - _speed))
+ {
+ _interp = 0.0f;
+ _pos++;
+ }
+ // Interpolate between the two closest cameras.
+ const float k = std::min(std::max(_interp, 0.0f), 1.0f);
+
+ sibr::Camera & camStart = _cameras[std::min(int(_pos), int(_cameras.size()) - 1)];
+ sibr::Camera & camNext = _cameras[std::min(int(_pos) + 1, int(_cameras.size())-1)];
+
+ cam = sibr::Camera::interpolate(camStart, camNext, k);
+
+ _interp += _speed;
+ }
+ else {
+ cam = _cameras[_pos];
+ _pos++;
+ if (_pos == _cameras.size())
+ _playNoInterp = false;
+
+ }
+
+ // Preserve the znear and zfar.
+ cam.znear(znear);
+ cam.zfar(zfar);
+
+ if (_saving) {
+ std::ostringstream ssZeroPad;
+ ssZeroPad << std::setw(8) << std::setfill('0') << (_pos);
+ cam.setSavePath(_savingPath + "/" + ssZeroPad.str() + ".png");
+ //std::cout << "Saving frame as: " << cam.savePath() << std::endl;
+ }
+ if (_savingVideo) {
+ cam.setDebugVideo(true);
+ }
+ if (_pos >= _cameras.size())
+ {
+ stop();
+ SIBR_LOG << "[CameraRecorder] - Playback Finished" << std::endl;
+ }
+ }
+ else {
+ //std::cout << _playing << std::endl;
+ cam.setSavePath("");
+ cam.setDebugVideo(false);
+ }
+ }
+
+ void CameraRecorder::playback(void)
+ {
+ stop();
+ _playing = true;
+ SIBR_LOG << "[CameraRecorder] - Playing" << std::endl;
+ }
+
+ void CameraRecorder::record(void)
+ {
+ stop();
+ _recording = true;
+ SIBR_LOG << "[CameraRecorder] - Recording" << std::endl;
+ }
+
+ void sibr::CameraRecorder::saving(std::string savePath)
+ {
+ _saving = true;
+ _savingPath = savePath;
+ SIBR_LOG << "[CameraRecorder] - Recording" << std::endl;
+ }
+
+ void CameraRecorder::savingVideo(bool saveVideo)
+ {
+ _savingVideo = saveVideo;
+ }
+
+ void sibr::CameraRecorder::stopSaving(void)
+ {
+ _saving = false;
+ _savingPath = "";
+ }
+
+ void CameraRecorder::stop(void)
+ {
+ _recording = _playing = false;
+ _pos = 0;
+ _interp = 0.0f;
+ }
+
+ void CameraRecorder::reset(void)
+ {
+ stop();
+ _cameras.clear();
+ }
+
+ bool CameraRecorder::load(const std::string& filename)
+ {
+ reset();
+
+ sibr::ByteStream stream;
+
+ if (stream.load(filename) == false)
+ return false;
+
+ int32 num = 0;
+
+ std::cout << " CameraRecorder::load " << num << std::endl;
+
+ stream >> num;
+ while (num > 0)
+ {
+ Camera cam;
+ stream >> cam;
+ _cameras.emplace_back(std::move(cam));
+ --num;
+ }
+ SIBR_LOG << "[CameraRecorder] - Loaded from " << filename << std::endl;
+ return stream;
+ }
+
+ void CameraRecorder::save(const std::string& filename)
+ {
+ sibr::ByteStream stream;
+ int32 num = (int32)_cameras.size();
+ stream << num;
+ for (const Camera& cam : _cameras)
+ stream << cam;
+
+ stream.saveToFile(filename);
+ SIBR_LOG << "[CameraRecorder] - Saved " << num << " cameras to " << filename << std::endl;
+ }
+
+ bool CameraRecorder::safeLoad(const std::string & filename, int w, int h)
+ {
+ Path path = Path(filename);
+
+ if (path.extension().string() == ".out") {
+ loadBundle(filename, w, h);
+ return true;
+ } else if (path.extension().string() == ".path") {
+ return load(filename);
+ }
+ SIBR_WRG << "Unable to load camera path" << std::endl;
+ return false;
+ }
+
+ void CameraRecorder::loadBundle(const std::string & filePath, int w, int h)
+ {
+ const std::string bundlerFile = filePath;
+ SIBR_LOG << "Loading bundle path." << std::endl;
+
+ // check bundler file
+ std::ifstream bundle_file(bundlerFile);
+ SIBR_ASSERT(bundle_file.is_open());
+
+ // read number of images
+ std::string line;
+ getline(bundle_file, line); // ignore first line - contains version
+ int numImages = 0;
+ bundle_file >> numImages; // read first value (number of images)
+ getline(bundle_file, line); // ignore the rest of the line
+
+ std::vector cameras(numImages);
+ // Parse bundle.out file for camera calibration parameters
+ for (int i = 0; i < numImages; i++) {
+
+ Matrix4f m;
+ bundle_file >> m(0) >> m(1) >> m(2) >> m(3) >> m(4);
+ bundle_file >> m(5) >> m(6) >> m(7) >> m(8) >> m(9);
+ bundle_file >> m(10) >> m(11) >> m(12) >> m(13) >> m(14);
+
+ cameras[i] = InputCamera::Ptr(new InputCamera(i, w, h, m, true));
+
+ cameras[i]->znear(0.2f); cameras[i]->zfar(250.f);
+
+ }
+
+ for (const InputCamera::Ptr cam : cameras)
+ {
+ _cameras.push_back(*cam);
+ }
+
+ }
+
+ void CameraRecorder::loadColmap(const std::string &filePath, int w, int h)
+ {
+ SIBR_LOG << "Loading colmap path." << std::endl;
+ boost::filesystem::path colmapDir ( filePath );
+
+ SIBR_LOG << "DEBUG: colmap path dir " << colmapDir.parent_path().string() << std::endl;
+
+ std::vector path = InputCamera::loadColmap(colmapDir.parent_path().string(), float(0.01), 1000, false );
+ for (const InputCamera::Ptr cam : path)
+ {
+ _cameras.push_back(*cam);
+ }
+ }
+
+ void CameraRecorder::loadLookat(const std::string &filePath, int w, int h)
+ {
+ SIBR_LOG << "Loading lookat path." << std::endl;
+ std::vector path = InputCamera::loadLookat(filePath, std::vector{Vector2u(w, h)});
+ for (const InputCamera::Ptr cam : path)
+ {
+ _cameras.push_back(*cam);
+ }
+ }
+
+ void CameraRecorder::saveAsBundle(const std::string & filePath, const int height, const int step)
+ {
+
+ std::ofstream out(filePath.c_str(), std::ios::binary);
+ if (!out.good()) {
+ SIBR_LOG << "ERROR: cannot write to the file '" << filePath << "'" << std::endl;
+ return;
+ }
+
+ if(_cameras.empty()) {
+ return;
+ }
+
+ const int size = static_cast(_cameras.size() / step);
+
+ out << "# Bundle file v0.3\n";
+ out << size << " " << 0 << "\n";
+
+ for (int i = 0; i < _cameras.size(); i += step) {
+
+ const sibr::Camera cam = _cameras[i];
+ sibr::Quaternionf q = cam.rotation();
+ sibr::Matrix3f m1 = q.toRotationMatrix();
+ sibr::Vector3f pos = -m1.transpose() * cam.position();
+
+ float m[15];
+ m[0] = 0.5f*height / tan(cam.fovy() / 2.f); m[1] = 0.0f; m[2] = 0.0f;
+ m[3] = m1(0, 0), m[4] = m1(1, 0), m[5] = m1(2, 0);
+ m[6] = m1(0, 1), m[7] = m1(1, 1), m[8] = m1(2, 1);
+ m[9] = m1(0, 2), m[10] = m1(1, 2), m[11] = m1(2, 2);
+ m[12] = pos.x(), m[13] = pos.y(), m[14] = pos.z();
+
+ out << m[0] << " " << m[1] << " " << m[2] << std::endl;
+ out << m[3] << " " << m[4] << " " << m[5] << std::endl;
+ out << m[6] << " " << m[7] << " " << m[8] << std::endl;
+ out << m[9] << " " << m[10] << " " << m[11] << std::endl;
+ out << m[12] << " " << m[13] << " " << m[14] << std::endl;
+ }
+ out << std::endl;
+ out.close();
+
+ SIBR_LOG << "[CameraRecorder] - Saved " << _cameras.size() << " cameras to " << filePath << " (using fovy " <<_cameras[0].fovy() << ")." << std::endl;
+
+ }
+
+ void CameraRecorder::saveAsColmap(const std::string& filePath, const int height, const int width)
+ {
+
+ std::string basepath = parentDirectory(filePath);
+ std::cout << basepath << std::endl;
+ std::string images_filepath = basepath + "/images.txt";
+ std::string cameras_filepath = basepath + "/cameras.txt";
+
+ std::ofstream out_images(images_filepath.c_str(), std::ios::binary);
+ std::ofstream out_cameras(cameras_filepath.c_str(), std::ios::binary);
+
+ if (!out_images.good()) {
+ SIBR_LOG << "ERROR: cannot write to the file '" << filePath << "'" << std::endl;
+ return;
+ }
+ if (!out_cameras.good()) {
+ SIBR_LOG << "ERROR: cannot write to the file '" << filePath << "'" << std::endl;
+ return;
+ }
+
+ if (_cameras.empty()) {
+ return;
+ }
+
+ const int size = static_cast(_cameras.size());
+
+ sibr::Matrix3f converter;
+ converter << 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+
+
+
+ out_images << "# Image list with two lines of data per image:" << std::endl;
+ out_images << "# IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME" << std::endl;
+ out_images << "# POINTS2D[] as (X, Y, POINT3D_ID)" << std::endl;
+ for (int i = 0; i < _cameras.size(); i++) {
+ sibr::Matrix3f tmp = _cameras[i].rotation().toRotationMatrix() * converter;
+ sibr::Matrix3f Qinv = tmp.transpose();
+ sibr::Quaternionf q = quatFromMatrix(Qinv);
+ sibr::Vector3f t = converter * _cameras[i].rotation().toRotationMatrix().transpose() * (-_cameras[i].position());
+
+
+ out_images << i << " " << -_cameras[i].rotation().x() << " " << -_cameras[i].rotation().w() << " " << -_cameras[i].rotation().z() << " " << _cameras[i].rotation().y() << " " <<
+ _cameras[i].view()(0, 3) << " " << -_cameras[i].view()(1, 3) << " " << -_cameras[i].view()(2, 3) << " " << i << " " << "00000000.png" << std::endl << std::endl;
+
+ float focal = 0.5f * height / tan(_cameras[i].fovy() / 2.f);
+ //float focal = 1.0f / (tan(0.5f * cam.fovy()) * 2.0f / float(height));
+ out_cameras << i << " " << "PINHOLE" << " " << width << " " << height << " " << focal << " " << focal << " " << width / 2.0 << " " << height / 2.0 << std::endl;
+ }
+
+ out_images << std::endl;
+ out_images.close();
+ out_cameras << std::endl;
+ out_cameras.close();
+ SIBR_LOG << "[CameraRecorder] - Saved " << _cameras.size() << " cameras to " << filePath << " (using fovy " << _cameras[0].fovy() << ")." << std::endl;
+
+ }
+
+
+ void CameraRecorder::saveAsFRIBRBundle(const std::string & dirPath, const int width, const int height)
+ {
+ const std::string bundlepath = dirPath + "/path.rd.out";
+ const std::string listpath = dirPath + "/list.txt";
+ const std::string imagesDir = dirPath + "/visualize/";
+ sibr::makeDirectory(dirPath);
+ sibr::makeDirectory(imagesDir);
+ std::ofstream out(bundlepath);
+ std::ofstream outList(listpath);
+ if (out.good() && outList.good()) {
+ const int size = static_cast(_cameras.size() / 1);
+ out << "# Bundle file v0.3\n";
+ out << size << " " << 0 << "\n";
+ sibr::Matrix3f converter;
+ converter << 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+ sibr::Matrix3f from_cv;
+ from_cv << 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+ for (int i = 0; i < _cameras.size(); ++i) {
+
+ const sibr::Camera cam = _cameras[i];
+
+ sibr::Matrix3f orientation = cam.rotation().toRotationMatrix();
+ sibr::Vector3f position = cam.position();
+ sibr::Matrix3f rotation_cv = converter.transpose() * orientation.transpose() * converter;
+ sibr::Matrix3f rotation_bundler = from_cv * rotation_cv;
+ sibr::Vector3f position_cv = converter.transpose() * position;
+ sibr::Vector3f translation_cv = -(rotation_cv * position_cv);
+ sibr::Vector3f pos = from_cv * translation_cv;
+
+ sibr::Matrix3f m1 = rotation_bundler.transpose();
+ float m[15];
+ m[0] = 0.5f*height / tan(cam.fovy() / 2.f); m[1] = 0.0f; m[2] = 0.0f;
+ m[3] = m1(0, 0), m[4] = m1(1, 0), m[5] = m1(2, 0);
+ m[6] = m1(0, 1), m[7] = m1(1, 1), m[8] = m1(2, 1);
+ m[9] = m1(0, 2), m[10] = m1(1, 2), m[11] = m1(2, 2);
+ m[12] = pos.x(), m[13] = pos.y(), m[14] = pos.z();
+ out << m[0] << " " << m[1] << " " << m[2] << std::endl;
+ out << m[3] << " " << m[4] << " " << m[5] << std::endl;
+ out << m[6] << " " << m[7] << " " << m[8] << std::endl;
+ out << m[9] << " " << m[10] << " " << m[11] << std::endl;
+ out << m[12] << " " << m[13] << " " << m[14] << std::endl;
+
+ const std::string imageName = sibr::intToString<8>(i) + ".jpg";
+ outList << "visualize/" + imageName << " 0 " << m[0] << std::endl;
+
+ cv::Mat3b dummy(height, width);
+ cv::imwrite(imagesDir + imageName, dummy);
+ }
+ out << std::endl;
+ out.close();
+ outList.close();
+
+ SIBR_LOG << "[CameraRecorder] - Saved " << _cameras.size() << " cameras to " << dirPath << "." << std::endl;
+ }
+ }
+
+ void CameraRecorder::saveAsLookAt(const std::string & filePath) const
+ {
+ InputCamera::saveAsLookat(_cameras, filePath);
+ }
+
+ // offline path rendering
+ bool CameraRecorder::loadPath(const std::string& pathFileName, int w, int h) {
+ _savingPath = parentDirectory(pathFileName);
+ if (!fileExists(pathFileName)) {
+ SIBR_WRG << "Camera path " << pathFileName << " doesnt exist. " << std::endl;
+ return false;
+ }
+ _ow = w, _oh = h;
+ if (boost::filesystem::extension(pathFileName) == ".out")
+ loadBundle(pathFileName, w, h);
+ else if (boost::filesystem::extension(pathFileName) == ".lookat")
+ loadLookat(pathFileName, w, h);
+ else if (boost::filesystem::extension(pathFileName) == ".txt")
+ loadColmap(pathFileName, w, h);
+ else
+ load(pathFileName);
+ return true;
+ }
+
+ void CameraRecorder::recordOfflinePath(const std::string& outPathDir, ViewBase::Ptr view, const std::string& prefix) {
+ sibr::ImageRGBA32F::Ptr outImage;
+ outImage.reset(new ImageRGBA32F(_ow, _oh));
+ std::string outpathd = outPathDir;
+
+ sibr::RenderTargetRGBA32F::Ptr outFrame;
+ outFrame.reset(new RenderTargetRGBA32F(_ow, _oh));
+ std::string outFileName;
+
+ boost::filesystem::path dstFolder;
+
+ outpathd = outPathDir;
+
+ if (outPathDir == "pathOutput" && _savingPath != "") { // default to path parent, saved by loadPath
+ outpathd = _savingPath + "/" + "pathOutput";
+ dstFolder = outpathd;
+ if (!directoryExists(outpathd) && !boost::filesystem::create_directories(dstFolder))
+ SIBR_ERR << "Error creating directory " << dstFolder << std::endl;
+ }
+
+ if( prefix != "" )
+ dstFolder = outpathd = outpathd + "/" + prefix;
+ else
+ dstFolder = outpathd ;
+
+ if (!directoryExists(outpathd) && !boost::filesystem::create_directories(dstFolder))
+ SIBR_ERR << "Error creating directory " << dstFolder << std::endl;
+
+ std::cout << "Rendering path with " << _cameras.size() << " cameras to " << outpathd << std::endl;
+
+ for (int i = 0; i < _cameras.size(); ++i) {
+ outFrame->clear();
+ std::ostringstream ssZeroPad;
+ ssZeroPad << std::setw(8) << std::setfill('0') << i;
+ outFileName = outpathd + "/" + ssZeroPad.str() + ".png";
+ std::cout << outFileName << " " << std::endl;
+ view->onRenderIBR(*outFrame, _cameras[i]);
+ outFrame->readBack(*outImage);
+ outImage->save(outFileName, false);
+ }
+ std::cout << std::endl;
+
+ std::cout << "Done rendering path. " << std::endl;
+
+ }
+
+ void CameraRecorder::saveImage(const std::string& outPathDir, const Camera& cam, int w, int h) {
+ sibr::ImageRGBA32F::Ptr outImage;
+ _ow = w, _oh = h;
+ outImage.reset(new ImageRGBA32F(_ow, _oh));
+ std::string outpathd = outPathDir;
+
+ sibr::RenderTargetRGBA32F::Ptr outFrame;
+ outFrame.reset(new RenderTargetRGBA32F(_ow, _oh));
+ std::string outFileName;
+
+ boost::filesystem::path dstFolder;
+
+ outpathd = outPathDir;
+
+ if (outPathDir == "") { // default to path parent, saved by loadPath
+ outpathd = _dsPath + "/" + "pathOutput";
+ dstFolder = outpathd;
+ if (!directoryExists(outpathd) && !boost::filesystem::create_directories(dstFolder))
+ SIBR_ERR << "Error creating directory " << dstFolder << std::endl;
+ }
+
+ dstFolder = outpathd;
+
+ if (!directoryExists(outpathd) && !boost::filesystem::create_directories(dstFolder))
+ SIBR_ERR << "Error creating directory " << dstFolder << std::endl;
+
+ std::cout << "Saving current camera to " << outpathd << std::endl;
+
+ outFrame->clear();
+ std::ostringstream ssZeroPad;
+ static int i = 0;
+ ssZeroPad << std::setw(8) << std::setfill('0') << i++;
+ outFileName = outpathd + "/" + ssZeroPad.str() + ".png";
+ std::cout << outFileName << " " << std::endl;
+ _view->onRenderIBR(*outFrame, cam);
+ outFrame->readBack(*outImage);
+ outImage->save(outFileName, false);
+ std::cout << std::endl;
+ std::cout << "Done saving image. " << std::endl;
+ }
+
+} // namespace sibr
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.hpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..44dd414495ce45eeca7b82845926c023846a8bcf
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/CameraRecorder.hpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+#pragma once
+
+# include
+# include "core/assets/Config.hpp"
+# include "core/graphics/Camera.hpp"
+# include "core/view/ViewBase.hpp"
+
+
+# define SIBR_CAMERARECORDER_DEFAULTFILE "camera-record.bytes"
+
+namespace sibr
+{
+ /** This class handles the recording and replay of a stream of cameras.
+ \ingroup sibr_assets
+ */
+ class SIBR_ASSETS_EXPORT CameraRecorder
+ {
+ public:
+
+ /**
+ Default constructor.
+ */
+ CameraRecorder(void) :
+ _pos(0), _recording(false), _playing(false), _saving(false), _savingPath(""), _savingVideo(false), _savingVideoPath(""), _speed(1.0f), _interp(0.0f), _playNoInterp(false) {
+ //load();
+ }
+ /**
+ Default destructor.
+ */
+ ~CameraRecorder( void ) {
+ }
+
+ /**
+ This method supports two modes: if the recorder is currently recording,
+ the camera argument will be saved into the recording; else if the recorder
+ is playing, the camera argument will be set to the current replaid camera.
+ \param cam A reference to the camera to record/update.
+ */
+ void use( Camera& cam );
+
+ /**
+ Start playing the recorded camera stream from the beginning, at a rate of one step for each "use" call.
+ */
+ void playback( void );
+
+ /**
+ Start recording a new camera stream, at a rate of one camera saved for each "use" call.
+ */
+ void record( void );
+
+ /**
+ Start asking the renderer to save the frames, at a rate of one image saved for each "use" call.
+ */
+ void saving(std::string savePath);
+
+ /**
+ Toggle the save flag for video frames when replaying.
+ \param saveVideo the new flag status
+ */
+ void savingVideo(bool saveVideo);
+
+ /**
+ Stop saving.
+ */
+ void stopSaving(void);
+
+ /**
+ Stop playing/recording.
+ */
+ void stop( void );
+
+ /**
+ Clear the current recording.
+ */
+ void reset( void );
+
+ /**
+ Set value of play no interpolation
+ */
+ void playNoInterpolation( bool val ) { _playNoInterp = val; }
+
+ /**
+ Load a recorded camera stream from a given file.
+ \param filename Optional path to the file to load from. By default will try to
+ load SIBR_CAMERARECORDER_DEFAULTFILE from the current directory.
+ \return a boolean denoting the loading success/failure.
+ */
+ bool load( const std::string& filename=SIBR_CAMERARECORDER_DEFAULTFILE );
+
+ /**
+ Save the current recording stream to a given file.
+ \param filename Optional path to the file to write to. By default will try to
+ write to SIBR_CAMERARECORDER_DEFAULTFILE in the current directory.
+ */
+ void save( const std::string& filename=SIBR_CAMERARECORDER_DEFAULTFILE );
+
+ /** Load recorded path based on file extension.
+ *\param filename the file to load
+ *\param w resoltuion width
+ *\param h resolution height
+ *\return a success boolean
+ *\note w and h are needed when loading a Bundle.
+ */
+ bool safeLoad(const std::string& filename, int w = 1920, int h = 1080);
+
+ /**
+ Load a recording stream saved as a bundle file (useful for path from FRIBR).
+ \param filePath Path to the bundle file to write to.
+ \param w the image width to use for Fov computation
+ \param h the image height
+ */
+ void loadBundle(const std::string & filePath, int w = 1920, int h = 1080);
+
+ /**
+ *Load a camera path generated by the camera editor / bledner plugin
+ *\param filePath Path to the .lookat file.
+ *\param w Width of the cameras to create.
+ *\param h Height of the cameras to create.
+ */
+ void loadLookat(const std::string &filePath, int w = 1920, int h = 1080);
+
+ /**
+ *Load a camera path generated by colmap requires filename images.txt for now TODO GD; fix this
+ *\param filePath Path to the images.txt file; assumes that a cameras.txt is "next to" it;
+ *\param w Width of the cameras to create.
+ *\param h Height of the cameras to create.
+ */
+ void loadColmap(const std::string &filePath, int w = 1920, int h = 1080);
+
+
+ /**
+ Save the current recording stream as a bundle file.
+ \param filePath Path to the bundle file to write to.
+ \param height the height in pixels of the camera. Used to compute focal length in mm as expected by bundle.
+ \param step set to a value greater than 1 to save every "step" camera in the recording stream.
+ */
+ void saveAsBundle(const std::string & filePath, const int height, const int step = 1);
+ void saveAsColmap(const std::string& filePath, const int height, const int width);
+
+ /**
+ Save the current recording stream as a bundle file and a series of empty images for FRIBR compatibility.
+ \param dirPath Path to the directory to export to.
+ \param width the width in pixels of the camera.
+ \param height the height in pixels of the camera.
+ */
+ void saveAsFRIBRBundle(const std::string & dirPath, const int width, const int height);
+
+ /**
+ Save the current recording stream as a lookat file.
+ \param filePath Path to the lookat file to write to.
+ */
+ void saveAsLookAt(const std::string& filePath) const;
+
+ /**
+ \return a boolean denoting if the recorder is currently playing.
+ */
+ bool isPlaying() const { return _playing; }
+
+ /**
+ \return a boolean denoting if the recorder is currently recording.
+ */
+ bool isRecording() const { return _recording; }
+
+ /**
+ \return a boolean denoting if the recorder is currently asking frames to be saved.
+ */
+ bool isSaving() const { return _saving; }
+
+ /**
+ \return A reference to the current stream of recorded cameras.
+ */
+ std::vector& cams() { return _cameras; }
+
+ /**
+ Updates the cameras from a vector, usefull to play already loaded path.
+ */
+ void cams(std::vector& cams) { _cameras = cams; }
+
+
+ /**
+ Load a path, based on file extension name. Cameras loaded into _cameras
+ */
+ bool loadPath(const std::string& pathFileName, int w, int h);
+
+ /**
+ Play path for offline rendering using abstract View interface
+ */
+ void recordOfflinePath(const std::string& outPathDir, ViewBase::Ptr view, const std::string& prefix);
+
+ /**
+ Save an image
+ */
+ void setViewPath(ViewBase::Ptr view, const std::string& dataset_path) { _view = view; _dsPath = dataset_path; };
+
+ void saveImage(const std::string& outPathDir, const Camera& cam, int w, int h);
+
+ /**
+ * \return the interpolation speed
+ */
+ float & speed() { return _speed; }
+
+ private:
+ std::string _dsPath; // path to dataset
+ ViewBase::Ptr _view; // view to save images
+ uint _pos; ///< Current camera ID for replay.
+ std::vector _cameras; ///< List of recorded cameras.
+ bool _recording; ///< Are we currently recording.
+ bool _playing; ///< Are we currently playing.
+ bool _saving; ///< Are we saving the path as images.
+ std::string _savingPath; ///< Destination base path for saved images.
+ bool _savingVideo; ///< Are we saving the path as video.
+ std::string _savingVideoPath; ///< Destination base path for saved video.
+ float _speed; ///< Playback speed.
+ float _interp; ///< Current interpoaltion factor.
+ bool _playNoInterp; ///< Just play the cameras, make sure focal is preserved
+ int _ow, _oh; ///< offline output path resolution
+ };
+
+ ///// DEFINITIONS /////
+
+
+
+} // namespace sibr
+
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/Config.hpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/Config.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3386bc132505fb74fc7d335ba8c175f795ae5812
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/Config.hpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+#pragma once
+
+# include "core/graphics/Config.hpp"
+# include
+
+
+#ifdef SIBR_OS_WINDOWS
+//// Export Macro (used for creating DLLs) ////
+# ifdef SIBR_STATIC_DEFINE
+# define SIBR_EXPORT
+# define SIBR_NO_EXPORT
+# else
+# ifndef SIBR_ASSETS_EXPORT
+# ifdef SIBR_ASSETS_EXPORTS
+ /* We are building this library */
+# define SIBR_ASSETS_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define SIBR_ASSETS_EXPORT __declspec(dllimport)
+# endif
+# endif
+# ifndef SIBR_NO_EXPORT
+# define SIBR_NO_EXPORT
+# endif
+# endif
+# else
+# define SIBR_ASSETS_EXPORT
+# endif
+
+namespace sibr
+{
+ /**
+ * Utility that converts an integer id to a string using
+ * the "most used" format.
+ * \param id the id to convert (fi 7)
+ * \return the corresponding string (fi "0000007")
+ * \ingroup sibr_assets
+ */
+ inline std::string imageIdToString( int id ) {
+ std::ostringstream oss;
+ oss << std::setfill('0') << std::setw(8) << id;
+ return oss.str();
+ }
+
+ /** Generate a string representation of an integer, padded with zeros.
+ * \param id the integer
+ * \return the padded string
+ * \note The template int value determines the padding count.
+ * \ingroup sibr_assets
+ * */
+ template std::string intToString(int id) {
+ std::ostringstream oss;
+ oss << std::setfill('0') << std::setw(N) << id;
+ return oss.str();
+ }
+
+ /**
+ * Get the default path and filename used for the proxy
+ * mesh.
+ * \param datasetPath the base path
+ * \return the mesh path
+ * \ingroup sibr_assets
+ */
+ inline std::string getProxyFilename( const std::string& datasetPath ) {
+ return datasetPath + "/pmvs/models/pmvs_recon.ply";
+ }
+
+ /**
+ * Loading status for streaming.
+ * \todo Rename the following status into: NotLoaded, CPULoading, CPUReady, GPUReady, Failure.
+ * \ingroup sibr_assets
+ */
+ namespace LoadingStatus
+ {
+ enum Enum
+ {
+ NotLoaded = 0,
+ InProgress,
+ CPUReady,
+ Successful,
+ Failure,
+
+ Count
+ };
+ } // namespace LoadingStatus
+
+} // namespace sibr
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/IFileLoader.hpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/IFileLoader.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9d24dc248526f58b2ec7486a589f36502ba0f05c
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/IFileLoader.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+#pragma once
+
+# include "core/assets/Config.hpp"
+
+namespace sibr
+{
+ /** General file loading interface.
+ \ingroup sibr_assets
+ */
+ class SIBR_ASSETS_EXPORT IFileLoader
+ {
+ public:
+
+ /** Destructor. */
+ virtual ~IFileLoader( void ) { }
+
+ /** Load the file content from disk.
+ \param filename path to the file
+ \param verbose display information
+ \return a boolean denoting success
+ */
+ virtual bool load( const std::string& filename, bool verbose = true ) = 0;
+ };
+
+} // namespace sibr
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ImageListFile.cpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ImageListFile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c354d7557147dac2f5c69a8a143e1380afc0f49b
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/ImageListFile.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+
+# include
+# include
+# include "core/assets/ImageListFile.hpp"
+
+namespace sibr
+{
+ bool ImageListFile::load( const std::string& filename, bool verbose )
+ {
+
+ std::fstream file(filename, std::ios::in);
+
+ _infos.clear();
+ if (file)
+ {
+ while (file.eof() == false)
+ {
+ Infos i;
+ file >> i.filename >> i.width >> i.height;
+ if (i.filename.size())
+ _infos.emplace_back(std::move(i));
+ }
+
+ // store basename
+ boost::filesystem::path path(filename);
+ _basename = path.parent_path().string();
+
+ if( verbose )
+ SIBR_FLOG << "'"<< filename <<"' successfully loaded." << std::endl;
+
+ return true;
+ }
+ else
+ SIBR_WRG << "file not found: '"<& infos( void ) const { return _infos; }
+
+ /** Image absename.
+ *\return the basename
+ **/
+ const std::string& basename( void ) const { return _basename; }
+
+ /** Load images.
+ \return the loaded images
+ */
+ template
+ std::vector loadImages( void ) const;
+
+ /** Load images, applying an active images file filter.
+ \param ac the active list file
+ \return the loaded images
+ \note Non-active images are present but empty.
+ */
+ template
+ std::vector loadImages( const ActiveImageFile& ac) const;
+
+
+ private:
+ std::vector _infos; ///< Image infos.
+ std::string _basename; ///< Root name.
+
+ };
+
+ ///// DEFINITIONS /////
+
+
+ template
+ std::vector ImageListFile::loadImages( const ActiveImageFile& ac ) const {
+ std::vector out;
+
+ SIBR_LOG << "[ImageListFile] loading images";
+ out.resize(_infos.size());
+ if (_infos.empty() == false)
+ {
+ #pragma omp parallel for
+ for (int i = 0; i < _infos.size(); ++i)
+ if( ac.active()[i] )
+ out[i].load(_basename + "/" + _infos.at(i).filename, false);
+ }
+ else
+ SIBR_WRG << "cannot load images (ImageListFile is empty. Did you use ImageListFile::load(...) before ?";
+
+ std::cout << std::endl;
+ return out;
+ }
+
+ template
+ std::vector ImageListFile::loadImages( void ) const {
+ std::vector out;
+
+ std::cerr << "[ImageListFile] loading images";
+ out.resize(_infos.size());
+ if (_infos.empty() == false)
+ {
+ #pragma omp parallel for
+ for (int i = 0; i < _infos.size(); ++i)
+ out[i].load(_basename + "/" + _infos.at(i).filename, false);
+ }
+ else
+ SIBR_WRG << "cannot load images (ImageListFile is empty. Did you use ImageListFile::load(...) before ?";
+
+ return out;
+ }
+
+} // namespace sibr
diff --git a/extensions/RaDe-GS/SIBR_viewers/src/core/assets/InputCamera.cpp b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/InputCamera.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..341f5db2c6355c18922fc6b5391cb6e19c34b451
--- /dev/null
+++ b/extensions/RaDe-GS/SIBR_viewers/src/core/assets/InputCamera.cpp
@@ -0,0 +1,1577 @@
+/*
+ * Copyright (C) 2020, 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 sibr@inria.fr and/or George.Drettakis@inria.fr
+ */
+
+
+#include "core/assets/ActiveImageFile.hpp"
+#include "core/assets/InputCamera.hpp"
+#include
+#include
+#include "core/system/String.hpp"
+#include "picojson/picojson.hpp"
+
+
+// Colmap binary stuff
+#include "colmapheader.h"
+typedef uint32_t image_t;
+typedef uint32_t camera_t;
+typedef uint64_t point3D_t;
+typedef uint32_t point2D_t;
+
+#define SIBR_INPUTCAMERA_BINARYFILE_VERSION 10
+#define IBRVIEW_TOPVIEW_SAVEVERSION "version002"
+#define FOCAL_X_UNDEFINED -1
+
+namespace sibr
+{
+ InputCamera::InputCamera(float f, float k1, float k2, int w, int h, int id) :
+ _focal(f), _k1(k1), _k2(k2), _w(w), _h(h), _id(id), _active(true), _name(""), _focalx(FOCAL_X_UNDEFINED)
+ {
+ // Update fov and aspect ratio.
+ float fov = 2.0f * atan(0.5f * h / f);
+ float aspect = float(w) / float(h);
+
+ Camera::aspect(aspect);
+ Camera::fovy(fov);
+
+ _id = id;
+ }
+
+ InputCamera::InputCamera(float fy, float fx, float k1, float k2, int w, int h, int id) :
+ _focal(fy), _k1(k1), _k2(k2), _w(w), _h(h), _id(id), _active(true), _name(""), _focalx(fx)
+ {
+ // Update fov and aspect ratio.
+ float fovY = 2.0f * atan(0.5f * h / fy);
+ float fovX = 2.0f * atan(0.5f * w / fx);
+
+ Camera::aspect(tan(fovX / 2) / tan(fovY / 2));
+ Camera::fovy(fovY);
+
+ _id = id;
+ }
+
+
+ InputCamera::InputCamera(int id, int w, int h, sibr::Matrix4f m, bool active) :
+ _active(active)
+ {
+ Vector3f t;
+ float r[9];
+
+ for (int i = 0; i < 9; i++) r[i] = m(3 + i);
+ for (int i = 0; i < 3; i++) t[i] = m(12 + i);
+
+ _w = w;
+ _h = h;
+
+ _focal = m(0);
+ _focalx = FOCAL_X_UNDEFINED;
+ _k1 = m(1);
+ _k2 = m(2);
+
+ float fov = 2.0f * atan(0.5f * h / m(0));
+ float aspect = float(w) / float(h);
+
+ sibr::Matrix3f matRotation;
+ matRotation <<
+ r[0], r[1], r[2],
+ r[3], r[4], r[5],
+ r[6], r[7], r[8]
+ ;
+
+ Camera::aspect(aspect);
+ Camera::fovy(fov);
+
+ // http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html#S6
+ // Do pos = -R' * t
+ const sibr::Matrix3f orientation = matRotation.transpose();
+ sibr::Vector3f position = -orientation * t;
+ Camera::position(position);
+ Camera::rotation(Quaternionf(orientation));
+
+
+ Camera::principalPoint({ 0.5f, 0.5f });
+
+
+ _id = id;
+ _name = "";
+ }
+
+
+
+ InputCamera::InputCamera(int id, int w, int h, sibr::Vector3f& position, sibr::Matrix3f& orientation, float focal, float k1, float k2, bool active) :
+ _active(active)
+ {
+
+
+ _w = w;
+ _h = h;
+
+ _focal = focal;
+ _focalx = FOCAL_X_UNDEFINED;
+ _k1 = k1;
+ _k2 = k2;
+
+ float fov = 2.0f * atan(0.5f * h / _focal);
+ float aspect = float(w) / float(h);
+
+
+
+ Camera::aspect(aspect);
+ Camera::fovy(fov);
+
+ // http://www.cs.cornell.edu/~snavely/bundler/bundler-v0.4-manual.html#S6
+ // Do pos = -R' * t
+
+ Camera::position(position);
+ Camera::rotation(Quaternionf(orientation));
+
+ _id = id;
+ _name = "";
+ }
+
+ InputCamera::InputCamera(const Camera& c, int w, int h) : Camera(c) {
+ _focal = 1.0f / (tan(0.5f * fovy()) * 2.0f / float(h));
+ _focalx = FOCAL_X_UNDEFINED;
+ _k1 = _k2 = 0;
+ _w = w;
+ _h = h;
+ _id = 0;
+ _name = "";
+ _active = true;
+ aspect(float(_w) / float(_h));
+ }
+
+ // ------------------------------------------------------------------------
+
+ void InputCamera::size(uint w, uint h) { _w = w; _h = h; }
+ uint InputCamera::w(void) const { return _w; }
+ uint InputCamera::h(void) const { return _h; }
+ bool InputCamera::isActive(void) const { return _active; }
+
+ /* compatibility for preprocess (depth) */
+
+
+ Vector3f InputCamera::projectScreen(const Vector3f& pt) const {
+ Vector3f proj_pt = project(pt);
+ Vector3f screen_pt((proj_pt[0] + 1.f) * _w / 2.0f, (1.f - proj_pt[1]) * _h / 2.0f, proj_pt[2] * 0.5f + 0.5f);
+
+ return screen_pt;
+ }
+
+ float InputCamera::focal() const { return _focal; };
+ float InputCamera::focalx() const { return _focalx; };
+ float InputCamera::k1() const { return _k1; };
+ float InputCamera::k2() const { return _k2; };
+
+ InputCamera InputCamera::resizedH(int h) const {
+
+ int w = int(_aspect * h);
+
+ float sibr_focal = h * _focal / _h;
+ float k1 = _k1;
+ float k2 = _k2;
+ int id = _id;
+
+ sibr::Matrix4f m;
+
+ sibr::InputCamera cam(sibr_focal, k1, k2, w, h, id);
+
+ cam.rotation(rotation());
+ cam.position(position());
+
+ cam.znear(znear());
+ cam.zfar(zfar());
+ cam.name(name());
+
+ return cam;
+ }
+
+ InputCamera InputCamera::resizedW(int w) const {
+
+ int h = int(float(w) / _aspect);
+
+ float sibr_focal = h * _focal / _h;
+ float k1 = _k1;
+ float k2 = _k2;
+ int id = _id;
+
+ sibr::Matrix4f m;
+
+ sibr::InputCamera cam(sibr_focal, k1, k2, w, h, id);
+
+ cam.rotation(rotation());
+ cam.position(position());
+
+ cam.znear(znear());
+ cam.zfar(zfar());
+ cam.name(name());
+
+ return cam;
+ }
+
+
+
+ std::vector InputCamera::load(const std::string& datasetPath, float zNear, float zFar, const std::string& bundleName, const std::string& listName)
+ {
+ const std::string bundlerFile = datasetPath + "/cameras/" + bundleName;
+ const std::string listFile = datasetPath + "/images/" + listName;
+ const std::string clipFile = datasetPath + "/clipping_planes.txt";
+
+ // Loading clipping planes if they are available.
+ SIBR_LOG << "Loading clipping planes from " << clipFile << std::endl;
+
+ struct Z {
+ Z() {}
+ Z(float f, float n) : far(f), near(n) {}
+ float far;
+ float near;
+ };
+ std::vector nearsFars;
+
+ { // Load znear & zfar for unprojecting depth samples
+
+ float z;
+ std::ifstream zfile(clipFile);
+ // During preprocessing clipping planes are not yet defined
+ // the preprocess utility "depth" defines this
+ // SIBR_ASSERT(zfile.is_open());
+ if (zfile.is_open()) {
+ int num_z_values = 0;
+ while (zfile >> z) {
+ if (num_z_values % 2 == 0) {
+ nearsFars.push_back(Z());
+ nearsFars[nearsFars.size() - 1].near = z;
+ }
+ else {
+ nearsFars[nearsFars.size() - 1].far = z;
+ }
+ ++num_z_values;
+ }
+
+ if (num_z_values > 0 && num_z_values % 2 != 0) {
+ nearsFars.resize(nearsFars.size() - 1);
+ }
+
+ if (nearsFars.size() == 0) {
+ SIBR_WRG << " Could not extract at leat 2 clipping planes from '" << clipFile << "' ." << std::endl;
+ }
+ }
+ else {
+ SIBR_WRG << "Cannot open '" << clipFile << "' (not clipping plane loaded)." << std::endl;
+ }
+
+ }
+
+ // Load cameras and images infos.
+ SIBR_LOG << "Loading input cameras." << std::endl;
+ auto cameras = InputCamera::loadBundle(bundlerFile, zNear, zFar, listFile);
+
+ if (!nearsFars.empty()) {
+ for (int cid = 0; cid < cameras.size(); ++cid) {
+ const int zid = std::min(cid, int(nearsFars.size()) - 1);
+ cameras[cid]->znear(nearsFars[zid].near);
+ cameras[cid]->zfar(nearsFars[zid].far);
+ }
+ }
+
+ // Load active images
+ ActiveImageFile activeImageFile;
+ activeImageFile.setNumImages((int)cameras.size());
+ // load active image file and set (in)active
+ if (activeImageFile.load(datasetPath + "/active_images.txt", false)) {
+ for (int i = 0; i < (int)cameras.size(); i++) {
+ if (!activeImageFile.active()[i])
+ cameras[i]->setActive(false);
+ }
+ }
+
+ // Load excluded images
+ ActiveImageFile excludeImageFile;
+ excludeImageFile.setNumImages((int)cameras.size());
+ // load exclude image file and set *in*active
+ if (excludeImageFile.load(datasetPath + "/exclude_images.txt", false)) {
+ for (int i = 0; i < (int)cameras.size(); i++) {
+ // Attn (GD): invert the meaning of active for exclude:
+ // only file numbers explicitly in exclude_images are set
+ // to active, and these are the only ones we set to *inactive*
+ // should really create a separate class or have a flag "invert"
+ if (excludeImageFile.active()[i])
+ cameras[i]->setActive(false);
+ }
+ }
+ return cameras;
+ }
+
+ std::vector InputCamera::loadNVM(const std::string& nvmPath, float zNear, float zFar, std::vector wh)
+ {
+ std::ifstream in(nvmPath);
+ std::vector cameras;
+
+ if (in.is_open())
+ {
+ int rotation_parameter_num = 4;
+ bool format_r9t = false;
+ std::string token;
+ if (in.peek() == 'N')
+ {
+ in >> token; //file header
+ if (strstr(token.c_str(), "R9T"))
+ {
+ rotation_parameter_num = 9; //rotation as 3x3 matrix
+ format_r9t = true;
+ }
+ }
+
+ int ncam = 0, npoint = 0, nproj = 0;
+ // read # of cameras
+ in >> ncam; if (ncam <= 1) return std::vector();
+
+ //read the camera parameters
+
+ std::function matrix = [](const double q[9])
+ {
+
+ Eigen::Matrix3f m;
+ double qq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
+ double qw, qx, qy, qz;
+ if (qq > 0)
+ {
+ qw = q[0] / qq;
+ qx = q[1] / qq;
+ qy = q[2] / qq;
+ qz = q[3] / qq;
+ }
+ else
+ {
+ qw = 1;
+ qx = qy = qz = 0;
+ }
+ m(0, 0) = float(qw * qw + qx * qx - qz * qz - qy * qy);
+ m(0, 1) = float(2 * qx * qy - 2 * qz * qw);
+ m(0, 2) = float(2 * qy * qw + 2 * qz * qx);
+ m(1, 0) = float(2 * qx * qy + 2 * qw * qz);
+ m(1, 1) = float(qy * qy + qw * qw - qz * qz - qx * qx);
+ m(1, 2) = float(2 * qz * qy - 2 * qx * qw);
+ m(2, 0) = float(2 * qx * qz - 2 * qy * qw);
+ m(2, 1) = float(2 * qy * qz + 2 * qw * qx);
+ m(2, 2) = float(qz * qz + qw * qw - qy * qy - qx * qx);
+
+ return m;
+ };
+
+ for (int i = 0; i < ncam; ++i)
+ {
+ double f, q[9], c[3], d[2];
+ in >> token >> f;
+ for (int j = 0; j < rotation_parameter_num; ++j) in >> q[j];
+ in >> c[0] >> c[1] >> c[2] >> d[0] >> d[1];
+
+ std::string image_path = sibr::parentDirectory(nvmPath) + "/" + token;
+ sibr::Vector2i resolution = sibr::IImage::imageResolution(image_path);
+
+ if (resolution.x() < 0 || resolution.y() < 0)
+ {
+ std::cerr << "Could not get resolution for input image: " << image_path << std::endl;
+ return std::vector();
+ }
+
+ int wIm = 1, hIm = 1;
+ if (ncam == wh.size()) {
+ wIm = wh[i].x();
+ hIm = wh[i].y();
+ }
+ else {
+ wIm = resolution.x();
+ hIm = resolution.y();
+ }
+
+ //camera_data[i].SetFocalLength(f);
+ cameras.emplace_back(new InputCamera((float)f, (float)d[0], (float)d[1], wIm, hIm, i));
+
+ float fov = 2.0f * atan(0.5f * hIm / (float)f);
+ float aspect = float(wIm) / float(hIm);
+ cameras[i]->aspect(aspect);
+ cameras[i]->fovy(fov);
+
+ //translation
+ Vector3f posCam((float)c[0], (float)c[1], (float)c[2]);
+
+ if (format_r9t)
+ {
+
+ std::cout << " WARNING THIS PART OF THE CODE WAS NEVER TESTED. IT IS SUPPOSED NOT TO WORK PROPERLY" << std::endl;
+ Eigen::Matrix3f matRotation;
+ matRotation <<
+ float(q[0]), float(q[1]), float(q[2]),
+ float(q[3]), float(q[4]), float(q[5]),
+ float(q[6]), float(q[7]), float(q[8])
+ ;
+ matRotation.transposeInPlace();
+
+
+ cameras[i]->position(posCam);
+ cameras[i]->rotation(Quaternionf(matRotation));
+
+ }
+ else
+ {
+
+ Eigen::Matrix3f converter;
+ converter <<
+ 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+ //older format for compability
+ Quaternionf quat((float)q[0], (float)q[1], (float)q[2], (float)q[3]);
+ Eigen::Matrix3f matRotation = converter.transpose() * quat.toRotationMatrix();
+ matRotation.transposeInPlace();
+
+ cameras[i]->position(posCam);
+ cameras[i]->rotation(Quaternionf(matRotation));
+
+ }
+ //camera_data[i].SetNormalizedMeasurementDistortion(d[0]);
+ cameras[i]->name(token);
+ }
+ std::cout << ncam << " cameras; " << npoint << " 3D points; " << nproj << " projections\n";
+ }
+ else {
+ SIBR_WRG << "Cannot open '" << nvmPath << std::endl;
+ }
+
+ return cameras;
+ }
+
+ std::vector InputCamera::loadLookat(const std::string& lookatPath, const std::vector& wh, float znear, float zfar)
+ {
+
+ std::ifstream in(lookatPath);
+ std::vector cameras;
+
+ if (in.is_open())
+ {
+ int i = 0;
+ for (std::string line; safeGetline(in, line); i++)
+ {
+ int w = 1024, h = 768;
+ if (wh.size() > 0) {
+ int whI = std::min(i, (int)wh.size() - 1);
+ w = wh[whI].x();
+ h = wh[whI].y();
+ }
+ else {
+ std::cout << "Warning default image size of 1024*768 is supposed for camera" << std::endl;
+ }
+
+ bool use_fovx = false;
+ std::string camName = line.substr(0, line.find(" "));
+ size_t originPos = line.find("-D origin=") + 10;
+ size_t targetPos = line.find("-D target=") + 10;
+ size_t upPos = line.find("-D up=") + 6;
+ size_t fovPos = line.find("-D fovy=") + 8;
+ int delta_fov = 9;
+ if (fovPos < 8) {
+ std::cout << "Warning: Fovy not found, backing to Fovx mode" << std::endl;
+ fovPos = line.find("-D fov=") + 7;
+ use_fovx = true;
+ delta_fov = 8;
+ }
+ size_t clipPos = line.find("-D clip=") + 8;
+ size_t aspectPos = line.find("-D aspect=") + 10;
+ size_t endPos = line.size();
+
+ std::string originStr = line.substr(originPos, targetPos - originPos - 11);
+ std::string targetStr = line.substr(targetPos, upPos - targetPos - 7);
+ std::string upStr = line.substr(upPos, fovPos - upPos - delta_fov);
+ std::string fovStr = line.substr(fovPos, clipPos - fovPos - 9);
+ std::string clipStr = line.substr(clipPos, endPos - clipPos);
+
+ std::vector vecVal;
+ boost::split(vecVal, originStr, [](char c) {return c == ','; });
+ Vector3f Eye(std::strtof(vecVal[0].c_str(), 0), std::strtof(vecVal[1].c_str(), 0), std::strtof(vecVal[2].c_str(), 0));
+ boost::split(vecVal, targetStr, [](char c) {return c == ','; });
+ Vector3f At(std::strtof(vecVal[0].c_str(), 0), std::strtof(vecVal[1].c_str(), 0), std::strtof(vecVal[2].c_str(), 0));
+
+ boost::split(vecVal, upStr, [](char c) {return c == ','; });
+ Vector3f Up(std::strtof(vecVal[0].c_str(), 0), std::strtof(vecVal[1].c_str(), 0), std::strtof(vecVal[2].c_str(), 0));
+
+ float fov = std::strtof(fovStr.c_str(), 0);
+
+ boost::split(vecVal, clipStr, [](char c) {return c == ','; });
+ Vector2f clip(std::strtof(vecVal[0].c_str(), 0), std::strtof(vecVal[1].c_str(), 0));
+
+ Vector3f zAxis((Eye - At).normalized());
+ Vector3f xAxis((Up.cross(zAxis)).normalized());
+ Vector3f yAxis(zAxis.cross(xAxis));
+
+ Vector3f transl(-Eye.dot(xAxis), -Eye.dot(yAxis), -Eye.dot(zAxis));
+
+ Eigen::Matrix3f rotation;
+ rotation << xAxis, yAxis, zAxis;
+ rotation.transposeInPlace();
+
+ Eigen::Matrix4f mLook;
+ mLook.setZero();
+ mLook.block<3, 3>(0, 0) = rotation;
+ mLook.block<3, 1>(0, 3) = transl;
+ mLook(3, 3) = 1;
+
+ float fovRad = fov * float(M_PI) / 180;
+ float sibr_focal = 0.5f * h / tan(fovRad / 2.0f); //Lookat file contain the vertical field of view now
+ if (use_fovx) {
+ sibr_focal = 0.5f * w / tan(fovRad / 2.0f); //Lookat file contain the vertical field of view now
+ }
+
+ Eigen::Matrix4f r(mLook);
+ /*float m[15] = {
+ sibr_focal,0,0,
+ r(0,0),r(0,1),r(0,2),
+ r(1,0),r(1,1),r(1,2),
+ r(2,0),r(2,1),r(2,2),
+ r(0,3),r(1,3),r(2,3)
+ };
+ */
+ Eigen::Matrix4f m;
+ m(0) = sibr_focal; m(1) = 0; m(2) = 0;
+ m(3) = r(0, 0); m(4) = r(0, 1); m(5) = r(0, 2);
+ m(6) = r(1, 0); m(7) = r(1, 1); m(8) = r(1, 2);
+ m(9) = r(2, 0); m(10) = r(2, 1); m(11) = r(2, 2);
+ m(12) = r(0, 3); m(13) = r(1, 3); m(14) = r(2, 3);
+
+
+ bool isActive = true;
+
+ cameras.emplace_back(new InputCamera((int)cameras.size(), w, h, m, isActive));
+
+ if (znear > 0) {
+ cameras[i]->znear(znear);
+ }
+ else {
+ cameras[i]->znear(clip.x());
+ }
+ if (zfar > 0) {
+ cameras[i]->zfar(zfar);
+ }
+ else {
+ cameras[i]->zfar(clip.y());
+ }
+ cameras[i]->name(camName);
+ }
+
+ }
+ else {
+ SIBR_WRG << "Cannot open '" << lookatPath << std::endl;
+ }
+
+ return cameras;
+
+ }
+
+ std::string InputCamera::lookatString() const {
+ std::string infos = std::string(" -D origin=") +
+ std::to_string(position()[0]) +
+ std::string(",") +
+ std::to_string(position()[1]) +
+ std::string(",") +
+ std::to_string(position()[2]) +
+ std::string(" -D target=") +
+ std::to_string(position()[0] +
+ dir()[0]) +
+ std::string(",") +
+ std::to_string(position()[1] +
+ dir()[1]) +
+ std::string(",") +
+ std::to_string(position()[2] +
+ dir()[2]) +
+ std::string(" -D up=") +
+ std::to_string(up()[0]) +
+ std::string(",") +
+ std::to_string(up()[1]) +
+ std::string(",") +
+ std::to_string(up()[2]) +
+ std::string(" -D fovy=") +
+ std::to_string(180 * fovy() / M_PI) +
+ std::string(" -D clip=") +
+ std::to_string(znear()) +
+ std::string(",") +
+ std::to_string(zfar()) +
+ std::string("\n");
+ return infos;
+ }
+
+ void InputCamera::saveAsLookat(const std::vector& cams, const std::string& fileName) {
+
+ std::ofstream fileRender(fileName, std::ios::out | std::ios::trunc);
+ for (const auto& cam : cams) {
+
+ fileRender << cam->name() << cam->lookatString();
+ }
+
+ fileRender.close();
+ }
+
+ void InputCamera::saveImageSizes(const std::vector& cams, const std::string& fileName) {
+
+ std::ofstream fileRender(fileName, std::ios::out | std::ios::trunc);
+ for (const auto& cam : cams) {
+
+ fileRender << cam->w() << "x" << cam->h() << "\n";
+ }
+
+ fileRender.close();
+ }
+
+
+
+
+ std::vector InputCamera::loadColmap(const std::string& colmapSparsePath, const float zNear, const float zFar, const int fovXfovYFlag)
+ {
+ const std::string camerasListing = colmapSparsePath + "/cameras.txt";
+ const std::string imagesListing = colmapSparsePath + "/images.txt";
+
+ const std::string camerasListing2 = colmapSparsePath + "/cameras.txt2";
+ const std::string imagesListing2 = colmapSparsePath + "/images.txt2";
+
+ std::ifstream camerasFile(camerasListing);
+ std::ifstream imagesFile(imagesListing);
+ std::ofstream camerasFile2(camerasListing2);
+ std::ofstream imagesFile2(imagesListing2);
+ if (!camerasFile.is_open()) {
+ SIBR_ERR << "Unable to load camera colmap file" << std::endl;
+ }
+ if (!imagesFile.is_open()) {
+ SIBR_WRG << "Unable to load images colmap file" << std::endl;
+ }
+
+ std::vector cameras;
+
+ std::string line;
+
+ struct CameraParametersColmap {
+ size_t id;
+ size_t width;
+ size_t height;
+ float fx;
+ float fy;
+ float dx;
+ float dy;
+ };
+
+ std::map cameraParameters;
+
+ std::map> camidtokens;
+
+ while (safeGetline(camerasFile, line)) {
+ if (line.empty() || line[0] == '#') {
+ continue;
+ }
+
+ std::vector tokens = sibr::split(line, ' ');
+ if (tokens.size() < 8) {
+ SIBR_WRG << "Unknown line." << std::endl;
+ continue;
+ }
+ if (tokens[1] != "PINHOLE" && tokens[1] != "OPENCV") {
+ SIBR_WRG << "Unknown camera type." << std::endl;
+ continue;
+ }
+
+ CameraParametersColmap params;
+ params.id = std::stol(tokens[0]);
+ params.width = std::stol(tokens[2]);
+ params.height = std::stol(tokens[3]);
+ params.fx = std::stof(tokens[4]);
+ params.fy = std::stof(tokens[5]);
+ params.dx = std::stof(tokens[6]);
+ params.dy = std::stof(tokens[7]);
+
+ cameraParameters[params.id] = params;
+
+ camidtokens[params.id] = tokens;
+ }
+
+ // Now load the individual images and their extrinsic parameters
+ sibr::Matrix3f converter;
+ converter << 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+
+ int camid = 0;
+ int valid = 0;
+ while (safeGetline(imagesFile, line)) {
+ if (line.empty() || line[0] == '#') {
+ continue;
+ }
+ std::vector tokens = sibr::split(line, ' ');
+ if (tokens.size() < 10) {
+ SIBR_WRG << "Unknown line." << std::endl;
+ continue;
+ }
+
+ uint cId = std::stoi(tokens[0]) - 1;
+ float qw = std::stof(tokens[1]);
+ float qx = std::stof(tokens[2]);
+ float qy = std::stof(tokens[3]);
+ float qz = std::stof(tokens[4]);
+ float tx = std::stof(tokens[5]);
+ float ty = std::stof(tokens[6]);
+ float tz = std::stof(tokens[7]);
+ size_t id = std::stol(tokens[8]);
+
+ std::string imageName = tokens[9];
+
+ if (cameraParameters.find(id) == cameraParameters.end())
+ {
+ SIBR_ERR << "Could not find intrinsics for image: "
+ << tokens[9] << std::endl;
+ }
+ const CameraParametersColmap& camParams = cameraParameters[id];
+
+ const sibr::Quaternionf quat(qw, qx, qy, qz);
+ const sibr::Matrix3f orientation = quat.toRotationMatrix().transpose() * converter;
+ sibr::Vector3f translation(tx, ty, tz);
+
+ sibr::Vector3f position = -(orientation * converter * translation);
+
+ sibr::InputCamera::Ptr camera;
+ if (fovXfovYFlag) {
+ camera = std::make_shared(InputCamera(camParams.fy, camParams.fx, 0.0f, 0.0f, int(camParams.width), int(camParams.height), int(cId)));
+ }
+ else {
+ camera = std::make_shared(InputCamera(camParams.fy, 0.0f, 0.0f, int(camParams.width), int(camParams.height), int(cId)));
+ }
+
+ camera->name(imageName);
+ camera->position(position);
+ camera->rotation(sibr::Quaternionf(orientation));
+ camera->znear(zNear);
+ camera->zfar(zFar);
+
+ if (camera->position().x() < 0)
+ {
+ camerasFile2 << ++valid;
+ for (int i = 1; i < camidtokens[id].size(); i++)
+ camerasFile2 << " " << camidtokens[id][i];
+ camerasFile2 << "\n\n";
+
+ imagesFile2<< valid;
+ for (int i = 1; i < tokens.size() - 1; i++)
+ imagesFile2 << " " << tokens[i];
+ imagesFile2 << " " << valid << std::endl;
+ imagesFile2 << "\n\n";
+ }
+
+ cameras.push_back(camera);
+
+ ++camid;
+ // Skip the observations.
+ safeGetline(imagesFile, line);
+ }
+
+
+ return cameras;
+ }
+
+ std::vector InputCamera::loadBundle(const std::string& bundlerPath, float zNear, float zFar, const std::string& listImagePath, bool path)
+ {
+ SIBR_LOG << "Loading input cameras." << std::endl;
+
+ // check bundler file
+ std::ifstream bundle_file(bundlerPath);
+ if (!bundle_file.is_open()) {
+ SIBR_ERR << "Unable to load bundle file at path \"" << bundlerPath << "\"." << std::endl;
+ return {};
+ }
+
+ const std::string listImages = listImagePath.empty() ? (bundlerPath + "/../list_images.txt") : listImagePath;
+ std::ifstream list_images(listImages);
+ if (!list_images.is_open()) {
+ SIBR_ERR << "Unable to load list_images file at path \"" << listImages << "\"." << std::endl;
+ return {};
+ }
+
+ // read number of images
+ std::string line;
+ getline(bundle_file, line); // ignore first line - contains version
+ int numImages = 0;
+ bundle_file >> numImages; // read first value (number of images)
+ getline(bundle_file, line); // ignore the rest of the line
+
+ // Read all filenames
+ struct ImgInfos
+ {
+ std::string name;
+ int id;
+ int w, h;
+ };
+ std::vector imgInfos;
+ {
+ ImgInfos infos;
+ while (true)
+ {
+ list_images >> infos.name;
+ if (infos.name.empty()) break;
+ list_images >> infos.w >> infos.h;
+ infos.name.erase(infos.name.find_last_of("."), std::string::npos);
+ infos.id = atoi(infos.name.c_str());
+ imgInfos.push_back(infos);
+ infos.name.clear();
+ }
+ }
+
+ ImgInfos infoPrevImage;
+ bool shortListImages = false;
+ // check if list images has the same number of cameras as path, else assume we read the dataset list_images.txt
+ if (path && imgInfos.size() != numImages)
+ shortListImages = true;
+
+
+
+
+ std::vector cameras(numImages);
+ // Parse bundle.out file for camera calibration parameters
+ for (int i = 0, infosId = 0; i < numImages; i++) {
+
+ ImgInfos infos;
+ std::string camName;
+
+ if (!shortListImages) {
+ infoPrevImage = infos = imgInfos[infosId];
+ camName = infos.name;
+ if (infosId > imgInfos.size())
+ break;
+ }
+ else {
+ // hack; use info of last available image, but (always) change name
+ if( i < imgInfos.size())
+ infoPrevImage = infos = imgInfos[infosId];
+ else
+ infos = infoPrevImage;
+
+ std::stringstream ss;
+ ss << std::setw(10) << std::setfill('0') << i;
+ std::string s = ss.str();
+ camName = std::string("path_camera") + s;
+ }
+
+ Matrix4f m; // bundler params
+
+ bundle_file >> m(0) >> m(1) >> m(2) >> m(3) >> m(4);
+ bundle_file >> m(5) >> m(6) >> m(7) >> m(8) >> m(9);
+ bundle_file >> m(10) >> m(11) >> m(12) >> m(13) >> m(14);
+
+ cameras[infosId] = InputCamera::Ptr(new InputCamera(infosId, infos.w, infos.h, m, true));
+ cameras[infosId]->name(camName);
+ cameras[infosId]->znear(zNear); cameras[infosId]->zfar(zFar);
+
+ ++infosId;
+ }
+
+ return cameras;
+ }
+
+ std::vector InputCamera::loadBundleFRIBR(const std::string& bundlerPath, float zNear, float zFar, const std::string& listImagePath)
+ {
+ SIBR_LOG << "Loading input cameras." << std::endl;
+
+ // check bundler file
+ std::ifstream bundle_file(bundlerPath);
+ if (!bundle_file.is_open()) {
+ SIBR_ERR << "Unable to load bundle file at path \"" << bundlerPath << "\"." << std::endl;
+ return {};
+ }
+
+
+ // read number of images
+ std::string line;
+ getline(bundle_file, line); // ignore first line - contains version
+ int numImages = 0;
+ bundle_file >> numImages; // read first value (number of images)
+ getline(bundle_file, line); // ignore the rest of the line
+
+ std::vector cameras(numImages);
+
+ Eigen::Matrix3f to_cv, converter;
+ to_cv << 1.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f;
+ converter <<
+ 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+ // Parse bundle.out file for camera calibration parameters
+ for (int i = 0; i < numImages; i++) {
+
+ float f, k1, k2;
+ bundle_file >> f >> k1 >> k2;
+
+ float r00, r01, r02;
+ float r10, r11, r12;
+ float r20, r21, r22;
+ bundle_file >> r00 >> r01 >> r02
+ >> r10 >> r11 >> r12
+ >> r20 >> r21 >> r22;
+
+ Eigen::Matrix3f rotation;
+ rotation(0, 0) = r00;
+ rotation(0, 1) = r01;
+ rotation(0, 2) = r02;
+ rotation(1, 0) = r10;
+ rotation(1, 1) = r11;
+ rotation(1, 2) = r12;
+ rotation(2, 0) = r20;
+ rotation(2, 1) = r21;
+ rotation(2, 2) = r22;
+
+ sibr::Matrix3f orientation = (to_cv * rotation).transpose();
+
+ float tx, ty, tz;
+ bundle_file >> tx >> ty >> tz;
+ sibr::Vector3f position = -orientation * (to_cv * Eigen::Vector3f(tx, ty, tz));
+
+ std::stringstream pad_stream;
+ pad_stream << std::setfill('0') << std::setw(10) << i - 2 << ".png";
+ std::string image_path = sibr::parentDirectory(bundlerPath) + "/" + listImagePath + pad_stream.str();
+
+ sibr::Vector2u resolution(2, 2);
+ sibr::ImageRGB temp;
+ if (!temp.load(image_path)) {
+
+ pad_stream.str("");
+ pad_stream << std::setfill('0') << std::setw(8) << i << ".jpg";
+ image_path = sibr::parentDirectory(bundlerPath) + "/" + listImagePath + pad_stream.str();
+ temp.load(image_path);
+ }
+ resolution = temp.size();
+
+ if (resolution.x() < 0 || resolution.y() < 0)
+ {
+ std::cerr << "Could not get resolution for calibrated camera: " << image_path << std::endl;
+ return {};
+ }
+
+ float dx = resolution.x() * 0.5f;
+ float dy = resolution.y() * 0.5f;
+
+ orientation = /*converter.transpose() **/ orientation * converter;
+ position = /*converter.transpose() **/ position;
+
+ cameras[i] = InputCamera::Ptr(new InputCamera(i, resolution.x(), resolution.y(), position, orientation, f, k1, k2, true));
+ cameras[i]->name(pad_stream.str());
+ cameras[i]->znear(zNear); cameras[i]->zfar(zFar);
+
+ }
+
+ return cameras;
+ }
+
+ std::vector InputCamera::loadMeshroom(const std::string& meshroomSFMPath, const float zNear, const float zFar)
+ {
+
+ std::string file_path = meshroomSFMPath + "/cameras.sfm";
+
+ std::ifstream json_file(file_path, std::ios::in);
+
+ if (!json_file)
+ {
+ std::cerr << "file loading failed: " << file_path << std::endl;
+ return std::vector();
+ }
+
+ std::vector cameras;
+
+ picojson::value v;
+ picojson::set_last_error(std::string());
+ std::string err = picojson::parse(v, json_file);
+ if (!err.empty()) {
+ picojson::set_last_error(err);
+ json_file.setstate(std::ios::failbit);
+ }
+
+ picojson::array& views = v.get("views").get();
+ picojson::array& intrinsincs = v.get("intrinsics").get();
+ picojson::array& poses = v.get("poses").get();
+
+ int numCameras = int(poses.size());
+ //meras.resize(numCameras);
+
+ sibr::Matrix3f converter;
+ converter << 1.0f, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+
+ size_t pose_idx, view_idx, intrinsic_idx;
+ std::vector splitS;
+
+
+ for (size_t i = 0; i < numCameras; ++i)
+ {
+
+ Matrix4f m;
+ //std::vector splitS;
+
+ pose_idx = i;
+ std::string pose_id = poses[pose_idx].get("poseId").get();
+
+ for (size_t j = 0; j < views.size(); j++) {
+ if (pose_id.compare(views[j].get("poseId").get()) == 0) {
+ view_idx = j;
+ break;
+ }
+ }
+
+ std::string intrinsics_id = views[view_idx].get("intrinsicId").get();
+
+ for (size_t k = 0; k < intrinsincs.size(); k++) {
+ if (intrinsics_id.compare(intrinsincs[k].get("intrinsicId").get()) == 0) {
+ intrinsic_idx = k;
+ break;
+ }
+ }
+
+ m(0) = std::stof(intrinsincs[intrinsic_idx].get("pxFocalLength").get());
+ float dx = std::stof(intrinsincs[intrinsic_idx].get("principalPoint").get()[0].get());
+ float dy = std::stof(intrinsincs[intrinsic_idx].get("principalPoint").get()[1].get());
+
+ //std::stof(intrinsincs[intrinsic_idx].get("distortionParams").get()[0].get());
+ m(1) = dx;
+ //std::stof(intrinsincs[intrinsic_idx].get("distortionParams").get()[1].get());
+ m(2) = dy;
+
+ std::string camName = pose_id + ".exr";
+ int width = std::stoi(views[view_idx].get("width").get());
+ int height = std::stoi(views[view_idx].get("height").get());
+
+ uint camId = uint(i);
+
+ picojson::array& center = poses[pose_idx].get("pose").get("transform").get("center").get();
+ picojson::array& rotation = poses[pose_idx].get("pose").get("transform").get("rotation").get();
+
+ std::vector rows;
+ Eigen::Vector3f row;
+ Eigen::Vector3f position(std::stof(center[0].get()), std::stof(center[1].get()), std::stof(center[2].get()));
+ Eigen::Matrix3f orientation;
+
+ for (int ii = 0; ii < 3; ++ii) {
+ for (int jj = 0; jj < 3; ++jj)
+ row(jj) = std::stof(rotation[jj + ii * 3].get());
+ rows.push_back(row);
+ }
+
+ orientation.row(0) = rows[0];
+ orientation.row(1) = rows[1];
+ orientation.row(2) = rows[2];
+ orientation = orientation * converter;
+
+ for (int ii = 0; ii < 9; ii++) {
+ m(3 + ii) = orientation(ii);
+ }
+
+ const sibr::Vector3f finTrans = -orientation.transpose() * position;
+ for (int ii = 0; ii < 3; ii++) {
+ m(12 + ii) = finTrans[ii];
+ }
+
+ sibr::InputCamera::Ptr cam = std::make_shared(camId, width, height, m, true);
+ cam->name(camName);
+ cam->znear(zNear);
+ cam->zfar(zFar);
+ cameras.push_back(cam);
+
+ }
+ return cameras;
+ }
+
+ Vector3f InputCamera::unprojectImgSpaceInvertY(const sibr::Vector2i& pixelPos, const float& depth) const
+ {
+ sibr::Vector2f pos2dGL(2.0f * ((pixelPos.cast() + sibr::Vector2f(0.5, 0.5)).cwiseQuotient(sibr::Vector2f(w(), h()))) - sibr::Vector2f(1, 1)); //to [-1,1]
+ pos2dGL.y() = -pos2dGL.y();
+ return unproject(sibr::Vector3f(pos2dGL.x(), pos2dGL.y(), depth));
+ }
+
+ Vector3f InputCamera::projectImgSpaceInvertY(const Vector3f& point3d) const
+ {
+ sibr::Vector3f pos2dGL = project(point3d);
+ pos2dGL.y() = -pos2dGL.y();
+ sibr::Vector2f pos2dImg = (0.5f * (pos2dGL.xy() + sibr::Vector2f(1, 1))).cwiseProduct(sibr::Vector2f(w(), h()));
+ return sibr::Vector3f(pos2dImg.x(), pos2dImg.y(), pos2dGL.z());
+ }
+
+ bool InputCamera::loadFromBinary(const std::string& filename)
+ {
+ ByteStream bytes;
+
+ if (bytes.load(filename))
+ {
+ uint8 version;
+ float focal;
+ float k1;
+ float k2;
+ uint16 w;
+ uint16 h;
+ Vector3f pos;
+ Quaternionf rot;
+ float fov;
+ float aspect;
+ float znear;
+ float zfar;
+
+ bytes
+ >> version;
+
+ if (version != SIBR_INPUTCAMERA_BINARYFILE_VERSION)
+ {
+ // Maybe the file format has been updated, or your binary file is not about InputCamera...
+ SIBR_ERR << "incorrect file format (version number does not correspond)." << std::endl;
+
+ return false;
+ }
+
+ bytes
+ >> focal >> k1 >> k2 >> w >> h
+ >> pos.x() >> pos.y() >> pos.z()
+ >> rot.w() >> rot.x() >> rot.y() >> rot.z()
+ >> fov >> aspect >> znear >> zfar
+ ;
+
+ _focal = focal;
+ _k1 = k1;
+ _k2 = k2;
+ _w = (uint)w;
+ _h = (uint)h;
+ Camera::position(pos);
+ Camera::rotation(rot);
+ Camera::fovy(fov);
+ Camera::aspect(aspect);
+ Camera::znear(znear);
+ Camera::zfar(zfar);
+
+ return true;
+ }
+ else
+ {
+ SIBR_WRG << "cannot open file '" << filename << "'." << std::endl;
+ }
+ return false;
+ }
+
+ void InputCamera::saveToBinary(const std::string& filename) const
+ {
+ ByteStream bytes;
+
+ uint8 version = SIBR_INPUTCAMERA_BINARYFILE_VERSION;
+ float focal = _focal;
+ float k1 = _k1;
+ float k2 = _k2;
+ uint16 w = (uint16)_w;
+ uint16 h = (uint16)_h;
+ Vector3f pos = position();
+ Quaternionf rot = rotation();
+ float fov = _fov;
+ float aspect = _aspect;
+ float znear = _znear;
+ float zfar = _zfar;
+
+ bytes
+ << version
+ << focal << k1 << k2 << w << h
+ << pos.x() << pos.y() << pos.z()
+ << rot.w() << rot.x() << rot.y() << rot.z()
+ << fov << aspect << znear << zfar
+ ;
+
+ bytes.saveToFile(filename);
+ }
+
+ void InputCamera::readFromFile(std::istream& infile)
+ {
+ std::string version;
+ infile >> version;
+ if (version != IBRVIEW_TOPVIEW_SAVEVERSION)
+ {
+ SIBR_WRG << "Sorry but your TopView camera configuration "
+ "is too old (we added new features since!)" << std::endl;
+ return;
+ }
+
+ Vector3f v;
+ infile >> v.x() >> v.y() >> v.z();
+ Quaternionf q;
+ infile >> q.x() >> q.y() >> q.z() >> q.w();
+ set(v, q);
+ }
+
+ void InputCamera::writeToFile(std::ostream& outfile) const
+ {
+ outfile << IBRVIEW_TOPVIEW_SAVEVERSION "\n";
+ Vector3f v = transform().position();
+ Quaternionf q = transform().rotation();
+ outfile << " " << v.x() << " " << v.y() << " " << v.z() << " ";
+ outfile << q.x() << " " << q.y() << " " << q.z() << " " << q.w();
+ }
+
+ std::string InputCamera::toBundleString(bool negativeZ, bool recomputeFocal) const {
+
+ std::stringstream ss;
+ ss << std::setprecision(16);
+ float focal;
+ if( recomputeFocal )
+ focal = 0.5f * h() / tan(fovy() / 2.0f); // We cannot set the focal but we need to compute it
+ else
+ focal = _focal;
+
+ Eigen::Matrix3f r = transform().rotation().toRotationMatrix();
+ sibr::Vector3f t = -transform().rotation().toRotationMatrix().transpose() * position();
+
+ ss << focal << " " << k1() << " " << k2() << "\n"; // The focal is set to zero in the loading module we use fov=2.0f * atan( 0.5f*h / focal) here
+ if (!negativeZ) {
+ ss << r(0) << " " << r(1) << " " << r(2) << "\n";
+ ss << r(3) << " " << r(4) << " " << r(5) << "\n";
+ ss << r(6) << " " << r(7) << " " << r(8) << "\n";
+ ss << t(0) << " " << t(1) << " " << t(2) << "\n";
+ }
+ else {
+ ss << r(0) << " " << -r(2) << " " << r(1) << "\n";
+ ss << r(3) << " " << -r(5) << " " << r(4) << "\n";
+ ss << r(6) << " " << -r(8) << " " << r(7) << "\n";
+ ss << t(0) << " " << t(1) << " " << t(2) << "\n";
+ }
+
+ return ss.str();
+ }
+
+ std::vector InputCamera::getImageCorners() const
+ {
+ return { {0,0}, {_w - 1, 0}, {_w - 1,_h - 1}, {0, _h - 1} };
+ }
+
+ void InputCamera::saveAsBundle(const std::vector& cams, const std::string& fileName, bool negativeZ, const bool exportImages, bool oldFocal) {
+
+ std::ofstream outputBundleCam;
+ outputBundleCam.open(fileName);
+ outputBundleCam << "# Bundle file v0.3" << std::endl;
+ outputBundleCam << cams.size() << " " << 0 << std::endl;
+
+ for (int c = 0; c < cams.size(); c++) {
+ auto& camIm = cams[c];
+ outputBundleCam << camIm->toBundleString(negativeZ, oldFocal);
+ }
+
+ outputBundleCam.close();
+
+ // Export the images list and empty images (useful for fribr).
+ if (exportImages) {
+ std::ofstream outList;
+ const std::string listpath = fileName + "/../list_images.txt";
+ const std::string imagesDir = fileName + "/../visualize/";
+ sibr::makeDirectory(imagesDir);
+
+ outList.open(listpath);
+ if (outList.good()) {
+ for (int i = 0; i < cams.size(); ++i) {
+ const sibr::InputCamera::Ptr cam = cams[i];
+ const std::string imageName = cam->name().empty() ? sibr::intToString<8>(i) + ".jpg" : cam->name();
+ outList << "visualize/" << imageName << " " << cam->w() << " " << cam->h() << std::endl;
+ cv::Mat3b dummy(cam->h(), cam->w());
+ cv::imwrite(imagesDir + imageName, dummy);
+ }
+ outList.close();
+ }
+ else {
+ SIBR_WRG << "Unable to export images list to path \"" << listpath << "\"." << std::endl;
+ }
+ }
+ }
+
+ void InputCamera::saveAsLookat(const std::vector& cams, const std::string& fileName)
+ {
+
+ std::ofstream file(fileName, std::ios::out | std::ios::trunc);
+ if (!file.is_open()) {
+ SIBR_WRG << "Unable to save to file at path " << fileName << std::endl;
+ return;
+ }
+ // Get the padding count.
+ const int len = int(std::floor(std::log10(cams.size()))) + 1;
+ for (size_t cid = 0; cid < cams.size(); ++cid) {
+ const auto& cam = cams[cid];
+ std::string id = std::to_string(cid);
+ const std::string pad = std::string(len - id.size(), '0');
+
+ const sibr::Vector3f& pos = cam.position();
+ const sibr::Vector3f& up = cam.up();
+ const sibr::Vector3f tgt = cam.position() + cam.dir();
+
+
+ file << "Cam" << pad << id;
+ file << " -D origin=" << pos[0] << "," << pos[1] << "," << pos[2];
+ file << " -D target=" << tgt[0] << "," << tgt[1] << "," << tgt[2];
+ file << " -D up=" << up[0] << "," << up[1] << "," << up[2];
+ file << " -D fovy=" << cam.fovy();
+ file << " -D clip=" << cam.znear() << "," << cam.zfar();
+ file << "\n";
+ }
+
+ file.close();
+ }
+
+ std::vector InputCamera::loadColmapBin(const std::string& colmapSparsePath, const float zNear, const float zFar, const int fovXfovYFlag)
+ {
+ const std::string camerasListing = colmapSparsePath + "/cameras.bin";
+ const std::string imagesListing = colmapSparsePath + "/images.bin";
+
+
+ std::ifstream camerasFile(camerasListing, std::ios::binary);
+ std::ifstream imagesFile(imagesListing, std::ios::binary);
+
+ if (!camerasFile.is_open()) {
+ SIBR_ERR << "Unable to load camera colmap file" << camerasListing << std::endl;
+ }
+ if (!imagesFile.is_open()) {
+ SIBR_WRG << "Unable to load images colmap file" << imagesListing << std::endl;
+ }
+
+ std::vector cameras;
+
+ std::string line;
+
+ struct CameraParametersColmap {
+ size_t id;
+ size_t width;
+ size_t height;
+ float fx;
+ float fy;
+ float dx;
+ float dy;
+ };
+
+ std::map cameraParameters;
+ const size_t num_cameras = ReadBinaryLittleEndian(&camerasFile);
+
+ for (size_t i = 0; i < num_cameras ; ++i) {
+
+ CameraParametersColmap params;
+
+ params.id = ReadBinaryLittleEndian(&camerasFile);
+ int model_id = ReadBinaryLittleEndian(&camerasFile);
+ params.width = ReadBinaryLittleEndian(&camerasFile);
+ params.height = ReadBinaryLittleEndian(&camerasFile);
+ std::vector Params(4);
+
+ ReadBinaryLittleEndian(&camerasFile, &Params);
+ params.fx = float(Params[0]);
+ params.fy = float(Params[1]);
+ params.dx = float(Params[2]);
+ params.dy = float(Params[3]);
+ cameraParameters[params.id] = params;
+ }
+
+ // Now load the individual images and their extrinsic parameters
+ sibr::Matrix3f converter;
+ converter << 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, -1;
+
+ const size_t num_reg_images = ReadBinaryLittleEndian(&imagesFile);
+ for (size_t i = 0; i < num_reg_images; ++i) {
+
+ uint cId = ReadBinaryLittleEndian(&imagesFile);
+ float qw = float(ReadBinaryLittleEndian