diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..0429e0b574e2f7ab3a2722ea6816b90c292325a1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,58 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +anigen/representations/mesh/flexicubes/images/block_init.png filter=lfs diff=lfs merge=lfs -text +anigen/representations/mesh/flexicubes/images/teaser_top.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/dog.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/lamp.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/machine_arm.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/owl.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/trex.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/whale.png filter=lfs diff=lfs merge=lfs -text +assets/images/teaser.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/machine_dog.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/spongebob.png filter=lfs diff=lfs merge=lfs -text +assets/gifs/eagle.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/evo.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/horse.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/iron_boy.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/machine_arm.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/machine_dog.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/mairo.gif filter=lfs diff=lfs merge=lfs -text +assets/gifs/money_tree.gif filter=lfs diff=lfs merge=lfs -text +assets/cond_images/brickbob.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/bruno_star.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/evo.png filter=lfs diff=lfs merge=lfs -text +assets/cond_images/iron_boy.png filter=lfs diff=lfs merge=lfs -text diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..15beddfe3a7d3504fceda0a7481616d0ff39d1c5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,63 @@ +FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3.10 python3-pip python3.10-dev \ + git git-lfs ffmpeg libsm6 libxext6 libgl1 libegl1 \ + build-essential ninja-build cmake rsync \ + && rm -rf /var/lib/apt/lists/* \ + && git lfs install + +RUN useradd -m -u 1000 user +USER user + +ENV HOME=/home/user \ + PATH=/home/user/.local/bin:$PATH \ + PYTHONUNBUFFERED=1 \ + PIP_NO_CACHE_DIR=1 \ + HF_HOME=/home/user/.cache/huggingface \ + TORCH_HOME=/home/user/.cache/torch \ + ATTN_BACKEND=xformers \ + SPARSE_ATTN_BACKEND=xformers \ + TORCH_CUDA_ARCH_LIST="7.5;8.6;8.9" + +WORKDIR $HOME/app + +COPY --chown=user:user . $HOME/app + +RUN python3.10 -m pip install --upgrade pip setuptools wheel + +RUN python3.10 -m pip install \ + torch==2.4.0 torchvision==0.19.0 \ + --index-url https://download.pytorch.org/whl/cu121 + +RUN python3.10 -m pip install \ + pillow imageio imageio-ffmpeg tqdm easydict scipy ninja psutil safetensors \ + scikit-learn opencv-python-headless rembg onnxruntime \ + trimesh xatlas pyvista pymeshfix igraph pygltflib geffnet \ + transformers \ + gradio==4.44.1 gradio_litmodel3d==0.0.1 "huggingface_hub<0.25" + +RUN python3.10 -m pip install \ + git+https://github.com/EasternJournalist/utils3d.git@9a4eb15e4021b67b12c460c7057d642626897ec8 + +RUN python3.10 -m pip install \ + "pytorch3d==0.7.8" \ + --find-links https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu121_pyt240/download.html + +RUN python3.10 -m pip install \ + xformers==0.0.27.post2 --index-url https://download.pytorch.org/whl/cu121 + +RUN python3.10 -m pip install spconv-cu121 + +RUN python3.10 -m pip install \ + kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.4.0_cu121.html + +RUN python3.10 -m pip install \ + "git+https://github.com/NVlabs/nvdiffrast.git" --no-build-isolation + +EXPOSE 7860 + +CMD ["python3.10", "app.py"] + diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..62319af92473d93bdaf3ea2e8c1f23f69059be9b --- /dev/null +++ b/README.md @@ -0,0 +1,231 @@ +--- +title: AniGen +sdk: gradio +sdk_version: 4.44.1 +python_version: 3.10.13 +startup_duration_timeout: 2h +--- + +

AniGen: Unified S3 Fields for Animatable 3D Asset Generation

+

arXiv +Project Page + +Tripo +

+

+ +AniGen is a unified framework that directly generates animate-ready 3D assets conditioned on a single image. Our key insight is to represent shape, skeleton, and skinning as mutually consistent *$S^3$ Fields* (Shape, Skeleton, Skin) defined over a shared spatial domain. To enable the robust learning of these fields, we introduce two technical innovations: (i) a *confidence-decaying skeleton field* that explicitly handles the geometric ambiguity of bone prediction at Voronoi boundaries, and (ii) a *dual skin feature field* that decouples skinning weights from specific joint counts, allowing a fixed-architecture network to predict rigs of arbitrary complexity. Built upon a two-stage flow-matching pipeline, AniGen first synthesizes a sparse structural scaffold and then generates dense geometry and articulation in a structured latent space. Extensive experiments demonstrate that AniGen substantially outperforms state-of-the-art sequential baselines in rig validity and animation quality, generalizing effectively to in-the-wild images across diverse categories including animals, humanoids, and machinery. + + +## ๐Ÿ”ฎ Overview + +AniGen takes a **single image** as input and automatically produces a fully rigged, animate-ready 3D asset, complete with a coherent mesh, an articulated skeleton, and smooth skinning weights. The generated assets can be directly imported into standard 3D pipelines and driven by off-the-shelf motion data, enabling immediate deployment across a wide spectrum of downstream applications, including **embodied AI** agent construction, **physics-based simulation**, **character animation**, **dynamic scene creation**, and **articulated object manipulation**. + + + + + + + + + + + + + + +

Machine Arm

Machine Dog

Money Tree

Iron Boy

Mairo

Evo

Horse

Eagle
+ + +## ๐Ÿ“ฆ Installation + +### Prerequisites +- **System**: The code is currently tested only on **Linux**. +- **Hardware**: An NVIDIA GPU with at least 18GB of memory is necessary. The code has been verified on NVIDIA A800 and RTX3090 GPUs. +- **Software**: + - The [CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit-archive) is needed to compile certain submodules. The code has been tested with CUDA versions 11.8 and 12.2. + - [Conda](https://docs.anaconda.com/miniconda/install/#quick-command-line-install) is recommended for managing dependencies. + - Python version 3.8 or higher is required. + +### Installation Steps +1. Clone the repo: + ```sh + git clone --recurse-submodules https://github.com/VAST-AI-Research/AniGen.git + cd AniGen + ``` + +2. Install the dependencies: + + We recommend using [uv](https://docs.astral.sh/uv/) for fast, reliable installs. The setup script will also work with plain `pip` if `uv` is not available. + + Create a new virtual environment and install everything: + ```sh + source ./setup.sh --new-env --all + ``` + + If your network connection to PyPI is unstable or slow, you can use the Tsinghua mirror: + ```sh + source ./setup.sh --new-env --all --tsinghua + ``` + + If you already have an environment with PyTorch installed, install into it directly: + ```sh + source ./setup.sh --basic + ``` + + > [!NOTE] + > The setup script auto-detects your CUDA version and installs matching wheels for PyTorch, spconv, pytorch3d, and nvdiffrast. [DSINE](https://github.com/baegwangbin/DSINE) (used for surface normal estimation) is loaded at runtime via `torch.hub` and does not require separate installation. + + + +## ๐Ÿค– Pretrained Models + +We provide the following pretrained models on [Hugging Face](https://huggingface.co/VAST-AI/AniGen/tree/main). Please make sure to download all necessary weights from this page, including the required dinov2, dsine, and vgg checkpoints. + +> [!TIP] +> **Recommended:** Use **SS-Flow-Duet** + **SLAT-Flow-Auto** if you do not have specific requirements. +> - For more detailed skeleton (including character fingers) โ†’ **SS-Flow-Duet** +> - For better geometry generalization โ†’ **SS-Flow-Solo** +> - **SLAT-Flow-Control** supports density levels 0โ€“4, but if the density condition significantly deviates from the proper value for the object, skinning weights may be damaged. + +| DAE Model | Description | Download | +| --- | --- | --- | +| SS-DAE | Encoder&Decoder of SS | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/ss_dae) | +| SLAT-DAE | Encoder&Decoder of SLAT | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/slat_dae) | + +| SS Model | Description | Download | +| --- | --- | --- | +| SS-Flow-Duet | Detailed Skeleton (Full-FT Geo) | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/ss_flow_duet) | +| SS-Flow-Epic | Geometry&Skeleton Balanced (LoRA-FT Geo) | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/ss_flow_epic) | +| SS-Flow-Solo | Accurate Geometry (Freeze Geo) | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/ss_flow_solo) | + +| SLAT Model | Description | Download | +| --- | --- | --- | +| SLAT-Flow-Auto | Automatically Determine Joint Number | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/slat_flow_auto) | +| SLAT-Flow-Control | Controllable Joint Density | [Download](https://huggingface.co/VAST-AI/AniGen/tree/main/ckpts/anigen/slat_flow_control) | + + +## ๐Ÿ’ก Usage + +### Minimal Example + +Here is an [example](example.py) of how to use the pretrained models for 3D asset generation. + + +After running the code, you will get the following files: +- `mesh.glb`: a rigged mesh file +- `skeleton.glb`: a skeleton visualization file +- `processed_image.png`: the masked image as the condition + +### AniGen Pipeline (Rigged Mesh + Skeleton) + +For AniGen checkpoints in this repo (e.g. `ckpts/anigen/ss_flow_solo` + `ckpts/anigen/slat_flow_control`), you can run: +```sh +python example.py --image_path assets/cond_images/trex.png +``` + +### Web Demo + +[app.py](app.py) provides a simple web demo for 3D asset generation. Since this demo is based on [Gradio](https://gradio.app/), additional dependencies are required: +```sh +source ./setup.sh --demo +``` + +If needed, you can also install the demo dependencies via the Tsinghua mirror: +```sh +source ./setup.sh --demo --tsinghua +``` + +After installing the dependencies, you can run the demo with the following command: +```sh +python app.py +``` + +Then, you can access the demo at the address shown in the terminal. + +***The web demo is also available on [Hugging Face Spaces](https://huggingface.co/spaces/VAST-AI/AniGen)!*** + + + +## ๐Ÿ‹๏ธ Training + +### Training Data + +Sample training data is available at [AniGen_sample_data](https://huggingface.co/datasets/VAST-AI/AniGen_sample_data). To prepare your own data, refer to [TRELLIS](https://github.com/microsoft/TRELLIS) and the sample data format. + +### Prerequisites + +> [!NOTE] +> Training requires the **CUBVH** extension (`extensions/CUBVH/`), which is automatically built by `setup.sh`. It is **not** needed for inference (`app.py`, `example.py`). + +### Training Commands + +The pipeline has five stages. Later stages depend on earlier ones, so please train in order: + +```sh +# Stage 1: Skin AutoEncoder +python train.py --config configs/anigen_skin_ae.json --output_dir outputs/anigen_skin_ae + +# Stage 2: Sparse Structure DAE +python train.py --config configs/ss_dae.json --output_dir outputs/ss_dae + +# Stage 3: Structured Latent DAE +python train.py --config configs/slat_dae.json --output_dir outputs/slat_dae + +# Stage 4: SS Flow Matching (image-conditioned generation) +python train.py --config configs/ss_flow_duet.json --output_dir outputs/ss_flow_duet + +# Stage 5: SLAT Flow Matching (image-conditioned generation) +python train.py --config configs/slat_flow_auto.json --output_dir outputs/slat_flow_auto +``` + +### Multi-Node / Multi-GPU + +Append the following flags for distributed training across multiple machines and GPUs: + +```sh +python train.py --config configs/.json --output_dir outputs/ \ + --num_nodes XX --node_rank XX --master_addr XX --master_port XX +``` + +### Model Variants + +Other SS Flow variants (`ss_flow_epic`, `ss_flow_solo`) and SLAT Flow variants (`slat_flow_control`, `slat_flow_gsn_auto`) are available under `ckpts/anigen/`. Their config files can be found at `ckpts/anigen//config.json`. + +### Resume / Restart + +Training automatically resumes from the latest checkpoint in `--output_dir`. To start fresh, pass `--ckpt none`. + + +## License + +This project's source code is released under the [MIT License](LICENSE). + +> [!IMPORTANT] +> This repository includes third-party components with additional license restrictions. In particular, `extensions/CUBVH/` contains BVH code derived from NVIDIA's [instant-ngp](https://github.com/NVlabs/instant-ngp), which is licensed for **non-commercial / research use only**. See [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md) for details. + +## Acknowledgements + +- [TRELLIS](https://github.com/microsoft/TRELLIS) by Microsoft +- [cuBVH](https://github.com/ashawkey/cubvh) by Jiaxiang Tang +- [tiny-cuda-nn](https://github.com/NVlabs/tiny-cuda-nn) and [instant-ngp](https://github.com/NVlabs/instant-ngp) by Thomas Mรผller / NVIDIA +- [FlexiCubes](https://github.com/nv-tlabs/FlexiCubes) by NVIDIA + +We sincerely appreciate the contributions of these excellent projects and their authors. We believe open source helps accelerate research, lower barriers to innovation, and make progress more accessible to the broader community. + + + +## ๐Ÿ“œ Citation + +If you find this work helpful, please consider citing our paper: + +```bibtex +@article{huang2026anigen, + title = {AniGen: Unified $S^3$ Fields for Animatable 3D Asset Generation}, + author = {Huang, Yi-Hua and Zhou, Zi-Xin and He, Yuting and Chang, Chirui + and Pu, Cheng-Feng and Yang, Ziyi and Guo, Yuan-Chen + and Cao, Yan-Pei and Qi, Xiaojuan}, + journal = {ACM SIGGRAPH}, + year = {2026} +} +``` diff --git a/THIRD_PARTY_LICENSES.md b/THIRD_PARTY_LICENSES.md new file mode 100644 index 0000000000000000000000000000000000000000..80af48aa9f835bc31726695eb5e324d120354442 --- /dev/null +++ b/THIRD_PARTY_LICENSES.md @@ -0,0 +1,30 @@ +# Third-Party Licenses + +## extensions/CUBVH/ โ€” cuBVH (CUDA Mesh BVH Acceleration) + +Originally created by [Jiaxiang Tang (ashawkey)](https://github.com/ashawkey/cubvh), +modified by Yi-Hua Huang (yihua7). + +### MIT License (cubvh overall) +- File: `extensions/CUBVH/LICENSE` +- Copyright (c) 2022 Jiaxiang Tang (ashawkey) +- Copyright (c) 2025 Yi-Hua Huang (yihua7) + +### NVIDIA Source Code License โ€” Non-Commercial (BVH from instant-ngp) +- File: `extensions/CUBVH/LICENSE_NVIDIA` +- Copyright (c) 2022, NVIDIA Corporation & affiliates +- **USE RESTRICTED TO NON-COMMERCIAL / RESEARCH PURPOSES ONLY** + +### BSD 3-Clause License (gpu_memory.h from tiny-cuda-nn) +- File header: `extensions/CUBVH/include/gpu/gpu_memory.h` +- Copyright (c) 2020-2022, NVIDIA CORPORATION + +### Apache License 2.0 (pcg32.h) +- File header: `extensions/CUBVH/include/gpu/pcg32.h` +- Author: Wenzel Jakob, modified by tiny-cuda-nn + +## anigen/representations/mesh/flexicubes/ โ€” FlexiCubes + +- File: `anigen/representations/mesh/flexicubes/LICENSE.txt` +- Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES +- Apache License 2.0 diff --git a/anigen/__init__.py b/anigen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..20d240afc9c26a21aee76954628b3d4ef9a1ccbd --- /dev/null +++ b/anigen/__init__.py @@ -0,0 +1,6 @@ +from . import models +from . import modules +from . import pipelines +from . import renderers +from . import representations +from . import utils diff --git a/anigen/datasets/__init__.py b/anigen/datasets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..064aa8135e9289cc1e39802cd63d7d30ba03d16a --- /dev/null +++ b/anigen/datasets/__init__.py @@ -0,0 +1,32 @@ +import importlib + +__attributes = { + 'AniGenSparseStructure': 'anigen_sparse_structure', + 'AniGenSparseFeat2Skeleton': 'anigen_sparse_feat2skeleton', + 'AniGenSparseFeat2Render': 'anigen_sparse_feat2render', + + 'AniGenSparseStructureLatent': 'anigen_sparse_structure_latent', + 'TextConditionedAniGenSparseStructureLatent': 'anigen_sparse_structure_latent', + 'ImageConditionedAniGenSparseStructureLatent': 'anigen_sparse_structure_latent', + + 'AniGenSLat': 'anigen_structured_latent', + 'AniGenTextConditionedSLat': 'anigen_structured_latent', + 'AniGenImageConditionedSLat': 'anigen_structured_latent', +} + +__submodules = [] + +__all__ = list(__attributes.keys()) + __submodules + +def __getattr__(name): + if name not in globals(): + if name in __attributes: + module_name = __attributes[name] + module = importlib.import_module(f".{module_name}", __name__) + globals()[name] = getattr(module, name) + elif name in __submodules: + module = importlib.import_module(f".{name}", __name__) + globals()[name] = module + else: + raise AttributeError(f"module {__name__} has no attribute {name}") + return globals()[name] diff --git a/anigen/datasets/anigen_sparse_feat2skeleton.py b/anigen/datasets/anigen_sparse_feat2skeleton.py new file mode 100644 index 0000000000000000000000000000000000000000..d3075623cd711da841c5e905ec349703a3bc5d10 --- /dev/null +++ b/anigen/datasets/anigen_sparse_feat2skeleton.py @@ -0,0 +1,290 @@ +import os +from PIL import Image +import json +import numpy as np +import pandas as pd +import torch +import utils3d.torch +from ..modules.sparse.basic import SparseTensor +from .components import StandardDatasetBase + + +class AniGenSparseFeat2Skeleton(StandardDatasetBase): + """ + SparseFeat2Render dataset. + + Args: + roots (str): paths to the dataset + image_size (int): size of the image + model (str): model name + resolution (int): resolution of the data + min_aesthetic_score (float): minimum aesthetic score + max_num_voxels (int): maximum number of voxels + """ + def __init__( + self, + roots: str, + image_size: int, + model: str = 'dinov2_vitl14_reg', + resolution: int = 64, + min_aesthetic_score: float = 5.0, + max_num_voxels: int = 32768, + load_cubvh: bool = False, + skl_dilation_iter: int = 0, + skl_dilation_random_aug: bool = False, + skl_dilation_random_aug_prob: float = 0.5, + filter_bad_skin: bool = False, + + test_mode: bool = True, # Test the model performance + is_test: bool = False, # Train or validation + skin_accum_as_flow: bool = False, # Accumulate skin weights from bottom to top as flow-by probability + local_rank: int = 0, + joint_merge_res: int = 64, + **kwargs, + ): + self.image_size = image_size + self.model = model + self.resolution = resolution + self.min_aesthetic_score = min_aesthetic_score + self.max_num_voxels = max_num_voxels + self.value_range = (0, 1) + self.load_cubvh = load_cubvh + self.skl_dilation_iter = skl_dilation_iter + self.skl_dilation_random_aug = skl_dilation_random_aug + self.skl_dilation_random_aug_prob = skl_dilation_random_aug_prob + self.filter_bad_skin = filter_bad_skin + + self.test_mode = test_mode + self.is_test = is_test + self.skin_accum_as_flow = skin_accum_as_flow + self.local_rank = local_rank + self.joint_merge_res = joint_merge_res + + super().__init__(roots, **kwargs) + self.is_bad_skin_list = self.metadata['is_bad_skin'].values + + def filter_metadata(self, metadata): + stats = {} + metadata = metadata[metadata[f'feature_{self.model}']] + stats['With features'] = len(metadata) + metadata = metadata[metadata['aesthetic_score'] >= self.min_aesthetic_score] + stats[f'Aesthetic score >= {self.min_aesthetic_score}'] = len(metadata) + metadata = metadata[metadata['num_voxels'] <= self.max_num_voxels] + stats[f'Num voxels <= {self.max_num_voxels}'] = len(metadata) + + if 'is_bad_skeleton' in metadata.columns: + metadata = metadata[~metadata['is_bad_skeleton']] + if self.filter_bad_skin and 'is_bad_skin' in metadata.columns: + metadata = metadata[~metadata['is_bad_skin']] + + if self.test_mode: + metadata = metadata[metadata['is_test']] if self.is_test else metadata[~metadata['is_test']] + + return metadata, stats + + def _get_image(self, root, instance): + with open(os.path.join(root, 'renders', instance, 'transforms.json')) as f: + metadata = json.load(f) + n_views = len(metadata['frames']) + view = np.random.randint(n_views) + metadata = metadata['frames'][view] + fov = metadata['camera_angle_x'] + intrinsics = utils3d.torch.intrinsics_from_fov_xy(torch.tensor(fov), torch.tensor(fov)) + c2w = torch.tensor(metadata['transform_matrix']) + c2w[:3, 1:3] *= -1 + extrinsics = torch.inverse(c2w) + + image_path = os.path.join(root, 'renders', instance, metadata['file_path']) + image = Image.open(image_path) + alpha = image.getchannel(3) + image = image.convert('RGB') + image = image.resize((self.image_size, self.image_size), Image.Resampling.LANCZOS) + alpha = alpha.resize((self.image_size, self.image_size), Image.Resampling.LANCZOS) + image = torch.tensor(np.array(image)).permute(2, 0, 1).float() / 255.0 + alpha = torch.tensor(np.array(alpha)).float() / 255.0 + + return { + 'image': image, + 'alpha': alpha, + 'extrinsics': extrinsics, + 'intrinsics': intrinsics, + } + + def _get_feat(self, root, instance): + DATA_RESOLUTION = 64 + feats_path = os.path.join(root, 'features', self.model, f'{instance}.npz') + feats_data = np.load(feats_path, allow_pickle=True) + coords = torch.tensor(feats_data['indices']).int() + feats = torch.tensor(feats_data['patchtokens']).float() + + position = utils3d.io.read_ply(os.path.join(root, 'voxels', f'{instance}_skeleton.ply'))[0] + coords_skl = ((torch.tensor(position) + 0.5) * self.resolution).int().contiguous() + ss_skl = torch.zeros(1, self.resolution, self.resolution, self.resolution, dtype=torch.long) + ss_skl[0, coords_skl[:,0], coords_skl[:,1], coords_skl[:,2]] = 1 + ss_skl_ori = ss_skl.clone() + if self.skl_dilation_random_aug or self.skl_dilation_iter > 0: + size = max(0, self.skl_dilation_iter) * 2 + 1 + if self.skl_dilation_iter > 0: + kernel = torch.ones(1, 1, size, size, size, dtype=torch.float32, device=ss_skl.device) + ss_skl = torch.nn.functional.conv3d(ss_skl.float()[None], kernel, padding=self.skl_dilation_iter) + ss_skl = (ss_skl > 0).long().squeeze(0) + coords_skl = torch.nonzero(ss_skl[0], as_tuple=False).int() + if self.skl_dilation_random_aug and np.random.rand() < self.skl_dilation_random_aug_prob: + size_small, size_large = size - 2, size + 2 + kernel_large = torch.ones(1, 1, size_large, size_large, size_large, dtype=torch.float32, device=ss_skl_ori.device) + ss_skl_large = torch.nn.functional.conv3d(ss_skl_ori.float()[None], kernel_large, padding=size_large//2) + ss_skl_large = (ss_skl_large > 0).long().squeeze(0) + if size_small > 1: + kernel_small = torch.ones(1, 1, size_small, size_small, size_small, dtype=torch.float32, device=ss_skl_ori.device) + ss_skl_small = torch.nn.functional.conv3d(ss_skl_ori.float()[None], kernel_small, padding=size_small//2) + ss_skl_small = (ss_skl_small > 0).long().squeeze(0) + else: + ss_skl_small = torch.zeros_like(ss_skl) + + ss_skl_random_mask = torch.rand_like(ss_skl.float()) < 0.5 + ss_skl = ss_skl_small * ss_skl_random_mask.long() + ss_skl_large * (1 - ss_skl_random_mask.long()) + coords_skl = torch.nonzero(ss_skl[0], as_tuple=False).int() + feats_skl = torch.zeros((coords_skl.shape[0], 0), dtype=torch.float32) + + if self.resolution != DATA_RESOLUTION: + factor = DATA_RESOLUTION // self.resolution + coords = coords // factor + coords, idx = coords.unique(return_inverse=True, dim=0) + feats = torch.scatter_reduce( + torch.zeros(coords.shape[0], feats.shape[1], device=feats.device), + dim=0, + index=idx.unsqueeze(-1).expand(-1, feats.shape[1]), + src=feats, + reduce='mean' + ) + coords_skl = coords_skl // factor + coords_skl, idx = coords_skl.unique(return_inverse=True, dim=0) + feats_skl = torch.scatter_reduce( + torch.zeros(coords_skl.shape[0], feats_skl.shape[1], device=feats_skl.device), + dim=0, + index=idx.unsqueeze(-1).expand(-1, feats_skl.shape[1]), + src=feats_skl, + reduce='mean' + ) + + return { + 'coords': coords, + 'feats': feats, + 'coords_skl': coords_skl, + 'feats_skl': feats_skl, + } + + @torch.no_grad() + def visualize_sample(self, sample: dict): + return sample['image'] + + @staticmethod + def collate_fn(batch): + pack = {} + coords = [] + coords_skl = [] + for i, b in enumerate(batch): + coords.append(torch.cat([torch.full((b['coords'].shape[0], 1), i, dtype=torch.int32), b['coords']], dim=-1)) + coords_skl.append(torch.cat([torch.full((b['coords_skl'].shape[0], 1), i, dtype=torch.int32), b['coords_skl']], dim=-1)) + coords = torch.cat(coords) + feats = torch.cat([b['feats'] for b in batch]) + pack['feats'] = SparseTensor( + coords=coords, + feats=feats, + ) + coords_skl = torch.cat(coords_skl) + feats_skl = torch.cat([b['feats_skl'] for b in batch]) + pack['feats_skl'] = SparseTensor( + coords=coords_skl, + feats=feats_skl, + ) + + pack['image'] = torch.stack([b['image'] for b in batch]) + pack['alpha'] = torch.stack([b['alpha'] for b in batch]) + pack['extrinsics'] = torch.stack([b['extrinsics'] for b in batch]) + pack['intrinsics'] = torch.stack([b['intrinsics'] for b in batch]) + + pack['joints'] = [b['joints'] for b in batch] + pack['parents'] = [b['parents'] for b in batch] + pack['skin'] = [b['skin'] for b in batch] + pack['is_bad_skin'] = [b['is_bad_skin'] for b in batch] + + # collate other data + keys = [k for k in batch[0].keys() if k not in ['coords', 'feats', 'coords_skl', 'feats_skl', 'image', 'alpha', 'extrinsics', 'intrinsics', 'joints', 'parents', 'skin']] + for k in keys: + if isinstance(batch[0][k], torch.Tensor): + pack[k] = torch.stack([b[k] for b in batch]) + elif isinstance(batch[0][k], list): + pack[k] = sum([b[k] for b in batch], []) + else: + pack[k] = [b[k] for b in batch] + + return pack + + def _get_geo(self, root, instance): + skeleton_path = os.path.join(root, 'skeleton', instance, 'skeleton_voxelized.npz') + skl_data = np.load(skeleton_path, allow_pickle=True) + verts, face = np.array(skl_data['vertices'], dtype=np.float32), skl_data['faces'] + mesh = { + "vertices" : torch.from_numpy(verts), + "faces" : torch.from_numpy(face), + } + geo = {"mesh": mesh} + if self.load_cubvh: + from cubvh import cuBVH + torch.cuda.set_device(self.local_rank) + cubvh_path = os.path.join(root, 'skeleton', instance, 'cubvh.pth') + if os.path.exists(cubvh_path): + bvh = torch.load(cubvh_path, weights_only=False) + if isinstance(bvh, cuBVH): + bvh = bvh.to('cpu') + else: + device = torch.device(f"cuda:{self.local_rank}") + bvh = cuBVH(mesh["vertices"], mesh["faces"], device=device) + bvh = bvh.to('cpu') + torch.save(bvh, cubvh_path) + geo["cubvh"] = bvh + return geo + + def _get_skeleton(self, root, instance): + skeleton_path = os.path.join(root, 'skeleton', instance, 'skeleton_voxelized.npz') + skl_data = np.load(skeleton_path, allow_pickle=True) + joints, parents, skin = skl_data['joints'], skl_data['parents'], skl_data['skin'] + parents[parents==None] = -1 + parents = np.array(parents, dtype=np.int32) + + skin[np.where(skl_data['skin'].max(axis=1)==0)[0], 0] = 1.0 + skin = skin / skin.sum(-1, keepdims=True) + + if self.skin_accum_as_flow: + root_idx = np.where(parents == -1)[0][0] + def sum_children(joint_idx, skin_weights): + children = np.where(parents == joint_idx)[0] + for child in children: + skin_weights[:, joint_idx] += sum_children(child, skin_weights) + return skin_weights[:, joint_idx] + sum_children(root_idx, skin) + skin = np.clip(skin, 0, 1) + + is_bad_skin = self.metadata['is_bad_skin'][instance] + + return { + 'joints': torch.from_numpy(joints).float(), + 'parents': torch.from_numpy(parents).int(), + 'skin': torch.from_numpy(skin).float(), + 'is_bad_skin': is_bad_skin + } + + def get_instance(self, root, instance): + image = self._get_image(root, instance) + feat = self._get_feat(root, instance) + geo = self._get_geo(root, instance) + skl = self._get_skeleton(root, instance) + + return { + **image, + **feat, + **geo, + **skl, + 'instance': instance, + } diff --git a/anigen/datasets/anigen_sparse_structure.py b/anigen/datasets/anigen_sparse_structure.py new file mode 100644 index 0000000000000000000000000000000000000000..c4c9fff6f55383a00e4e3933e28fc8d94072d0c8 --- /dev/null +++ b/anigen/datasets/anigen_sparse_structure.py @@ -0,0 +1,124 @@ +import os +import json +from typing import Union +import numpy as np +import pandas as pd +import torch +from torch.utils.data import Dataset +import utils3d +from .components import StandardDatasetBase +from ..representations.octree import DfsOctree as Octree +from ..renderers import OctreeRenderer + + +class AniGenSparseStructure(StandardDatasetBase): + """ + Sparse structure dataset + + Args: + roots (str): path to the dataset + resolution (int): resolution of the voxel grid + min_aesthetic_score (float): minimum aesthetic score of the instances to be included in the dataset + """ + + def __init__(self, + roots, + resolution: int = 64, + min_aesthetic_score: float = 5.0, + skl_dilation_iter: int = 0, + **kwargs, + ): + self.resolution = resolution + self.min_aesthetic_score = min_aesthetic_score + self.skl_dilation_iter = skl_dilation_iter + self.value_range = (0, 1) + + super().__init__(roots) + + def filter_metadata(self, metadata): + stats = {} + metadata = metadata[metadata[f'voxelized']] + stats['Voxelized'] = len(metadata) + metadata = metadata[metadata['aesthetic_score'] >= self.min_aesthetic_score] + stats[f'Aesthetic score >= {self.min_aesthetic_score}'] = len(metadata) + return metadata, stats + + def get_ply_instance(self, root, instance, dilation_iter=None): + if dilation_iter is None: + dilation_iter = self.skl_dilation_iter + + position = utils3d.io.read_ply(os.path.join(root, 'voxels', f'{instance}.ply'))[0] + coords = ((torch.tensor(position) + 0.5) * self.resolution).int().contiguous() + ss = torch.zeros(1, self.resolution, self.resolution, self.resolution, dtype=torch.long) + ss[:, coords[:, 0], coords[:, 1], coords[:, 2]] = 1 + if dilation_iter > 0: + # 3D Dilation + size = dilation_iter * 2 + 1 + kernel = torch.ones(1, 1, size, size, size, dtype=torch.float32, device=ss.device) + ss = torch.nn.functional.conv3d(ss.float()[None], kernel, padding=dilation_iter) + ss = (ss > 0).long().squeeze(0) + return ss + + def get_instance(self, root, instance): + ss = self.get_ply_instance(root, instance, dilation_iter=0) + ss_skl = self.get_ply_instance(root, f'{instance}_skeleton', dilation_iter=self.skl_dilation_iter) + return {'ss': ss, 'ss_skl': ss_skl, 'instance': instance} + + @torch.no_grad() + def visualize_sample(self, ss: Union[torch.Tensor, dict]): + ss = ss if isinstance(ss, torch.Tensor) else ss['ss'] + + renderer = OctreeRenderer() + renderer.rendering_options.resolution = 512 + renderer.rendering_options.near = 0.8 + renderer.rendering_options.far = 1.6 + renderer.rendering_options.bg_color = (0, 0, 0) + renderer.rendering_options.ssaa = 4 + renderer.pipe.primitive = 'voxel' + + # Build camera + yaws = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + yaws_offset = 0. # np.random.uniform(-np.pi / 4, np.pi / 4) + yaws = [y + yaws_offset for y in yaws] + pitch = np.linspace(-np.pi / 4, np.pi / 4, num=4) # [np.random.uniform(-np.pi / 4, np.pi / 4) for _ in range(4)] + + exts = [] + ints = [] + for yaw, pitch in zip(yaws, pitch): + orig = torch.tensor([ + np.sin(yaw) * np.cos(pitch), + np.cos(yaw) * np.cos(pitch), + np.sin(pitch), + ]).float().cuda() * 2 + fov = torch.deg2rad(torch.tensor(30)).cuda() + extrinsics = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intrinsics = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + exts.append(extrinsics) + ints.append(intrinsics) + + images = [] + + # Build each representation + ss = ss.cuda() + for i in range(ss.shape[0]): + representation = Octree( + depth=10, + aabb=[-0.5, -0.5, -0.5, 1, 1, 1], + device='cuda', + primitive='voxel', + sh_degree=0, + primitive_config={'solid': True}, + ) + coords = torch.nonzero(ss[i, 0], as_tuple=False) + representation.position = coords.float() / self.resolution + representation.depth = torch.full((representation.position.shape[0], 1), int(np.log2(self.resolution)), dtype=torch.uint8, device='cuda') + + image = torch.zeros(3, 1024, 1024).cuda() + tile = [2, 2] + for j, (ext, intr) in enumerate(zip(exts, ints)): + res = renderer.render(representation, ext, intr, colors_overwrite=representation.position) + image[:, 512 * (j // tile[1]):512 * (j // tile[1] + 1), 512 * (j % tile[1]):512 * (j % tile[1] + 1)] = res['color'] + images.append(image) + + return torch.stack(images) + \ No newline at end of file diff --git a/anigen/datasets/anigen_sparse_structure_latent.py b/anigen/datasets/anigen_sparse_structure_latent.py new file mode 100644 index 0000000000000000000000000000000000000000..3a925c30906c3193ddc699ed0b034004a83afeb6 --- /dev/null +++ b/anigen/datasets/anigen_sparse_structure_latent.py @@ -0,0 +1,238 @@ +import os +import json +from typing import * +import numpy as np +import torch +import utils3d +from ..representations.octree import DfsOctree as Octree +from ..renderers import OctreeRenderer +from .components import StandardDatasetBase, TextConditionedMixin, ImageConditionedMixin +from .. import models +from ..utils.dist_utils import read_file_dist +import torch.nn.functional as F + + +class AniGenSparseStructureLatentVisMixin: + def __init__( + self, + *args, + pretrained_ss_dec: str = None, + ss_dec_path: Optional[str] = '', + ss_dec_ckpt: Optional[str] = 'final', + **kwargs + ): + super().__init__(*args, **kwargs) + self.ss_dec = None + self.pretrained_ss_dec = pretrained_ss_dec + self.ss_dec_path = ss_dec_path + self.ss_dec_ckpt = ss_dec_ckpt + + def _loading_ss_dec(self): + if self.ss_dec is not None: + return + if self.ss_dec_path is not None: + cfg = json.load(open(os.path.join(self.ss_dec_path, 'config.json'), 'r')) + decoder = getattr(models, cfg['models']['decoder']['name'])(**cfg['models']['decoder']['args']) + ckpt_path = os.path.join(self.ss_dec_path, 'ckpts', f'decoder_{self.ss_dec_ckpt}.pt') + decoder.load_state_dict(torch.load(ckpt_path, map_location='cpu', weights_only=True)) + # decoder.load_state_dict(torch.load(read_file_dist(ckpt_path), map_location='cpu', weights_only=True)) # Got stuck... + else: + decoder = models.from_pretrained(self.pretrained_ss_dec) + self.ss_dec = decoder.cuda().eval() + + def _delete_ss_dec(self): + del self.ss_dec + self.ss_dec = None + + @torch.no_grad() + def decode_latent(self, z, z_skl, batch_size=4): + self._loading_ss_dec() + ss = [] + ss_skl = [] + if self.normalization is not None: + z = z * self.std.to(z.device) + self.mean.to(z.device) + if self.normalization_skl is not None: + z_skl = z_skl * self.std_skl.to(z_skl.device) + self.mean_skl.to(z_skl.device) + for i in range(0, z.shape[0], batch_size): + z_, z_skl_ = z[i:i+batch_size], z_skl[i:i+batch_size] + ss_, ss_skl_ = self.ss_dec(z_, z_skl_) + ss.append(ss_) + ss_skl.append(ss_skl_) + ss = torch.cat(ss, dim=0) + ss_skl = torch.cat(ss_skl, dim=0) + self._delete_ss_dec() + return ss, ss_skl + + @torch.no_grad() + def visualize_sample(self, x_0: Union[torch.Tensor, dict], x_0_skl: Optional[Union[torch.Tensor, dict]]=None, **kwargs): + + x_0_skl = x_0_skl if isinstance(x_0, torch.Tensor) else x_0['x_0_skl'] + x_0 = x_0 if isinstance(x_0, torch.Tensor) else x_0['x_0'] + x_0, x_0_skl = self.decode_latent(x_0.cuda(), x_0_skl.cuda()) + + renderer = OctreeRenderer() + renderer.rendering_options.resolution = 512 + renderer.rendering_options.near = 0.8 + renderer.rendering_options.far = 1.6 + renderer.rendering_options.bg_color = (0, 0, 0) + renderer.rendering_options.ssaa = 4 + renderer.pipe.primitive = 'voxel' + + # Build camera + yaws = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + yaws_offset = 0 # np.random.uniform(-np.pi / 4, np.pi / 4) + yaws = [y + yaws_offset for y in yaws] + pitch = np.linspace(-np.pi / 4, np.pi / 4, 4) # [np.random.uniform(-np.pi / 4, np.pi / 4) for _ in range(4)] + + exts = [] + ints = [] + for yaw, pitch in zip(yaws, pitch): + orig = torch.tensor([ + np.sin(yaw) * np.cos(pitch), + np.cos(yaw) * np.cos(pitch), + np.sin(pitch), + ]).float().cuda() * 2 + fov = torch.deg2rad(torch.tensor(30)).cuda() + extrinsics = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intrinsics = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + exts.append(extrinsics) + ints.append(intrinsics) + + images = [] + x_0 = x_0.cuda() + for i in range(x_0.shape[0]): + representation = Octree( + depth=10, + aabb=[-0.5, -0.5, -0.5, 1, 1, 1], + device='cuda', + primitive='voxel', + sh_degree=0, + primitive_config={'solid': True}, + ) + coords = torch.nonzero(x_0[i, 0] > 0, as_tuple=False) + resolution = x_0.shape[-1] + representation.position = coords.float() / resolution + representation.depth = torch.full((representation.position.shape[0], 1), int(np.log2(resolution)), dtype=torch.uint8, device='cuda') + image = torch.zeros(3, 1024, 1024).cuda() + tile = [2, 2] + for j, (ext, intr) in enumerate(zip(exts, ints)): + res = renderer.render(representation, ext, intr, colors_overwrite=representation.position) + image[:, 512 * (j // tile[1]):512 * (j // tile[1] + 1), 512 * (j % tile[1]):512 * (j % tile[1] + 1)] = res['color'] + images.append(image) + + x_0_skl = x_0_skl.cuda() + for i in range(x_0_skl.shape[0]): + representation = Octree( + depth=10, + aabb=[-0.5, -0.5, -0.5, 1, 1, 1], + device='cuda', + primitive='voxel', + sh_degree=0, + primitive_config={'solid': True}, + ) + coords = torch.nonzero(x_0_skl[i, 0] > 0, as_tuple=False) + resolution = x_0_skl.shape[-1] + representation.position = coords.float() / resolution + representation.depth = torch.full((representation.position.shape[0], 1), int(np.log2(resolution)), dtype=torch.uint8, device='cuda') + image = torch.zeros(3, 1024, 1024).cuda() + tile = [2, 2] + for j, (ext, intr) in enumerate(zip(exts, ints)): + res = renderer.render(representation, ext, intr, colors_overwrite=representation.position) + image[:, 512 * (j // tile[1]):512 * (j // tile[1] + 1), 512 * (j % tile[1]):512 * (j % tile[1] + 1)] = res['color'] + images[i] = torch.cat([images[i], image], dim=2) + + return torch.stack(images) + + +class AniGenSparseStructureLatent(AniGenSparseStructureLatentVisMixin, StandardDatasetBase): + """ + Sparse structure latent dataset + + Args: + roots (str): path to the dataset + latent_model (str): name of the latent model + min_aesthetic_score (float): minimum aesthetic score + normalization (dict): normalization stats + pretrained_ss_dec (str): name of the pretrained sparse structure decoder + ss_dec_path (str): path to the sparse structure decoder, if given, will override the pretrained_ss_dec + ss_dec_ckpt (str): name of the sparse structure decoder checkpoint + """ + def __init__(self, + roots: str, + *, + latent_model: str, + min_aesthetic_score: float = 5.0, + normalization: Optional[dict] = None, + normalization_skl: Optional[dict] = None, + pretrained_ss_dec: str = None, + ss_dec_path: Optional[str] = '', + ss_dec_ckpt: Optional[str] = 'final', + **kwargs, + ): + self.latent_model = latent_model + self.min_aesthetic_score = min_aesthetic_score + self.normalization = normalization + self.normalization_skl = normalization_skl + self.value_range = (0, 1) + + super().__init__( + roots, + pretrained_ss_dec=pretrained_ss_dec, + ss_dec_path=ss_dec_path, + ss_dec_ckpt=ss_dec_ckpt, + **kwargs, + ) + + if self.normalization is not None: + data = np.load(self.normalization) + self.mean = torch.tensor(data['feats_mean']) + self.std = torch.tensor(data['feats_std']) + if self.normalization_skl is not None: + data = np.load(self.normalization_skl) + self.mean_skl = torch.tensor(data['feats_skl_mean']) + self.std_skl = torch.tensor(data['feats_skl_std']).clip(min=1e-3) + + def filter_metadata(self, metadata): + stats = {} + metadata = metadata[metadata[f'ss_latent_{self.latent_model}']] + stats['With sparse structure latents'] = len(metadata) + metadata = metadata[metadata['aesthetic_score'] >= self.min_aesthetic_score] + stats[f'Aesthetic score >= {self.min_aesthetic_score}'] = len(metadata) + + if 'is_bad_skeleton' in metadata.columns: + metadata = metadata[~metadata['is_bad_skeleton']] + if 'is_bad_skin' in metadata.columns: + metadata = metadata[~metadata['is_bad_skin']] + + return metadata, stats + + def get_instance(self, root, instance): + latent = np.load(os.path.join(root, 'ss_latents', self.latent_model, f'{instance}.npz')) + z = torch.tensor(latent['mean']).float() + z_skl = torch.tensor(latent['mean_skl']).float() + if self.normalization is not None: + z = (z - self.mean) / self.std + if self.normalization_skl is not None: + z_skl = (z_skl - self.mean_skl) / self.std_skl + + pack = { + 'instance': instance, + 'x_0': z, + 'x_0_skl': z_skl, + } + return pack + + +class TextConditionedAniGenSparseStructureLatent(TextConditionedMixin, AniGenSparseStructureLatent): + """ + Text-conditioned sparse structure dataset + """ + pass + + +class ImageConditionedAniGenSparseStructureLatent(ImageConditionedMixin, AniGenSparseStructureLatent): + """ + Image-conditioned sparse structure dataset + """ + pass + \ No newline at end of file diff --git a/anigen/datasets/anigen_structured_latent.py b/anigen/datasets/anigen_structured_latent.py new file mode 100644 index 0000000000000000000000000000000000000000..bb461136cef2a18b80e0d584f8e47fe01c0312e1 --- /dev/null +++ b/anigen/datasets/anigen_structured_latent.py @@ -0,0 +1,327 @@ +import json +import os +from typing import * +import numpy as np +import torch +import utils3d.torch +from .components import StandardDatasetBase, TextConditionedMixin, ImageConditionedMixin +from ..modules.sparse.basic import SparseTensor +from .. import models +from ..utils.render_utils import get_renderer +from ..utils.dist_utils import read_file_dist +from ..utils.data_utils import load_balanced_group_indices +import copy +import torch.nn.functional as F + + +class AniGenSLatVisMixin: + def __init__( + self, + *args, + pretrained_slat_dec: str = None, + slat_dec_path: Optional[str] = None, + slat_dec_ckpt: Optional[str] = None, + load_cubvh: bool = False, + **kwargs + ): + super().__init__(*args, **kwargs) + self.slat_dec = None + self.pretrained_slat_dec = pretrained_slat_dec + self.slat_dec_path = slat_dec_path + self.slat_dec_ckpt = slat_dec_ckpt + self.load_cubvh = load_cubvh + + def _loading_slat_dec(self): + if self.slat_dec is not None: + return + if self.slat_dec_path is not None: + cfg = json.load(open(os.path.join(self.slat_dec_path, 'config.json'), 'r')) + decoder = getattr(models, cfg['models']['decoder']['name'])(**cfg['models']['decoder']['args']) + ckpt_path = os.path.join(self.slat_dec_path, 'ckpts', f'decoder_{self.slat_dec_ckpt}.pt') + # decoder.load_state_dict(torch.load(read_file_dist(ckpt_path), map_location='cpu', weights_only=True)) + decoder.load_state_dict(torch.load(ckpt_path, map_location='cpu', weights_only=True)) + else: + decoder = models.from_pretrained(self.pretrained_slat_dec) + self.slat_dec = decoder.cuda().eval() + + def _delete_slat_dec(self): + del self.slat_dec + self.slat_dec = None + + @torch.no_grad() + def decode_latent(self, z, z_skl, gt_joints=None, gt_parents=None, batch_size=4, gt_reps=None, gt_reps_skl=None): + self._loading_slat_dec() + reps = [] + reps_skl = [] + if gt_reps is not None: + skins_gt_ssskin = [] + if gt_reps_skl is not None: + skins_gt_sklskin = [] + if self.normalization is not None: + z = z * self.std.to(z.device) + self.mean.to(z.device) + z_skl = z_skl * self.std_skl.to(z.device) + self.mean_skl.to(z.device) + for i in range(0, z.shape[0], batch_size): + gt_j, gt_p = None if gt_joints is None else gt_joints[i:i+batch_size], None if gt_parents is None else gt_parents[i:i+batch_size] + z_, z_skl_ = z[i:i+batch_size], z_skl[i:i+batch_size] + rep, rep_skl = self.slat_dec(z_, z_skl_, gt_joints=gt_j, gt_parents=gt_p) + reps.append(rep) + reps_skl.append(rep_skl) + if gt_reps is not None: + skins_gt_ssskin.append(self.slat_dec.skinweight_forward(gt_reps[i:i+batch_size], rep_skl, gt_joints=gt_j, gt_parents=gt_p, return_skin_pred_only=True)) + if gt_reps_skl is not None: + skins_gt_sklskin.append(self.slat_dec.skinweight_forward(rep, gt_reps_skl[i:i+batch_size], gt_joints=gt_j, gt_parents=gt_p, return_skin_pred_only=True)) + reps = sum(reps, []) + reps_skl = sum(reps_skl, []) + self._delete_slat_dec() + to_return = (reps, reps_skl) + if gt_reps is not None: + skins_gt_ssskin = sum(skins_gt_ssskin, []) + to_return += (skins_gt_ssskin,) + if gt_reps_skl is not None: + skins_gt_sklskin = sum(skins_gt_sklskin, []) + to_return += (skins_gt_sklskin,) + return to_return + +class AniGenSLat(AniGenSLatVisMixin, StandardDatasetBase): + """ + structured latent dataset + + Args: + roots (str): path to the dataset + latent_model (str): name of the latent model + min_aesthetic_score (float): minimum aesthetic score + max_num_voxels (int): maximum number of voxels + normalization (dict): normalization stats + pretrained_slat_dec (str): name of the pretrained slat decoder + slat_dec_path (str): path to the slat decoder, if given, will override the pretrained_slat_dec + slat_dec_ckpt (str): name of the slat decoder checkpoint + """ + def __init__(self, + roots: str, + *, + latent_model: str, + use_joint_num_cond: bool = False, + min_aesthetic_score: float = 5.0, + max_num_voxels: int = 32768, + normalization: Optional[dict] = None, + pretrained_slat_dec: str = None, + slat_dec_path: Optional[str] = None, + slat_dec_ckpt: Optional[str] = None, + local_rank: int = 0, + **kwargs, + ): + self.normalization = normalization + self.latent_model = latent_model + self.use_joint_num_cond = use_joint_num_cond + self.min_aesthetic_score = min_aesthetic_score + self.max_num_voxels = max_num_voxels + self.value_range = (0, 1) + self.local_rank = local_rank + + super().__init__( + roots, + pretrained_slat_dec=pretrained_slat_dec, + slat_dec_path=slat_dec_path, + slat_dec_ckpt=slat_dec_ckpt, + **kwargs, + ) + + self.loads = [self.metadata.loc[sha256, 'num_voxels'] for _, sha256 in self.instances] + + if self.normalization is not None: + self.mean = torch.tensor(self.normalization['mean']).reshape(1, -1) + self.std = torch.tensor(self.normalization['std']).reshape(1, -1) + self.mean_skl = torch.tensor(self.normalization['mean_skl']).reshape(1, -1) + self.std_skl = torch.tensor(self.normalization['std_skl']).reshape(1, -1) + + def filter_metadata(self, metadata): + stats = {} + metadata = metadata[metadata[f'latent_{self.latent_model}']] + stats['With latent'] = len(metadata) + metadata = metadata[metadata['aesthetic_score'] >= self.min_aesthetic_score] + stats[f'Aesthetic score >= {self.min_aesthetic_score}'] = len(metadata) + # metadata = metadata[metadata['num_voxels'] <= self.max_num_voxels] + # stats[f'Num voxels <= {self.max_num_voxels}'] = len(metadata) + + if 'is_bad_skeleton' in metadata.columns: + metadata = metadata[~metadata['is_bad_skeleton']] + if 'is_bad_skin' in metadata.columns: + metadata = metadata[~metadata['is_bad_skin']] + + return metadata, stats + + @torch.no_grad() + def visualize_sample(self, data: dict): + return {} + x_0 = data['x_0'] + x_0_skl = data['x_0_skl'] + reps, reps_skl = self.decode_latent(x_0.cuda(), x_0_skl.cuda(), data['joints']) + + # Build camera + yaws = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + yaws_offset = np.random.uniform(-np.pi / 4, np.pi / 4) + yaws = [y + yaws_offset for y in yaws] + pitch = [np.random.uniform(-np.pi / 4, np.pi / 4) for _ in range(4)] + + exts = [] + ints = [] + for yaw, pitch in zip(yaws, pitch): + orig = torch.tensor([ + np.sin(yaw) * np.cos(pitch), + np.cos(yaw) * np.cos(pitch), + np.sin(pitch), + ]).float().cuda() * 2 + fov = torch.deg2rad(torch.tensor(40)).cuda() + extrinsics = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intrinsics = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + exts.append(extrinsics) + ints.append(intrinsics) + + renderer = get_renderer(reps[0]) + images = [] + for representation in reps: + image = torch.zeros(3, 1024, 1024).cuda() + tile = [2, 2] + for j, (ext, intr) in enumerate(zip(exts, ints)): + res = renderer.render(representation, ext, intr) + image[:, 512 * (j // tile[1]):512 * (j // tile[1] + 1), 512 * (j % tile[1]):512 * (j % tile[1] + 1)] = res['color'] + images.append(image) + images = torch.stack(images) + + return images + + def _get_skeleton(self, root, instance): + skeleton_path = os.path.join(root, 'skeleton', instance, 'skeleton_voxelized.npz') + skl_data = np.load(skeleton_path, allow_pickle=True) + joints, parents, skin = skl_data['joints'], skl_data['parents'], skl_data['skin'] + parents[parents==None] = -1 + parents = np.array(parents, dtype=np.int32) + ret = { + 'joints': torch.from_numpy(joints).float(), + 'parents': torch.from_numpy(parents).int(), + 'skin': torch.from_numpy(skin).float(), + } + if self.use_joint_num_cond: + ret['joints_num'] = int(joints.shape[0]) + return ret + + def _get_geo(self, root, instance): + skeleton_path = os.path.join(root, 'skeleton', instance, 'skeleton_voxelized.npz') + skl_data = np.load(skeleton_path, allow_pickle=True) + verts, face = np.array(skl_data['vertices'], dtype=np.float32), skl_data['faces'] + mesh = { + "vertices" : torch.from_numpy(verts), + "faces" : torch.from_numpy(face), + } + geo = {"mesh": mesh} + if self.load_cubvh: + from cubvh import cuBVH + torch.cuda.set_device(self.local_rank) + cubvh_path = os.path.join(root, 'skeleton', instance, 'cubvh.pth') + if os.path.exists(cubvh_path): + cubvh = torch.load(cubvh_path, weights_only=False) + else: + cubvh = cuBVH(mesh["vertices"], mesh["faces"]) + torch.save(cubvh, cubvh_path) + geo["cubvh"] = cubvh + return geo + + def get_instance(self, root, instance): + data = np.load(os.path.join(root, 'latents', self.latent_model, f'{instance}.npz')) + coords = torch.tensor(data['coords']).int() + feats = torch.tensor(data['feats']).float() + coords_skl = torch.tensor(data['coords_skl']).int() + feats_skl = torch.tensor(data['feats_skl']).float() + if self.normalization is not None: + feats = (feats - self.mean) / self.std + feats_skl = (feats_skl - self.mean_skl) / self.std_skl + return { + 'coords': coords, + 'feats': feats, + 'coords_skl': coords_skl, + 'feats_skl': feats_skl, + 'instance': instance, + **self._get_skeleton(root, instance), + **self._get_geo(root, instance), + } + + @staticmethod + def collate_fn(batch, split_size=None): + if split_size is None: + group_idx = [list(range(len(batch)))] + else: + group_idx = load_balanced_group_indices([b['coords'].shape[0] for b in batch], split_size) + packs = [] + for group in group_idx: + sub_batch = [batch[i] for i in group] + pack = {} + coords = [] + feats = [] + coords_skl = [] + feats_skl = [] + layout = [] + layout_skl = [] + start = 0 + start_skl = 0 + for i, b in enumerate(sub_batch): + coords.append(torch.cat([torch.full((b['coords'].shape[0], 1), i, dtype=torch.int32), b['coords']], dim=-1)) + feats.append(b['feats']) + coords_skl.append(torch.cat([torch.full((b['coords_skl'].shape[0], 1), i, dtype=torch.int32), b['coords_skl']], dim=-1)) + feats_skl.append(b['feats_skl']) + layout.append(slice(start, start + b['coords'].shape[0])) + layout_skl.append(slice(start_skl, start_skl + b['coords_skl'].shape[0])) + start += b['coords'].shape[0] + start_skl += b['coords_skl'].shape[0] + coords = torch.cat(coords) + feats = torch.cat(feats) + pack['x_0'] = SparseTensor( + coords=coords, + feats=feats, + ) + pack['x_0']._shape = torch.Size([len(group), *sub_batch[0]['feats'].shape[1:]]) + pack['x_0'].register_spatial_cache('layout', layout) + + coords_skl = torch.cat(coords_skl) + feats_skl = torch.cat(feats_skl) + pack['x_0_skl'] = SparseTensor( + coords=coords_skl, + feats=feats_skl, + ) + pack['x_0_skl']._shape = torch.Size([len(group), *sub_batch[0]['feats_skl'].shape[1:]]) + pack['x_0_skl'].register_spatial_cache('layout', layout_skl) + + pack['joints'] = [b['joints'] for b in sub_batch] + pack['parents'] = [b['parents'] for b in sub_batch] + pack['skin'] = [b['skin'] for b in sub_batch] + if 'joints_num' in sub_batch[0]: + pack['joints_num'] = torch.tensor([b['joints_num'] for b in sub_batch], dtype=torch.long) + + # collate other data + keys = [k for k in sub_batch[0].keys() if k not in ['coords', 'feats', 'coords_skl', 'feats_skl', 'joints', 'parents', 'skin', 'joints_num']] + for k in keys: + if isinstance(sub_batch[0][k], torch.Tensor): + pack[k] = torch.stack([b[k] for b in sub_batch]) + elif isinstance(sub_batch[0][k], list): + pack[k] = sum([b[k] for b in sub_batch], []) + else: + pack[k] = [b[k] for b in sub_batch] + + packs.append(pack) + + if split_size is None: + return packs[0] + return packs + + +class TextConditionedSLat(TextConditionedMixin, AniGenSLat): + """ + Text conditioned structured latent dataset + """ + pass + + +class AniGenImageConditionedSLat(ImageConditionedMixin, AniGenSLat): + """ + Image conditioned structured latent dataset + """ + pass diff --git a/anigen/datasets/components.py b/anigen/datasets/components.py new file mode 100644 index 0000000000000000000000000000000000000000..1b250fc4814d9c9fde278d86dea00f88c6b0ccf7 --- /dev/null +++ b/anigen/datasets/components.py @@ -0,0 +1,143 @@ +from typing import * +from abc import abstractmethod +import os +import json +import torch +import numpy as np +import pandas as pd +from PIL import Image +from torch.utils.data import Dataset + + +class StandardDatasetBase(Dataset): + """ + Base class for standard datasets. + + Args: + roots (str): paths to the dataset + """ + + def __init__(self, + roots: str, + instances: List[str] = None, + **kwargs, + ): + super().__init__() + self.roots = roots.split(',') + self.instances = [] + self.metadata = pd.DataFrame() + + self._stats = {} + for root in self.roots: + key = os.path.basename(root) + self._stats[key] = {} + metadata = pd.read_csv(os.path.join(root, 'metadata.csv')) + self._stats[key]['Total'] = len(metadata) + metadata, stats = self.filter_metadata(metadata) + self._stats[key].update(stats) + self.instances.extend([(root, sha256) for sha256 in metadata['sha256'].values]) + metadata.set_index('sha256', inplace=True) + self.metadata = pd.concat([self.metadata, metadata]) + + if instances is not None: + self.test_mode = False + self.instances = [inst for inst in self.instances if inst[1] in instances] + + @abstractmethod + def filter_metadata(self, metadata: pd.DataFrame) -> Tuple[pd.DataFrame, Dict[str, int]]: + pass + + @abstractmethod + def get_instance(self, root: str, instance: str) -> Dict[str, Any]: + pass + + def __len__(self): + return len(self.instances) + + def __getitem__(self, index) -> Dict[str, Any]: + try: + root, instance = self.instances[index] + return self.get_instance(root, instance) + except Exception as e: + print(e) + return self.__getitem__(np.random.randint(0, len(self))) + + def __str__(self): + lines = [] + lines.append(self.__class__.__name__) + lines.append(f' - Total instances: {len(self)}') + lines.append(f' - Sources:') + for key, stats in self._stats.items(): + lines.append(f' - {key}:') + for k, v in stats.items(): + lines.append(f' - {k}: {v}') + return '\n'.join(lines) + + +class TextConditionedMixin: + def __init__(self, roots, **kwargs): + super().__init__(roots, **kwargs) + self.captions = {} + for instance in self.instances: + sha256 = instance[1] + self.captions[sha256] = json.loads(self.metadata.loc[sha256]['captions']) + + def filter_metadata(self, metadata): + metadata, stats = super().filter_metadata(metadata) + metadata = metadata[metadata['captions'].notna()] + stats['With captions'] = len(metadata) + return metadata, stats + + def get_instance(self, root, instance): + pack = super().get_instance(root, instance) + text = np.random.choice(self.captions[instance]) + pack['cond'] = text + return pack + + +class ImageConditionedMixin: + def __init__(self, roots, *, image_size=518, **kwargs): + self.image_size = image_size + super().__init__(roots, **kwargs) + + def filter_metadata(self, metadata): + metadata, stats = super().filter_metadata(metadata) + metadata = metadata[metadata[f'cond_rendered']] + stats['Cond rendered'] = len(metadata) + return metadata, stats + + def get_instance(self, root, instance): + pack = super().get_instance(root, instance) + + image_root = os.path.join(root, 'renders_cond', instance) + with open(os.path.join(image_root, 'transforms.json')) as f: + metadata = json.load(f) + n_views = len(metadata['frames']) + view = np.random.randint(n_views) + metadata = metadata['frames'][view] + + image_path = os.path.join(image_root, metadata['file_path']) + image = Image.open(image_path) + + alpha = np.array(image.getchannel(3)) + bbox = np.array(alpha).nonzero() + bbox = [bbox[1].min(), bbox[0].min(), bbox[1].max(), bbox[0].max()] + center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2] + hsize = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) / 2 + aug_size_ratio = 1.2 + aug_hsize = hsize * aug_size_ratio + aug_center_offset = [0, 0] + aug_center = [center[0] + aug_center_offset[0], center[1] + aug_center_offset[1]] + aug_bbox = [int(aug_center[0] - aug_hsize), int(aug_center[1] - aug_hsize), int(aug_center[0] + aug_hsize), int(aug_center[1] + aug_hsize)] + image = image.crop(aug_bbox) + + image = image.resize((self.image_size, self.image_size), Image.Resampling.LANCZOS) + alpha = image.getchannel(3) + image = image.convert('RGB') + image = torch.tensor(np.array(image)).permute(2, 0, 1).float() / 255.0 + alpha = torch.tensor(np.array(alpha)).float() / 255.0 + image = image * alpha.unsqueeze(0) + pack['cond'] = image + + return pack + \ No newline at end of file diff --git a/anigen/models/__init__.py b/anigen/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0aad5c2aeaaf0ef8cb105c2ad3d79a86a7b35588 --- /dev/null +++ b/anigen/models/__init__.py @@ -0,0 +1,67 @@ +import importlib + +__attributes = { + 'AniGenSparseStructureEncoder': 'anigen_sparse_structure_vae', + 'AniGenSparseStructureDecoder': 'anigen_sparse_structure_vae', + 'AniGenSparseStructureFlowModel': 'anigen_sparse_structure_flow', + 'AniGenSparseStructureFlowModelInpaint': 'anigen_sparse_structure_flow_inpaint', + 'AniGenElasticSLatEncoder': 'structured_latent_vae', + 'AniGenElasticSLatMeshDecoder': 'structured_latent_vae', + 'AniGenElasticSLatGaussianDecoder': 'structured_latent_vae', + 'AniGenSLatFlowModel': 'anigen_structured_latent_flow', + 'AniGenElasticSLatFlowModel': 'anigen_structured_latent_flow', + 'AniGenElasticSLatFlowModelOld': 'anigen_structured_latent_flow_old', + 'SkinAutoEncoder': 'structured_latent_vae', +} + +__submodules = [] + +__all__ = list(__attributes.keys()) + __submodules + +def __getattr__(name): + if name not in globals(): + if name in __attributes: + module_name = __attributes[name] + module = importlib.import_module(f".{module_name}", __name__) + globals()[name] = getattr(module, name) + elif name in __submodules: + module = importlib.import_module(f".{name}", __name__) + globals()[name] = module + else: + raise AttributeError(f"module {__name__} has no attribute {name}") + return globals()[name] + + +def from_pretrained(path: str, **kwargs): + """ + Load a model from a pretrained checkpoint. + + Args: + path: The path to the checkpoint. Can be either local path or a Hugging Face model name. + NOTE: config file and model file should take the name f'{path}.json' and f'{path}.safetensors' respectively. + **kwargs: Additional arguments for the model constructor. + """ + import os + import json + from safetensors.torch import load_file + is_local = os.path.exists(f"{path}.json") and os.path.exists(f"{path}.safetensors") + + if is_local: + config_file = f"{path}.json" + model_file = f"{path}.safetensors" + else: + print(f"{path}.json and {path}.safetensors not found, trying to download from Hugging Face Hub.") + from huggingface_hub import hf_hub_download + path_parts = path.split('/') + repo_id = f'{path_parts[0]}/{path_parts[1]}' + model_name = '/'.join(path_parts[2:]) + config_file = hf_hub_download(repo_id, f"{model_name}.json") + model_file = hf_hub_download(repo_id, f"{model_name}.safetensors") + + with open(config_file, 'r') as f: + config = json.load(f) + model = __getattr__(config['name'])(**config['args'], **kwargs) + model.load_state_dict(load_file(model_file)) + + return model + diff --git a/anigen/models/anigen_sparse_structure_flow.py b/anigen/models/anigen_sparse_structure_flow.py new file mode 100644 index 0000000000000000000000000000000000000000..930c60b941ff95ffdcfb0c55f3de81dcfbfcd890 --- /dev/null +++ b/anigen/models/anigen_sparse_structure_flow.py @@ -0,0 +1,487 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from ..modules.utils import convert_module_to_f16, convert_module_to_f32 +from ..modules.transformer import AbsolutePositionEmbedder, ModulatedTransformerCrossBlock +from ..modules.spatial import patchify, unpatchify + + +class TimestepEmbedder(nn.Module): + """ + Embeds scalar timesteps into vector representations. + """ + def __init__(self, hidden_size, frequency_embedding_size=256): + super().__init__() + self.mlp = nn.Sequential( + nn.Linear(frequency_embedding_size, hidden_size, bias=True), + nn.SiLU(), + nn.Linear(hidden_size, hidden_size, bias=True), + ) + self.frequency_embedding_size = frequency_embedding_size + + @staticmethod + def timestep_embedding(t, dim, max_period=10000): + """ + Create sinusoidal timestep embeddings. + + Args: + t: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + dim: the dimension of the output. + max_period: controls the minimum frequency of the embeddings. + + Returns: + an (N, D) Tensor of positional embeddings. + """ + # https://github.com/openai/glide-text2im/blob/main/glide_text2im/nn.py + half = dim // 2 + freqs = torch.exp( + -np.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half + ).to(device=t.device) + args = t[:, None].float() * freqs[None] + embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) + if dim % 2: + embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) + return embedding + + def forward(self, t): + t_freq = self.timestep_embedding(t, self.frequency_embedding_size) + t_emb = self.mlp(t_freq) + return t_emb + + +class AniGenSparseStructureFlowModel(nn.Module): + def __init__( + self, + resolution: int, + in_channels: int, + in_channels_skl: int, + model_channels: int, + model_channels_skl: int, + cond_channels: int, + out_channels: int, + out_channels_skl: int, + num_blocks: int, + num_heads: Optional[int] = None, + num_head_channels: Optional[int] = 64, + mlp_ratio: float = 4, + patch_size: int = 2, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + share_mod: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + use_lora_ss: bool = False, + lora_lr_rate_ss: float = 0.1, + modules_to_freeze: Optional[List[str]] = ["blocks", "input_layer", "out_layer", "pos_emb", "t_embedder"], + adapter_ss_to_skl: bool = True, + adapter_skl_to_ss: bool = True, + predict_x0: bool = False, + predict_x0_skl: bool = False, + t_eps: float = 5e-2, + t_scale: float = 1e3, + z_is_global: bool = False, + z_skl_is_global: bool = False, + global_token_num: int = 1024, + global_token_num_skl: int = 1024, + cross_adapter_every: int = 4, + skl_cross_from_ss: bool = False, + ): + super().__init__() + self.resolution = resolution + self.in_channels = in_channels + self.in_channels_skl = in_channels_skl + self.model_channels = model_channels + self.model_channels_skl = model_channels_skl + self.cond_channels = cond_channels + self.out_channels = out_channels + self.out_channels_skl = out_channels_skl + self.num_blocks = num_blocks + self.num_heads = num_heads or model_channels // num_head_channels + self.mlp_ratio = mlp_ratio + self.patch_size = patch_size + self.pe_mode = pe_mode + self.use_fp16 = use_fp16 + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.qk_rms_norm = qk_rms_norm + self.qk_rms_norm_cross = qk_rms_norm_cross + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch or use_lora_ss + self.use_lora_ss = use_lora_ss + self.modules_to_freeze = modules_to_freeze + self.adapter_ss_to_skl = adapter_ss_to_skl + self.adapter_skl_to_ss = adapter_skl_to_ss + self.predict_x0 = predict_x0 + self.predict_x0_skl = predict_x0_skl + self.t_eps = t_eps + self.t_scale = t_scale + self.z_is_global = z_is_global + self.z_skl_is_global = z_skl_is_global + self.global_token_num = global_token_num + self.global_token_num_skl = global_token_num_skl + self.cross_adapter_every = int(cross_adapter_every) + self.skl_cross_from_ss = skl_cross_from_ss + + self.t_embedder = TimestepEmbedder(model_channels) + self.t_embedder_skl = TimestepEmbedder(model_channels_skl) + if share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(model_channels, 6 * model_channels, bias=True) + ) + self.adaLN_modulation_skl = nn.Sequential( + nn.SiLU(), + nn.Linear(model_channels_skl, 6 * model_channels_skl, bias=True) + ) + + if pe_mode == "ape": + coords = torch.meshgrid(*[torch.arange(res, device=self.device) for res in [resolution // patch_size] * 3], indexing='ij') + coords = torch.stack(coords, dim=-1).reshape(-1, 3) + if self.z_is_global: + pos_embedder = AbsolutePositionEmbedder(model_channels, 1) + pos_emb = pos_embedder(torch.arange(self.global_token_num, device=self.device)[:, None]) + else: + pos_embedder = AbsolutePositionEmbedder(model_channels, 3) + pos_emb = pos_embedder(coords) + self.register_buffer("pos_emb", pos_emb) + if self.z_skl_is_global: + pos_embedder_skl = AbsolutePositionEmbedder(model_channels_skl, 1) + pos_emb_skl = pos_embedder_skl(torch.arange(self.global_token_num_skl, device=self.device)[:, None]) + else: + pos_embedder_skl = AbsolutePositionEmbedder(model_channels_skl, 3) + pos_emb_skl = pos_embedder_skl(coords) + self.register_buffer("pos_emb_skl", pos_emb_skl) + + self.input_layer = nn.Linear(in_channels * patch_size**3, model_channels) + self.input_layer_skl = nn.Linear(in_channels_skl * patch_size**3, model_channels_skl) + + shallow = max(1, num_blocks // 3) + middle = max(1, num_blocks // 3 * 2) + self.blocks = nn.ModuleList([ + ModulatedTransformerCrossBlock( + model_channels, + cond_channels, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode='full', + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + share_mod=share_mod, + qk_rms_norm=self.qk_rms_norm, + qk_rms_norm_cross=self.qk_rms_norm_cross, + use_lora_self=self.use_lora_ss and idx >= middle, + lora_rank_self=8, + use_lora_cross=self.use_lora_ss, + lora_rank_cross=8+(idx // shallow)*8, + lora_lr_rate=lora_lr_rate_ss, + ) + for idx in range(num_blocks) + ]) + self.blocks_skl = nn.ModuleList([ + ModulatedTransformerCrossBlock( + model_channels_skl, + cond_channels if not self.skl_cross_from_ss else model_channels, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode='full', + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + share_mod=share_mod, + qk_rms_norm=self.qk_rms_norm, + qk_rms_norm_cross=self.qk_rms_norm_cross, + use_context_norm=self.skl_cross_from_ss, + ) + for _ in range(num_blocks) + ]) + + # When using global tokens, ss and skl token counts may differ, so we use cross-attention + # for information exchange at a configurable frequency. + self.use_cross_adapter = (self.z_is_global or self.z_skl_is_global) and ( + self.adapter_ss_to_skl or self.adapter_skl_to_ss + ) + + if self.adapter_ss_to_skl and not self.use_cross_adapter: + self.adapter_ss_to_skl_layers = nn.ModuleList([ + nn.Linear(model_channels, model_channels_skl) for _ in range(num_blocks) + ]) + if self.adapter_skl_to_ss and not self.use_cross_adapter: + self.adapter_skl_to_ss_layers = nn.ModuleList([ + nn.Linear(model_channels_skl, model_channels) for _ in range(num_blocks) + ]) + + self.cross_adapter_every = max(1, self.cross_adapter_every) + self.cross_block_indices: List[int] = [ + idx for idx in range(num_blocks) if (idx + 1) % self.cross_adapter_every == 0 + ] + if self.use_cross_adapter and len(self.cross_block_indices) == 0 and num_blocks > 0: + self.cross_block_indices = [num_blocks - 1] + if self.use_cross_adapter and len(self.cross_block_indices) > 0: + if self.adapter_ss_to_skl: + self.cross_blocks_ss_to_skl = nn.ModuleList([ + ModulatedTransformerCrossBlock( + model_channels_skl, + model_channels, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode='full', + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + share_mod=share_mod, + qk_rms_norm=self.qk_rms_norm, + qk_rms_norm_cross=self.qk_rms_norm_cross, + ) + for _ in self.cross_block_indices + ]) + self.cross_blocks_ss_to_skl_out = nn.ModuleList([ + nn.Linear(model_channels_skl, model_channels_skl, bias=True) + for _ in self.cross_block_indices + ]) + if self.adapter_skl_to_ss: + self.cross_blocks_skl_to_ss = nn.ModuleList([ + ModulatedTransformerCrossBlock( + model_channels, + model_channels_skl, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode='full', + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + share_mod=share_mod, + qk_rms_norm=self.qk_rms_norm, + qk_rms_norm_cross=self.qk_rms_norm_cross, + ) + for _ in self.cross_block_indices + ]) + self.cross_blocks_skl_to_ss_out = nn.ModuleList([ + nn.Linear(model_channels, model_channels, bias=True) + for _ in self.cross_block_indices + ]) + + self.out_layer = nn.Linear(model_channels, out_channels * patch_size**3) + self.out_layer_skl = nn.Linear(model_channels_skl, out_channels_skl * patch_size**3) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + + if self.use_pretrain_branch and self.freeze_pretrain_branch: + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for name, param in m.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, nn.Module): + for name, param in mod.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, torch.Tensor): + if mod.requires_grad: + mod.requires_grad = False + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.blocks.apply(convert_module_to_f16) + self.blocks_skl.apply(convert_module_to_f16) + if hasattr(self, "adapter_ss_to_skl_layers"): + self.adapter_ss_to_skl_layers.apply(convert_module_to_f16) + if hasattr(self, "adapter_skl_to_ss_layers"): + self.adapter_skl_to_ss_layers.apply(convert_module_to_f16) + if getattr(self, "use_cross_adapter", False): + if hasattr(self, "cross_blocks_ss_to_skl"): + self.cross_blocks_ss_to_skl.apply(convert_module_to_f16) + self.cross_blocks_ss_to_skl_out.apply(convert_module_to_f16) + if hasattr(self, "cross_blocks_skl_to_ss"): + self.cross_blocks_skl_to_ss.apply(convert_module_to_f16) + self.cross_blocks_skl_to_ss_out.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.blocks.apply(convert_module_to_f32) + self.blocks_skl.apply(convert_module_to_f32) + if hasattr(self, "adapter_ss_to_skl_layers"): + self.adapter_ss_to_skl_layers.apply(convert_module_to_f32) + if hasattr(self, "adapter_skl_to_ss_layers"): + self.adapter_skl_to_ss_layers.apply(convert_module_to_f32) + if getattr(self, "use_cross_adapter", False): + if hasattr(self, "cross_blocks_ss_to_skl"): + self.cross_blocks_ss_to_skl.apply(convert_module_to_f32) + self.cross_blocks_ss_to_skl_out.apply(convert_module_to_f32) + if hasattr(self, "cross_blocks_skl_to_ss"): + self.cross_blocks_skl_to_ss.apply(convert_module_to_f32) + self.cross_blocks_skl_to_ss_out.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + # Initialize timestep embedding MLP: + nn.init.normal_(self.t_embedder.mlp[0].weight, std=0.02) + nn.init.normal_(self.t_embedder.mlp[2].weight, std=0.02) + nn.init.normal_(self.t_embedder_skl.mlp[0].weight, std=0.02) + nn.init.normal_(self.t_embedder_skl.mlp[2].weight, std=0.02) + + # Zero-out adaLN modulation layers in DiT blocks: + if self.share_mod: + nn.init.constant_(self.adaLN_modulation[-1].weight, 0) + nn.init.constant_(self.adaLN_modulation[-1].bias, 0) + nn.init.constant_(self.adaLN_modulation_skl[-1].weight, 0) + nn.init.constant_(self.adaLN_modulation_skl[-1].bias, 0) + else: + for block in self.blocks: + nn.init.constant_(block.adaLN_modulation[-1].weight, 0) + nn.init.constant_(block.adaLN_modulation[-1].bias, 0) + for block in self.blocks_skl: + nn.init.constant_(block.adaLN_modulation[-1].weight, 0) + nn.init.constant_(block.adaLN_modulation[-1].bias, 0) + + # Zero-out output layers: + nn.init.constant_(self.out_layer.weight, 0) + nn.init.constant_(self.out_layer.bias, 0) + nn.init.constant_(self.out_layer_skl.weight, 0) + nn.init.constant_(self.out_layer_skl.bias, 0) + + # Zero-out adapter layers if exist + if hasattr(self, "adapter_ss_to_skl_layers"): + for layer in self.adapter_ss_to_skl_layers: + nn.init.constant_(layer.weight, 0) + nn.init.constant_(layer.bias, 0) + if hasattr(self, "adapter_skl_to_ss_layers"): + for layer in self.adapter_skl_to_ss_layers: + nn.init.constant_(layer.weight, 0) + nn.init.constant_(layer.bias, 0) + + # Zero-out cross adapter output projections (so we can safely finetune from pretrained ckpt) + if getattr(self, "use_cross_adapter", False): + if hasattr(self, "cross_blocks_ss_to_skl_out"): + for layer in self.cross_blocks_ss_to_skl_out: + nn.init.constant_(layer.weight, 0) + nn.init.constant_(layer.bias, 0) + if hasattr(self, "cross_blocks_skl_to_ss_out"): + for layer in self.cross_blocks_skl_to_ss_out: + nn.init.constant_(layer.weight, 0) + nn.init.constant_(layer.bias, 0) + + def forward(self, x: torch.Tensor, x_skl: torch.Tensor, t: torch.Tensor, cond: torch.Tensor, **kwargs) -> torch.Tensor: + if not self.z_is_global: + assert [*x.shape] == [x.shape[0], self.in_channels, *[self.resolution] * 3], \ + f"Input shape mismatch, got {x.shape}, expected {[x.shape[0], self.in_channels, *[self.resolution] * 3]}" + if not self.z_skl_is_global: + assert [*x_skl.shape] == [x_skl.shape[0], self.in_channels_skl, *[self.resolution] * 3], \ + f"Input shape mismatch, got {x_skl.shape}, expected {[x_skl.shape[0], self.in_channels_skl, *[self.resolution] * 3]}" + + if self.predict_x0: + xt = x.clone() + if self.predict_x0_skl: + xt_skl = x_skl.clone() + + if not self.z_is_global: + h = patchify(x, self.patch_size) + h = h.view(*h.shape[:2], -1).permute(0, 2, 1).contiguous() + else: + h = x + if not self.z_skl_is_global: + h_skl = patchify(x_skl, self.patch_size) + h_skl = h_skl.view(*h_skl.shape[:2], -1).permute(0, 2, 1).contiguous() + else: + h_skl = x_skl + + h = self.input_layer(h) + h = h + self.pos_emb[None] + h_skl = self.input_layer_skl(h_skl) + h_skl = h_skl + self.pos_emb_skl[None] + + t_emb = self.t_embedder(t) + t_emb_skl = self.t_embedder_skl(t) + if self.share_mod: + t_emb = self.adaLN_modulation(t_emb) + t_emb_skl = self.adaLN_modulation_skl(t_emb_skl) + t_emb = t_emb.type(self.dtype) + t_emb_skl = t_emb_skl.type(self.dtype) + + h = h.type(self.dtype) + h_skl = h_skl.type(self.dtype) + cond = cond.type(self.dtype) + + cross_pos_to_idx = None + if self.use_cross_adapter and len(self.cross_block_indices) > 0: + cross_pos_to_idx = {bidx: cidx for cidx, bidx in enumerate(self.cross_block_indices)} + + for idx, block, block_skl in zip(range(len(self.blocks)), self.blocks, self.blocks_skl): + f = block(h, t_emb, cond) + f_skl = block_skl(h_skl, t_emb_skl, h if self.skl_cross_from_ss else cond) + + if self.use_cross_adapter and cross_pos_to_idx is not None and idx in cross_pos_to_idx: + cidx = cross_pos_to_idx[idx] + if self.adapter_ss_to_skl: + out_skl = self.cross_blocks_ss_to_skl[cidx](f_skl, t_emb_skl, f) + h_skl = f_skl + self.cross_blocks_ss_to_skl_out[cidx](out_skl - f_skl) + else: + h_skl = f_skl + + if self.adapter_skl_to_ss: + out = self.cross_blocks_skl_to_ss[cidx](f, t_emb, f_skl) + h = f + self.cross_blocks_skl_to_ss_out[cidx](out - f) + else: + h = f + else: + # Non-global (or no cross block at this idx): keep previous behavior. + if self.adapter_ss_to_skl and (not self.use_cross_adapter): + h_skl = f_skl + self.adapter_ss_to_skl_layers[idx](f) + else: + h_skl = f_skl + + if self.adapter_skl_to_ss and (not self.use_cross_adapter): + h = f + self.adapter_skl_to_ss_layers[idx](f_skl) + else: + h = f + h = h.type(x.dtype) + h = F.layer_norm(h, h.shape[-1:]) + h = self.out_layer(h) + h_skl = h_skl.type(x_skl.dtype) + h_skl = F.layer_norm(h_skl, h_skl.shape[-1:]) + h_skl = self.out_layer_skl(h_skl) + + if not self.z_is_global: + h = h.permute(0, 2, 1).view(h.shape[0], h.shape[2], *[self.resolution // self.patch_size] * 3) + h = unpatchify(h, self.patch_size).contiguous() + + if not self.z_skl_is_global: + h_skl = h_skl.permute(0, 2, 1).view(h_skl.shape[0], h_skl.shape[2], *[self.resolution // self.patch_size] * 3) + h_skl = unpatchify(h_skl, self.patch_size).contiguous() + + if self.predict_x0: + t_normalized = t / self.t_scale + factor = (1 / t_normalized.clamp_min(self.t_eps)).reshape([t.shape[0], *([1] * (x.dim() - 1))]) + h = (xt - h) * factor + if self.predict_x0_skl: + t_normalized = t / self.t_scale + factor = (1 / t_normalized.clamp_min(self.t_eps)).reshape([t.shape[0], *([1] * (x_skl.dim() - 1))]) + h_skl = (xt_skl - h_skl) * factor + + return h, h_skl diff --git a/anigen/models/anigen_sparse_structure_vae.py b/anigen/models/anigen_sparse_structure_vae.py new file mode 100644 index 0000000000000000000000000000000000000000..4532d8c1b5513ece43b177a232a43fe420fa8537 --- /dev/null +++ b/anigen/models/anigen_sparse_structure_vae.py @@ -0,0 +1,729 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +from ..modules.norm import GroupNorm32, ChannelLayerNorm32 +from ..modules.spatial import pixel_shuffle_3d +from ..modules.utils import zero_module, convert_module_to_f16, convert_module_to_f32 +from ..modules.transformer import FeedForwardNet, TransformerBlock, TransformerCrossBlock, AbsolutePositionEmbedder + + +def norm_layer(norm_type: str, *args, **kwargs) -> nn.Module: + """ + Return a normalization layer. + """ + if norm_type == "group": + return GroupNorm32(32, *args, **kwargs) + elif norm_type == "layer": + return ChannelLayerNorm32(*args, **kwargs) + else: + raise ValueError(f"Invalid norm type {norm_type}") + + +class ResBlock3d(nn.Module): + def __init__( + self, + channels: int, + out_channels: Optional[int] = None, + norm_type: Literal["group", "layer"] = "layer", + ): + super().__init__() + self.channels = channels + self.out_channels = out_channels or channels + + self.norm1 = norm_layer(norm_type, channels) + self.norm2 = norm_layer(norm_type, self.out_channels) + self.conv1 = nn.Conv3d(channels, self.out_channels, 3, padding=1) + self.conv2 = zero_module(nn.Conv3d(self.out_channels, self.out_channels, 3, padding=1)) + self.skip_connection = nn.Conv3d(channels, self.out_channels, 1) if channels != self.out_channels else nn.Identity() + + def forward(self, x: torch.Tensor) -> torch.Tensor: + h = self.norm1(x) + h = F.silu(h) + h = self.conv1(h) + h = self.norm2(h) + h = F.silu(h) + h = self.conv2(h) + h = h + self.skip_connection(x) + return h + + +class DownsampleBlock3d(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + mode: Literal["conv", "avgpool"] = "conv", + ): + assert mode in ["conv", "avgpool"], f"Invalid mode {mode}" + + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + + if mode == "conv": + self.conv = nn.Conv3d(in_channels, out_channels, 2, stride=2) + elif mode == "avgpool": + assert in_channels == out_channels, "Pooling mode requires in_channels to be equal to out_channels" + + def forward(self, x: torch.Tensor) -> torch.Tensor: + if hasattr(self, "conv"): + return self.conv(x) + else: + return F.avg_pool3d(x, 2) + + +class UpsampleBlock3d(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + mode: Literal["conv", "nearest"] = "conv", + ): + assert mode in ["conv", "nearest"], f"Invalid mode {mode}" + + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + + if mode == "conv": + self.conv = nn.Conv3d(in_channels, out_channels*8, 3, padding=1) + elif mode == "nearest": + assert in_channels == out_channels, "Nearest mode requires in_channels to be equal to out_channels" + + def forward(self, x: torch.Tensor) -> torch.Tensor: + if hasattr(self, "conv"): + x = self.conv(x) + return pixel_shuffle_3d(x, 2) + else: + return F.interpolate(x, scale_factor=2, mode="nearest") + + +class AniGenSparseStructureEncoder(nn.Module): + """ + Encoder for Sparse Structure (\mathcal{E}_S in the paper Sec. 3.3). + + Args: + in_channels (int): Channels of the input. + latent_channels (int): Channels of the latent representation. + num_res_blocks (int): Number of residual blocks at each resolution. + channels (List[int]): Channels of the encoder blocks. + num_res_blocks_middle (int): Number of residual blocks in the middle. + norm_type (Literal["group", "layer"]): Type of normalization layer. + use_fp16 (bool): Whether to use FP16. + """ + def __init__( + self, + in_channels: int, + in_channels_skl: int, + latent_channels: int, + latent_channels_skl: int, + num_res_blocks: int, + channels: List[int], + num_res_blocks_middle: int = 2, + norm_type: Literal["group", "layer"] = "layer", + use_fp16: bool = False, + encode_global: bool = False, + global_token_num: int = 1024, + encode_global_skl: bool = True, + global_token_num_skl: int = 1024, + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + modules_to_freeze: Optional[List[str]] = ["input_layer", "blocks", "middle_block", "out_layer"], + latent_denoising: bool = False, + latent_denoising_skl: bool = True, + normalize_z: bool = False, + normalize_z_skl: bool = True, + normalize_scale: float = 1.0 + ): + super().__init__() + self.in_channels = in_channels + self.in_channels_skl = in_channels_skl + self.latent_channels = latent_channels + self.latent_channels_skl = latent_channels_skl + self.num_res_blocks = num_res_blocks + self.channels = channels + self.num_res_blocks_middle = num_res_blocks_middle + self.norm_type = norm_type + self.use_fp16 = use_fp16 + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.encode_global = encode_global + self.global_token_num = global_token_num + self.encode_global_skl = encode_global_skl + self.global_token_num_skl = global_token_num_skl + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch + self.latent_denoising = latent_denoising + self.latent_denoising_skl = latent_denoising_skl + self.normalize_latent = normalize_z and latent_denoising + self.normalize_latent_skl = normalize_z_skl and latent_denoising_skl + self.normalize_scale = normalize_scale + + self.input_layer = nn.Conv3d(self.in_channels, channels[0], 3, padding=1) + self.input_layer_skl = nn.Conv3d(self.in_channels_skl, channels[0], 3, padding=1) + + self.blocks = nn.ModuleList([]) + self.blocks_skl = nn.ModuleList([]) + for i, ch in enumerate(channels): + self.blocks.extend([ + ResBlock3d(ch, ch) + for _ in range(num_res_blocks) + ]) + self.blocks_skl.extend([ + ResBlock3d(ch, ch) + for _ in range(num_res_blocks) + ]) + if i < len(channels) - 1: + self.blocks.append( + DownsampleBlock3d(ch, channels[i+1]) + ) + self.blocks_skl.append( + DownsampleBlock3d(ch, channels[i+1]) + ) + + self.middle_block = nn.Sequential(*[ + ResBlock3d(channels[-1], channels[-1]) + for _ in range(num_res_blocks_middle) + ]) + self.middle_block_skl = nn.Sequential(*[ + ResBlock3d(channels[-1] if _ == 0 else channels[-1], channels[-1]) + for _ in range(num_res_blocks_middle) + ]) + + if self.encode_global: + # Initial Tokens and PE + self.init_tokens_ss = nn.Parameter(torch.zeros(1, global_token_num, channels[-1])) + pos_embedder = AbsolutePositionEmbedder(channels[-1], 1) + coords = torch.arange(global_token_num, device=self.device).reshape(-1, 1) + tokens_pos_emb = pos_embedder(coords) + self.register_buffer('tokens_pos_emb_ss', tokens_pos_emb) + # Grids PE + upsample_factor = 2 ** (len(channels) - 1) + self.base_size_ss = 64 // upsample_factor + pos_embedder = AbsolutePositionEmbedder(channels[-1], 3) + coords = torch.meshgrid(*[torch.arange(res, device=self.device) for res in [self.base_size_ss] * 3], indexing='ij') + coords = torch.stack(coords, dim=-1).reshape(-1, 3) + grid_pos_emb = pos_embedder(coords) + self.register_buffer("grid_pos_emb_ss", grid_pos_emb) + # Token projection layer + self.token_proj_ss = nn.Linear(channels[-1]*2, channels[-1]) + + # Out layers + self.out_layer = nn.ModuleList( + [TransformerCrossBlock( + channels=channels[-1], + ctx_channels=channels[-1]*2, + out_channels=channels[-1], + num_heads=16, + attn_mode="full", + qkv_bias=False, + x_is_query=False)] + + [TransformerBlock( + channels=channels[-1], + out_channels=channels[-1], + num_heads=16, + attn_mode="full", + qkv_bias=False, + ) for _ in range(4)] + + [FeedForwardNet( + channels=channels[-1], + out_channels=latent_channels*2 if not self.latent_denoising else latent_channels)] + ) + else: + self.out_layer = nn.Sequential( + norm_layer(norm_type, channels[-1]), + nn.SiLU(), + nn.Conv3d(channels[-1], latent_channels*2 if not self.latent_denoising else latent_channels, 3, padding=1) + ) + + if self.encode_global_skl: + # Initial Tokens and PE + self.init_tokens = nn.Parameter(torch.zeros(1, global_token_num_skl, channels[-1])) + pos_embedder = AbsolutePositionEmbedder(channels[-1], 1) + coords = torch.arange(global_token_num_skl, device=self.device).reshape(-1, 1) + tokens_pos_emb = pos_embedder(coords) + self.register_buffer('tokens_pos_emb', tokens_pos_emb) + # Grids PE + upsample_factor = 2 ** (len(channels) - 1) + self.base_size = 64 // upsample_factor + pos_embedder = AbsolutePositionEmbedder(channels[-1], 3) + coords = torch.meshgrid(*[torch.arange(res, device=self.device) for res in [self.base_size] * 3], indexing='ij') + coords = torch.stack(coords, dim=-1).reshape(-1, 3) + grid_pos_emb = pos_embedder(coords) + self.register_buffer("grid_pos_emb", grid_pos_emb) + # Token projection layer + self.token_proj = nn.Linear(channels[-1]*2, channels[-1]) + + # Out layers + self.out_layer_skl = nn.ModuleList( + [TransformerCrossBlock( + channels=channels[-1], + ctx_channels=channels[-1]*2, + out_channels=channels[-1], + num_heads=16, + attn_mode="full", + qkv_bias=False, + x_is_query=False)] + + [TransformerBlock( + channels=channels[-1], + out_channels=channels[-1], + num_heads=16, + attn_mode="full", + qkv_bias=False, + ) for _ in range(4)] + + [FeedForwardNet( + channels=channels[-1], + out_channels=latent_channels_skl*2 if not self.latent_denoising_skl else latent_channels_skl)] + ) + else: + self.out_layer_skl = nn.Sequential( + norm_layer(norm_type, channels[-1]), + nn.SiLU(), + nn.Conv3d(channels[-1], latent_channels_skl*2 if not self.latent_denoising_skl else latent_channels_skl, 3, padding=1) + ) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + + if self.use_pretrain_branch and self.freeze_pretrain_branch: + # Freeze: self.input_layer, self.blocks, self.middle_block, self.out_layer + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for param in m.parameters(): + param.requires_grad = False + else: + for param in mod.parameters(): + param.requires_grad = False + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.use_fp16 = True + self.dtype = torch.float16 + self.blocks.apply(convert_module_to_f16) + self.middle_block.apply(convert_module_to_f16) + self.blocks_skl.apply(convert_module_to_f16) + self.middle_block_skl.apply(convert_module_to_f16) + if self.encode_global_skl: + self.token_proj.apply(convert_module_to_f16) + self.out_layer_skl.apply(convert_module_to_f16) + if self.encode_global: + self.token_proj_ss.apply(convert_module_to_f16) + self.out_layer.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.use_fp16 = False + self.dtype = torch.float32 + self.blocks.apply(convert_module_to_f32) + self.middle_block.apply(convert_module_to_f32) + self.blocks_skl.apply(convert_module_to_f32) + self.middle_block_skl.apply(convert_module_to_f32) + if self.encode_global_skl: + self.token_proj.apply(convert_module_to_f32) + self.out_layer_skl.apply(convert_module_to_f32) + if self.encode_global: + self.token_proj_ss.apply(convert_module_to_f32) + self.out_layer.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.kaiming_uniform_(module.weight, nonlinearity='linear') + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def forward(self, x: torch.Tensor, x_skl: torch.Tensor = None, sample_posterior: bool = False, return_raw: bool = False) -> torch.Tensor: + h = self.input_layer(x) + h = h.type(self.dtype) + h_skl = self.input_layer_skl(x_skl) + h_skl = h_skl.type(self.dtype) + + for block, block_skl in zip(self.blocks, self.blocks_skl): + h_skl = block_skl(h_skl) + h = block(h) + h_skl = self.middle_block_skl(h_skl) + h = self.middle_block(h) + + if self.encode_global: + B, C, D, H, W = h.shape + h = h.view(B, C, D*H*W).permute(0, 2, 1) # B, N, C + h = torch.cat([h, self.grid_pos_emb_ss[None].expand(B, -1, -1)], dim=-1).type(h.dtype) + init_tokens = torch.cat([self.init_tokens_ss, self.tokens_pos_emb_ss[None].expand_as(self.init_tokens_ss)], dim=-1).type(h.dtype) + tokens = self.token_proj_ss(init_tokens.expand(B, -1, -1)) + h = self.out_layer[0](tokens, h) # B, global_token_num, C + for layer in self.out_layer[1:]: + h = layer(h) + h = h.type(x.dtype) + if self.latent_denoising: + if self.normalize_latent: + h = nn.functional.normalize(h, dim=-1) * self.normalize_scale + mean = h + logvar = torch.zeros_like(h) + else: + mean, logvar = h.chunk(2, dim=2) # B, global_token_num, C + if sample_posterior and not self.latent_denoising: + std = torch.exp(0.5 * logvar) + z = mean + std * torch.randn_like(std) + else: + z = mean + else: + h = h.type(x.dtype) + h = self.out_layer(h) + if self.latent_denoising: + if self.normalize_latent: + h = nn.functional.normalize(h, dim=1) * self.normalize_scale + mean = h + logvar = torch.zeros_like(h) + else: + mean, logvar = h.chunk(2, dim=1) + if sample_posterior and not self.latent_denoising: + std = torch.exp(0.5 * logvar) + z = mean + std * torch.randn_like(std) + else: + z = mean + + if self.encode_global_skl: + B, C, D, H, W = h_skl.shape + h_skl = h_skl.view(B, C, D*H*W).permute(0, 2, 1) # B, N, C + h_skl = torch.cat([h_skl, self.grid_pos_emb[None].expand(B, -1, -1)], dim=-1).type(h_skl.dtype) + init_tokens = torch.cat([self.init_tokens, self.tokens_pos_emb[None].expand_as(self.init_tokens)], dim=-1).type(h_skl.dtype) + tokens = self.token_proj(init_tokens.expand(B, -1, -1)) + h_skl = self.out_layer_skl[0](tokens, h_skl) # B, global_token_num_skl, C + for layer in self.out_layer_skl[1:]: + h_skl = layer(h_skl) + h_skl = h_skl.type(x_skl.dtype) + if self.latent_denoising_skl: + if self.normalize_latent_skl: + h_skl = nn.functional.normalize(h_skl, dim=-1) * self.normalize_scale + mean_skl = h_skl + logvar_skl = torch.zeros_like(h_skl) + else: + mean_skl, logvar_skl = h_skl.chunk(2, dim=2) # B, global_token_num_skl, C + if sample_posterior and not self.latent_denoising_skl: + std_skl = torch.exp(0.5 * logvar_skl) + z_skl = mean_skl + std_skl * torch.randn_like(std_skl) + else: + z_skl = mean_skl + else: + h_skl = h_skl.type(x_skl.dtype) + h_skl = self.out_layer_skl(h_skl) + if self.latent_denoising_skl: + if self.normalize_latent_skl: + h_skl = nn.functional.normalize(h_skl, dim=1) * self.normalize_scale + mean_skl = h_skl + logvar_skl = torch.zeros_like(h_skl) + else: + mean_skl, logvar_skl = h_skl.chunk(2, dim=1) + if sample_posterior and not self.latent_denoising_skl: + std_skl = torch.exp(0.5 * logvar_skl) + z_skl = mean_skl + std_skl * torch.randn_like(std_skl) + else: + z_skl = mean_skl + + if self.latent_denoising: + mean = mean.detach() + if self.latent_denoising_skl: + mean_skl = mean_skl.detach() + + if return_raw: + return z, mean, logvar, z_skl, mean_skl, logvar_skl + return z, z_skl + + +class AniGenSparseStructureDecoder(nn.Module): + """ + Decoder for Sparse Structure (\mathcal{D}_S in the paper Sec. 3.3). + + Args: + out_channels (int): Channels of the output. + latent_channels (int): Channels of the latent representation. + num_res_blocks (int): Number of residual blocks at each resolution. + channels (List[int]): Channels of the decoder blocks. + num_res_blocks_middle (int): Number of residual blocks in the middle. + norm_type (Literal["group", "layer"]): Type of normalization layer. + use_fp16 (bool): Whether to use FP16. + """ + def __init__( + self, + out_channels: int, + out_channels_skl: int, + latent_channels: int, + latent_channels_skl: int, + num_res_blocks: int, + channels: List[int], + num_res_blocks_middle: int = 2, + norm_type: Literal["group", "layer"] = "layer", + use_fp16: bool = False, + encode_global: bool = False, + global_token_num: int = 1024, + encode_global_skl: bool = True, + global_token_num_skl: int = 1024, + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + modules_to_freeze: Optional[List[str]] = ["input_layer", "blocks", "middle_block", "out_layer"], + normalize_z: bool = False, + normalize_z_skl: bool = True, + normalize_scale: float = 1.0, + ): + super().__init__() + self.out_channels = out_channels + self.out_channels_skl = out_channels_skl + self.latent_channels = latent_channels + self.latent_channels_skl = latent_channels_skl + self.num_res_blocks = num_res_blocks + self.channels = channels + self.num_res_blocks_middle = num_res_blocks_middle + self.norm_type = norm_type + self.use_fp16 = use_fp16 + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.encode_global = encode_global + self.global_token_num = global_token_num + self.encode_global_skl = encode_global_skl + self.global_token_num_skl = global_token_num_skl + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch + self.normalize_z = normalize_z + self.normalize_z_skl = normalize_z_skl + self.normalize_scale = normalize_scale + + if self.encode_global: + # Initial Grids and PE + upsample_factor = 2 ** (len(channels) - 1) + self.base_size_ss = 64 // upsample_factor + self.init_grids_ss = nn.Parameter(torch.zeros(1, channels[0], self.base_size_ss**3).permute(0, 2, 1).contiguous().clone()) # 1, N, C + pos_embedder = AbsolutePositionEmbedder(channels[0], 3) + coords = torch.meshgrid(*[torch.arange(res, device=self.device) for res in [self.base_size_ss] * 3], indexing='ij') + coords = torch.stack(coords, dim=-1).reshape(-1, 3) + grid_pos_emb = pos_embedder(coords) + self.register_buffer("grid_pos_emb_ss", grid_pos_emb) + # Tokens PE + pos_embedder = AbsolutePositionEmbedder(channels[0], 1) + coords = torch.arange(global_token_num, device=self.device).reshape(-1, 1) + tokens_pos_emb = pos_embedder(coords) + self.register_buffer('tokens_pos_emb_ss', tokens_pos_emb) + # Token projection layer + self.token_proj_ss = nn.Linear(channels[0]*2, channels[0]) + + # Input layers + self.input_layer = nn.ModuleList( + [TransformerBlock( + channels=channels[0] if _ != 0 else latent_channels + channels[0], + out_channels=channels[0], + num_heads=4 if _ == 0 else 16, + attn_mode="full", + qkv_bias=False, + ) for _ in range(4)] + + [TransformerCrossBlock( + channels=channels[0], + ctx_channels=channels[0], + out_channels=channels[0], + num_heads=16, + attn_mode="full", + qkv_bias=False, + x_is_query=False)] + ) + else: + self.input_layer = nn.Conv3d(latent_channels, channels[0], 3, padding=1) + + if self.encode_global_skl: + # Initial Grids and PE + upsample_factor = 2 ** (len(channels) - 1) + self.base_size = 64 // upsample_factor + self.init_grids = nn.Parameter(torch.zeros(1, channels[0], self.base_size**3).permute(0, 2, 1).contiguous().clone()) # 1, N, C + pos_embedder = AbsolutePositionEmbedder(channels[0], 3) + coords = torch.meshgrid(*[torch.arange(res, device=self.device) for res in [self.base_size] * 3], indexing='ij') + coords = torch.stack(coords, dim=-1).reshape(-1, 3) + grid_pos_emb = pos_embedder(coords) + self.register_buffer("grid_pos_emb", grid_pos_emb) + # Tokens PE + pos_embedder = AbsolutePositionEmbedder(channels[0], 1) + coords = torch.arange(global_token_num_skl, device=self.device).reshape(-1, 1) + tokens_pos_emb = pos_embedder(coords) + self.register_buffer('tokens_pos_emb', tokens_pos_emb) + # Token projection layer + self.token_proj = nn.Linear(channels[0]*2, channels[0]) + + # Input layers + self.input_layer_skl = nn.ModuleList( + [TransformerBlock( + channels=channels[0] if _ != 0 else latent_channels_skl + channels[0], + out_channels=channels[0], + num_heads=4 if _ == 0 else 16, + attn_mode="full", + qkv_bias=False, + ) for _ in range(4)] + + [TransformerCrossBlock( + channels=channels[0], + ctx_channels=channels[0], + out_channels=channels[0], + num_heads=16, + attn_mode="full", + qkv_bias=False, + x_is_query=False)] + ) + else: + self.input_layer_skl = nn.Conv3d(latent_channels_skl, channels[0], 3, padding=1) + + self.middle_block = nn.Sequential(*[ + ResBlock3d(channels[0], channels[0]) + for _ in range(num_res_blocks_middle) + ]) + self.middle_block_skl = nn.Sequential(*[ + ResBlock3d(channels[0] if _ == 0 else channels[0], channels[0]) + for _ in range(num_res_blocks_middle) + ]) + + self.blocks = nn.ModuleList([]) + self.blocks_skl = nn.ModuleList([]) + for i, ch in enumerate(channels): + self.blocks.extend([ + ResBlock3d(ch, ch) + for _ in range(num_res_blocks) + ]) + if i < len(channels) - 1: + self.blocks.append( + UpsampleBlock3d(ch, channels[i+1]) + ) + self.blocks_skl.extend([ + ResBlock3d(ch, ch) + for _ in range(num_res_blocks) + ]) + if i < len(channels) - 1: + self.blocks_skl.append( + UpsampleBlock3d(ch, channels[i+1]) + ) + + self.out_layer = nn.Sequential( + norm_layer(norm_type, channels[-1]), + nn.SiLU(), + nn.Conv3d(channels[-1], self.out_channels, 3, padding=1) + ) + self.out_layer_skl = nn.Sequential( + norm_layer(norm_type, channels[-1]), + nn.SiLU(), + nn.Conv3d(channels[-1], self.out_channels_skl, 3, padding=1) + ) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + + if self.use_pretrain_branch and self.freeze_pretrain_branch: + # Freeze: self.input_layer, self.blocks, self.middle_block, self.out_layer + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for param in m.parameters(): + param.requires_grad = False + else: + for param in mod.parameters(): + param.requires_grad = False + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.use_fp16 = True + self.dtype = torch.float16 + self.blocks.apply(convert_module_to_f16) + self.middle_block.apply(convert_module_to_f16) + self.blocks_skl.apply(convert_module_to_f16) + self.middle_block_skl.apply(convert_module_to_f16) + if self.encode_global_skl: + self.token_proj.apply(convert_module_to_f16) + self.input_layer_skl.apply(convert_module_to_f16) + if self.encode_global: + self.token_proj_ss.apply(convert_module_to_f16) + self.input_layer.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.use_fp16 = False + self.dtype = torch.float32 + self.blocks.apply(convert_module_to_f32) + self.middle_block.apply(convert_module_to_f32) + self.blocks_skl.apply(convert_module_to_f32) + self.middle_block_skl.apply(convert_module_to_f32) + if self.encode_global_skl: + self.token_proj.apply(convert_module_to_f32) + self.input_layer_skl.apply(convert_module_to_f32) + if self.encode_global: + self.token_proj_ss.apply(convert_module_to_f32) + self.input_layer.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.kaiming_uniform_(module.weight, nonlinearity='linear') + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def forward(self, x: torch.Tensor, x_skl: torch.Tensor) -> torch.Tensor: + h = F.normalize(x, dim=1) * self.normalize_scale if self.normalize_z else x + h_skl = F.normalize(x_skl, dim=1) * self.normalize_scale if self.normalize_z_skl else x_skl + if self.encode_global: + B, _, _ = h.shape + h = torch.cat([h, self.tokens_pos_emb_ss[None].expand(B, -1, -1)], dim=-1).type(self.dtype) + h = h.type(self.dtype) + for layer in self.input_layer[:-1]: + h = layer(h) + init_grids = torch.cat([self.init_grids_ss, self.grid_pos_emb_ss[None].expand_as(self.init_grids_ss)], dim=-1).type(self.dtype) + grids = self.token_proj_ss(init_grids.expand(B, -1, -1)) + h = self.input_layer[-1](grids, h) # B, N, C + h = h.permute(0, 2, 1).view(B, -1, self.base_size, self.base_size, self.base_size) + else: + h = self.input_layer(h) + h = h.type(self.dtype) + if self.encode_global_skl: + B, _, _ = h_skl.shape + h_skl = torch.cat([h_skl, self.tokens_pos_emb[None].expand(B, -1, -1)], dim=-1).type(self.dtype) + h_skl = h_skl.type(self.dtype) + for layer in self.input_layer_skl[:-1]: + h_skl = layer(h_skl) + init_grids = torch.cat([self.init_grids, self.grid_pos_emb[None].expand_as(self.init_grids)], dim=-1).type(self.dtype) + grids = self.token_proj(init_grids.expand(B, -1, -1)) + h_skl = self.input_layer_skl[-1](grids, h_skl) # B, N, C + h_skl = h_skl.permute(0, 2, 1).view(B, -1, self.base_size, self.base_size, self.base_size) + else: + h_skl = self.input_layer_skl(h_skl) + h_skl = h_skl.type(self.dtype) + h_skl = self.middle_block_skl(h_skl) + h = self.middle_block(h) + for block, block_skl in zip(self.blocks, self.blocks_skl): + h_skl = block_skl(h_skl) + h = block(h) + h = h.type(x.dtype) + h = self.out_layer(h) + h_skl = h_skl.type(x.dtype) + h_skl = self.out_layer_skl(h_skl) + return h, h_skl diff --git a/anigen/models/anigen_structured_latent_flow.py b/anigen/models/anigen_structured_latent_flow.py new file mode 100644 index 0000000000000000000000000000000000000000..c77f8c8c845e8a4d4cf0e475f59953fe1fc21294 --- /dev/null +++ b/anigen/models/anigen_structured_latent_flow.py @@ -0,0 +1,553 @@ +from typing import * +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np + +from anigen.modules.transformer import blocks +from ..modules.utils import zero_module, convert_module_to_f16, convert_module_to_f32 +from ..modules.transformer import AbsolutePositionEmbedder +from ..modules.norm import LayerNorm32 +from ..modules import sparse as sp +from ..modules.sparse.transformer import ModulatedSparseTransformerCrossBlock +from .sparse_elastic_mixin import SparseTransformerElasticMixin + + +class TimestepEmbedder(nn.Module): + """ + Embeds scalar timesteps into vector representations. + """ + def __init__(self, hidden_size, frequency_embedding_size=256): + super().__init__() + self.mlp = nn.Sequential( + nn.Linear(frequency_embedding_size, hidden_size, bias=True), + nn.SiLU(), + nn.Linear(hidden_size, hidden_size, bias=True), + ) + self.frequency_embedding_size = frequency_embedding_size + + @staticmethod + def timestep_embedding(t, dim, max_period=10000): + """ + Create sinusoidal timestep embeddings. + + Args: + t: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + dim: the dimension of the output. + max_period: controls the minimum frequency of the embeddings. + + Returns: + an (N, D) Tensor of positional embeddings. + """ + # https://github.com/openai/glide-text2im/blob/main/glide_text2im/nn.py + half = dim // 2 + freqs = torch.exp( + -np.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half + ).to(device=t.device) + args = t[:, None].float() * freqs[None] + embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) + if dim % 2: + embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) + return embedding + + def forward(self, t): + t_freq = self.timestep_embedding(t, self.frequency_embedding_size) + t_emb = self.mlp(t_freq) + return t_emb + + +class SparseResBlock3d(nn.Module): + def __init__( + self, + channels: int, + emb_channels: int, + out_channels: Optional[int] = None, + downsample: bool = False, + upsample: bool = False, + ): + super().__init__() + self.channels = channels + self.emb_channels = emb_channels + self.out_channels = out_channels or channels + self.downsample = downsample + self.upsample = upsample + + assert not (downsample and upsample), "Cannot downsample and upsample at the same time" + + self.norm1 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6) + self.norm2 = LayerNorm32(self.out_channels, elementwise_affine=False, eps=1e-6) + self.conv1 = sp.SparseConv3d(channels, self.out_channels, 3) + self.conv2 = zero_module(sp.SparseConv3d(self.out_channels, self.out_channels, 3)) + self.emb_layers = nn.Sequential( + nn.SiLU(), + nn.Linear(emb_channels, 2 * self.out_channels, bias=True), + ) + self.skip_connection = sp.SparseLinear(channels, self.out_channels) if channels != self.out_channels else nn.Identity() + self.updown = None + if self.downsample: + self.updown = sp.SparseDownsample(2) + elif self.upsample: + self.updown = sp.SparseUpsample(2) + + def _updown(self, x: sp.SparseTensor) -> sp.SparseTensor: + if self.updown is not None: + x = self.updown(x) + return x + + def forward(self, x: sp.SparseTensor, emb: torch.Tensor) -> sp.SparseTensor: + emb_out = self.emb_layers(emb).type(x.dtype) + scale, shift = torch.chunk(emb_out, 2, dim=1) + + x = self._updown(x) + h = x.replace(self.norm1(x.feats)) + h = h.replace(F.silu(h.feats)) + h = self.conv1(h) + h = h.replace(self.norm2(h.feats)) * (1 + scale) + shift + h = h.replace(F.silu(h.feats)) + h = self.conv2(h) + h = h + self.skip_connection(x) + + return h + + +class AniGenSLatFlowModel(nn.Module): + def __init__( + self, + resolution: int, + in_channels: int, + in_channels_vert_skin: int, + in_channels_skl: int, + model_channels: int, + model_channels_vert_skin: int, + model_channels_skl: int, + cond_channels: int, + out_channels: int, + out_channels_vert_skin: int, + out_channels_skl: int, + num_blocks: int, + num_heads: Optional[int] = None, + num_head_channels: Optional[int] = 64, + num_heads_vert_skin: Optional[int] = None, + num_head_channels_vert_skin: Optional[int] = 64, + num_heads_skl: Optional[int] = None, + num_head_channels_skl: Optional[int] = 64, + mlp_ratio: float = 4, + patch_size: int = 2, + num_io_res_blocks: int = 2, + num_io_res_blocks_vert_skin: int = 2, + num_io_res_blocks_skl: int = 2, + io_block_channels: List[int] = None, + io_block_channels_vert_skin: List[int] = None, + io_block_channels_skl: List[int] = None, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + use_skip_connection: bool = True, + share_mod: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + modules_to_freeze: Optional[List[str]] = ['blocks', 'input_blocks','input_layer', 'out_blocks', 'out_layer', 't_embedder'], + predict_x0: bool = False, + t_eps: float = 5e-2, + t_scale: float = 1e3, + use_joint_num_cond: bool = False, + joint_num_max: int = 60, + joint_num_fourier_bands: int = 6, + ): + super().__init__() + + self.pretrain_class_name = ["AniGenSlatFlowImage"] + + self.resolution = resolution + self.in_channels = in_channels + self.in_channels_vert_skin = in_channels_vert_skin + self.in_channels_skl = in_channels_skl + self.model_channels = model_channels + self.model_channels_vert_skin = model_channels_vert_skin + self.model_channels_skl = model_channels_skl + self.cond_channels = cond_channels + self.out_channels = out_channels + self.out_channels_vert_skin = out_channels_vert_skin + self.out_channels_skl = out_channels_skl + self.num_blocks = num_blocks + self.num_heads = num_heads or model_channels // num_head_channels + self.num_heads_vert_skin = num_heads_vert_skin or model_channels_vert_skin // num_head_channels_vert_skin + self.num_heads_skl = num_heads_skl or model_channels_skl // num_head_channels_skl + self.mlp_ratio = mlp_ratio + self.patch_size = patch_size + self.num_io_res_blocks = num_io_res_blocks + self.num_io_res_blocks_vert_skin = num_io_res_blocks_vert_skin + self.num_io_res_blocks_skl = num_io_res_blocks_skl + self.io_block_channels = io_block_channels + self.io_block_channels_vert_skin = io_block_channels_vert_skin + self.io_block_channels_skl = io_block_channels_skl + self.pe_mode = pe_mode + self.use_fp16 = use_fp16 + self.use_checkpoint = use_checkpoint + self.use_skip_connection = use_skip_connection + self.share_mod = share_mod + self.qk_rms_norm = qk_rms_norm + self.qk_rms_norm_cross = qk_rms_norm_cross + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.predict_x0 = predict_x0 + self.t_eps = t_eps + self.t_scale = t_scale + self.use_joint_num_cond = use_joint_num_cond + self.joint_num_max = joint_num_max + self.joint_num_fourier_bands = joint_num_fourier_bands + + if self.io_block_channels is not None: + assert int(np.log2(patch_size)) == np.log2(patch_size), "Patch size must be a power of 2" + assert np.log2(patch_size) == len(io_block_channels), "Number of IO ResBlocks must match the number of stages" + + self.t_embedder = TimestepEmbedder(model_channels) + self.t_embedder_vert_skin = TimestepEmbedder(model_channels_vert_skin) + self.t_embedder_skl = TimestepEmbedder(model_channels_skl) + + if self.use_joint_num_cond: + # Joint-number conditioning (applied to skin + skeleton branches). + # If joints_num is missing/<=0, use learnable unconditional embeddings. + self.joint_num_embedder_vert_skin = nn.Sequential( + nn.Linear(2 * joint_num_fourier_bands, model_channels_vert_skin, bias=True), + nn.SiLU(), + nn.Linear(model_channels_vert_skin, model_channels_vert_skin, bias=True), + ) + self.joint_num_embedder_skl = nn.Sequential( + nn.Linear(2 * joint_num_fourier_bands, model_channels_skl, bias=True), + nn.SiLU(), + nn.Linear(model_channels_skl, model_channels_skl, bias=True), + ) + self.joint_num_uncond_vert_skin = nn.Parameter(torch.zeros(model_channels_vert_skin)) + self.joint_num_uncond_skl = nn.Parameter(torch.zeros(model_channels_skl)) + if share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(model_channels, 6 * model_channels, bias=True) + ) + self.adaLN_modulation_vert_skin = nn.Sequential( + nn.SiLU(), + nn.Linear(model_channels_vert_skin, 6 * model_channels_vert_skin, bias=True) + ) + self.adaLN_modulation_skl = nn.Sequential( + nn.SiLU(), + nn.Linear(model_channels_skl, 6 * model_channels_skl, bias=True) + ) + + if pe_mode == "ape": + self.pos_embedder = AbsolutePositionEmbedder(model_channels) + self.pos_embedder_vert_skin = AbsolutePositionEmbedder(model_channels_vert_skin) + self.pos_embedder_skl = AbsolutePositionEmbedder(model_channels_skl) + + # Causuality in conditioning: + # Geometry <- Conditioned Image (Cross Attention) + # Skinning <- Geometry (Adapter Layer) + Skeleton (Cross Attention) + # Skeleton <- Skinning (Cross Attention) + causial_cond_channels_dict = {'': cond_channels, '_vert_skin': self.model_channels_skl, '_skl': self.model_channels_vert_skin} + + for postfix in ['', '_vert_skin', '_skl']: + # Input blocks + setattr(self, f'input_layer{postfix}', sp.SparseLinear( + getattr(self, f'in_channels{postfix}'), + getattr(self, f'model_channels{postfix}') if getattr(self, f'io_block_channels{postfix}') is None else getattr(self, f'io_block_channels{postfix}')[0] + )) + + setattr(self, f'input_blocks{postfix}', nn.ModuleList([])) + io_block_channels = getattr(self, f'io_block_channels{postfix}') + model_channels = getattr(self, f'model_channels{postfix}') + num_io_res_blocks = getattr(self, f'num_io_res_blocks{postfix}') + if io_block_channels is not None: + for chs, next_chs in zip(io_block_channels, io_block_channels[1:] + [model_channels]): + getattr(self, f'input_blocks{postfix}').extend([ + SparseResBlock3d( + chs, + model_channels, + out_channels=chs, + ) + for _ in range(num_io_res_blocks-1) + ]) + getattr(self, f'input_blocks{postfix}').append( + SparseResBlock3d( + chs, + model_channels, + out_channels=next_chs, + downsample=True, + ) + ) + + # Transformer blocks + cond_channels_block = causial_cond_channels_dict[postfix] + setattr(self, f'blocks{postfix}', nn.ModuleList([ + ModulatedSparseTransformerCrossBlock( + getattr(self, f'model_channels{postfix}'), + cond_channels_block, + num_heads=getattr(self, f'num_heads{postfix}'), + mlp_ratio=self.mlp_ratio, + attn_mode='full', + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + share_mod=self.share_mod, + qk_rms_norm=self.qk_rms_norm, + qk_rms_norm_cross=self.qk_rms_norm_cross, + norm_for_context=True, + ) + for _ in range(num_blocks) + ])) + + # Output blocks + setattr(self, f'out_blocks{postfix}', nn.ModuleList([])) + if io_block_channels is not None: + for chs, prev_chs in zip(reversed(io_block_channels), [model_channels] + list(reversed(io_block_channels[1:]))): + getattr(self, f'out_blocks{postfix}').append( + SparseResBlock3d( + prev_chs * 2 if self.use_skip_connection else prev_chs, + model_channels, + out_channels=chs, + upsample=True, + ) + ) + getattr(self, f'out_blocks{postfix}').extend([ + SparseResBlock3d( + chs * 2 if self.use_skip_connection else chs, + model_channels, + out_channels=chs, + ) + for _ in range(num_io_res_blocks-1) + ]) + setattr(self, f'out_layer{postfix}', sp.SparseLinear(model_channels if io_block_channels is None else io_block_channels[0], getattr(self, f'out_channels{postfix}'))) + + self.adapter_geo_to_skin = nn.ModuleList([ + sp.SparseLinear(self.model_channels, self.model_channels_vert_skin) for _ in range(num_blocks) + ]) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch + # self.is_geometry_branch_frozen = self.use_pretrain_branch and self.freeze_pretrain_branch and all([module in modules_to_freeze for module in ['blocks', 'input_blocks','input_layer', 'out_blocks', 'out_layer', 't_embedder']]) + + if self.use_pretrain_branch and self.freeze_pretrain_branch: + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for param in m.parameters(): + param.requires_grad = False + else: + for param in mod.parameters(): + param.requires_grad = False + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + for postfix in ['', '_vert_skin', '_skl']: + getattr(self, f'input_blocks{postfix}').apply(convert_module_to_f16) + getattr(self, f'blocks{postfix}').apply(convert_module_to_f16) + getattr(self, f'out_blocks{postfix}').apply(convert_module_to_f16) + self.adapter_geo_to_skin.apply(convert_module_to_f16) + if self.use_joint_num_cond: + self.joint_num_embedder_vert_skin.apply(convert_module_to_f16) + self.joint_num_embedder_skl.apply(convert_module_to_f16) + self.joint_num_uncond_vert_skin.data = self.joint_num_uncond_vert_skin.data.half() + self.joint_num_uncond_skl.data = self.joint_num_uncond_skl.data.half() + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + for postfix in ['', '_vert_skin', '_skl']: + getattr(self, f'input_blocks{postfix}').apply(convert_module_to_f32) + getattr(self, f'blocks{postfix}').apply(convert_module_to_f32) + getattr(self, f'out_blocks{postfix}').apply(convert_module_to_f32) + self.adapter_geo_to_skin.apply(convert_module_to_f32) + if self.use_joint_num_cond: + self.joint_num_embedder_vert_skin.apply(convert_module_to_f32) + self.joint_num_embedder_skl.apply(convert_module_to_f32) + self.joint_num_uncond_vert_skin.data = self.joint_num_uncond_vert_skin.data.float() + self.joint_num_uncond_skl.data = self.joint_num_uncond_skl.data.float() + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + for postfix in ['', '_vert_skin', '_skl']: + nn.init.normal_(getattr(self, f't_embedder{postfix}').mlp[0].weight, std=0.02) + nn.init.normal_(getattr(self, f't_embedder{postfix}').mlp[2].weight, std=0.02) + if self.share_mod: + nn.init.constant_(getattr(self, f'adaLN_modulation{postfix}')[-1].weight, 0) + nn.init.constant_(getattr(self, f'adaLN_modulation{postfix}')[-1].bias, 0) + else: + for block in getattr(self, f'blocks{postfix}'): + nn.init.constant_(block.adaLN_modulation[-1].weight, 0) + nn.init.constant_(block.adaLN_modulation[-1].bias, 0) + nn.init.constant_(getattr(self, f'out_layer{postfix}').weight, 0) + nn.init.constant_(getattr(self, f'out_layer{postfix}').bias, 0) + + for layer in self.adapter_geo_to_skin: + nn.init.constant_(layer.weight, 0) + nn.init.constant_(layer.bias, 0) + + if self.use_joint_num_cond: + # Joint-number conditioning layers + for emb in [self.joint_num_embedder_vert_skin, self.joint_num_embedder_skl]: + for m in emb.modules(): + if isinstance(m, nn.Linear): + torch.nn.init.xavier_uniform_(m.weight) + if m.bias is not None: + nn.init.constant_(m.bias, 0) + + def _fourier_encode_joint_num(self, joints_num: torch.Tensor) -> torch.Tensor: + """Fourier features for joints_num in [0, joint_num_max].""" + # Keep dtype consistent with model (e.g., fp16) to avoid Linear dtype mismatch. + dtype = getattr(self, 'dtype', torch.float32) + x = (joints_num.to(dtype=dtype) / float(self.joint_num_max)).clamp(0.0, 1.0) + x = x[:, None] + freqs = (2.0 ** torch.arange(self.joint_num_fourier_bands, device=x.device, dtype=x.dtype)) * math.pi + angles = x * freqs[None, :] + return torch.cat([torch.sin(angles), torch.cos(angles)], dim=-1) + + def _get_joint_num_emb(self, joints_num: Optional[torch.Tensor], batch_size: int, device: torch.device) -> Tuple[torch.Tensor, torch.Tensor]: + """Return (emb_vert_skin, emb_skl), shape [B, C_*].""" + if joints_num is None: + joints_num = torch.zeros(batch_size, device=device) + elif not torch.is_tensor(joints_num): + joints_num = torch.tensor(joints_num, device=device) + joints_num = joints_num.to(device=device) + if joints_num.dim() == 0: + joints_num = joints_num[None].expand(batch_size) + joints_num = joints_num.reshape(batch_size) + + mask_dtype = getattr(self, 'dtype', torch.float32) + uncond_mask = (joints_num <= 0).to(dtype=mask_dtype, device=device)[:, None] + joints_num = joints_num.clamp(min=0, max=self.joint_num_max) + + fourier = self._fourier_encode_joint_num(joints_num) + emb_vs_cond = self.joint_num_embedder_vert_skin(fourier) + emb_skl_cond = self.joint_num_embedder_skl(fourier) + + emb_vs_uncond = self.joint_num_uncond_vert_skin[None].expand(batch_size, -1) + emb_skl_uncond = self.joint_num_uncond_skl[None].expand(batch_size, -1) + + # Blend: uncond_mask==1 -> unconditional, uncond_mask==0 -> conditional. + emb_vs = emb_vs_cond * (1.0 - uncond_mask) + emb_vs_uncond * uncond_mask + emb_skl = emb_skl_cond * (1.0 - uncond_mask) + emb_skl_uncond * uncond_mask + return emb_vs, emb_skl + + def forward_stage( + self, + x: sp.SparseTensor, + t: torch.Tensor, + postfix, + stage, + cond_emb: Optional[torch.Tensor] = None, + t_emb=None, + skips=None, + original_dtype=None, + ) -> sp.SparseTensor: + input_layer = getattr(self, f'input_layer{postfix}') + t_embedder = getattr(self, f't_embedder{postfix}') + input_blocks = getattr(self, f'input_blocks{postfix}') + pos_embedder = getattr(self, f'pos_embedder{postfix}') + out_blocks = getattr(self, f'out_blocks{postfix}') + out_layer = getattr(self, f'out_layer{postfix}') + adaLN_modulation = getattr(self, f'adaLN_modulation{postfix}') if self.share_mod else None + + if stage == 'in': + h = input_layer(x).type(self.dtype) + t_emb = t_embedder(t) + if cond_emb is not None: + t_emb = t_emb + cond_emb + t_emb = t_emb.type(self.dtype) + t_mod = adaLN_modulation(t_emb).type(self.dtype) if self.share_mod else t_emb + skips = [] + # pack with input blocks + for block in input_blocks: + h = block(h, t_emb) + skips.append(h.feats) + if self.pe_mode == "ape": + h = h + pos_embedder(h.coords[:, 1:]).type(self.dtype) + return h, t_emb, t_mod, skips + elif stage == 'out': + h = x + # unpack with output blocks + for block, skip in zip(out_blocks, reversed(skips)): + if self.use_skip_connection: + h = block(h.replace(torch.cat([h.feats, skip], dim=1)), t_emb) + else: + h = block(h, t_emb) + h = h.replace(F.layer_norm(h.feats, h.feats.shape[-1:])) + h = out_layer(h.type(original_dtype)) + return h + else: + raise ValueError(f"Unknown stage: {stage}") + + def forward(self, x: sp.SparseTensor, x_skl: sp.SparseTensor, t: torch.Tensor, cond: torch.Tensor, joints_num: Optional[torch.Tensor] = None, **kwargs) -> sp.SparseTensor: + cond = cond.type(self.dtype) + feats, feats_vert_skin = x.feats[:, :self.in_channels], x.feats[:, self.in_channels:] + x, x_vert_skin = x.replace(feats), x.replace(feats_vert_skin) + if self.predict_x0: + xt_feats_skin, xt_feats_skl = feats_vert_skin.clone(), x_skl.feats.clone() + + joint_emb_vs, joint_emb_skl = None, None + if self.use_joint_num_cond: + # joint-number conditioning for skin + skeleton + joint_emb_vs, joint_emb_skl = self._get_joint_num_emb(joints_num, x.shape[0], x.device) + joint_emb_vs = joint_emb_vs.type(self.dtype) + joint_emb_skl = joint_emb_skl.type(self.dtype) + + in_dicts = {'': x, '_vert_skin': x_vert_skin, '_skl': x_skl} + cond_emb_dicts = {'': None, '_vert_skin': joint_emb_vs, '_skl': joint_emb_skl} + postfix_keys = list(in_dicts.keys()) + for postfix in postfix_keys: + cond_emb = cond_emb_dicts[postfix] + in_dicts[postfix], in_dicts[f't_emb{postfix}'], in_dicts[f't_mod{postfix}'], in_dicts[f'skips{postfix}'] = self.forward_stage(in_dicts[postfix], t, postfix, stage='in', cond_emb=cond_emb) + for block, block_skin, block_skl, adapter in zip(self.blocks, self.blocks_vert_skin, self.blocks_skl, self.adapter_geo_to_skin): + h, h_skin, h_skl = in_dicts[''], in_dicts['_vert_skin'], in_dicts['_skl'] + f = block(h, in_dicts['t_mod'], cond) + f_skin = block_skin(h_skin, in_dicts['t_mod_vert_skin'], h_skl) + adapter(h) + f_skl = block_skl(h_skl, in_dicts['t_mod_skl'], h_skin) + in_dicts[''], in_dicts['_vert_skin'], in_dicts['_skl'] = f, f_skin, f_skl + for postfix in postfix_keys: + in_dicts[postfix] = self.forward_stage( + in_dicts[postfix], + t, + postfix, + stage='out', + t_emb=in_dicts[f't_emb{postfix}'], + skips=in_dicts[f'skips{postfix}'], + original_dtype=x.dtype, + ) + if self.predict_x0: + t_normalized = t / self.t_scale + factor = (1 / t_normalized.clamp_min(self.t_eps))[:, None] + in_dicts['_vert_skin'] = in_dicts['_vert_skin'].replace((in_dicts['_vert_skin'].feats - xt_feats_skin) * factor[in_dicts['_vert_skin'].coords[:, 0]]) + in_dicts['_skl'] = in_dicts['_skl'].replace((in_dicts['_skl'].feats - xt_feats_skl) * factor[in_dicts['_skl'].coords[:, 0]]) + x_out = x.replace(torch.cat([in_dicts[''].feats, in_dicts['_vert_skin'].feats], dim=1)) + x_skl_out = x_skl.replace(in_dicts['_skl'].feats) + return x_out, x_skl_out + +class AniGenElasticSLatFlowModel(SparseTransformerElasticMixin, AniGenSLatFlowModel): + """ + SLat Flow Model with elastic memory management. + Used for training with low VRAM. + """ + pass diff --git a/anigen/models/sparse_elastic_mixin.py b/anigen/models/sparse_elastic_mixin.py new file mode 100644 index 0000000000000000000000000000000000000000..66d204c89bedabc2afd1795cdfc6f5d58a6b1ac0 --- /dev/null +++ b/anigen/models/sparse_elastic_mixin.py @@ -0,0 +1,24 @@ +from contextlib import contextmanager +from typing import * +import math +from ..modules import sparse as sp +from ..utils.elastic_utils import ElasticModuleMixin + + +class SparseTransformerElasticMixin(ElasticModuleMixin): + def _get_input_size(self, x: sp.SparseTensor, *args, **kwargs): + return x.feats.shape[0] + + @contextmanager + def with_mem_ratio(self, mem_ratio=1.0): + if mem_ratio == 1.0: + yield 1.0 + return + num_blocks = len(self.blocks) + num_checkpoint_blocks = min(math.ceil((1 - mem_ratio) * num_blocks) + 1, num_blocks) + exact_mem_ratio = 1 - (num_checkpoint_blocks - 1) / num_blocks + for i in range(num_blocks): + self.blocks[i].use_checkpoint = i < num_checkpoint_blocks + yield exact_mem_ratio + for i in range(num_blocks): + self.blocks[i].use_checkpoint = False diff --git a/anigen/models/structured_latent_vae/__init__.py b/anigen/models/structured_latent_vae/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c5c9299f74995b2750ee7edbeabe607ab116db36 --- /dev/null +++ b/anigen/models/structured_latent_vae/__init__.py @@ -0,0 +1,3 @@ +from .anigen_encoder import AniGenElasticSLatEncoder +from .anigen_decoder import AniGenElasticSLatMeshDecoder +from .skin_models import SkinAutoEncoder \ No newline at end of file diff --git a/anigen/models/structured_latent_vae/anigen_base.py b/anigen/models/structured_latent_vae/anigen_base.py new file mode 100644 index 0000000000000000000000000000000000000000..b6a83158bffc41113dc71246f90ed3eb171cc8fb --- /dev/null +++ b/anigen/models/structured_latent_vae/anigen_base.py @@ -0,0 +1,256 @@ +from typing import * +import torch +import torch.nn as nn +from ...modules import sparse as sp +from ...modules.utils import zero_module, convert_module_to_f16, convert_module_to_f32 +from ...modules.sparse.transformer import SparseTransformerMultiContextCrossBlock, SparseTransformerBlock +from ...modules.transformer import AbsolutePositionEmbedder, TransformerCrossBlock + + +class FreqPositionalEmbedder(nn.Module): + def __init__(self, in_dim, include_input=True, max_freq_log2=8, num_freqs=8, log_sampling=True, periodic_fns=None): + super().__init__() + self.in_dim = in_dim + self.out_dim = None + self.include_input = include_input + self.max_freq_log2 = max_freq_log2 + self.num_freqs = num_freqs + self.log_sampling = log_sampling + self.periodic_fns = periodic_fns if periodic_fns is not None else [ + torch.sin, torch.cos + ] + self.create_embedding_fn() + + def create_embedding_fn(self): + embed_fns = [] + d = self.in_dim + out_dim = 0 + if self.include_input: + embed_fns.append(lambda x: x) + out_dim += d + + max_freq = self.max_freq_log2 + N_freqs = self.num_freqs + + if self.log_sampling: + freq_bands = 2. ** torch.linspace(0., max_freq, steps=N_freqs) + else: + freq_bands = torch.linspace(2. ** 0., 2. ** max_freq, steps=N_freqs) + + for freq in freq_bands: + for p_fn in self.periodic_fns: + embed_fns.append(lambda x, p_fn=p_fn, freq=freq: p_fn(x * freq)) + out_dim += d + + self.embed_fns = embed_fns + self.out_dim = out_dim + + def forward(self, inputs): + return torch.cat([fn(inputs) for fn in self.embed_fns], -1) + + +def block_attn_config(self, attn_mode_attr='attn_mode'): + """ + Return the attention configuration of the model. + """ + attn_mode = getattr(self, attn_mode_attr) + for i in range(self.num_blocks): + if attn_mode == "shift_window": + yield "serialized", self.window_size, 0, (16 * (i % 2),) * 3, sp.SerializeMode.Z_ORDER + elif attn_mode == "shift_sequence": + yield "serialized", self.window_size, self.window_size // 2 * (i % 2), (0, 0, 0), sp.SerializeMode.Z_ORDER + elif attn_mode == "shift_order": + yield "serialized", self.window_size, 0, (0, 0, 0), sp.SerializeModes[i % 4] + elif attn_mode == "full": + yield "full", None, None, None, None + elif attn_mode == "swin": + yield "windowed", self.window_size, None, self.window_size // 2 * (i % 2), None + + +class AniGenSparseTransformerBase(nn.Module): + """ + Sparse Transformer without output layers. + Serve as the base class for encoder and decoder. + """ + def __init__( + self, + in_channels: int, + in_channels_skl: int, + in_channels_skin: int, + model_channels: int, + model_channels_skl: int, + model_channels_skin: int, + num_blocks: int, + num_heads: Optional[int] = None, + num_heads_skl: int = 8, + num_heads_skin: int = 8, + num_head_channels: Optional[int] = 64, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + attn_mode_cross: Literal["full", "serialized", "windowed"] = "full", + window_size: Optional[int] = None, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + qk_rms_norm: bool = False, + + skin_cross_from_geo: bool = True, + skl_cross_from_geo: bool = True, + skin_skl_cross: bool = True, + ): + super().__init__() + self.in_channels = in_channels + self.in_channels_skl = in_channels_skl + self.in_channels_skin = in_channels_skin + self.model_channels = model_channels + self.model_channels_skl = model_channels_skl + self.model_channels_skin = model_channels_skin + self.num_blocks = num_blocks + self.window_size = window_size + self.num_heads = num_heads or model_channels // num_head_channels + self.mlp_ratio = mlp_ratio + self.attn_mode = attn_mode + self.attn_mode_cross = attn_mode_cross + self.pe_mode = pe_mode + self.use_fp16 = use_fp16 + self.use_checkpoint = use_checkpoint + self.qk_rms_norm = qk_rms_norm + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.skin_cross_from_geo = skin_cross_from_geo + self.skl_cross_from_geo = skl_cross_from_geo + self.skin_skl_cross = skin_skl_cross + + if pe_mode == "ape": + self.pos_embedder = AbsolutePositionEmbedder(model_channels) + self.pos_embedder_skl = AbsolutePositionEmbedder(model_channels_skl) + self.pos_embedder_skin = AbsolutePositionEmbedder(model_channels_skin) + + self.input_layer = sp.SparseLinear(in_channels, model_channels) + self.input_layer_skl = sp.SparseLinear(in_channels_skl, model_channels_skl) + self.input_layer_skin = sp.SparseLinear(in_channels_skin, model_channels_skin) + + self.blocks = nn.ModuleList([ + SparseTransformerBlock( + model_channels, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + qk_rms_norm=self.qk_rms_norm, + ) + for attn_mode, window_size, shift_sequence, shift_window, serialize_mode in block_attn_config(self) + ]) + + ctx_channels = [] + if skin_skl_cross: + ctx_channels.append(model_channels_skl) + if skin_cross_from_geo: + ctx_channels.append(model_channels) + self.blocks_skin = nn.ModuleList([ + SparseTransformerMultiContextCrossBlock( + model_channels_skin, + ctx_channels=ctx_channels, + num_heads=num_heads_skin, + mlp_ratio=self.mlp_ratio, + attn_mode=attn_mode, + attn_mode_cross=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + qk_rms_norm=self.qk_rms_norm, + cross_attn_cache_suffix='_skin', + ) + for attn_mode, window_size, shift_sequence, shift_window, serialize_mode in block_attn_config(self, "attn_mode_cross") + ]) + + ctx_channels = [] + if skin_skl_cross: + ctx_channels.append(model_channels_skin) + if skl_cross_from_geo: + ctx_channels.append(model_channels) + self.blocks_skl = nn.ModuleList([ + SparseTransformerMultiContextCrossBlock( + model_channels_skl, + ctx_channels=ctx_channels, + num_heads=num_heads_skl, + mlp_ratio=self.mlp_ratio, + attn_mode=attn_mode, + attn_mode_cross=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + qk_rms_norm=self.qk_rms_norm, + cross_attn_cache_suffix='_skl', + ) + for attn_mode, window_size, shift_sequence, shift_window, serialize_mode in block_attn_config(self, "attn_mode_cross") + ]) + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.blocks.apply(convert_module_to_f16) + self.blocks_skl.apply(convert_module_to_f16) + self.blocks_skin.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.blocks.apply(convert_module_to_f32) + self.blocks_skl.apply(convert_module_to_f32) + self.blocks_skin.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def forward_input_layer(self, x: sp.SparseTensor, layer, pos_embedder) -> sp.SparseTensor: + h = layer(x) + if self.pe_mode == "ape": + h = h + pos_embedder(x.coords[:, 1:]) + h = h.type(self.dtype) + return h + + def forward(self, x: sp.SparseTensor, x_skl: sp.SparseTensor, x_skin: sp.SparseTensor) -> sp.SparseTensor: + h = self.forward_input_layer(x, self.input_layer, self.pos_embedder) + h_skl = self.forward_input_layer(x_skl, self.input_layer_skl, self.pos_embedder_skl) + h_skin = self.forward_input_layer(x_skin, self.input_layer_skin, self.pos_embedder_skin) + + for block, block_skl, block_skin in zip(self.blocks, self.blocks_skl, self.blocks_skin): + f, f_skl, f_skin = h, h_skl, h_skin + h = block(f) + skl_contexts, skin_contexts = [], [] + if self.skin_skl_cross: + skl_contexts.append(f_skin) + skin_contexts.append(f_skl) + if self.skl_cross_from_geo: + skl_contexts.append(f) + if self.skin_cross_from_geo: + skin_contexts.append(f) + h_skl = block_skl(f_skl, skl_contexts) + h_skin = block_skin(f_skin, skin_contexts) + return h, h_skl, h_skin diff --git a/anigen/models/structured_latent_vae/anigen_decoder.py b/anigen/models/structured_latent_vae/anigen_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..beb4078dd17e520583d9900088849aa2c94fbfac --- /dev/null +++ b/anigen/models/structured_latent_vae/anigen_decoder.py @@ -0,0 +1,834 @@ +from typing import * +import contextlib +import torch +import torch.nn as nn +from ...modules.sparse.transformer import SparseTransformerMultiContextCrossBlock, SparseTransformerBlock +from ...modules.utils import zero_module, convert_module_to_f16, convert_module_to_f32 +from ...modules import sparse as sp +from ...representations import MeshExtractResult +from ...representations.mesh import AniGenSparseFeatures2Mesh, AniGenSklFeatures2Skeleton +from ..sparse_elastic_mixin import SparseTransformerElasticMixin +from pytorch3d.ops import knn_points +from .anigen_base import AniGenSparseTransformerBase, FreqPositionalEmbedder +from .skin_models import SKIN_MODEL_DICT +import torch.nn.functional as F +from ...representations.skeleton.grouping import GROUPING_STRATEGIES + + +class SparseSubdivideBlock3d(nn.Module): + """ + A 3D subdivide block that can subdivide the sparse tensor. + + Args: + channels: channels in the inputs and outputs. + out_channels: if specified, the number of output channels. + num_groups: the number of groups for the group norm. + """ + def __init__( + self, + channels: int, + resolution: int, + out_channels: Optional[int] = None, + num_groups: int = 32, + sub_divide: bool = True, + conv_as_residual: bool = False, + ): + super().__init__() + self.channels = channels + self.resolution = resolution + self.out_resolution = resolution * 2 if sub_divide else resolution + self.out_channels = out_channels or channels + self.sub_divide = sub_divide + self.conv_as_residual = conv_as_residual + + self.act_layers = nn.Sequential( + sp.SparseGroupNorm32(num_groups, channels), + sp.SparseSiLU() + ) + + self.sub = sp.SparseSubdivide() if sub_divide else nn.Identity() + + self.out_layers = nn.Sequential( + sp.SparseConv3d(channels, self.out_channels, 3, indice_key=f"res_{self.out_resolution}"), + sp.SparseGroupNorm32(num_groups, self.out_channels), + sp.SparseSiLU(), + zero_module(sp.SparseConv3d(self.out_channels, self.out_channels, 3, indice_key=f"res_{self.out_resolution}")), + ) + + if self.out_channels == channels and not self.conv_as_residual: + self.skip_connection = nn.Identity() + else: + self.skip_connection = sp.SparseConv3d(channels, self.out_channels, 1, indice_key=f"res_{self.out_resolution}") + + def forward(self, x: sp.SparseTensor) -> sp.SparseTensor: + """ + Apply the block to a Tensor, conditioned on a timestep embedding. +SparseConv3d + Args: + x: an [N x C x ...] Tensor of features. + Returns: + an [N x C x ...] Tensor of outputs. + """ + h = self.act_layers(x) + h = self.sub(h) + x = self.sub(x) + h = self.out_layers(h) + h = h + self.skip_connection(x) + return h + + +class SparseDownsampleWithCache(nn.Module): + """SparseDownsample that stores upsample caches under a unique suffix. + + This avoids cache-key collisions when stacking multiple down/up stages. + """ + def __init__(self, factor: Union[int, Tuple[int, ...], List[int]], cache_suffix: str): + super().__init__() + self.factor = tuple(factor) if isinstance(factor, (list, tuple)) else factor + self.cache_suffix = cache_suffix + self._down = sp.SparseDownsample(self.factor) + + def forward(self, x: sp.SparseTensor) -> sp.SparseTensor: + out = self._down(x) + + dim = out.coords.shape[-1] - 1 + factor = self.factor if isinstance(self.factor, tuple) else (self.factor,) * dim + k_coords = f'upsample_{factor}_coords' + k_layout = f'upsample_{factor}_layout' + k_idx = f'upsample_{factor}_idx' + coords = out.get_spatial_cache(k_coords) + layout = out.get_spatial_cache(k_layout) + idx = out.get_spatial_cache(k_idx) + if any(v is None for v in [coords, layout, idx]): + raise ValueError('Downsample cache not found after SparseDownsample.') + + # spconv expects int32 indices; SparseDownsample produces int64 coords. + if out.coords.dtype != torch.int32: + out = sp.SparseTensor( + out.feats, + out.coords.to(torch.int32), + out.shape, + out.layout, + scale=out._scale, + spatial_cache=out._spatial_cache, + ) + + out.register_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_coords', coords) + out.register_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_layout', layout) + out.register_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_idx', idx) + # Remove unsuffixed keys to prevent later stages overwriting them. + try: + del out._spatial_cache[k_coords] + del out._spatial_cache[k_layout] + del out._spatial_cache[k_idx] + except Exception: + pass + return out + + +class SparseUpsampleWithCache(nn.Module): + """SparseUpsample that reads upsample caches under a unique suffix.""" + def __init__(self, factor: Union[int, Tuple[int, ...], List[int]], cache_suffix: str): + super().__init__() + self.factor = tuple(factor) if isinstance(factor, (list, tuple)) else factor + self.cache_suffix = cache_suffix + + def forward(self, x: sp.SparseTensor) -> sp.SparseTensor: + dim = x.coords.shape[-1] - 1 + factor = self.factor if isinstance(self.factor, tuple) else (self.factor,) * dim + new_coords = x.get_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_coords') + new_layout = x.get_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_layout') + idx = x.get_spatial_cache(f'upsample_{factor}_{self.cache_suffix}_idx') + if any(v is None for v in [new_coords, new_layout, idx]): + raise ValueError('Upsample cache not found. Must be paired with SparseDownsampleWithCache.') + if new_coords.dtype != torch.int32: + new_coords = new_coords.to(torch.int32) + new_feats = x.feats[idx] + out = sp.SparseTensor(new_feats, new_coords, x.shape, new_layout) + out._scale = tuple([s * f for s, f in zip(x._scale, factor)]) + out._spatial_cache = x._spatial_cache + return out + + +class SparseSkinUNetNLevel(nn.Module): + """A simple N-down/N-up sparse UNet for local smoothing. + + Note: `SparseSubdivideBlock3d` uses `resolution` only to name spconv `indice_key`s. + We must provide distinct (and stage-appropriate) values per hierarchy to avoid + rulebook collisions across different coordinate sets. + """ + def __init__(self, channels: int, base_resolution: int, num_groups: int = 32, num_levels: int = 3): + super().__init__() + + if num_levels < 1: + raise ValueError(f"num_levels must be >= 1, got {num_levels}") + self.channels = channels + self.base_resolution = int(base_resolution) + self.num_groups = num_groups + self.num_levels = int(num_levels) + + def res_block(resolution: int): + return SparseSubdivideBlock3d( + channels=channels, + resolution=resolution, + out_channels=channels, + sub_divide=False, + conv_as_residual=True, + num_groups=num_groups, + ) + + # resolutions[i] corresponds to the i-th encoder stage (before downsample) + resolutions: List[int] = [max(1, self.base_resolution // (2 ** i)) for i in range(self.num_levels)] + bottom_resolution = max(1, self.base_resolution // (2 ** self.num_levels)) + + self.enc = nn.ModuleList([res_block(r) for r in resolutions]) + self.down = nn.ModuleList([SparseDownsampleWithCache(2, f'unet{i}') for i in range(self.num_levels)]) + self.mid = res_block(bottom_resolution) + + # Decoder blocks operate at the same resolutions as encoder blocks. + self.up = nn.ModuleList([SparseUpsampleWithCache(2, f'unet{i}') for i in range(self.num_levels)]) + self.fuse = nn.ModuleList([sp.SparseLinear(channels * 2, channels) for _ in range(self.num_levels)]) + self.dec = nn.ModuleList([res_block(r) for r in resolutions]) + + def forward(self, x: sp.SparseTensor) -> sp.SparseTensor: + in_dtype = x.feats.dtype + if x.coords.dtype != torch.int32: + x = sp.SparseTensor( + x.feats, + x.coords.to(torch.int32), + x.shape, + x.layout, + scale=x._scale, + spatial_cache=x._spatial_cache, + ) + + # spconv implicit_gemm has a runtime tuner that can fail for some sparse + # rulebooks under AMP + fp16/bf16. Running UNet convs in fp32 avoids that. + if hasattr(torch, 'autocast'): + autocast_ctx = torch.autocast(device_type=x.device.type, enabled=False) + else: + # Older torch fallback + autocast_ctx = torch.cuda.amp.autocast(enabled=False) if x.device.type == 'cuda' else contextlib.nullcontext() + + with autocast_ctx: + x_fp32 = x if x.feats.dtype == torch.float32 else x.replace(x.feats.float()) + + skips: List[sp.SparseTensor] = [] + h = x_fp32 + for i in range(self.num_levels): + s = self.enc[i](h) + skips.append(s) + h = self.down[i](s) + + h = self.mid(h) + + for i in reversed(range(self.num_levels)): + h_up = self.up[i](h) + s = skips[i] + h = self.fuse[i](h_up.replace(torch.cat([h_up.feats, s.feats], dim=-1))) + h = self.dec[i](h) + + u0 = h + + if in_dtype != u0.feats.dtype: + u0 = u0.replace(u0.feats.to(dtype=in_dtype)) + return u0 + + +class AniGenSLatMeshDecoder(AniGenSparseTransformerBase): + def __init__( + self, + resolution: int, + model_channels: int, + model_channels_skl: int, + model_channels_skin: int, + + latent_channels: int, + latent_channels_skl: int, + latent_channels_vertskin: int, + + num_blocks: int, + num_heads: Optional[int] = None, + num_head_channels: Optional[int] = 64, + + num_heads_skl: int = 32, + num_heads_skin: int = 32, + + skin_cross_from_groupped: bool = False, + h_skin_unet_num_levels: int = 4, + + skin_decoder_config: Optional[Dict[str, Any]] = {}, + + upsample_skl: bool = False, + skl_defined_on_center: bool = True, + mlp_ratio: float = 4, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "swin", + attn_mode_cross: Literal["full", "serialized", "windowed"] = "full", + window_size: int = 8, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + qk_rms_norm: bool = False, + representation_config: dict = None, + + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + modules_to_freeze: Optional[List[str]] = ["blocks", "upsample", "out_layer", "skin_decoder"], + + skin_cross_from_geo: bool = False, + skl_cross_from_geo: bool = False, + skin_skl_cross: bool = False, + skin_ae_name: str = "SkinAE", + + normalize_z: bool = False, + normalize_scale: float = 1.0, + + jp_residual_fields: bool = True, + jp_hyper_continuous: bool = True, + + grouping_strategy: Literal["mean_shift", "threshold"] = "mean_shift", + + vertex_skin_feat_interp_sparse: bool = False, + vertex_skin_feat_interp_nearest: bool = False, + vertex_skin_feat_interp_use_deformed_grid: bool = False, + vertex_skin_feat_interp_trilinear: bool = False, + flexicube_disable_deform: bool = False, + vertex_skin_feat_nodeform_trilinear: bool = False, + ): + super().__init__( + in_channels=latent_channels, + in_channels_skl=latent_channels_skl, + in_channels_skin=latent_channels_vertskin, + model_channels=model_channels, + model_channels_skl=model_channels_skl, + model_channels_skin=model_channels_skin, + num_blocks=num_blocks, + num_heads=num_heads, + num_heads_skl=num_heads_skl, + num_heads_skin=num_heads_skin, + num_head_channels=num_head_channels, + mlp_ratio=mlp_ratio, + attn_mode=attn_mode, + attn_mode_cross=attn_mode_cross, + window_size=window_size, + pe_mode=pe_mode, + use_fp16=use_fp16, + use_checkpoint=use_checkpoint, + qk_rms_norm=qk_rms_norm, + skin_cross_from_geo=skin_cross_from_geo, + skl_cross_from_geo=skl_cross_from_geo, + skin_skl_cross=skin_skl_cross, + ) + self.pretrain_class_name = ["AniGenElasticSLatMeshDecoder", skin_ae_name] + self.pretrain_ckpt_filter_prefix = {skin_ae_name: "skin_decoder"} + self.latent_channels = latent_channels + self.latent_channels_skl = latent_channels_skl + self.latent_channels_vertskin = latent_channels_vertskin + self.jp_residual_fields = jp_residual_fields + self.jp_hyper_continuous = jp_hyper_continuous + self.grouping_func = GROUPING_STRATEGIES[grouping_strategy] + self.skin_cross_from_groupped = skin_cross_from_groupped + + self.normalize_z = normalize_z + self.normalize_scale = normalize_scale + + skin_decoder_config['use_fp16'] = use_fp16 + self.skin_decoder = SKIN_MODEL_DICT[skin_decoder_config.pop('model_type')](**skin_decoder_config) + self.skin_feat_channels = self.skin_decoder.skin_feat_channels + + # Optional local smoothing UNet on h_skin (independent of grouped cross-attn). + # If `h_skin_unet_num_levels < 0`, UNet is disabled. + self.h_skin_unet_num_levels = int(h_skin_unet_num_levels) + if self.h_skin_unet_num_levels >= 1: + self.h_skin_unet = SparseSkinUNetNLevel( + model_channels_skin, + base_resolution=resolution, + num_levels=self.h_skin_unet_num_levels, + ) + else: + self.h_skin_unet = None + + if self.skin_cross_from_groupped: + # Trainable parent feature for root joints (where parent_idx < 0). + self.root_parent_feat = nn.Parameter(torch.zeros(self.skin_feat_channels)) + + # Joint feature preprocessing: [joint_skin, fourier(joint_xyz), parent_skin] -> proj -> self-attn + self.joints_pos_embedder = FreqPositionalEmbedder( + in_dim=3, + include_input=True, + max_freq_log2=6, + num_freqs=6, + log_sampling=True, + ) + joints_pe_dim = self.joints_pos_embedder.out_dim + joints_in_dim = self.skin_feat_channels + joints_pe_dim + self.skin_feat_channels + self.joints_ctx_channels = model_channels_skin + self.joints_in_proj = nn.Sequential( + nn.Linear(joints_in_dim, self.joints_ctx_channels, bias=True), + nn.SiLU(), + nn.LayerNorm(self.joints_ctx_channels, elementwise_affine=True), + ) + self.joints_self_attn = nn.ModuleList([ + SparseTransformerBlock( + self.joints_ctx_channels, + num_heads=num_heads_skin, + mlp_ratio=self.mlp_ratio, + attn_mode="full", + window_size=None, + use_checkpoint=self.use_checkpoint, + use_rope=False, + qk_rms_norm=self.qk_rms_norm, + ln_affine=True, + ) for _ in range(4) + ]) + + # Coordinate PE for h_skin before cross-attn: coords in [-1, 1] -> Fourier PE -> proj(C), concat, fuse back to C. + self.h_skin_coord_embedder = FreqPositionalEmbedder( + in_dim=3, + include_input=True, + max_freq_log2=6, + num_freqs=6, + log_sampling=True, + ) + h_skin_pe_dim = self.h_skin_coord_embedder.out_dim + self.h_skin_coord_proj = nn.Linear(h_skin_pe_dim, model_channels_skin, bias=True) + self.h_skin_coord_fuse = sp.SparseLinear(model_channels_skin * 2, model_channels_skin) + + self.skin_cross_groupped_net = SparseTransformerMultiContextCrossBlock( + model_channels_skin, + # Context includes processed joint tokens + raw joint skin feats (skip connection). + ctx_channels=[self.joints_ctx_channels + self.skin_feat_channels], + num_heads=num_heads_skin, + mlp_ratio=self.mlp_ratio, + attn_mode="full", + attn_mode_cross="full", + cross_attn_cache_suffix='_skin_cross_from_groupped', + ) + + self.resolution = resolution + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch + self.upsample_skl = upsample_skl + self.rep_config = representation_config + self.mesh_extractor = AniGenSparseFeatures2Mesh( + res=self.resolution*4, + use_color=self.rep_config.get('use_color', False), + skin_feat_channels=self.skin_feat_channels, + predict_skin=True, + vertex_skin_feat_interp_sparse=vertex_skin_feat_interp_sparse, + vertex_skin_feat_interp_nearest=vertex_skin_feat_interp_nearest, + vertex_skin_feat_interp_use_deformed_grid=vertex_skin_feat_interp_use_deformed_grid, + vertex_skin_feat_interp_trilinear=vertex_skin_feat_interp_trilinear, + flexicube_disable_deform=flexicube_disable_deform, + vertex_skin_feat_nodeform_trilinear=vertex_skin_feat_nodeform_trilinear, + ) + self.out_channels = self.mesh_extractor.feats_channels + self.upsample = nn.ModuleList([ + SparseSubdivideBlock3d( + channels=model_channels, + resolution=resolution, + out_channels=model_channels // 4 + ), + SparseSubdivideBlock3d( + channels=model_channels // 4, + resolution=resolution * 2, + out_channels=model_channels // 8 + ) + ]) + upsample_skin_blocks = [] + upsample_skin_blocks.extend([ + SparseSubdivideBlock3d( + channels=model_channels_skin, + resolution=resolution, + out_channels=model_channels // 4 + ), + SparseSubdivideBlock3d( + channels=model_channels // 4, + resolution=resolution * 2, + out_channels=model_channels // 8 + ) + ]) + + self.upsample_skin_net = nn.ModuleList(upsample_skin_blocks) + self.out_layer = sp.SparseLinear(model_channels // 8, self.out_channels) + self.out_layer_skin = sp.SparseLinear(model_channels // 8, self.skin_feat_channels*8) + self.out_layer_skl_skin = sp.SparseLinear(model_channels // 8 if upsample_skl else model_channels_skl, self.skin_feat_channels if skl_defined_on_center else self.skin_feat_channels * 8) + self.use_conf_jp = self.rep_config.get('use_conf_jp', False) or self.jp_hyper_continuous + self.use_conf_skin = self.rep_config.get('use_conf_skin', False) + + res_skl = self.resolution * 4 if self.upsample_skl else self.resolution + self.skeleton_extractor = AniGenSklFeatures2Skeleton(skin_feat_channels=self.skin_feat_channels, device=self.device, res=res_skl, use_conf_jp=self.use_conf_jp, use_conf_skin=self.use_conf_skin, predict_skin=True, defined_on_center=skl_defined_on_center, jp_hyper_continuous=self.jp_hyper_continuous, jp_residual_fields=self.jp_residual_fields) + + self.out_channels_skl = self.skeleton_extractor.feats_channels + if self.upsample_skl: + self.upsample_skl_net = nn.ModuleList([ + SparseSubdivideBlock3d( + channels=model_channels_skl, + resolution=resolution, + out_channels=model_channels // 4 + ), + SparseSubdivideBlock3d( + channels=model_channels // 4, + resolution=resolution * 2, + out_channels=model_channels // 8 + ) + ]) + self.out_layer_skl = sp.SparseLinear(model_channels // 8, self.out_channels_skl) + else: + self.out_layer_skl = sp.SparseLinear(model_channels_skl, self.out_channels_skl) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + else: + self.convert_to_fp32() + + if self.use_pretrain_branch and self.freeze_pretrain_branch: + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for name, param in m.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, nn.Module): + for name, param in mod.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, torch.Tensor): + if mod.requires_grad: + mod.requires_grad = False + + def initialize_weights(self) -> None: + super().initialize_weights() + scale = 1e-4 + # Kaiming initialization for output layers (better for ReLU/SiLU-like activations) + nn.init.kaiming_normal_(self.out_layer.weight, mode='fan_in', nonlinearity='relu') + self.out_layer.weight.data.mul_(scale) + nn.init.constant_(self.out_layer.bias, 0) + + nn.init.kaiming_normal_(self.out_layer_skl.weight, mode='fan_in', nonlinearity='relu') + self.out_layer_skl.weight.data.mul_(scale) + nn.init.constant_(self.out_layer_skl.bias, 0) + + # Initialize skin layer: + self.skin_decoder.initialize_weights() + nn.init.kaiming_normal_(self.out_layer_skin.weight, mode='fan_in', nonlinearity='relu') + self.out_layer_skin.weight.data.mul_(scale) + nn.init.constant_(self.out_layer_skin.bias, 0) + + nn.init.kaiming_normal_(self.out_layer_skl_skin.weight, mode='fan_in', nonlinearity='relu') + self.out_layer_skl_skin.weight.data.mul_(scale) + nn.init.constant_(self.out_layer_skl_skin.bias, 0) + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + super().convert_to_fp16() + self.upsample.apply(convert_module_to_f16) + self.upsample_skin_net.apply(convert_module_to_f16) + if self.upsample_skl: + self.upsample_skl_net.apply(convert_module_to_f16) + if self.skin_cross_from_groupped: + # Joint preprocessing and cross-attn should match model dtype. + self.root_parent_feat.data = self.root_parent_feat.data.half() + self.joints_in_proj.apply(convert_module_to_f16) + self.joints_self_attn.apply(convert_module_to_f16) + + # `convert_module_to_f16` doesn't include `nn.LayerNorm`, so cast LN params explicitly. + for _m in self.joints_in_proj.modules(): + if isinstance(_m, nn.LayerNorm): + if _m.weight is not None: + _m.weight.data = _m.weight.data.half() + if _m.bias is not None: + _m.bias.data = _m.bias.data.half() + + # IMPORTANT: `SparseTransformerBlock` uses `LayerNorm32` which internally + # normalizes in fp32 (`x.float()`), so its parameters must stay fp32. + for _m in self.joints_self_attn.modules(): + if isinstance(_m, nn.LayerNorm): + if _m.weight is not None: + _m.weight.data = _m.weight.data.float() + if _m.bias is not None: + _m.bias.data = _m.bias.data.float() + + self.skin_cross_groupped_net.apply(convert_module_to_f16) + self.h_skin_coord_proj.apply(convert_module_to_f16) + self.h_skin_coord_fuse.apply(convert_module_to_f16) + + # UNet is executed in fp32 (see `SparseSkinUNetNLevel.forward`), so keep its + # weights in fp32 to avoid dtype mismatches inside spconv. + if self.h_skin_unet is not None: + self.h_skin_unet.apply(convert_module_to_f32) + self.skin_decoder.convert_to_fp16() + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + super().convert_to_fp32() + self.upsample.apply(convert_module_to_f32) + self.upsample_skin_net.apply(convert_module_to_f32) + if self.upsample_skl: + self.upsample_skl_net.apply(convert_module_to_f32) + if self.skin_cross_from_groupped: + self.root_parent_feat.data = self.root_parent_feat.data.float() + self.joints_in_proj.apply(convert_module_to_f32) + self.joints_self_attn.apply(convert_module_to_f32) + + for _m in self.joints_in_proj.modules(): + if isinstance(_m, nn.LayerNorm): + if _m.weight is not None: + _m.weight.data = _m.weight.data.float() + if _m.bias is not None: + _m.bias.data = _m.bias.data.float() + for _m in self.joints_self_attn.modules(): + if isinstance(_m, nn.LayerNorm): + if _m.weight is not None: + _m.weight.data = _m.weight.data.float() + if _m.bias is not None: + _m.bias.data = _m.bias.data.float() + + self.skin_cross_groupped_net.apply(convert_module_to_f32) + self.h_skin_coord_proj.apply(convert_module_to_f32) + self.h_skin_coord_fuse.apply(convert_module_to_f32) + if self.h_skin_unet is not None: + self.h_skin_unet.apply(convert_module_to_f32) + self.skin_decoder.convert_to_fp32() + + def to_representation(self, x: sp.SparseTensor) -> List[MeshExtractResult]: + """ + Convert a batch of network outputs to 3D representations. + + Args: + x: The [N x * x C] sparse tensor output by the network. + + Returns: + list of representations + """ + ret = [] + for i in range(x.shape[0]): + mesh = self.mesh_extractor(x[i], training=self.training) + ret.append(mesh) + return ret + + def to_representation_skl(self, x: sp.SparseTensor) -> List[MeshExtractResult]: + """ + Convert a batch of network outputs to skeleton representations. + + Args: + x: The [N x * x C] sparse tensor output by the network. + + Returns: + list of skeleton representations + """ + ret = [] + for i in range(x.shape[0]): + skl = self.skeleton_extractor(x[i], training=self.training) + ret.append(skl) + return ret + + def forward(self, x: sp.SparseTensor, x_skl: sp.SparseTensor, gt_joints=None, gt_parents=None) -> List[MeshExtractResult]: + x0 = x + x_skin = sp.SparseTensor(feats=x0.feats[:, self.latent_channels:], coords=x0.coords.clone()) + x = x0.replace(x0.feats[:, :self.latent_channels]) + if self.normalize_z: + x_skin = x_skin.replace(F.normalize(x_skin.feats, dim=-1)) + x_skl = x_skl.replace(F.normalize(x_skl.feats, dim=-1)) + + # Backbone forward + h, h_skl, h_skin = super().forward(x, x_skl, x_skin) + + # Optional smoothing on h_skin. + if self.h_skin_unet is not None: + h_skin = self.h_skin_unet(h_skin) + + # Skeleton prediction + if self.upsample_skl: + for block_skl in self.upsample_skl_net: + h_skl = block_skl(h_skl) + h_skl_middle = h_skl.type(x_skl.dtype) + h_skl = self.out_layer_skl(h_skl_middle) + h_skl_skin = self.out_layer_skl_skin(h_skl_middle) + h_skl = h_skl.replace(torch.cat([h_skl.feats, h_skl_skin.feats], dim=-1)) + skeletons = self.to_representation_skl(h_skl) + skin_feats_joints_list = self.skeleton_grouping(skeletons, gt_joints=gt_joints, gt_parents=gt_parents) + + # Skin cross with grouped joint features + if self.skin_cross_from_groupped: + coords_xyz = h_skin.coords[:, 1:].to(device=h_skin.device, dtype=torch.float32) + coords_norm = (coords_xyz + 0.5) / self.resolution * 2.0 - 1.0 + coords_pe = self.h_skin_coord_embedder(coords_norm) + coords_pe = coords_pe.to(device=h_skin.device, dtype=h_skin.feats.dtype) + coords_pe = self.h_skin_coord_proj(coords_pe) + h_skin = h_skin.replace(torch.cat([h_skin.feats, coords_pe], dim=-1)) + h_skin = self.h_skin_coord_fuse(h_skin) + joints_ctx = self._build_processed_joints_context( + skeletons, + skin_feats_joints_list, + device=h_skin.device, + dtype=h_skin.feats.dtype, + ) + h_skin = self.skin_cross_groupped_net(h_skin, [joints_ctx]) + for block in self.upsample_skin_net: + h_skin = block(h_skin) + h_skin = h_skin.type(x.dtype) + h_skin = self.out_layer_skin(h_skin) + + # Mesh prediction + for block in self.upsample: + h = block(h) + h_middle = h.type(x.dtype) + h = self.out_layer(h_middle) + h = h.replace(torch.cat([h.feats, h_skin.feats], dim=-1)) + meshes = self.to_representation(h) + + self.skinweight_forward(meshes, skeletons, gt_joints=gt_joints, gt_parents=gt_parents) + return meshes, skeletons + + def _joints_feats_list_to_sparse( + self, + joints_feats_list: List[torch.Tensor], + device: Optional[torch.device] = None, + dtype: Optional[torch.dtype] = None, + ) -> sp.SparseTensor: + if device is None: + device = self.device + if dtype is None: + dtype = self.dtype + feats_per_batch: List[torch.Tensor] = [] + for joints_feats in joints_feats_list: + joints_feats = joints_feats.to(device=device, dtype=dtype) + feats_per_batch.append(joints_feats) + feats = torch.cat(feats_per_batch, dim=0) + # Coords are [batch, x, y, z]. We encode token index into x and keep y/z = 0. + batch_indices: List[torch.Tensor] = [] + x_indices: List[torch.Tensor] = [] + for bi, joints_feats in enumerate(feats_per_batch): + ji = int(joints_feats.shape[0]) + batch_indices.append(torch.full((ji,), bi, device=device, dtype=torch.int32)) + x_indices.append(torch.arange(ji, device=device, dtype=torch.int32)) + b = torch.cat(batch_indices, dim=0) + x = torch.cat(x_indices, dim=0) + yz = torch.zeros((x.shape[0], 2), device=device, dtype=torch.int32) + coords = torch.cat([b[:, None], x[:, None], yz], dim=1) + return sp.SparseTensor(feats=feats, coords=coords) + + def _build_processed_joints_context( + self, + skeletons: List[Any], + skin_feats_joints_list: List[torch.Tensor], + device: torch.device, + dtype: torch.dtype, + ) -> sp.SparseTensor: + processed: List[torch.Tensor] = [] + raw_skin: List[torch.Tensor] = [] + for rep_skl, skin_feats_joints in zip(skeletons, skin_feats_joints_list): + joints = rep_skl.joints_grouped + parents = rep_skl.parents_grouped + if joints is None or parents is None: + raise ValueError('Expected grouped joints/parents for skin_cross_from_groupped.') + joints = joints.to(device=device, dtype=dtype) + parents = parents.to(device=device) + skin_feats_joints = skin_feats_joints.to(device=device, dtype=dtype) + raw_skin.append(skin_feats_joints) + + pe = self.joints_pos_embedder(joints).to(device=device, dtype=dtype) + + # Parent skin features (root uses trainable parameter) + parent_idx = parents.to(torch.long) + valid = parent_idx >= 0 + root_feat = self.root_parent_feat.to(device=device, dtype=dtype) + parent_feat_root = root_feat.unsqueeze(0).expand(skin_feats_joints.shape[0], -1) + parent_feat_gather = skin_feats_joints[parent_idx.clamp(min=0)] + parent_feat = torch.where(valid.unsqueeze(1), parent_feat_gather, parent_feat_root) + + joint_in = torch.cat([skin_feats_joints, pe, parent_feat], dim=-1) + joint_h = self.joints_in_proj(joint_in) + processed.append(joint_h) + + joints_ctx = self._joints_feats_list_to_sparse(processed, device=device, dtype=dtype) + for blk in self.joints_self_attn: + joints_ctx = blk(joints_ctx) + # Skip connection: concatenate original joint skin feats after self-attn. + joints_skip = self._joints_feats_list_to_sparse(raw_skin, device=device, dtype=dtype) + joints_ctx = joints_ctx.replace(torch.cat([joints_ctx.feats, joints_skip.feats], dim=-1)) + return joints_ctx + + def skeleton_grouping(self, reps_skl, gt_joints=None, gt_parents=None, skin_feats_skl_list=None, return_skin_pred_only=False): + skin_feats_joints_list = [] + for i, rep_skl in zip(range(len(reps_skl)), reps_skl): + if gt_joints is not None: + joints_grouped = gt_joints[i] + parents_grouped = gt_parents[i] + elif rep_skl.joints_grouped is None: + with torch.no_grad(): + joints_grouped, parents_grouped = self.grouping_func(joints=rep_skl.joints, parents=rep_skl.parents, joints_conf=rep_skl.conf_j, parents_conf=rep_skl.conf_p) + else: + joints_grouped = rep_skl.joints_grouped + parents_grouped = rep_skl.parents_grouped + + if not return_skin_pred_only: + rep_skl.joints_grouped = joints_grouped + rep_skl.parents_grouped = parents_grouped + + # Calculate NN indices for joints + positions_skl = rep_skl.positions + _, joints_nn_idx, _ = knn_points(positions_skl[None], joints_grouped[None].detach(), K=1, norm=2, return_nn=False) + joints_nn_idx = joints_nn_idx[0, :, 0] + skin_feats_skl = rep_skl.skin_feats if skin_feats_skl_list is None else skin_feats_skl_list[i] + + # Average the predicted joint features + conf_skin = torch.sigmoid(rep_skl.conf_skin) if rep_skl.conf_skin is not None else torch.ones_like(skin_feats_skl[:, :1]) + + skin_feats_joints = torch.zeros([joints_grouped.shape[0], skin_feats_skl.shape[-1]], device=self.device, dtype=skin_feats_skl.dtype) + skin_feats_square_joints = skin_feats_joints.clone() + skin_conf_joints = torch.zeros([joints_grouped.shape[0], 1], device=self.device, dtype=skin_feats_skl.dtype) + + skin_feats_joints.scatter_add_(0, joints_nn_idx[:, None].expand(-1, skin_feats_skl.shape[-1]), skin_feats_skl * conf_skin) + skin_feats_square_joints.scatter_add_(0, joints_nn_idx[:, None].expand(-1, skin_feats_skl.shape[-1]), skin_feats_skl.square() * conf_skin) + skin_conf_joints.scatter_add_(0, joints_nn_idx[:, None], conf_skin) + + skin_feats_joints = skin_feats_joints / skin_conf_joints.clamp(min=1e-6) + skin_feats_square_joints = skin_feats_square_joints / skin_conf_joints.clamp(min=1e-6) + skin_feats_joints_var = skin_feats_square_joints - skin_feats_joints.square() + skin_feats_joints_var_loss = skin_feats_joints_var.mean() + + if not return_skin_pred_only: + rep_skl.skin_feats_joints_var_loss = skin_feats_joints_var_loss + rep_skl.skin_feats_joints = skin_feats_joints + skin_feats_joints_list.append(skin_feats_joints) + return skin_feats_joints_list + + def skinweight_forward(self, reps, reps_skl, gt_joints=None, gt_parents=None, return_skin_pred_only=False, skin_feats_verts_list=None, skin_feats_skl_list=None, *args, **kwargs): + if return_skin_pred_only: + skin_preds = [] + if reps_skl[0].parents_grouped is None or return_skin_pred_only: + skin_feats_joints_list = self.skeleton_grouping(reps_skl, gt_joints=gt_joints, gt_parents=gt_parents, skin_feats_skl_list=skin_feats_skl_list, return_skin_pred_only=return_skin_pred_only) + else: + skin_feats_joints_list = [rep_skl.skin_feats_joints for rep_skl in reps_skl] + for i, rep, rep_skl in zip(range(len(reps)), reps, reps_skl): + # Joint skinning features + skin_feats_joints = skin_feats_joints_list[i] + # Vertex skinning features + skin_feats_verts = rep.vertex_skin_feats if skin_feats_verts_list is None else skin_feats_verts_list[i] + # Predict skin weights + parents_grouped = rep_skl.parents_grouped + skin_pred = self.skin_decoder(skin_feats_verts[None], skin_feats_joints[None], parents_grouped[None]) + skin_pred = skin_pred[0] + if return_skin_pred_only: + skin_preds.append(skin_pred) + else: + reps_skl[i].skin_pred = skin_pred + if return_skin_pred_only: + return skin_preds + + +class AniGenElasticSLatMeshDecoder(SparseTransformerElasticMixin, AniGenSLatMeshDecoder): + """ + Slat VAE Mesh decoder with elastic memory management. + Used for training with low VRAM. + """ + pass diff --git a/anigen/models/structured_latent_vae/anigen_encoder.py b/anigen/models/structured_latent_vae/anigen_encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..2a0ff6666441291c3cfe6f4cebad7cc2aea41e2f --- /dev/null +++ b/anigen/models/structured_latent_vae/anigen_encoder.py @@ -0,0 +1,318 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +from ...modules import sparse as sp +from ..sparse_elastic_mixin import SparseTransformerElasticMixin +from .anigen_base import AniGenSparseTransformerBase, FreqPositionalEmbedder +from pytorch3d.ops import knn_points +from .skin_models import SkinEncoder + + +def block_attn_config(self): + """ + Return the attention configuration of the model. + """ + for i in range(self.num_blocks): + if self.attn_mode == "shift_window": + yield "serialized", self.window_size, 0, (16 * (i % 2),) * 3, sp.SerializeMode.Z_ORDER + elif self.attn_mode == "shift_sequence": + yield "serialized", self.window_size, self.window_size // 2 * (i % 2), (0, 0, 0), sp.SerializeMode.Z_ORDER + elif self.attn_mode == "shift_order": + yield "serialized", self.window_size, 0, (0, 0, 0), sp.SerializeModes[i % 4] + elif self.attn_mode == "full": + yield "full", None, None, None, None + elif self.attn_mode == "swin": + yield "windowed", self.window_size, None, self.window_size // 2 * (i % 2), None + + +class FeedForwardNet(nn.Module): + def __init__(self, channels: int, channels_out: int=None, mlp_ratio: float = 4.0): + super().__init__() + channels_out = channels if channels_out is None else channels_out + self.mlp = nn.Sequential( + nn.Linear(channels, int(channels * mlp_ratio)), + nn.GELU(approximate="tanh"), + nn.Linear(int(channels * mlp_ratio), channels_out), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.mlp(x) + + +class AniGenSLatEncoder(AniGenSparseTransformerBase): + def __init__( + self, + resolution: int, + in_channels: int, + + model_channels: int, + model_channels_skl: int, + model_channels_skin: int, + + latent_channels: int, + latent_channels_skl: int, + latent_channels_vertskin: int, + + num_blocks: int, + num_heads: Optional[int] = None, + num_head_channels: Optional[int] = 64, + + num_heads_skl: int = 32, + num_heads_skin: int = 32, + + skl_pos_embed_freq: int = 10, + skin_encoder_config: Optional[Dict[str, Any]] = {}, + encode_upsampled_skin_feat: bool = True, + skin_ae_name: Optional[str] = "SkinAE", + + mlp_ratio: float = 4, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "swin", + attn_mode_cross: Literal["full", "serialized", "windowed"] = "full", + window_size: int = 8, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + qk_rms_norm: bool = False, + + use_pretrain_branch: bool = True, + freeze_pretrain_branch: bool = True, + modules_to_freeze: Optional[List[str]] = ["input_layer", "blocks", "out_layer", "skin_encoder"], + + skin_cross_from_geo: bool = True, + skl_cross_from_geo: bool = True, + skin_skl_cross: bool = True, + + latent_denoising: bool = True, + normalize_z: bool = True, + normalize_scale: float = 1.0, + + jp_residual_fields: bool = False, + jp_hyper_continuous: bool = False, + ): + self.use_pretrain_branch = use_pretrain_branch + self.freeze_pretrain_branch = freeze_pretrain_branch + self.skl_pos_embed_freq = skl_pos_embed_freq + self.latent_denoising = latent_denoising + self.normalize_latent = normalize_z and latent_denoising + self.normalize_scale = normalize_scale + self.jp_residual_fields = jp_residual_fields + self.jp_hyper_continuous = jp_hyper_continuous + + super().__init__( + in_channels=in_channels, + in_channels_skl=model_channels_skl, + in_channels_skin=model_channels_skin, + model_channels=model_channels, + model_channels_skl=model_channels_skl, + model_channels_skin=model_channels_skin, + num_blocks=num_blocks, + num_heads=num_heads, + num_heads_skl=num_heads_skl, + num_heads_skin=num_heads_skin, + num_head_channels=num_head_channels, + mlp_ratio=mlp_ratio, + attn_mode=attn_mode, + attn_mode_cross=attn_mode_cross, + window_size=window_size, + pe_mode=pe_mode, + use_fp16=use_fp16, + use_checkpoint=use_checkpoint, + qk_rms_norm=qk_rms_norm, + skin_cross_from_geo=skin_cross_from_geo, + skl_cross_from_geo=skl_cross_from_geo, + skin_skl_cross=skin_skl_cross, + ) + self.pretrain_class_name = ["AniGenElasticSLatEncoder", skin_ae_name] + self.pretrain_ckpt_filter_prefix = {skin_ae_name: "skin_encoder"} + self.resolution = resolution + + self.latent_channels = latent_channels + self.latent_channels_skl = latent_channels_skl + self.latent_channels_vertskin = latent_channels_vertskin + + skin_encoder_config['use_fp16'] = use_fp16 + self.skin_encoder = SkinEncoder(**skin_encoder_config) + self.encode_upsampled_skin_feat = encode_upsampled_skin_feat + self.in_layer_skin = FeedForwardNet(channels=self.skin_encoder.skin_feat_channels * (8 if encode_upsampled_skin_feat else 1), channels_out=model_channels_skin) + + self.pos_embedder_fourier = FreqPositionalEmbedder(in_dim=4 if self.jp_hyper_continuous else 3, max_freq_log2=self.skl_pos_embed_freq, num_freqs=self.skl_pos_embed_freq, include_input=True) + self.root_embedding = nn.Parameter(torch.zeros(1, self.pos_embedder_fourier.out_dim)) + + # Channel Balance + self.in_layer_jp_skl = FeedForwardNet(channels=2 * self.pos_embedder_fourier.out_dim, channels_out=model_channels_skl//4) + self.in_layer_skin_skl = FeedForwardNet(channels=self.skin_encoder.skin_feat_channels, channels_out=model_channels_skl-(model_channels_skl//4)) + + self.out_layer = sp.SparseLinear(model_channels, 2 * latent_channels) + if self.latent_denoising: + self.out_layer_skl = sp.SparseLinear(model_channels_skl, latent_channels_skl) + self.out_layer_vertskin = sp.SparseLinear(model_channels_skin, latent_channels_vertskin) + else: + self.out_layer_skl = sp.SparseLinear(model_channels_skl, 2 * latent_channels_skl) + self.out_layer_vertskin = sp.SparseLinear(model_channels_skin, 2 * latent_channels_vertskin) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + else: + self.convert_to_fp32() + + if 'all' in modules_to_freeze: + modules_to_freeze = list(set([k.split('.')[0] for k in self.state_dict().keys()])) + print(f"\033[93mFreezing all modules: {modules_to_freeze}\033[0m") + if self.use_pretrain_branch and self.freeze_pretrain_branch: + for module in modules_to_freeze: + if hasattr(self, module): + mod = getattr(self, module) + if isinstance(mod, nn.ModuleList): + for m in mod: + for name, param in m.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, nn.Module): + for name, param in mod.named_parameters(): + if 'lora' not in name: + param.requires_grad = False + elif isinstance(mod, torch.Tensor): + if mod.requires_grad: + mod.requires_grad = False + + def initialize_weights(self) -> None: + super().initialize_weights() + # Zero-out output layers: + nn.init.constant_(self.out_layer.weight, 0) + nn.init.constant_(self.out_layer.bias, 0) + + def skeleton_embedding(self, x, x_skl, joints_list, parents_list, skin_list, gt_meshes, bvh_list=None): + res = self.resolution + feats_new = [] + feats_skl_new = [] + coords_new = [] + coords_skl_new = [] + + joint_skin_embeds, vert_skin_embeds = self.skin_encoder(joints_list, parents_list, skin_list) + joints_pos_list = [] + + for i in range(len(joints_list)): + parent_idx = parents_list[i].clone() + + coords_new.append(x[i].coords) + coords_skl_new.append(x_skl[i].coords) + coords_new[-1][:, 0] = i + coords_skl_new[-1][:, 0] = i + + v_pos = (x[i].coords[:, 1:4] + 0.5) / res - 0.5 + v_pos_skl = (x_skl[i].coords[:, 1:4] + 0.5) / res - 0.5 + dist_nn_12, joints_nn_idx, _ = knn_points(v_pos_skl[None], joints_list[i][None], K=2, norm=2, return_nn=False) + joints_nn_idx = joints_nn_idx[0, :, 0] + + # Skeleton positional embedding + joints_pos = joints_list[i][joints_nn_idx] - (v_pos_skl if self.jp_residual_fields else 0) + parents_pos = joints_list[i][parent_idx[joints_nn_idx]] - (v_pos_skl if self.jp_residual_fields else 0) + if self.jp_hyper_continuous: + factor = (1 - (dist_nn_12[0, :, 0:1] / (dist_nn_12[0, :, 1:2] + 1e-8)).clamp(max=1.0)) + joints_pos = torch.cat([joints_pos, factor], dim=-1) + parents_pos = torch.cat([parents_pos, factor], dim=-1) + joints_pos_embed = self.pos_embedder_fourier(joints_pos) + parents_pos_embed = self.pos_embedder_fourier(parents_pos) + parents_pos_embed = torch.where(parent_idx[joints_nn_idx][:, None] == -1, self.root_embedding.expand_as(parents_pos_embed), parents_pos_embed) + jp_pos_embed_nn = torch.cat([joints_pos_embed, parents_pos_embed], dim=-1) + jp_pos_embed_nn = self.in_layer_jp_skl(jp_pos_embed_nn) + + # Skeleton skin embedding + j_skin_embed_nn = joint_skin_embeds[i][joints_nn_idx] + j_skin_embed_nn = self.in_layer_skin_skl(j_skin_embed_nn) + + # Concatenate + jp_skl_embed = torch.cat([jp_pos_embed_nn, j_skin_embed_nn], dim=-1) + feats_skl_new.append(jp_skl_embed) + + if self.encode_upsampled_skin_feat: + # Create 8 sub-voxel points + offsets = torch.tensor([ + [-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1, 1, 1], + [1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1] + ], device=v_pos.device, dtype=v_pos.dtype) * (0.25 / res) + query_pos = v_pos.unsqueeze(1) + offsets.unsqueeze(0) # (N, 8, 3) + query_pos_flat = query_pos.view(-1, 3) + else: + query_pos_flat = v_pos + + if bvh_list is not None: + bvh = bvh_list[i].to(v_pos.device) + _, face_id, uvw = bvh.unsigned_distance(query_pos_flat, return_uvw=True) + uvw = uvw.clamp(min=0.0) + uvw_sum = uvw.sum(dim=-1, keepdim=True).clamp_min(1e-6) + uvw = uvw / uvw_sum + face_id = gt_meshes[i]['faces'][face_id] + voxel_skin_embeds = (vert_skin_embeds[i][face_id] * uvw[..., None]).sum(1) + else: + gt_mesh_verts = gt_meshes[i]['vertices'] + _, mesh_nn_idx, _ = knn_points(query_pos_flat[None], gt_mesh_verts[None], K=1, norm=2, return_nn=False) + mesh_nn_idx = mesh_nn_idx[0, :, 0] + voxel_skin_embeds = vert_skin_embeds[i][mesh_nn_idx] + + voxel_skin_embeds = voxel_skin_embeds.view(v_pos.shape[0], -1) + voxel_skin_embeds = self.in_layer_skin(voxel_skin_embeds) + feats_new.append(voxel_skin_embeds) + joints_pos_list.append(joints_pos) + + x_new = sp.SparseTensor(coords=torch.cat(coords_new, dim=0), feats=torch.cat(feats_new, dim=0)) + x_skl_new = sp.SparseTensor(coords=torch.cat(coords_skl_new, dim=0), feats=torch.cat(feats_skl_new, dim=0)) + + return x_new, x_skl_new, joint_skin_embeds, vert_skin_embeds, joints_pos_list + + def encode_sample(self, x: sp.SparseTensor, out_layer: sp.SparseLinear, sample_posterior: bool = True, latent_denoising: bool = False): + x = x.type(torch.float32) + x = x.replace(F.layer_norm(x.feats, x.feats.shape[-1:])) + x = out_layer(x) + if latent_denoising: + if self.normalize_latent: + x = x.replace(nn.functional.normalize(x.feats, dim=-1) * self.normalize_scale) + mean, logvar = x.feats, torch.zeros_like(x.feats) + else: + mean, logvar = x.feats.chunk(2, dim=-1) + if sample_posterior and not latent_denoising: + std = torch.exp(0.5 * logvar) + z = mean + std * torch.randn_like(std) + else: + z = mean + z = x.replace(z) + if latent_denoising: + mean = mean.detach() + return z, mean, logvar + + def forward(self, x: sp.SparseTensor, x_skl: sp.SparseTensor, sample_posterior=True, return_raw=False, return_skin_encoded=False, **kwargs): + x_skin, x_skl, joint_skin_embeds, vert_skin_embeds, joints_pos = self.skeleton_embedding(x, x_skl, kwargs.get('gt_joints'), kwargs.get('gt_parents'), kwargs.get('gt_skin'), kwargs.get('gt_mesh'), kwargs.get('bvh_list', None)) + h, h_skl, h_skin = super().forward(x, x_skl, x_skin) + + z, mean, logvar = self.encode_sample(h, self.out_layer, sample_posterior, latent_denoising=False) + z_skl, mean_skl, logvar_skl = self.encode_sample(h_skl, self.out_layer_skl, sample_posterior, latent_denoising=self.latent_denoising) + z_skin, mean_skin, logvar_skin = self.encode_sample(h_skin, self.out_layer_vertskin, sample_posterior, latent_denoising=self.latent_denoising) + + z = z.replace(torch.cat([z.feats, z_skin.feats], dim=-1)) + mean, logvar = torch.cat([mean, mean_skin], dim=-1), torch.cat([logvar, logvar_skin], dim=-1) + + if not return_skin_encoded: + # Ordinary return without skin encoded features + if return_raw: + return z, mean, logvar, z_skl, mean_skl, logvar_skl, joint_skin_embeds, vert_skin_embeds, joints_pos + else: + return z, z_skl, joint_skin_embeds, vert_skin_embeds, joints_pos + else: + # Return skin encoded features as well for checking + if return_raw: + return z, mean, logvar, z_skl, mean_skl, logvar_skl, joint_skin_embeds, vert_skin_embeds, joints_pos, x_skin, x_skl + else: + return z, z_skl, joint_skin_embeds, vert_skin_embeds, joints_pos, x_skin, x_skl + + def encode_skin(self, joints_list: List[torch.Tensor], parents_list: List[torch.Tensor], skin_list: List[torch.Tensor]=None): + joint_skin_embeds, vert_skin_embeds = self.skin_encoder(joints_list, parents_list, skin_list) + return joint_skin_embeds, vert_skin_embeds + + +class AniGenElasticSLatEncoder(SparseTransformerElasticMixin, AniGenSLatEncoder): + """ + SLat VAE encoder with elastic memory management. + Used for training with low VRAM. + """ diff --git a/anigen/models/structured_latent_vae/base.py b/anigen/models/structured_latent_vae/base.py new file mode 100644 index 0000000000000000000000000000000000000000..ab0bf6a850b1c146e081c32ad92c7c44ead5ef6e --- /dev/null +++ b/anigen/models/structured_latent_vae/base.py @@ -0,0 +1,117 @@ +from typing import * +import torch +import torch.nn as nn +from ...modules.utils import convert_module_to_f16, convert_module_to_f32 +from ...modules import sparse as sp +from ...modules.transformer import AbsolutePositionEmbedder +from ...modules.sparse.transformer import SparseTransformerBlock + + +def block_attn_config(self): + """ + Return the attention configuration of the model. + """ + for i in range(self.num_blocks): + if self.attn_mode == "shift_window": + yield "serialized", self.window_size, 0, (16 * (i % 2),) * 3, sp.SerializeMode.Z_ORDER + elif self.attn_mode == "shift_sequence": + yield "serialized", self.window_size, self.window_size // 2 * (i % 2), (0, 0, 0), sp.SerializeMode.Z_ORDER + elif self.attn_mode == "shift_order": + yield "serialized", self.window_size, 0, (0, 0, 0), sp.SerializeModes[i % 4] + elif self.attn_mode == "full": + yield "full", None, None, None, None + elif self.attn_mode == "swin": + yield "windowed", self.window_size, None, self.window_size // 2 * (i % 2), None + + +class SparseTransformerBase(nn.Module): + """ + Sparse Transformer without output layers. + Serve as the base class for encoder and decoder. + """ + def __init__( + self, + in_channels: int, + model_channels: int, + num_blocks: int, + num_heads: Optional[int] = None, + num_head_channels: Optional[int] = 64, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + window_size: Optional[int] = None, + pe_mode: Literal["ape", "rope"] = "ape", + use_fp16: bool = False, + use_checkpoint: bool = False, + qk_rms_norm: bool = False, + ): + super().__init__() + self.in_channels = in_channels + self.model_channels = model_channels + self.num_blocks = num_blocks + self.window_size = window_size + self.num_heads = num_heads or model_channels // num_head_channels + self.mlp_ratio = mlp_ratio + self.attn_mode = attn_mode + self.pe_mode = pe_mode + self.use_fp16 = use_fp16 + self.use_checkpoint = use_checkpoint + self.qk_rms_norm = qk_rms_norm + self.dtype = torch.float16 if use_fp16 else torch.float32 + + if pe_mode == "ape": + self.pos_embedder = AbsolutePositionEmbedder(model_channels) + + self.input_layer = sp.SparseLinear(in_channels, model_channels) + self.blocks = nn.ModuleList([ + SparseTransformerBlock( + model_channels, + num_heads=self.num_heads, + mlp_ratio=self.mlp_ratio, + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + use_checkpoint=self.use_checkpoint, + use_rope=(pe_mode == "rope"), + qk_rms_norm=self.qk_rms_norm, + ) + for attn_mode, window_size, shift_sequence, shift_window, serialize_mode in block_attn_config(self) + ]) + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.blocks.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.blocks.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def forward(self, x: sp.SparseTensor) -> sp.SparseTensor: + h = self.input_layer(x) + if self.pe_mode == "ape": + h = h + self.pos_embedder(x.coords[:, 1:]) + h = h.type(self.dtype) + for block in self.blocks: + h = block(h) + return h diff --git a/anigen/models/structured_latent_vae/skin_models.py b/anigen/models/structured_latent_vae/skin_models.py new file mode 100644 index 0000000000000000000000000000000000000000..2ba6f102c4a41d843798dcb17e2684fae58497f1 --- /dev/null +++ b/anigen/models/structured_latent_vae/skin_models.py @@ -0,0 +1,252 @@ +import torch +import torch.nn as nn +from typing import * +from ..sparse_elastic_mixin import SparseTransformerElasticMixin +from ...modules.transformer import TransformerBlock, FeedForwardNet +from .anigen_base import FreqPositionalEmbedder, TransformerCrossBlock +from ...modules.utils import zero_module, convert_module_to_f16, convert_module_to_f32 + + +class Embedder(nn.Module): + def __init__(self, in_dim: int, out_dim: int, hidden_dim: int=None, depth: int = 4, mlp_ratio: float = 4.0, jp_embed_attn: bool = True): + super().__init__() + hidden_dim = out_dim if hidden_dim is None else hidden_dim + self.jp_embed_attn = jp_embed_attn + self.in_layer = FeedForwardNet(channels=in_dim, out_channels=hidden_dim, mlp_ratio=mlp_ratio) + if self.jp_embed_attn: + self.blocks = nn.ModuleList([TransformerBlock(hidden_dim, num_heads=8, attn_mode='full') for _ in range(depth)]) + for block in self.blocks: + block.to(torch.float16) + else: + self.blocks = nn.ModuleList([FeedForwardNet(channels=hidden_dim, out_channels=hidden_dim, mlp_ratio=mlp_ratio) for _ in range(depth)]) + self.out_layer = nn.Linear(hidden_dim, out_dim) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.in_layer(x) + h = x + for block in self.blocks: + h = block(h[None].type(torch.float16))[0] if self.jp_embed_attn else block(h) + x + h = self.out_layer(h.type(x.dtype)) + return h + + +class SkinEncoder(nn.Module): + def __init__(self, skin_feat_channels: int = 8, skl_pos_embed_freq: int = 10, jp_embedder_config: Optional[Dict[str, Any]] = {}, jp_embed_dim: int = 128, relative_pe=True, vert_feat_is_linear=True, normalize_feat=True, **kwargs): + super().__init__() + self.skin_feat_channels = skin_feat_channels + self.skl_pos_embed_freq = skl_pos_embed_freq + self.jp_embedder_config = jp_embedder_config + + self.pos_embedder_fourier = FreqPositionalEmbedder(in_dim=3, max_freq_log2=self.skl_pos_embed_freq, num_freqs=self.skl_pos_embed_freq, include_input=True) + self.pos_embedder_linear = nn.Linear(self.pos_embedder_fourier.out_dim, jp_embed_dim) + self.root_embedding = nn.Parameter(torch.zeros(1, jp_embed_dim)) + self.joint_embedder = Embedder(in_dim=2 * jp_embed_dim, out_dim=jp_embed_dim, **self.jp_embedder_config) + self.out_layer_vert = FeedForwardNet(channels=jp_embed_dim, out_channels=skin_feat_channels) + self.out_layer_joint = FeedForwardNet(channels=jp_embed_dim, out_channels=skin_feat_channels) + self.relative_pe = relative_pe + self.vert_feat_is_linear = vert_feat_is_linear + self.normalize_feat = normalize_feat + + def forward(self, joints_list: List[torch.Tensor], parents_list: List[torch.Tensor], skin_list: List[torch.Tensor]=None): + vert_skin_embeds = [] if skin_list is not None else None + joint_skin_embeds = [] + for i in range(len(joints_list)): + parent_idx = parents_list[i].clone() + joints = joints_list[i] + if self.relative_pe: + joints = joints - torch.cat([joints, joints[:1]])[parent_idx] + joints_pos_embed = self.pos_embedder_linear(self.pos_embedder_fourier(joints)) + joints_pos_embed = torch.cat([joints_pos_embed, self.root_embedding], dim=0) + parents_pos_embed = joints_pos_embed[parent_idx] + jp_pos_embed = torch.cat([joints_pos_embed[:-1], parents_pos_embed], dim=-1) + joints_embed = self.joint_embedder(jp_pos_embed) + if self.normalize_feat: + joints_embed = torch.nn.functional.normalize(joints_embed, dim=-1) + if skin_list is not None: + vert_skin = skin_list[i] + if self.vert_feat_is_linear: + joints_embed_for_vert = self.out_layer_vert(joints_embed) + vert_skin_embed = vert_skin @ joints_embed_for_vert + else: + vert_skin_embed = vert_skin @ joints_embed + vert_skin_embed = self.out_layer_vert(vert_skin_embed) + vert_skin_embeds.append(vert_skin_embed) + joints_embed = self.out_layer_joint(joints_embed) + joint_skin_embeds.append(joints_embed) + return joint_skin_embeds, vert_skin_embeds + + +def clamp_with_grad(x, min, max): + return x + (x.clamp(min, max) - x).detach() + + +class TreeTransformerSkinDecoder(nn.Module): + # The principles of the tree transformer skinning model: + # 1. joint features are related to the tree structure, since the decoding process is skeleton-agnostic. + # 2. decode the skinning weights directly, hoping the transformer can handle the skinning assignment. + # It's a pure learning-based method. + def __init__(self, + skin_feat_channels: int, + model_channels: int=512, + num_heads=4, + num_blocks=4, + vert_cross_blocks_num: int = 1, + use_fp16: bool = False): + super().__init__() + self.skin_feat_channels = skin_feat_channels + self.model_channels = model_channels + self.num_heads = num_heads + self.num_blocks = num_blocks + self.root_features = nn.Parameter(torch.zeros([1, skin_feat_channels]), requires_grad=True) + self.input_layer_vertex = nn.Linear(skin_feat_channels, model_channels) + self.input_layer_skin = nn.Linear(skin_feat_channels*2, model_channels) + assert vert_cross_blocks_num <= num_blocks, f"vert_cross_blocks_num should be less than or equal to num_blocks, got {vert_cross_blocks_num} and {num_blocks}." + self.vert_cross_blocks_num = vert_cross_blocks_num + self.blocks_vertex = nn.ModuleList([ + TransformerCrossBlock( + channels=model_channels, + ctx_channels=model_channels, + num_heads=num_heads, + mlp_ratio=4.0, + attn_mode="full", + no_self=True) + for _ in range(self.vert_cross_blocks_num) + ] + [ + FeedForwardNet( + channels=model_channels, + mlp_ratio=4.0, + out_channels=model_channels, + ) + for _ in range(num_blocks - self.vert_cross_blocks_num) + ]) + self.blocks_skin = nn.ModuleList([ + TransformerBlock( + channels=model_channels, + num_heads=num_heads, + mlp_ratio=4.0, + attn_mode="full") + for _ in range(num_blocks) + ]) + self.out_layer_vertex = nn.Sequential( + nn.Linear(model_channels, model_channels*4), + nn.GELU(approximate="tanh"), + nn.Linear(model_channels*4, model_channels+1), + ) + self.out_layer_skin = nn.Sequential( + nn.Linear(model_channels, model_channels*4), + nn.GELU(approximate="tanh"), + nn.Linear(model_channels*4, model_channels), + ) + self.temp_activation = nn.ELU(alpha=1.0) + self.dtype = torch.float16 if use_fp16 else torch.float32 + + @property + def device(self) -> torch.device: + """ + Return the device of the model. + """ + return next(self.parameters()).device + + def convert_to_fp16(self) -> None: + """ + Convert the torso of the model to float16. + """ + self.blocks_vertex.apply(convert_module_to_f16) + self.blocks_skin.apply(convert_module_to_f16) + + def convert_to_fp32(self) -> None: + """ + Convert the torso of the model to float32. + """ + self.blocks_vertex.apply(convert_module_to_f32) + self.blocks_skin.apply(convert_module_to_f32) + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def forward(self, vertex_features, joint_features, parents) -> torch.Tensor: + j_num = joint_features.shape[1] + h_v = vertex_features + h_v = self.input_layer_vertex(h_v) + h_j = joint_features + h_j = torch.cat([h_j, self.root_features[None]], dim=1) + parents = torch.where(parents < 0, torch.ones_like(parents)*j_num, parents) + h_j = torch.cat([h_j[:, :-1], h_j[:, parents[0]]], dim=-1) + h_j = self.input_layer_skin(h_j) + h_v = h_v.type(self.dtype) + h_j = h_j.type(self.dtype) + blocks_num = len(self.blocks_vertex) + for idx, block_v, block_j in zip(range(blocks_num), self.blocks_vertex, self.blocks_skin): + f_v, f_j = h_v, h_j + h_v = block_v(f_v, f_j) if idx < self.vert_cross_blocks_num else block_v(f_v) + h_j = block_j(f_j) + h_v = h_v.type(vertex_features.dtype) + h_j = h_j.type(joint_features.dtype) + h_v = self.out_layer_vertex(h_v) + h_j = self.out_layer_skin(h_j) + h_v, inv_temp = h_v[..., :-1], h_v[..., -1].unsqueeze(-1) + inv_temp = self.temp_activation(inv_temp) + self.temp_activation.alpha + 1.0 + skin_weights = torch.einsum("nac,nbc->nab", h_v, h_j) + skin_weights = torch.softmax(skin_weights * inv_temp, dim=-1) + return skin_weights + + +SKIN_MODEL_DICT = {'tree': TreeTransformerSkinDecoder} + + +class SkinAutoEncoder(nn.Module): + def __init__(self, encoder_config: Dict[str, Any], decoder_config: Dict[str, Any], use_fp16: bool = False): + super().__init__() + self.skin_encoder = SkinEncoder(**encoder_config) + decoder_config['use_fp16'] = use_fp16 + self.skin_decoder = SKIN_MODEL_DICT[decoder_config.pop('model_type')](**decoder_config) + + self.initialize_weights() + if use_fp16: + self.convert_to_fp16() + else: + self.convert_to_fp32() + + def convert_to_fp16(self) -> None: + self.skin_decoder.convert_to_fp16() + + def convert_to_fp32(self) -> None: + self.skin_decoder.convert_to_fp32() + + def initialize_weights(self) -> None: + # Initialize transformer layers: + def _basic_init(module): + if isinstance(module, nn.Linear): + torch.nn.init.xavier_uniform_(module.weight) + if module.bias is not None: + nn.init.constant_(module.bias, 0) + self.apply(_basic_init) + + def encode(self, joints_list: List[torch.Tensor], parents_list: List[torch.Tensor], skin_list: List[torch.Tensor]): + joint_skin_embeds, vert_skin_embeds = self.skin_encoder(joints_list, parents_list, skin_list) + return joint_skin_embeds, vert_skin_embeds + + def decode(self, vertex_features, joint_features, parents) -> torch.Tensor: + skin_weights = self.skin_decoder(vertex_features, joint_features, parents) + return skin_weights + + def forward(self, joints_list: List[torch.Tensor], parents_list: List[torch.Tensor], skin_list: List[torch.Tensor]): + joint_skin_embeds, vert_skin_embeds = self.skin_encoder(joints_list, parents_list, skin_list) + skin_pred_list = [] + for i in range(len(joints_list)): + skin_pred = self.skin_decoder(vert_skin_embeds[i][None], joint_skin_embeds[i][None], parents_list[i][None]) + skin_pred_list.append(skin_pred[0]) + return skin_pred_list, joint_skin_embeds, vert_skin_embeds + + +class AniGenElasticSLatEncoderGamma(SparseTransformerElasticMixin, SkinAutoEncoder): + """ + SLat VAE encoder with elastic memory management. + Used for training with low VRAM. + """ diff --git a/anigen/modules/attention/__init__.py b/anigen/modules/attention/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f452320d5dbc4c0aa1664e33f76c56ff4bbe2039 --- /dev/null +++ b/anigen/modules/attention/__init__.py @@ -0,0 +1,36 @@ +from typing import * + +BACKEND = 'flash_attn' +DEBUG = False + +def __from_env(): + import os + + global BACKEND + global DEBUG + + env_attn_backend = os.environ.get('ATTN_BACKEND') + env_sttn_debug = os.environ.get('ATTN_DEBUG') + + if env_attn_backend is not None and env_attn_backend in ['xformers', 'flash_attn', 'sdpa', 'naive']: + BACKEND = env_attn_backend + if env_sttn_debug is not None: + DEBUG = env_sttn_debug == '1' + + print(f"[ATTENTION] Using backend: {BACKEND}") + + +__from_env() + + +def set_backend(backend: Literal['xformers', 'flash_attn']): + global BACKEND + BACKEND = backend + +def set_debug(debug: bool): + global DEBUG + DEBUG = debug + + +from .full_attn import * +from .modules import * diff --git a/anigen/modules/attention/full_attn.py b/anigen/modules/attention/full_attn.py new file mode 100644 index 0000000000000000000000000000000000000000..d9ebf6380a78906d4c6e969c63223fb7b398e5a7 --- /dev/null +++ b/anigen/modules/attention/full_attn.py @@ -0,0 +1,140 @@ +from typing import * +import torch +import math +from . import DEBUG, BACKEND + +if BACKEND == 'xformers': + import xformers.ops as xops +elif BACKEND == 'flash_attn': + import flash_attn +elif BACKEND == 'sdpa': + from torch.nn.functional import scaled_dot_product_attention as sdpa +elif BACKEND == 'naive': + pass +else: + raise ValueError(f"Unknown attention backend: {BACKEND}") + + +__all__ = [ + 'scaled_dot_product_attention', +] + + +def _naive_sdpa(q, k, v): + """ + Naive implementation of scaled dot product attention. + """ + q = q.permute(0, 2, 1, 3) # [N, H, L, C] + k = k.permute(0, 2, 1, 3) # [N, H, L, C] + v = v.permute(0, 2, 1, 3) # [N, H, L, C] + scale_factor = 1 / math.sqrt(q.size(-1)) + attn_weight = q @ k.transpose(-2, -1) * scale_factor + attn_weight = torch.softmax(attn_weight, dim=-1) + out = attn_weight @ v + out = out.permute(0, 2, 1, 3) # [N, L, H, C] + return out + + +@overload +def scaled_dot_product_attention(qkv: torch.Tensor) -> torch.Tensor: + """ + Apply scaled dot product attention. + + Args: + qkv (torch.Tensor): A [N, L, 3, H, C] tensor containing Qs, Ks, and Vs. + """ + ... + +@overload +def scaled_dot_product_attention(q: torch.Tensor, kv: torch.Tensor) -> torch.Tensor: + """ + Apply scaled dot product attention. + + Args: + q (torch.Tensor): A [N, L, H, C] tensor containing Qs. + kv (torch.Tensor): A [N, L, 2, H, C] tensor containing Ks and Vs. + """ + ... + +@overload +def scaled_dot_product_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor: + """ + Apply scaled dot product attention. + + Args: + q (torch.Tensor): A [N, L, H, Ci] tensor containing Qs. + k (torch.Tensor): A [N, L, H, Ci] tensor containing Ks. + v (torch.Tensor): A [N, L, H, Co] tensor containing Vs. + + Note: + k and v are assumed to have the same coordinate map. + """ + ... + +def scaled_dot_product_attention(*args, **kwargs): + arg_names_dict = { + 1: ['qkv'], + 2: ['q', 'kv'], + 3: ['q', 'k', 'v'] + } + num_all_args = len(args) + len(kwargs) + assert num_all_args in arg_names_dict, f"Invalid number of arguments, got {num_all_args}, expected 1, 2, or 3" + for key in arg_names_dict[num_all_args][len(args):]: + assert key in kwargs, f"Missing argument {key}" + + if num_all_args == 1: + qkv = args[0] if len(args) > 0 else kwargs['qkv'] + assert len(qkv.shape) == 5 and qkv.shape[2] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, L, 3, H, C]" + device = qkv.device + + elif num_all_args == 2: + q = args[0] if len(args) > 0 else kwargs['q'] + kv = args[1] if len(args) > 1 else kwargs['kv'] + assert q.shape[0] == kv.shape[0], f"Batch size mismatch, got {q.shape[0]} and {kv.shape[0]}" + assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, C]" + assert len(kv.shape) == 5, f"Invalid shape for kv, got {kv.shape}, expected [N, L, 2, H, C]" + device = q.device + + elif num_all_args == 3: + q = args[0] if len(args) > 0 else kwargs['q'] + k = args[1] if len(args) > 1 else kwargs['k'] + v = args[2] if len(args) > 2 else kwargs['v'] + assert q.shape[0] == k.shape[0] == v.shape[0], f"Batch size mismatch, got {q.shape[0]}, {k.shape[0]}, and {v.shape[0]}" + assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, Ci]" + assert len(k.shape) == 4, f"Invalid shape for k, got {k.shape}, expected [N, L, H, Ci]" + assert len(v.shape) == 4, f"Invalid shape for v, got {v.shape}, expected [N, L, H, Co]" + device = q.device + + if BACKEND == 'xformers': + if num_all_args == 1: + q, k, v = qkv.unbind(dim=2) + elif num_all_args == 2: + k, v = kv.unbind(dim=2) + out = xops.memory_efficient_attention(q, k, v) + elif BACKEND == 'flash_attn': + if num_all_args == 1: + out = flash_attn.flash_attn_qkvpacked_func(qkv) + elif num_all_args == 2: + out = flash_attn.flash_attn_kvpacked_func(q, kv) + elif num_all_args == 3: + out = flash_attn.flash_attn_func(q, k, v) + elif BACKEND == 'sdpa': + if num_all_args == 1: + q, k, v = qkv.unbind(dim=2) + elif num_all_args == 2: + k, v = kv.unbind(dim=2) + q = q.permute(0, 2, 1, 3) # [N, H, L, C] + k = k.permute(0, 2, 1, 3) # [N, H, L, C] + v = v.permute(0, 2, 1, 3) # [N, H, L, C] + out = sdpa(q, k, v) # [N, H, L, C] + out = out.permute(0, 2, 1, 3) # [N, L, H, C] + elif BACKEND == 'naive': + if num_all_args == 1: + q, k, v = qkv.unbind(dim=2) + elif num_all_args == 2: + k, v = kv.unbind(dim=2) + out = _naive_sdpa(q, k, v) + else: + raise ValueError(f"Unknown attention module: {BACKEND}") + + return out diff --git a/anigen/modules/attention/modules.py b/anigen/modules/attention/modules.py new file mode 100644 index 0000000000000000000000000000000000000000..e843b624d6fb51e818c4b4826e817ba220368d96 --- /dev/null +++ b/anigen/modules/attention/modules.py @@ -0,0 +1,161 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +from .full_attn import scaled_dot_product_attention + + +class MultiHeadRMSNorm(nn.Module): + def __init__(self, dim: int, heads: int): + super().__init__() + self.scale = dim ** 0.5 + self.gamma = nn.Parameter(torch.ones(heads, dim)) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return (F.normalize(x.float(), dim = -1) * self.gamma * self.scale).to(x.dtype) + + +class RotaryPositionEmbedder(nn.Module): + def __init__(self, hidden_size: int, in_channels: int = 3): + super().__init__() + assert hidden_size % 2 == 0, "Hidden size must be divisible by 2" + self.hidden_size = hidden_size + self.in_channels = in_channels + self.freq_dim = hidden_size // in_channels // 2 + self.freqs = torch.arange(self.freq_dim, dtype=torch.float32) / self.freq_dim + self.freqs = 1.0 / (10000 ** self.freqs) + + def _get_phases(self, indices: torch.Tensor) -> torch.Tensor: + self.freqs = self.freqs.to(indices.device) + phases = torch.outer(indices, self.freqs) + phases = torch.polar(torch.ones_like(phases), phases) + return phases + + def _rotary_embedding(self, x: torch.Tensor, phases: torch.Tensor) -> torch.Tensor: + x_complex = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2)) + x_rotated = x_complex * phases + x_embed = torch.view_as_real(x_rotated).reshape(*x_rotated.shape[:-1], -1).to(x.dtype) + return x_embed + + def forward(self, q: torch.Tensor, k: torch.Tensor, indices: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Args: + q (sp.SparseTensor): [..., N, D] tensor of queries + k (sp.SparseTensor): [..., N, D] tensor of keys + indices (torch.Tensor): [..., N, C] tensor of spatial positions + """ + if indices is None: + indices = torch.arange(q.shape[-2], device=q.device) + if len(q.shape) > 2: + indices = indices.unsqueeze(0).expand(q.shape[:-2] + (-1,)) + + phases = self._get_phases(indices.reshape(-1)).reshape(*indices.shape[:-1], -1) + if phases.shape[1] < self.hidden_size // 2: + phases = torch.cat([phases, torch.polar( + torch.ones(*phases.shape[:-1], self.hidden_size // 2 - phases.shape[1], device=phases.device), + torch.zeros(*phases.shape[:-1], self.hidden_size // 2 - phases.shape[1], device=phases.device) + )], dim=-1) + q_embed = self._rotary_embedding(q, phases) + k_embed = self._rotary_embedding(k, phases) + return q_embed, k_embed + + +class LoRALinear(nn.Linear): + def __init__(self, in_features: int, out_features: int, bias: bool = True, rank: int = 4, lr_rate: float = 1.0): + super().__init__(in_features, out_features, bias) + self.rank = rank + self.lora_A = nn.Parameter(torch.zeros(in_features, rank)) + self.lora_B = nn.Parameter(torch.randn(rank, out_features) * 1e-2) + self.lr_rate = lr_rate + def forward(self, x: torch.Tensor) -> torch.Tensor: + return super().forward(x) + (x @ self.lora_A) @ self.lora_B * self.lr_rate + + +class MultiHeadAttention(nn.Module): + def __init__( + self, + channels: int, + num_heads: int, + ctx_channels: Optional[int]=None, + type: Literal["self", "cross"] = "self", + attn_mode: Literal["full", "windowed"] = "full", + window_size: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + qkv_bias: bool = True, + use_rope: bool = False, + qk_rms_norm: bool = False, + x_is_query: bool = False, + use_lora: bool = False, + lora_rank: int = 4, + lora_lr_rate: float = 1.0, + ): + super().__init__() + assert channels % num_heads == 0 + assert type in ["self", "cross"], f"Invalid attention type: {type}" + assert attn_mode in ["full", "windowed"], f"Invalid attention mode: {attn_mode}" + assert type == "self" or attn_mode == "full", "Cross-attention only supports full attention" + + if attn_mode == "windowed": + raise NotImplementedError("Windowed attention is not yet implemented") + + self.channels = channels + self.head_dim = channels // num_heads + self.ctx_channels = ctx_channels if ctx_channels is not None else channels + self.num_heads = num_heads + self._type = type + self.attn_mode = attn_mode + self.window_size = window_size + self.shift_window = shift_window + self.use_rope = use_rope + self.qk_rms_norm = qk_rms_norm + + if self._type == "self": + self.to_qkv = nn.Linear(channels, channels * 3, bias=qkv_bias) if not use_lora else LoRALinear(channels, channels * 3, bias=qkv_bias, rank=lora_rank, lr_rate=lora_lr_rate) + else: + self.to_q = (lambda x: x) if x_is_query else (nn.Linear(channels, channels, bias=qkv_bias) if not use_lora else LoRALinear(channels, channels, bias=qkv_bias, rank=lora_rank, lr_rate=lora_lr_rate)) + self.to_kv = nn.Linear(self.ctx_channels, channels * 2, bias=qkv_bias) if not use_lora else LoRALinear(self.ctx_channels, channels * 2, bias=qkv_bias, rank=lora_rank, lr_rate=lora_lr_rate) + + if self.qk_rms_norm: + self.q_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads) + self.k_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads) + + self.to_out = nn.Linear(channels, channels) if not use_lora else LoRALinear(channels, channels, rank=lora_rank, lr_rate=lora_lr_rate) + + if use_rope: + self.rope = RotaryPositionEmbedder(channels) + + def forward(self, x: torch.Tensor, context: Optional[torch.Tensor] = None, indices: Optional[torch.Tensor] = None) -> torch.Tensor: + B, L, C = x.shape + if self._type == "self": + qkv = self.to_qkv(x) + qkv = qkv.reshape(B, L, 3, self.num_heads, -1) + if self.use_rope: + q, k, v = qkv.unbind(dim=2) + q, k = self.rope(q, k, indices) + qkv = torch.stack([q, k, v], dim=2) + if self.attn_mode == "full": + if self.qk_rms_norm: + q, k, v = qkv.unbind(dim=2) + q = self.q_rms_norm(q) + k = self.k_rms_norm(k) + h = scaled_dot_product_attention(q, k, v) + else: + h = scaled_dot_product_attention(qkv) + elif self.attn_mode == "windowed": + raise NotImplementedError("Windowed attention is not yet implemented") + else: + Lkv = context.shape[1] + q = self.to_q(x) + kv = self.to_kv(context) + q = q.reshape(B, L, self.num_heads, -1) + kv = kv.reshape(B, Lkv, 2, self.num_heads, -1) + if self.qk_rms_norm: + q = self.q_rms_norm(q) + k, v = kv.unbind(dim=2) + k = self.k_rms_norm(k) + h = scaled_dot_product_attention(q, k, v) + else: + h = scaled_dot_product_attention(q, kv) + h = h.reshape(B, L, -1) + h = self.to_out(h) + return h diff --git a/anigen/modules/norm.py b/anigen/modules/norm.py new file mode 100644 index 0000000000000000000000000000000000000000..09035726081fb7afda2c62504d5474cfa483c58f --- /dev/null +++ b/anigen/modules/norm.py @@ -0,0 +1,25 @@ +import torch +import torch.nn as nn + + +class LayerNorm32(nn.LayerNorm): + def forward(self, x: torch.Tensor) -> torch.Tensor: + return super().forward(x.float()).type(x.dtype) + + +class GroupNorm32(nn.GroupNorm): + """ + A GroupNorm layer that converts to float32 before the forward pass. + """ + def forward(self, x: torch.Tensor) -> torch.Tensor: + return super().forward(x.float()).type(x.dtype) + + +class ChannelLayerNorm32(LayerNorm32): + def forward(self, x: torch.Tensor) -> torch.Tensor: + DIM = x.dim() + x = x.permute(0, *range(2, DIM), 1).contiguous() + x = super().forward(x) + x = x.permute(0, DIM-1, *range(1, DIM-1)).contiguous() + return x + \ No newline at end of file diff --git a/anigen/modules/sparse/__init__.py b/anigen/modules/sparse/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..726756c16dcfe0f04de0d2ea5bdce499fa220160 --- /dev/null +++ b/anigen/modules/sparse/__init__.py @@ -0,0 +1,102 @@ +from typing import * + +BACKEND = 'spconv' +DEBUG = False +ATTN = 'flash_attn' + +def __from_env(): + import os + + global BACKEND + global DEBUG + global ATTN + + env_sparse_backend = os.environ.get('SPARSE_BACKEND') + env_sparse_debug = os.environ.get('SPARSE_DEBUG') + env_sparse_attn = os.environ.get('SPARSE_ATTN_BACKEND') + if env_sparse_attn is None: + env_sparse_attn = os.environ.get('ATTN_BACKEND') + + if env_sparse_backend is not None and env_sparse_backend in ['spconv', 'torchsparse']: + BACKEND = env_sparse_backend + if env_sparse_debug is not None: + DEBUG = env_sparse_debug == '1' + if env_sparse_attn is not None and env_sparse_attn in ['xformers', 'flash_attn']: + ATTN = env_sparse_attn + + print(f"[SPARSE] Backend: {BACKEND}, Attention: {ATTN}") + + +__from_env() + + +def set_backend(backend: Literal['spconv', 'torchsparse']): + global BACKEND + BACKEND = backend + +def set_debug(debug: bool): + global DEBUG + DEBUG = debug + +def set_attn(attn: Literal['xformers', 'flash_attn']): + global ATTN + ATTN = attn + + +import importlib + +__attributes = { + 'SparseTensor': 'basic', + 'sparse_batch_broadcast': 'basic', + 'sparse_batch_op': 'basic', + 'sparse_cat': 'basic', + 'sparse_unbind': 'basic', + 'SparseGroupNorm': 'norm', + 'SparseLayerNorm': 'norm', + 'SparseGroupNorm32': 'norm', + 'SparseLayerNorm32': 'norm', + 'SparseReLU': 'nonlinearity', + 'SparseSiLU': 'nonlinearity', + 'SparseGELU': 'nonlinearity', + 'SparseActivation': 'nonlinearity', + 'SparseLinear': 'linear', + 'sparse_scaled_dot_product_attention': 'attention', + 'SerializeMode': 'attention', + 'sparse_serialized_scaled_dot_product_self_attention': 'attention', + 'sparse_windowed_scaled_dot_product_self_attention': 'attention', + 'SparseMultiHeadAttention': 'attention', + 'SparseConv3d': 'conv', + 'SparseInverseConv3d': 'conv', + 'SparseDownsample': 'spatial', + 'SparseUpsample': 'spatial', + 'SparseSubdivide' : 'spatial' +} + +__submodules = ['transformer'] + +__all__ = list(__attributes.keys()) + __submodules + +def __getattr__(name): + if name not in globals(): + if name in __attributes: + module_name = __attributes[name] + module = importlib.import_module(f".{module_name}", __name__) + globals()[name] = getattr(module, name) + elif name in __submodules: + module = importlib.import_module(f".{name}", __name__) + globals()[name] = module + else: + raise AttributeError(f"module {__name__} has no attribute {name}") + return globals()[name] + + +# For Pylance +if __name__ == '__main__': + from .basic import * + from .norm import * + from .nonlinearity import * + from .linear import * + from .attention import * + from .conv import * + from .spatial import * + import transformer diff --git a/anigen/modules/sparse/attention/__init__.py b/anigen/modules/sparse/attention/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5630d7f5d607cb6a1b23a814eda4e276f625609d --- /dev/null +++ b/anigen/modules/sparse/attention/__init__.py @@ -0,0 +1,5 @@ +from .full_attn import * +from .serialized_attn import * +from .windowed_attn import * +from .modules import * +from .windowed_attn_cross import * \ No newline at end of file diff --git a/anigen/modules/sparse/attention/full_attn.py b/anigen/modules/sparse/attention/full_attn.py new file mode 100644 index 0000000000000000000000000000000000000000..e9e27aeb98419621f3f9999fd3b11eebf2b90a40 --- /dev/null +++ b/anigen/modules/sparse/attention/full_attn.py @@ -0,0 +1,215 @@ +from typing import * +import torch +from .. import SparseTensor +from .. import DEBUG, ATTN + +if ATTN == 'xformers': + import xformers.ops as xops +elif ATTN == 'flash_attn': + import flash_attn +else: + raise ValueError(f"Unknown attention module: {ATTN}") + + +__all__ = [ + 'sparse_scaled_dot_product_attention', +] + + +@overload +def sparse_scaled_dot_product_attention(qkv: SparseTensor) -> SparseTensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + qkv (SparseTensor): A [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs. + """ + ... + +@overload +def sparse_scaled_dot_product_attention(q: SparseTensor, kv: Union[SparseTensor, torch.Tensor]) -> SparseTensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + q (SparseTensor): A [N, *, H, C] sparse tensor containing Qs. + kv (SparseTensor or torch.Tensor): A [N, *, 2, H, C] sparse tensor or a [N, L, 2, H, C] dense tensor containing Ks and Vs. + """ + ... + +@overload +def sparse_scaled_dot_product_attention(q: torch.Tensor, kv: SparseTensor) -> torch.Tensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + q (SparseTensor): A [N, L, H, C] dense tensor containing Qs. + kv (SparseTensor or torch.Tensor): A [N, *, 2, H, C] sparse tensor containing Ks and Vs. + """ + ... + +@overload +def sparse_scaled_dot_product_attention(q: SparseTensor, k: SparseTensor, v: SparseTensor) -> SparseTensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + q (SparseTensor): A [N, *, H, Ci] sparse tensor containing Qs. + k (SparseTensor): A [N, *, H, Ci] sparse tensor containing Ks. + v (SparseTensor): A [N, *, H, Co] sparse tensor containing Vs. + + Note: + k and v are assumed to have the same coordinate map. + """ + ... + +@overload +def sparse_scaled_dot_product_attention(q: SparseTensor, k: torch.Tensor, v: torch.Tensor) -> SparseTensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + q (SparseTensor): A [N, *, H, Ci] sparse tensor containing Qs. + k (torch.Tensor): A [N, L, H, Ci] dense tensor containing Ks. + v (torch.Tensor): A [N, L, H, Co] dense tensor containing Vs. + """ + ... + +@overload +def sparse_scaled_dot_product_attention(q: torch.Tensor, k: SparseTensor, v: SparseTensor) -> torch.Tensor: + """ + Apply scaled dot product attention to a sparse tensor. + + Args: + q (torch.Tensor): A [N, L, H, Ci] dense tensor containing Qs. + k (SparseTensor): A [N, *, H, Ci] sparse tensor containing Ks. + v (SparseTensor): A [N, *, H, Co] sparse tensor containing Vs. + """ + ... + +def sparse_scaled_dot_product_attention(*args, **kwargs): + arg_names_dict = { + 1: ['qkv'], + 2: ['q', 'kv'], + 3: ['q', 'k', 'v'] + } + num_all_args = len(args) + len(kwargs) + assert num_all_args in arg_names_dict, f"Invalid number of arguments, got {num_all_args}, expected 1, 2, or 3" + for key in arg_names_dict[num_all_args][len(args):]: + assert key in kwargs, f"Missing argument {key}" + + if num_all_args == 1: + qkv = args[0] if len(args) > 0 else kwargs['qkv'] + assert isinstance(qkv, SparseTensor), f"qkv must be a SparseTensor, got {type(qkv)}" + assert len(qkv.shape) == 4 and qkv.shape[1] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, *, 3, H, C]" + device = qkv.device + + s = qkv + q_seqlen = [qkv.layout[i].stop - qkv.layout[i].start for i in range(qkv.shape[0])] + kv_seqlen = q_seqlen + qkv = qkv.feats # [T, 3, H, C] + + elif num_all_args == 2: + q = args[0] if len(args) > 0 else kwargs['q'] + kv = args[1] if len(args) > 1 else kwargs['kv'] + assert isinstance(q, SparseTensor) and isinstance(kv, (SparseTensor, torch.Tensor)) or \ + isinstance(q, torch.Tensor) and isinstance(kv, SparseTensor), \ + f"Invalid types, got {type(q)} and {type(kv)}" + assert q.shape[0] == kv.shape[0], f"Batch size mismatch, got {q.shape[0]} and {kv.shape[0]}" + device = q.device + + if isinstance(q, SparseTensor): + assert len(q.shape) == 3, f"Invalid shape for q, got {q.shape}, expected [N, *, H, C]" + s = q + q_seqlen = [q.layout[i].stop - q.layout[i].start for i in range(q.shape[0])] + q = q.feats # [T_Q, H, C] + else: + assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, C]" + s = None + N, L, H, C = q.shape + q_seqlen = [L] * N + q = q.reshape(N * L, H, C) # [T_Q, H, C] + + if isinstance(kv, SparseTensor): + assert len(kv.shape) == 4 and kv.shape[1] == 2, f"Invalid shape for kv, got {kv.shape}, expected [N, *, 2, H, C]" + kv_seqlen = [kv.layout[i].stop - kv.layout[i].start for i in range(kv.shape[0])] + kv = kv.feats # [T_KV, 2, H, C] + else: + assert len(kv.shape) == 5, f"Invalid shape for kv, got {kv.shape}, expected [N, L, 2, H, C]" + N, L, _, H, C = kv.shape + kv_seqlen = [L] * N + kv = kv.reshape(N * L, 2, H, C) # [T_KV, 2, H, C] + + elif num_all_args == 3: + q = args[0] if len(args) > 0 else kwargs['q'] + k = args[1] if len(args) > 1 else kwargs['k'] + v = args[2] if len(args) > 2 else kwargs['v'] + assert isinstance(q, SparseTensor) and isinstance(k, (SparseTensor, torch.Tensor)) and type(k) == type(v) or \ + isinstance(q, torch.Tensor) and isinstance(k, SparseTensor) and isinstance(v, SparseTensor), \ + f"Invalid types, got {type(q)}, {type(k)}, and {type(v)}" + assert q.shape[0] == k.shape[0] == v.shape[0], f"Batch size mismatch, got {q.shape[0]}, {k.shape[0]}, and {v.shape[0]}" + device = q.device + + if isinstance(q, SparseTensor): + assert len(q.shape) == 3, f"Invalid shape for q, got {q.shape}, expected [N, *, H, Ci]" + s = q + q_seqlen = [q.layout[i].stop - q.layout[i].start for i in range(q.shape[0])] + q = q.feats # [T_Q, H, Ci] + else: + assert len(q.shape) == 4, f"Invalid shape for q, got {q.shape}, expected [N, L, H, Ci]" + s = None + N, L, H, CI = q.shape + q_seqlen = [L] * N + q = q.reshape(N * L, H, CI) # [T_Q, H, Ci] + + if isinstance(k, SparseTensor): + assert len(k.shape) == 3, f"Invalid shape for k, got {k.shape}, expected [N, *, H, Ci]" + assert len(v.shape) == 3, f"Invalid shape for v, got {v.shape}, expected [N, *, H, Co]" + kv_seqlen = [k.layout[i].stop - k.layout[i].start for i in range(k.shape[0])] + k = k.feats # [T_KV, H, Ci] + v = v.feats # [T_KV, H, Co] + else: + assert len(k.shape) == 4, f"Invalid shape for k, got {k.shape}, expected [N, L, H, Ci]" + assert len(v.shape) == 4, f"Invalid shape for v, got {v.shape}, expected [N, L, H, Co]" + N, L, H, CI, CO = *k.shape, v.shape[-1] + kv_seqlen = [L] * N + k = k.reshape(N * L, H, CI) # [T_KV, H, Ci] + v = v.reshape(N * L, H, CO) # [T_KV, H, Co] + + if DEBUG: + if s is not None: + for i in range(s.shape[0]): + assert (s.coords[s.layout[i]] == i).all(), f"SparseScaledDotProductSelfAttention: batch index mismatch" + if num_all_args in [2, 3]: + assert q.shape[:2] == [1, sum(q_seqlen)], f"SparseScaledDotProductSelfAttention: q shape mismatch" + if num_all_args == 3: + assert k.shape[:2] == [1, sum(kv_seqlen)], f"SparseScaledDotProductSelfAttention: k shape mismatch" + assert v.shape[:2] == [1, sum(kv_seqlen)], f"SparseScaledDotProductSelfAttention: v shape mismatch" + + if ATTN == 'xformers': + if num_all_args == 1: + q, k, v = qkv.unbind(dim=1) + elif num_all_args == 2: + k, v = kv.unbind(dim=1) + q = q.unsqueeze(0) + k = k.unsqueeze(0) + v = v.unsqueeze(0) + mask = xops.fmha.BlockDiagonalMask.from_seqlens(q_seqlen, kv_seqlen) + out = xops.memory_efficient_attention(q, k, v, mask)[0] + elif ATTN == 'flash_attn': + cu_seqlens_q = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(q_seqlen), dim=0)]).int().to(device) + if num_all_args in [2, 3]: + cu_seqlens_kv = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(kv_seqlen), dim=0)]).int().to(device) + if num_all_args == 1: + out = flash_attn.flash_attn_varlen_qkvpacked_func(qkv, cu_seqlens_q, max(q_seqlen)) + elif num_all_args == 2: + out = flash_attn.flash_attn_varlen_kvpacked_func(q, kv, cu_seqlens_q, cu_seqlens_kv, max(q_seqlen), max(kv_seqlen)) + elif num_all_args == 3: + out = flash_attn.flash_attn_varlen_func(q, k, v, cu_seqlens_q, cu_seqlens_kv, max(q_seqlen), max(kv_seqlen)) + else: + raise ValueError(f"Unknown attention module: {ATTN}") + + if s is not None: + return s.replace(out) + else: + return out.reshape(N, L, H, -1) diff --git a/anigen/modules/sparse/attention/modules.py b/anigen/modules/sparse/attention/modules.py new file mode 100644 index 0000000000000000000000000000000000000000..0ff35522b6c2280d29a6b5952097f83b632bf0b4 --- /dev/null +++ b/anigen/modules/sparse/attention/modules.py @@ -0,0 +1,151 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +from .. import SparseTensor +from .full_attn import sparse_scaled_dot_product_attention +from .serialized_attn import SerializeMode, sparse_serialized_scaled_dot_product_self_attention +from .windowed_attn import sparse_windowed_scaled_dot_product_self_attention +from .windowed_attn_cross import sparse_windowed_scaled_dot_product_cross_attention +from ...attention import RotaryPositionEmbedder + + +class SparseMultiHeadRMSNorm(nn.Module): + def __init__(self, dim: int, heads: int): + super().__init__() + self.scale = dim ** 0.5 + self.gamma = nn.Parameter(torch.ones(heads, dim)) + + def forward(self, x: Union[SparseTensor, torch.Tensor]) -> Union[SparseTensor, torch.Tensor]: + x_type = x.dtype + x = x.float() + if isinstance(x, SparseTensor): + x = x.replace(F.normalize(x.feats, dim=-1)) + else: + x = F.normalize(x, dim=-1) + return (x * self.gamma * self.scale).to(x_type) + + +class SparseMultiHeadAttention(nn.Module): + def __init__( + self, + channels: int, + num_heads: int, + ctx_channels: Optional[int] = None, + type: Literal["self", "cross"] = "self", + attn_mode: Literal["full", "serialized", "windowed"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + qkv_bias: bool = True, + use_rope: bool = False, + qk_rms_norm: bool = False, + cross_attn_cache_suffix: str = '', + ): + super().__init__() + assert channels % num_heads == 0 + assert type in ["self", "cross"], f"Invalid attention type: {type}" + assert attn_mode in ["full", "serialized", "windowed"], f"Invalid attention mode: {attn_mode}" + assert type == "self" or (attn_mode == "full" or attn_mode == "windowed"), "Cross-attention only supports full and windowed attention" + assert type == "self" or use_rope is False, "Rotary position embeddings only supported for self-attention" + self.channels = channels + self.ctx_channels = ctx_channels if ctx_channels is not None else channels + self.num_heads = num_heads + self._type = type + self.attn_mode = attn_mode + self.window_size = window_size + self.shift_sequence = shift_sequence + self.shift_window = shift_window + self.serialize_mode = serialize_mode + self.use_rope = use_rope + self.qk_rms_norm = qk_rms_norm + + if self._type == "self": + self.to_qkv = nn.Linear(channels, channels * 3, bias=qkv_bias) + else: + self.to_q = nn.Linear(channels, channels, bias=qkv_bias) + self.to_kv = nn.Linear(self.ctx_channels, channels * 2, bias=qkv_bias) + self.cross_attn_cache_suffix = cross_attn_cache_suffix + + if self.qk_rms_norm: + self.q_rms_norm = SparseMultiHeadRMSNorm(channels // num_heads, num_heads) + self.k_rms_norm = SparseMultiHeadRMSNorm(channels // num_heads, num_heads) + + self.to_out = nn.Linear(channels, channels) + + if use_rope: + self.rope = RotaryPositionEmbedder(channels) + + @staticmethod + def _linear(module: nn.Linear, x: Union[SparseTensor, torch.Tensor]) -> Union[SparseTensor, torch.Tensor]: + if isinstance(x, SparseTensor): + return x.replace(module(x.feats)) + else: + return module(x) + + @staticmethod + def _reshape_chs(x: Union[SparseTensor, torch.Tensor], shape: Tuple[int, ...]) -> Union[SparseTensor, torch.Tensor]: + if isinstance(x, SparseTensor): + return x.reshape(*shape) + else: + return x.reshape(*x.shape[:2], *shape) + + def _fused_pre(self, x: Union[SparseTensor, torch.Tensor], num_fused: int) -> Union[SparseTensor, torch.Tensor]: + if isinstance(x, SparseTensor): + x_feats = x.feats.unsqueeze(0) + else: + x_feats = x + x_feats = x_feats.reshape(*x_feats.shape[:2], num_fused, self.num_heads, -1) + return x.replace(x_feats.squeeze(0)) if isinstance(x, SparseTensor) else x_feats + + def _rope(self, qkv: SparseTensor) -> SparseTensor: + q, k, v = qkv.feats.unbind(dim=1) # [T, H, C] + q, k = self.rope(q, k, qkv.coords[:, 1:]) + qkv = qkv.replace(torch.stack([q, k, v], dim=1)) + return qkv + + def forward(self, x: Union[SparseTensor, torch.Tensor], context: Optional[Union[SparseTensor, torch.Tensor]] = None) -> Union[SparseTensor, torch.Tensor]: + if self._type == "self": + qkv = self._linear(self.to_qkv, x) + qkv = self._fused_pre(qkv, num_fused=3) + if self.use_rope: + qkv = self._rope(qkv) + if self.qk_rms_norm: + q, k, v = qkv.unbind(dim=1) + q = self.q_rms_norm(q) + k = self.k_rms_norm(k) + qkv = qkv.replace(torch.stack([q.feats, k.feats, v.feats], dim=1)) + if self.attn_mode == "full": + h = sparse_scaled_dot_product_attention(qkv) + elif self.attn_mode == "serialized": + h = sparse_serialized_scaled_dot_product_self_attention( + qkv, self.window_size, serialize_mode=self.serialize_mode, shift_sequence=self.shift_sequence, shift_window=self.shift_window + ) + elif self.attn_mode == "windowed": + h = sparse_windowed_scaled_dot_product_self_attention( + qkv, self.window_size, shift_window=self.shift_window + ) + else: + q = self._linear(self.to_q, x) + q = self._reshape_chs(q, (self.num_heads, -1)) + kv = self._linear(self.to_kv, context) + kv = self._fused_pre(kv, num_fused=2) + if self.qk_rms_norm: + q = self.q_rms_norm(q) + k, v = kv.unbind(dim=1) + k = self.k_rms_norm(k) + kv = kv.replace(torch.stack([k.feats, v.feats], dim=1)) + if self.attn_mode == "full": + h = sparse_scaled_dot_product_attention(q, kv) + elif self.attn_mode == "windowed": + q = self._fused_pre(q, num_fused=1) + h = sparse_windowed_scaled_dot_product_cross_attention( + q, kv, self.window_size, shift_window=self.shift_window, + cache_suffix=self.cross_attn_cache_suffix + ) + elif self.attn_mode == "serialized": + raise NotImplementedError("Serialized attention is not supported for cross-attention") + h = self._reshape_chs(h, (-1,)) + h = self._linear(self.to_out, h) + return h diff --git a/anigen/modules/sparse/attention/serialized_attn.py b/anigen/modules/sparse/attention/serialized_attn.py new file mode 100644 index 0000000000000000000000000000000000000000..5950b75b2f5a6d6e79ab6d472b8501aaa5ec4a26 --- /dev/null +++ b/anigen/modules/sparse/attention/serialized_attn.py @@ -0,0 +1,193 @@ +from typing import * +from enum import Enum +import torch +import math +from .. import SparseTensor +from .. import DEBUG, ATTN + +if ATTN == 'xformers': + import xformers.ops as xops +elif ATTN == 'flash_attn': + import flash_attn +else: + raise ValueError(f"Unknown attention module: {ATTN}") + + +__all__ = [ + 'sparse_serialized_scaled_dot_product_self_attention', +] + + +class SerializeMode(Enum): + Z_ORDER = 0 + Z_ORDER_TRANSPOSED = 1 + HILBERT = 2 + HILBERT_TRANSPOSED = 3 + + +SerializeModes = [ + SerializeMode.Z_ORDER, + SerializeMode.Z_ORDER_TRANSPOSED, + SerializeMode.HILBERT, + SerializeMode.HILBERT_TRANSPOSED +] + + +def calc_serialization( + tensor: SparseTensor, + window_size: int, + serialize_mode: SerializeMode = SerializeMode.Z_ORDER, + shift_sequence: int = 0, + shift_window: Tuple[int, int, int] = (0, 0, 0) +) -> Tuple[torch.Tensor, torch.Tensor, List[int]]: + """ + Calculate serialization and partitioning for a set of coordinates. + + Args: + tensor (SparseTensor): The input tensor. + window_size (int): The window size to use. + serialize_mode (SerializeMode): The serialization mode to use. + shift_sequence (int): The shift of serialized sequence. + shift_window (Tuple[int, int, int]): The shift of serialized coordinates. + + Returns: + (torch.Tensor, torch.Tensor): Forwards and backwards indices. + """ + fwd_indices = [] + bwd_indices = [] + seq_lens = [] + seq_batch_indices = [] + offsets = [0] + + if 'vox2seq' not in globals(): + import vox2seq + + # Serialize the input + serialize_coords = tensor.coords[:, 1:].clone() + serialize_coords += torch.tensor(shift_window, dtype=torch.int32, device=tensor.device).reshape(1, 3) + if serialize_mode == SerializeMode.Z_ORDER: + code = vox2seq.encode(serialize_coords, mode='z_order', permute=[0, 1, 2]) + elif serialize_mode == SerializeMode.Z_ORDER_TRANSPOSED: + code = vox2seq.encode(serialize_coords, mode='z_order', permute=[1, 0, 2]) + elif serialize_mode == SerializeMode.HILBERT: + code = vox2seq.encode(serialize_coords, mode='hilbert', permute=[0, 1, 2]) + elif serialize_mode == SerializeMode.HILBERT_TRANSPOSED: + code = vox2seq.encode(serialize_coords, mode='hilbert', permute=[1, 0, 2]) + else: + raise ValueError(f"Unknown serialize mode: {serialize_mode}") + + for bi, s in enumerate(tensor.layout): + num_points = s.stop - s.start + num_windows = (num_points + window_size - 1) // window_size + valid_window_size = num_points / num_windows + to_ordered = torch.argsort(code[s.start:s.stop]) + if num_windows == 1: + fwd_indices.append(to_ordered) + bwd_indices.append(torch.zeros_like(to_ordered).scatter_(0, to_ordered, torch.arange(num_points, device=tensor.device))) + fwd_indices[-1] += s.start + bwd_indices[-1] += offsets[-1] + seq_lens.append(num_points) + seq_batch_indices.append(bi) + offsets.append(offsets[-1] + seq_lens[-1]) + else: + # Partition the input + offset = 0 + mids = [(i + 0.5) * valid_window_size + shift_sequence for i in range(num_windows)] + split = [math.floor(i * valid_window_size + shift_sequence) for i in range(num_windows + 1)] + bwd_index = torch.zeros((num_points,), dtype=torch.int64, device=tensor.device) + for i in range(num_windows): + mid = mids[i] + valid_start = split[i] + valid_end = split[i + 1] + padded_start = math.floor(mid - 0.5 * window_size) + padded_end = padded_start + window_size + fwd_indices.append(to_ordered[torch.arange(padded_start, padded_end, device=tensor.device) % num_points]) + offset += valid_start - padded_start + bwd_index.scatter_(0, fwd_indices[-1][valid_start-padded_start:valid_end-padded_start], torch.arange(offset, offset + valid_end - valid_start, device=tensor.device)) + offset += padded_end - valid_start + fwd_indices[-1] += s.start + seq_lens.extend([window_size] * num_windows) + seq_batch_indices.extend([bi] * num_windows) + bwd_indices.append(bwd_index + offsets[-1]) + offsets.append(offsets[-1] + num_windows * window_size) + + fwd_indices = torch.cat(fwd_indices) + bwd_indices = torch.cat(bwd_indices) + + return fwd_indices, bwd_indices, seq_lens, seq_batch_indices + + +def sparse_serialized_scaled_dot_product_self_attention( + qkv: SparseTensor, + window_size: int, + serialize_mode: SerializeMode = SerializeMode.Z_ORDER, + shift_sequence: int = 0, + shift_window: Tuple[int, int, int] = (0, 0, 0) +) -> SparseTensor: + """ + Apply serialized scaled dot product self attention to a sparse tensor. + + Args: + qkv (SparseTensor): [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs. + window_size (int): The window size to use. + serialize_mode (SerializeMode): The serialization mode to use. + shift_sequence (int): The shift of serialized sequence. + shift_window (Tuple[int, int, int]): The shift of serialized coordinates. + shift (int): The shift to use. + """ + assert len(qkv.shape) == 4 and qkv.shape[1] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, *, 3, H, C]" + + serialization_spatial_cache_name = f'serialization_{serialize_mode}_{window_size}_{shift_sequence}_{shift_window}' + serialization_spatial_cache = qkv.get_spatial_cache(serialization_spatial_cache_name) + if serialization_spatial_cache is None: + fwd_indices, bwd_indices, seq_lens, seq_batch_indices = calc_serialization(qkv, window_size, serialize_mode, shift_sequence, shift_window) + qkv.register_spatial_cache(serialization_spatial_cache_name, (fwd_indices, bwd_indices, seq_lens, seq_batch_indices)) + else: + fwd_indices, bwd_indices, seq_lens, seq_batch_indices = serialization_spatial_cache + + M = fwd_indices.shape[0] + T = qkv.feats.shape[0] + H = qkv.feats.shape[2] + C = qkv.feats.shape[3] + + qkv_feats = qkv.feats[fwd_indices] # [M, 3, H, C] + + if DEBUG: + start = 0 + qkv_coords = qkv.coords[fwd_indices] + for i in range(len(seq_lens)): + assert (qkv_coords[start:start+seq_lens[i], 0] == seq_batch_indices[i]).all(), f"SparseWindowedScaledDotProductSelfAttention: batch index mismatch" + start += seq_lens[i] + + if all([seq_len == window_size for seq_len in seq_lens]): + B = len(seq_lens) + N = window_size + qkv_feats = qkv_feats.reshape(B, N, 3, H, C) + if ATTN == 'xformers': + q, k, v = qkv_feats.unbind(dim=2) # [B, N, H, C] + out = xops.memory_efficient_attention(q, k, v) # [B, N, H, C] + elif ATTN == 'flash_attn': + out = flash_attn.flash_attn_qkvpacked_func(qkv_feats) # [B, N, H, C] + else: + raise ValueError(f"Unknown attention module: {ATTN}") + out = out.reshape(B * N, H, C) # [M, H, C] + else: + if ATTN == 'xformers': + q, k, v = qkv_feats.unbind(dim=1) # [M, H, C] + q = q.unsqueeze(0) # [1, M, H, C] + k = k.unsqueeze(0) # [1, M, H, C] + v = v.unsqueeze(0) # [1, M, H, C] + mask = xops.fmha.BlockDiagonalMask.from_seqlens(seq_lens) + out = xops.memory_efficient_attention(q, k, v, mask)[0] # [M, H, C] + elif ATTN == 'flash_attn': + cu_seqlens = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(seq_lens), dim=0)], dim=0) \ + .to(qkv.device).int() + out = flash_attn.flash_attn_varlen_qkvpacked_func(qkv_feats, cu_seqlens, max(seq_lens)) # [M, H, C] + + out = out[bwd_indices] # [T, H, C] + + if DEBUG: + qkv_coords = qkv_coords[bwd_indices] + assert torch.equal(qkv_coords, qkv.coords), "SparseWindowedScaledDotProductSelfAttention: coordinate mismatch" + + return qkv.replace(out) diff --git a/anigen/modules/sparse/attention/windowed_attn.py b/anigen/modules/sparse/attention/windowed_attn.py new file mode 100644 index 0000000000000000000000000000000000000000..cd642c5252e29a3a5e59fad7ed3880b7b00bcf9a --- /dev/null +++ b/anigen/modules/sparse/attention/windowed_attn.py @@ -0,0 +1,135 @@ +from typing import * +import torch +import math +from .. import SparseTensor +from .. import DEBUG, ATTN + +if ATTN == 'xformers': + import xformers.ops as xops +elif ATTN == 'flash_attn': + import flash_attn +else: + raise ValueError(f"Unknown attention module: {ATTN}") + + +__all__ = [ + 'sparse_windowed_scaled_dot_product_self_attention', +] + + +def calc_window_partition( + tensor: SparseTensor, + window_size: Union[int, Tuple[int, ...]], + shift_window: Union[int, Tuple[int, ...]] = 0 +) -> Tuple[torch.Tensor, torch.Tensor, List[int], List[int]]: + """ + Calculate serialization and partitioning for a set of coordinates. + + Args: + tensor (SparseTensor): The input tensor. + window_size (int): The window size to use. + shift_window (Tuple[int, ...]): The shift of serialized coordinates. + + Returns: + (torch.Tensor): Forwards indices. + (torch.Tensor): Backwards indices. + (List[int]): Sequence lengths. + (List[int]): Sequence batch indices. + """ + DIM = tensor.coords.shape[1] - 1 + shift_window = (shift_window,) * DIM if isinstance(shift_window, int) else shift_window + window_size = (window_size,) * DIM if isinstance(window_size, int) else window_size + shifted_coords = tensor.coords.clone().detach() + shifted_coords[:, 1:] += torch.tensor(shift_window, device=tensor.device, dtype=torch.int32).unsqueeze(0) + + MAX_COORDS = shifted_coords[:, 1:].max(dim=0).values.tolist() + NUM_WINDOWS = [math.ceil((mc + 1) / ws) for mc, ws in zip(MAX_COORDS, window_size)] + OFFSET = torch.cumprod(torch.tensor([1] + NUM_WINDOWS[::-1]), dim=0).tolist()[::-1] + + shifted_coords[:, 1:] //= torch.tensor(window_size, device=tensor.device, dtype=torch.int32).unsqueeze(0) + shifted_indices = (shifted_coords * torch.tensor(OFFSET, device=tensor.device, dtype=torch.int32).unsqueeze(0)).sum(dim=1) + fwd_indices = torch.argsort(shifted_indices) + bwd_indices = torch.empty_like(fwd_indices) + bwd_indices[fwd_indices] = torch.arange(fwd_indices.shape[0], device=tensor.device) + seq_lens = torch.bincount(shifted_indices) + seq_batch_indices = torch.arange(seq_lens.shape[0], device=tensor.device, dtype=torch.int32) // OFFSET[0] + mask = seq_lens != 0 + seq_lens = seq_lens[mask].tolist() + seq_batch_indices = seq_batch_indices[mask].tolist() + + return fwd_indices, bwd_indices, seq_lens, seq_batch_indices + + +def sparse_windowed_scaled_dot_product_self_attention( + qkv: SparseTensor, + window_size: int, + shift_window: Tuple[int, int, int] = (0, 0, 0) +) -> SparseTensor: + """ + Apply windowed scaled dot product self attention to a sparse tensor. + + Args: + qkv (SparseTensor): [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs. + window_size (int): The window size to use. + shift_window (Tuple[int, int, int]): The shift of serialized coordinates. + shift (int): The shift to use. + """ + assert len(qkv.shape) == 4 and qkv.shape[1] == 3, f"Invalid shape for qkv, got {qkv.shape}, expected [N, *, 3, H, C]" + + serialization_spatial_cache_name = f'window_partition_{window_size}_{shift_window}' + serialization_spatial_cache = qkv.get_spatial_cache(serialization_spatial_cache_name) + if serialization_spatial_cache is None: + fwd_indices, bwd_indices, seq_lens, seq_batch_indices = calc_window_partition(qkv, window_size, shift_window) + qkv.register_spatial_cache(serialization_spatial_cache_name, (fwd_indices, bwd_indices, seq_lens, seq_batch_indices)) + else: + fwd_indices, bwd_indices, seq_lens, seq_batch_indices = serialization_spatial_cache + + M = fwd_indices.shape[0] + T = qkv.feats.shape[0] + H = qkv.feats.shape[2] + C = qkv.feats.shape[3] + + qkv_feats = qkv.feats[fwd_indices] # [M, 3, H, C] + + if DEBUG: + start = 0 + qkv_coords = qkv.coords[fwd_indices] + for i in range(len(seq_lens)): + seq_coords = qkv_coords[start:start+seq_lens[i]] + assert (seq_coords[:, 0] == seq_batch_indices[i]).all(), f"SparseWindowedScaledDotProductSelfAttention: batch index mismatch" + assert (seq_coords[:, 1:].max(dim=0).values - seq_coords[:, 1:].min(dim=0).values < window_size).all(), \ + f"SparseWindowedScaledDotProductSelfAttention: window size exceeded" + start += seq_lens[i] + + if all([seq_len == window_size for seq_len in seq_lens]): + B = len(seq_lens) + N = window_size + qkv_feats = qkv_feats.reshape(B, N, 3, H, C) + if ATTN == 'xformers': + q, k, v = qkv_feats.unbind(dim=2) # [B, N, H, C] + out = xops.memory_efficient_attention(q, k, v) # [B, N, H, C] + elif ATTN == 'flash_attn': + out = flash_attn.flash_attn_qkvpacked_func(qkv_feats) # [B, N, H, C] + else: + raise ValueError(f"Unknown attention module: {ATTN}") + out = out.reshape(B * N, H, C) # [M, H, C] + else: + if ATTN == 'xformers': + q, k, v = qkv_feats.unbind(dim=1) # [M, H, C] + q = q.unsqueeze(0) # [1, M, H, C] + k = k.unsqueeze(0) # [1, M, H, C] + v = v.unsqueeze(0) # [1, M, H, C] + mask = xops.fmha.BlockDiagonalMask.from_seqlens(seq_lens) + out = xops.memory_efficient_attention(q, k, v, mask)[0] # [M, H, C] + elif ATTN == 'flash_attn': + cu_seqlens = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(seq_lens), dim=0)], dim=0) \ + .to(qkv.device).int() + out = flash_attn.flash_attn_varlen_qkvpacked_func(qkv_feats, cu_seqlens, max(seq_lens)) # [M, H, C] + + out = out[bwd_indices] # [T, H, C] + + if DEBUG: + qkv_coords = qkv_coords[bwd_indices] + assert torch.equal(qkv_coords, qkv.coords), "SparseWindowedScaledDotProductSelfAttention: coordinate mismatch" + + return qkv.replace(out) diff --git a/anigen/modules/sparse/attention/windowed_attn_cross.py b/anigen/modules/sparse/attention/windowed_attn_cross.py new file mode 100644 index 0000000000000000000000000000000000000000..30f56a8932bc91545f6e574c43452e14fb128e9c --- /dev/null +++ b/anigen/modules/sparse/attention/windowed_attn_cross.py @@ -0,0 +1,131 @@ +from typing import * +import torch +import math +from .. import SparseTensor +from .. import DEBUG, ATTN + +if ATTN == 'xformers': + import xformers.ops as xops +elif ATTN == 'flash_attn': + import flash_attn +else: + raise ValueError(f"Unknown attention module: {ATTN}") + + +__all__ = [ + 'sparse_windowed_scaled_dot_product_cross_attention', +] + + +def calc_window_partition_cross( + tensor: SparseTensor, + context: SparseTensor, + window_size: Union[int, Tuple[int, ...]], + shift_window: Union[int, Tuple[int, ...]] = 0 +) -> Tuple[torch.Tensor, torch.Tensor, List[int], List[int]]: + """ + Calculate serialization and partitioning for a set of coordinates. + + Args: + tensor (SparseTensor): The input tensor. + window_size (int): The window size to use. + shift_window (Tuple[int, ...]): The shift of serialized coordinates. + + Returns: + (torch.Tensor): Forwards indices. + (torch.Tensor): Backwards indices. + (List[int]): Sequence lengths. + (List[int]): Sequence batch indices. + """ + + def calc_window_partition_(tensor, window_size, shift_window): + DIM = tensor.coords.shape[1] - 1 + shift_window = (shift_window,) * DIM if isinstance(shift_window, int) else shift_window + window_size = (window_size,) * DIM if isinstance(window_size, int) else window_size + shifted_coords = tensor.coords.clone().detach() + shifted_coords[:, 1:] += torch.tensor(shift_window, device=tensor.device, dtype=torch.int32).unsqueeze(0) + + MAX_COORDS = shifted_coords[:, 1:].max(dim=0).values.tolist() + NUM_WINDOWS = [math.ceil((mc + 1) / ws) for mc, ws in zip(MAX_COORDS, window_size)] + OFFSET = torch.cumprod(torch.tensor([1] + NUM_WINDOWS[::-1]), dim=0).tolist()[::-1] + + shifted_coords[:, 1:] //= torch.tensor(window_size, device=tensor.device, dtype=torch.int32).unsqueeze(0) + shifted_indices = (shifted_coords * torch.tensor(OFFSET, device=tensor.device, dtype=torch.int32).unsqueeze(0)).sum(dim=1) + fwd_indices = torch.argsort(shifted_indices) + bwd_indices = torch.empty_like(fwd_indices) + bwd_indices[fwd_indices] = torch.arange(fwd_indices.shape[0], device=tensor.device) + seq_lens = torch.bincount(shifted_indices) + seq_batch_indices = torch.arange(seq_lens.shape[0], device=tensor.device, dtype=torch.int32) // OFFSET[0] + return fwd_indices, bwd_indices, seq_lens, seq_batch_indices + + fwd_indices, bwd_indices, seq_lens, seq_batch_indices = calc_window_partition_(tensor, window_size, shift_window) + fwd_indices_context, bwd_indices_context, seq_lens_context, seq_batch_indices_context = calc_window_partition_(context, window_size, shift_window) + # Pad the shorter one to the shape of the other with 0 tail + max_len = max(seq_lens.shape[0], seq_lens_context.shape[0]) + if seq_lens.shape[0] < max_len: + pad_size = max_len - seq_lens.shape[0] + seq_lens = torch.cat([seq_lens, torch.zeros(pad_size, dtype=seq_lens.dtype, device=seq_lens.device)]) + if seq_lens_context.shape[0] < max_len: + pad_size = max_len - seq_lens_context.shape[0] + seq_lens_context = torch.cat([seq_lens_context, torch.zeros(pad_size, dtype=seq_lens_context.dtype, device=seq_lens_context.device)]) + mask = (seq_lens != 0) | (seq_lens_context != 0) + seq_lens = seq_lens[mask].tolist() + seq_lens_context = seq_lens_context[mask].tolist() + + return fwd_indices, bwd_indices, seq_lens, fwd_indices_context, bwd_indices_context, seq_lens_context + + +def sparse_windowed_scaled_dot_product_cross_attention( + q: SparseTensor, + kv: SparseTensor, + window_size: int, + shift_window: Tuple[int, int, int] = (0, 0, 0), + cache_suffix: str = '', +) -> SparseTensor: + """ + Apply windowed scaled dot product cross attention to a sparse tensor. + + Args: + q, kv (SparseTensor): [N, *, 3, H, C] sparse tensor containing Qs, Ks, and Vs. + window_size (int): The window size to use. + shift_window (Tuple[int, int, int]): The shift of serialized coordinates. + shift (int): The shift to use. + """ + assert len(q.shape) == 4 and q.shape[1] == 1, f"Invalid shape for q, got {q.shape}, expected [N, *, 1, H, C]" + assert len(kv.shape) == 4 and kv.shape[1] == 2, f"Invalid shape for kv, got {kv.shape}, expected [N, *, 2, H, C]" + + serialization_spatial_cache_name_q = f'window_partition_{window_size}_{shift_window}_cross_q' + cache_suffix + serialization_spatial_cache_q = q.get_spatial_cache(serialization_spatial_cache_name_q) + serialization_spatial_cache_name_kv = f'window_partition_{window_size}_{shift_window}_cross_kv' + cache_suffix + serialization_spatial_cache_kv = kv.get_spatial_cache(serialization_spatial_cache_name_kv) + if serialization_spatial_cache_q is None or serialization_spatial_cache_kv is None: + q_fwd_indices, q_bwd_indices, q_seq_lens, kv_fwd_indices, kv_bwd_indices, kv_seq_lens = calc_window_partition_cross(q, kv, window_size, shift_window) + q.register_spatial_cache(serialization_spatial_cache_name_q, (q_fwd_indices, q_bwd_indices, q_seq_lens)) + kv.register_spatial_cache(serialization_spatial_cache_name_kv, (kv_fwd_indices, kv_bwd_indices, kv_seq_lens)) + else: + kv_fwd_indices, kv_bwd_indices, kv_seq_lens = serialization_spatial_cache_kv + q_fwd_indices, q_bwd_indices, q_seq_lens = serialization_spatial_cache_q + + M_q, T_q, H_q, C_q = q_fwd_indices.shape[0], q.feats.shape[0], q.feats.shape[2], q.feats.shape[3] + M_kv, T_kv, H_kv, C_kv = kv_fwd_indices.shape[0], kv.feats.shape[0], kv.feats.shape[2], kv.feats.shape[3] + assert (H_q == H_kv and C_q == C_kv), \ + f"Mismatch in shapes: q ({M_q}, {T_q}, {H_q}, {C_q}), kv ({M_kv}, {T_kv}, {H_kv}, {C_kv})" + + q_feats = q.feats[q_fwd_indices] # [M, 1, H, C] + kv_feats = kv.feats[kv_fwd_indices] # [M, 2, H, C] + + if ATTN == 'xformers': + q, k, v = q_feats[:, 0], kv_feats.unbind(dim=1) # [M, H, C] + q = q.unsqueeze(0) # [1, M, H, C] + k = k.unsqueeze(0) # [1, M, H, C] + v = v.unsqueeze(0) # [1, M, H, C] + mask = xops.fmha.BlockDiagonalMask.from_seqlens(q_seq_lens, kv_seq_lens) + out = xops.memory_efficient_attention(q, k, v, mask)[0] # [M, H, C] + elif ATTN == 'flash_attn': + cu_seqlens_q = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(q_seq_lens), dim=0)], dim=0).to(q.device).int() + cu_seqlens_k = torch.cat([torch.tensor([0]), torch.cumsum(torch.tensor(kv_seq_lens), dim=0)], dim=0).to(kv.device).int() + out = flash_attn.flash_attn_varlen_kvpacked_func(q_feats[:, 0], kv_feats, cu_seqlens_q, cu_seqlens_k, max(q_seq_lens), max(kv_seq_lens)) # [M, H, C] + + out = out[q_bwd_indices] # [T, H, C] + return q.replace(out) + diff --git a/anigen/modules/sparse/basic.py b/anigen/modules/sparse/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..e0f01c3c0661581fec1310a9d1d176a031904eef --- /dev/null +++ b/anigen/modules/sparse/basic.py @@ -0,0 +1,465 @@ +from typing import * +import torch +import torch.nn as nn +from . import BACKEND, DEBUG +SparseTensorData = None # Lazy import + +import importlib +if BACKEND == 'torchsparse': + SparseTensorData = importlib.import_module('torchsparse').SparseTensor +elif BACKEND == 'spconv': + SparseTensorData = importlib.import_module('spconv.pytorch').SparseConvTensor + + +__all__ = [ + 'SparseTensor', + 'sparse_batch_broadcast', + 'sparse_batch_op', + 'sparse_cat', + 'sparse_unbind', +] + + +class SparseTensor: + """ + Sparse tensor with support for both torchsparse and spconv backends. + + Parameters: + - feats (torch.Tensor): Features of the sparse tensor. + - coords (torch.Tensor): Coordinates of the sparse tensor. + - shape (torch.Size): Shape of the sparse tensor. + - layout (List[slice]): Layout of the sparse tensor for each batch + - data (SparseTensorData): Sparse tensor data used for convolusion + + NOTE: + - Data corresponding to a same batch should be contiguous. + - Coords should be in [0, 1023] + """ + @overload + def __init__(self, feats: torch.Tensor, coords: torch.Tensor, shape: Optional[torch.Size] = None, layout: Optional[List[slice]] = None, **kwargs): ... + + @overload + def __init__(self, data, shape: Optional[torch.Size] = None, layout: Optional[List[slice]] = None, **kwargs): ... + + def __init__(self, *args, **kwargs): + # Lazy import of sparse tensor backend + global SparseTensorData + if SparseTensorData is None: + import importlib + if BACKEND == 'torchsparse': + SparseTensorData = importlib.import_module('torchsparse').SparseTensor + elif BACKEND == 'spconv': + SparseTensorData = importlib.import_module('spconv.pytorch').SparseConvTensor + + method_id = 0 + if len(args) != 0: + method_id = 0 if isinstance(args[0], torch.Tensor) else 1 + else: + method_id = 1 if 'data' in kwargs else 0 + + if method_id == 0: + feats, coords, shape, layout = args + (None,) * (4 - len(args)) + if 'feats' in kwargs: + feats = kwargs['feats'] + del kwargs['feats'] + if 'coords' in kwargs: + coords = kwargs['coords'] + del kwargs['coords'] + if 'shape' in kwargs: + shape = kwargs['shape'] + del kwargs['shape'] + if 'layout' in kwargs: + layout = kwargs['layout'] + del kwargs['layout'] + + if shape is None: + shape = self.__cal_shape(feats, coords) + if layout is None: + layout = self.__cal_layout(coords, shape[0]) + if BACKEND == 'torchsparse': + self.data = SparseTensorData(feats, coords, **kwargs) + elif BACKEND == 'spconv': + spatial_shape = list(coords.max(0)[0] + 1)[1:] + self.data = SparseTensorData(feats.reshape(feats.shape[0], -1), coords, spatial_shape, shape[0], **kwargs) + self.data._features = feats + elif method_id == 1: + data, shape, layout = args + (None,) * (3 - len(args)) + if 'data' in kwargs: + data = kwargs['data'] + del kwargs['data'] + if 'shape' in kwargs: + shape = kwargs['shape'] + del kwargs['shape'] + if 'layout' in kwargs: + layout = kwargs['layout'] + del kwargs['layout'] + + self.data = data + if shape is None: + shape = self.__cal_shape(self.feats, self.coords) + if layout is None: + layout = self.__cal_layout(self.coords, shape[0]) + + self._shape = shape + self._layout = layout + self._scale = kwargs.get('scale', (1, 1, 1)) + self._spatial_cache = kwargs.get('spatial_cache', {}) + + if DEBUG: + try: + assert self.feats.shape[0] == self.coords.shape[0], f"Invalid feats shape: {self.feats.shape}, coords shape: {self.coords.shape}" + assert self.shape == self.__cal_shape(self.feats, self.coords), f"Invalid shape: {self.shape}" + assert self.layout == self.__cal_layout(self.coords, self.shape[0]), f"Invalid layout: {self.layout}" + for i in range(self.shape[0]): + assert torch.all(self.coords[self.layout[i], 0] == i), f"The data of batch {i} is not contiguous" + except Exception as e: + print('Debugging information:') + print(f"- Shape: {self.shape}") + print(f"- Layout: {self.layout}") + print(f"- Scale: {self._scale}") + print(f"- Coords: {self.coords}") + raise e + + def __cal_shape(self, feats, coords): + shape = [] + shape.append(coords[:, 0].max().item() + 1) + shape.extend([*feats.shape[1:]]) + return torch.Size(shape) + + def __cal_layout(self, coords, batch_size): + seq_len = torch.bincount(coords[:, 0], minlength=batch_size) + offset = torch.cumsum(seq_len, dim=0) + layout = [slice((offset[i] - seq_len[i]).item(), offset[i].item()) for i in range(batch_size)] + return layout + + @property + def shape(self) -> torch.Size: + return self._shape + + def dim(self) -> int: + return len(self.shape) + + @property + def layout(self) -> List[slice]: + return self._layout + + @property + def feats(self) -> torch.Tensor: + if BACKEND == 'torchsparse': + return self.data.F + elif BACKEND == 'spconv': + return self.data.features + + @feats.setter + def feats(self, value: torch.Tensor): + if BACKEND == 'torchsparse': + self.data.F = value + elif BACKEND == 'spconv': + self.data.features = value + + @property + def coords(self) -> torch.Tensor: + if BACKEND == 'torchsparse': + return self.data.C + elif BACKEND == 'spconv': + return self.data.indices + + @coords.setter + def coords(self, value: torch.Tensor): + if BACKEND == 'torchsparse': + self.data.C = value + elif BACKEND == 'spconv': + self.data.indices = value + + @property + def dtype(self): + return self.feats.dtype + + @property + def device(self): + return self.feats.device + + @overload + def to(self, dtype: torch.dtype) -> 'SparseTensor': ... + + @overload + def to(self, device: Optional[Union[str, torch.device]] = None, dtype: Optional[torch.dtype] = None) -> 'SparseTensor': ... + + def to(self, *args, **kwargs) -> 'SparseTensor': + device = None + dtype = None + if len(args) == 2: + device, dtype = args + elif len(args) == 1: + if isinstance(args[0], torch.dtype): + dtype = args[0] + else: + device = args[0] + if 'dtype' in kwargs: + assert dtype is None, "to() received multiple values for argument 'dtype'" + dtype = kwargs['dtype'] + if 'device' in kwargs: + assert device is None, "to() received multiple values for argument 'device'" + device = kwargs['device'] + + new_feats = self.feats.to(device=device, dtype=dtype) + new_coords = self.coords.to(device=device) + return self.replace(new_feats, new_coords) + + def type(self, dtype): + new_feats = self.feats.type(dtype) + return self.replace(new_feats) + + def cpu(self) -> 'SparseTensor': + new_feats = self.feats.cpu() + new_coords = self.coords.cpu() + return self.replace(new_feats, new_coords) + + def cuda(self) -> 'SparseTensor': + new_feats = self.feats.cuda() + new_coords = self.coords.cuda() + return self.replace(new_feats, new_coords) + + def half(self) -> 'SparseTensor': + new_feats = self.feats.half() + return self.replace(new_feats) + + def float(self) -> 'SparseTensor': + new_feats = self.feats.float() + return self.replace(new_feats) + + def detach(self) -> 'SparseTensor': + new_coords = self.coords.detach() + new_feats = self.feats.detach() + return self.replace(new_feats, new_coords) + + def dense(self) -> torch.Tensor: + if BACKEND == 'torchsparse': + return self.data.dense() + elif BACKEND == 'spconv': + return self.data.dense() + + def reshape(self, *shape) -> 'SparseTensor': + new_feats = self.feats.reshape(self.feats.shape[0], *shape) + return self.replace(new_feats) + + def unbind(self, dim: int) -> List['SparseTensor']: + return sparse_unbind(self, dim) + + def replace(self, feats: torch.Tensor, coords: Optional[torch.Tensor] = None) -> 'SparseTensor': + new_shape = [self.shape[0]] + new_shape.extend(feats.shape[1:]) + if BACKEND == 'torchsparse': + new_data = SparseTensorData( + feats=feats, + coords=self.data.coords if coords is None else coords, + stride=self.data.stride, + spatial_range=self.data.spatial_range, + ) + new_data._caches = self.data._caches + elif BACKEND == 'spconv': + new_data = SparseTensorData( + self.data.features.reshape(self.data.features.shape[0], -1), + self.data.indices, + self.data.spatial_shape, + self.data.batch_size, + self.data.grid, + self.data.voxel_num, + self.data.indice_dict + ) + new_data._features = feats + new_data.benchmark = self.data.benchmark + new_data.benchmark_record = self.data.benchmark_record + new_data.thrust_allocator = self.data.thrust_allocator + new_data._timer = self.data._timer + new_data.force_algo = self.data.force_algo + new_data.int8_scale = self.data.int8_scale + if coords is not None: + new_data.indices = coords + new_tensor = SparseTensor(new_data, shape=torch.Size(new_shape), layout=self.layout, scale=self._scale, spatial_cache=self._spatial_cache) + return new_tensor + + @staticmethod + def full(aabb, dim, value, dtype=torch.float32, device=None) -> 'SparseTensor': + N, C = dim + x = torch.arange(aabb[0], aabb[3] + 1) + y = torch.arange(aabb[1], aabb[4] + 1) + z = torch.arange(aabb[2], aabb[5] + 1) + coords = torch.stack(torch.meshgrid(x, y, z, indexing='ij'), dim=-1).reshape(-1, 3) + coords = torch.cat([ + torch.arange(N).view(-1, 1).repeat(1, coords.shape[0]).view(-1, 1), + coords.repeat(N, 1), + ], dim=1).to(dtype=torch.int32, device=device) + feats = torch.full((coords.shape[0], C), value, dtype=dtype, device=device) + return SparseTensor(feats=feats, coords=coords) + + def __merge_sparse_cache(self, other: 'SparseTensor') -> dict: + new_cache = {} + for k in set(list(self._spatial_cache.keys()) + list(other._spatial_cache.keys())): + if k in self._spatial_cache: + new_cache[k] = self._spatial_cache[k] + if k in other._spatial_cache: + if k not in new_cache: + new_cache[k] = other._spatial_cache[k] + else: + new_cache[k].update(other._spatial_cache[k]) + return new_cache + + def __neg__(self) -> 'SparseTensor': + return self.replace(-self.feats) + + def __elemwise__(self, other: Union[torch.Tensor, 'SparseTensor'], op: callable) -> 'SparseTensor': + if isinstance(other, torch.Tensor): + try: + other = torch.broadcast_to(other, self.shape) + other = sparse_batch_broadcast(self, other) + except: + pass + if isinstance(other, SparseTensor): + other = other.feats + new_feats = op(self.feats, other) + new_tensor = self.replace(new_feats) + if isinstance(other, SparseTensor): + new_tensor._spatial_cache = self.__merge_sparse_cache(other) + return new_tensor + + def __add__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.add) + + def __radd__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.add) + + def __sub__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.sub) + + def __rsub__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, lambda x, y: torch.sub(y, x)) + + def __mul__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.mul) + + def __rmul__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.mul) + + def __truediv__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, torch.div) + + def __rtruediv__(self, other: Union[torch.Tensor, 'SparseTensor', float]) -> 'SparseTensor': + return self.__elemwise__(other, lambda x, y: torch.div(y, x)) + + def __getitem__(self, idx): + if isinstance(idx, int): + idx = [idx] + elif isinstance(idx, slice): + idx = range(*idx.indices(self.shape[0])) + elif isinstance(idx, torch.Tensor): + if idx.dtype == torch.bool: + assert idx.shape == (self.shape[0],), f"Invalid index shape: {idx.shape}" + idx = idx.nonzero().squeeze(1) + elif idx.dtype in [torch.int32, torch.int64]: + assert len(idx.shape) == 1, f"Invalid index shape: {idx.shape}" + else: + raise ValueError(f"Unknown index type: {idx.dtype}") + else: + raise ValueError(f"Unknown index type: {type(idx)}") + + coords = [] + feats = [] + for new_idx, old_idx in enumerate(idx): + coords.append(self.coords[self.layout[old_idx]].clone()) + coords[-1][:, 0] = new_idx + feats.append(self.feats[self.layout[old_idx]]) + coords = torch.cat(coords, dim=0).contiguous() + feats = torch.cat(feats, dim=0).contiguous() + return SparseTensor(feats=feats, coords=coords) + + def register_spatial_cache(self, key, value) -> None: + """ + Register a spatial cache. + The spatial cache can be any thing you want to cache. + The registery and retrieval of the cache is based on current scale. + """ + scale_key = str(self._scale) + if scale_key not in self._spatial_cache: + self._spatial_cache[scale_key] = {} + self._spatial_cache[scale_key][key] = value + + def get_spatial_cache(self, key=None): + """ + Get a spatial cache. + """ + scale_key = str(self._scale) + cur_scale_cache = self._spatial_cache.get(scale_key, {}) + if key is None: + return cur_scale_cache + return cur_scale_cache.get(key, None) + + +def sparse_batch_broadcast(input: SparseTensor, other: torch.Tensor) -> torch.Tensor: + """ + Broadcast a 1D tensor to a sparse tensor along the batch dimension then perform an operation. + + Args: + input (torch.Tensor): 1D tensor to broadcast. + target (SparseTensor): Sparse tensor to broadcast to. + op (callable): Operation to perform after broadcasting. Defaults to torch.add. + """ + coords, feats = input.coords, input.feats + broadcasted = torch.zeros_like(feats) + for k in range(input.shape[0]): + broadcasted[input.layout[k]] = other[k] + return broadcasted + + +def sparse_batch_op(input: SparseTensor, other: torch.Tensor, op: callable = torch.add) -> SparseTensor: + """ + Broadcast a 1D tensor to a sparse tensor along the batch dimension then perform an operation. + + Args: + input (torch.Tensor): 1D tensor to broadcast. + target (SparseTensor): Sparse tensor to broadcast to. + op (callable): Operation to perform after broadcasting. Defaults to torch.add. + """ + return input.replace(op(input.feats, sparse_batch_broadcast(input, other))) + + +def sparse_cat(inputs: List[SparseTensor], dim: int = 0) -> SparseTensor: + """ + Concatenate a list of sparse tensors. + + Args: + inputs (List[SparseTensor]): List of sparse tensors to concatenate. + """ + if dim == 0: + start = 0 + coords = [] + for input in inputs: + coords.append(input.coords.clone()) + coords[-1][:, 0] += start + start += input.shape[0] + coords = torch.cat(coords, dim=0) + feats = torch.cat([input.feats for input in inputs], dim=0) + output = SparseTensor( + coords=coords, + feats=feats, + ) + else: + feats = torch.cat([input.feats for input in inputs], dim=dim) + output = inputs[0].replace(feats) + + return output + + +def sparse_unbind(input: SparseTensor, dim: int) -> List[SparseTensor]: + """ + Unbind a sparse tensor along a dimension. + + Args: + input (SparseTensor): Sparse tensor to unbind. + dim (int): Dimension to unbind. + """ + if dim == 0: + return [input[i] for i in range(input.shape[0])] + else: + feats = input.feats.unbind(dim) + return [input.replace(f) for f in feats] diff --git a/anigen/modules/sparse/conv/__init__.py b/anigen/modules/sparse/conv/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..340a87126a8de574ee0276feb96b49824a2ce234 --- /dev/null +++ b/anigen/modules/sparse/conv/__init__.py @@ -0,0 +1,21 @@ +from .. import BACKEND + + +SPCONV_ALGO = 'auto' # 'auto', 'implicit_gemm', 'native' + +def __from_env(): + import os + + global SPCONV_ALGO + env_spconv_algo = os.environ.get('SPCONV_ALGO') + if env_spconv_algo is not None and env_spconv_algo in ['auto', 'implicit_gemm', 'native']: + SPCONV_ALGO = env_spconv_algo + print(f"[SPARSE][CONV] spconv algo: {SPCONV_ALGO}") + + +__from_env() + +if BACKEND == 'torchsparse': + from .conv_torchsparse import * +elif BACKEND == 'spconv': + from .conv_spconv import * diff --git a/anigen/modules/sparse/conv/conv_spconv.py b/anigen/modules/sparse/conv/conv_spconv.py new file mode 100644 index 0000000000000000000000000000000000000000..524bcd4a845b2d6bd090a5f74bc8859978727528 --- /dev/null +++ b/anigen/modules/sparse/conv/conv_spconv.py @@ -0,0 +1,80 @@ +import torch +import torch.nn as nn +from .. import SparseTensor +from .. import DEBUG +from . import SPCONV_ALGO + +class SparseConv3d(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding=None, bias=True, indice_key=None): + super(SparseConv3d, self).__init__() + if 'spconv' not in globals(): + import spconv.pytorch as spconv + algo = None + if SPCONV_ALGO == 'native': + algo = spconv.ConvAlgo.Native + elif SPCONV_ALGO == 'implicit_gemm': + algo = spconv.ConvAlgo.MaskImplicitGemm + if stride == 1 and (padding is None): + self.conv = spconv.SubMConv3d(in_channels, out_channels, kernel_size, dilation=dilation, bias=bias, indice_key=indice_key, algo=algo) + else: + self.conv = spconv.SparseConv3d(in_channels, out_channels, kernel_size, stride=stride, dilation=dilation, padding=padding, bias=bias, indice_key=indice_key, algo=algo) + self.stride = tuple(stride) if isinstance(stride, (list, tuple)) else (stride, stride, stride) + self.padding = padding + + def forward(self, x: SparseTensor) -> SparseTensor: + spatial_changed = any(s != 1 for s in self.stride) or (self.padding is not None) + new_data = self.conv(x.data) + new_shape = [x.shape[0], self.conv.out_channels] + new_layout = None if spatial_changed else x.layout + + if spatial_changed and (x.shape[0] != 1): + # spconv was non-1 stride will break the contiguous of the output tensor, sort by the coords + fwd = new_data.indices[:, 0].argsort() + bwd = torch.zeros_like(fwd).scatter_(0, fwd, torch.arange(fwd.shape[0], device=fwd.device)) + sorted_feats = new_data.features[fwd] + sorted_coords = new_data.indices[fwd] + unsorted_data = new_data + new_data = spconv.SparseConvTensor(sorted_feats, sorted_coords, unsorted_data.spatial_shape, unsorted_data.batch_size) # type: ignore + + out = SparseTensor( + new_data, shape=torch.Size(new_shape), layout=new_layout, + scale=tuple([s * stride for s, stride in zip(x._scale, self.stride)]), + spatial_cache=x._spatial_cache, + ) + + if spatial_changed and (x.shape[0] != 1): + out.register_spatial_cache(f'conv_{self.stride}_unsorted_data', unsorted_data) + out.register_spatial_cache(f'conv_{self.stride}_sort_bwd', bwd) + + return out + + +class SparseInverseConv3d(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None): + super(SparseInverseConv3d, self).__init__() + if 'spconv' not in globals(): + import spconv.pytorch as spconv + self.conv = spconv.SparseInverseConv3d(in_channels, out_channels, kernel_size, bias=bias, indice_key=indice_key) + self.stride = tuple(stride) if isinstance(stride, (list, tuple)) else (stride, stride, stride) + + def forward(self, x: SparseTensor) -> SparseTensor: + spatial_changed = any(s != 1 for s in self.stride) + if spatial_changed: + # recover the original spconv order + data = x.get_spatial_cache(f'conv_{self.stride}_unsorted_data') + bwd = x.get_spatial_cache(f'conv_{self.stride}_sort_bwd') + data = data.replace_feature(x.feats[bwd]) + if DEBUG: + assert torch.equal(data.indices, x.coords[bwd]), 'Recover the original order failed' + else: + data = x.data + + new_data = self.conv(data) + new_shape = [x.shape[0], self.conv.out_channels] + new_layout = None if spatial_changed else x.layout + out = SparseTensor( + new_data, shape=torch.Size(new_shape), layout=new_layout, + scale=tuple([s // stride for s, stride in zip(x._scale, self.stride)]), + spatial_cache=x._spatial_cache, + ) + return out diff --git a/anigen/modules/sparse/conv/conv_torchsparse.py b/anigen/modules/sparse/conv/conv_torchsparse.py new file mode 100644 index 0000000000000000000000000000000000000000..1d612582d4b31f90aca3c00b693bbbc2550dc62c --- /dev/null +++ b/anigen/modules/sparse/conv/conv_torchsparse.py @@ -0,0 +1,38 @@ +import torch +import torch.nn as nn +from .. import SparseTensor + + +class SparseConv3d(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None): + super(SparseConv3d, self).__init__() + if 'torchsparse' not in globals(): + import torchsparse + self.conv = torchsparse.nn.Conv3d(in_channels, out_channels, kernel_size, stride, 0, dilation, bias) + + def forward(self, x: SparseTensor) -> SparseTensor: + out = self.conv(x.data) + new_shape = [x.shape[0], self.conv.out_channels] + out = SparseTensor(out, shape=torch.Size(new_shape), layout=x.layout if all(s == 1 for s in self.conv.stride) else None) + out._spatial_cache = x._spatial_cache + out._scale = tuple([s * stride for s, stride in zip(x._scale, self.conv.stride)]) + return out + + +class SparseInverseConv3d(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, bias=True, indice_key=None): + super(SparseInverseConv3d, self).__init__() + if 'torchsparse' not in globals(): + import torchsparse + self.conv = torchsparse.nn.Conv3d(in_channels, out_channels, kernel_size, stride, 0, dilation, bias, transposed=True) + + def forward(self, x: SparseTensor) -> SparseTensor: + out = self.conv(x.data) + new_shape = [x.shape[0], self.conv.out_channels] + out = SparseTensor(out, shape=torch.Size(new_shape), layout=x.layout if all(s == 1 for s in self.conv.stride) else None) + out._spatial_cache = x._spatial_cache + out._scale = tuple([s // stride for s, stride in zip(x._scale, self.conv.stride)]) + return out + + + diff --git a/anigen/modules/sparse/linear.py b/anigen/modules/sparse/linear.py new file mode 100644 index 0000000000000000000000000000000000000000..a854e77ce87d1a190b9730d91f363a821ff250bd --- /dev/null +++ b/anigen/modules/sparse/linear.py @@ -0,0 +1,15 @@ +import torch +import torch.nn as nn +from . import SparseTensor + +__all__ = [ + 'SparseLinear' +] + + +class SparseLinear(nn.Linear): + def __init__(self, in_features, out_features, bias=True): + super(SparseLinear, self).__init__(in_features, out_features, bias) + + def forward(self, input: SparseTensor) -> SparseTensor: + return input.replace(super().forward(input.feats)) diff --git a/anigen/modules/sparse/nonlinearity.py b/anigen/modules/sparse/nonlinearity.py new file mode 100644 index 0000000000000000000000000000000000000000..f200098dd82011a3aeee1688b9eb17018fa78295 --- /dev/null +++ b/anigen/modules/sparse/nonlinearity.py @@ -0,0 +1,35 @@ +import torch +import torch.nn as nn +from . import SparseTensor + +__all__ = [ + 'SparseReLU', + 'SparseSiLU', + 'SparseGELU', + 'SparseActivation' +] + + +class SparseReLU(nn.ReLU): + def forward(self, input: SparseTensor) -> SparseTensor: + return input.replace(super().forward(input.feats)) + + +class SparseSiLU(nn.SiLU): + def forward(self, input: SparseTensor) -> SparseTensor: + return input.replace(super().forward(input.feats)) + + +class SparseGELU(nn.GELU): + def forward(self, input: SparseTensor) -> SparseTensor: + return input.replace(super().forward(input.feats)) + + +class SparseActivation(nn.Module): + def __init__(self, activation: nn.Module): + super().__init__() + self.activation = activation + + def forward(self, input: SparseTensor) -> SparseTensor: + return input.replace(self.activation(input.feats)) + diff --git a/anigen/modules/sparse/norm.py b/anigen/modules/sparse/norm.py new file mode 100644 index 0000000000000000000000000000000000000000..6b38a36682c098210000dc31d68ddc31ccd2929d --- /dev/null +++ b/anigen/modules/sparse/norm.py @@ -0,0 +1,58 @@ +import torch +import torch.nn as nn +from . import SparseTensor +from . import DEBUG + +__all__ = [ + 'SparseGroupNorm', + 'SparseLayerNorm', + 'SparseGroupNorm32', + 'SparseLayerNorm32', +] + + +class SparseGroupNorm(nn.GroupNorm): + def __init__(self, num_groups, num_channels, eps=1e-5, affine=True): + super(SparseGroupNorm, self).__init__(num_groups, num_channels, eps, affine) + + def forward(self, input: SparseTensor) -> SparseTensor: + nfeats = torch.zeros_like(input.feats) + for k in range(input.shape[0]): + if DEBUG: + assert (input.coords[input.layout[k], 0] == k).all(), f"SparseGroupNorm: batch index mismatch" + bfeats = input.feats[input.layout[k]] + bfeats = bfeats.permute(1, 0).reshape(1, input.shape[1], -1) + bfeats = super().forward(bfeats) + bfeats = bfeats.reshape(input.shape[1], -1).permute(1, 0) + nfeats[input.layout[k]] = bfeats + return input.replace(nfeats) + + +class SparseLayerNorm(nn.LayerNorm): + def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True): + super(SparseLayerNorm, self).__init__(normalized_shape, eps, elementwise_affine) + + def forward(self, input: SparseTensor) -> SparseTensor: + nfeats = torch.zeros_like(input.feats) + for k in range(input.shape[0]): + bfeats = input.feats[input.layout[k]] + bfeats = bfeats.permute(1, 0).reshape(1, input.shape[1], -1) + bfeats = super().forward(bfeats) + bfeats = bfeats.reshape(input.shape[1], -1).permute(1, 0) + nfeats[input.layout[k]] = bfeats + return input.replace(nfeats) + + +class SparseGroupNorm32(SparseGroupNorm): + """ + A GroupNorm layer that converts to float32 before the forward pass. + """ + def forward(self, x: SparseTensor) -> SparseTensor: + return super().forward(x.float()).type(x.dtype) + +class SparseLayerNorm32(SparseLayerNorm): + """ + A LayerNorm layer that converts to float32 before the forward pass. + """ + def forward(self, x: SparseTensor) -> SparseTensor: + return super().forward(x.float()).type(x.dtype) diff --git a/anigen/modules/sparse/spatial.py b/anigen/modules/sparse/spatial.py new file mode 100644 index 0000000000000000000000000000000000000000..ad7121473f335b307e2f7ea5f05c964d3aec0440 --- /dev/null +++ b/anigen/modules/sparse/spatial.py @@ -0,0 +1,110 @@ +from typing import * +import torch +import torch.nn as nn +from . import SparseTensor + +__all__ = [ + 'SparseDownsample', + 'SparseUpsample', + 'SparseSubdivide' +] + + +class SparseDownsample(nn.Module): + """ + Downsample a sparse tensor by a factor of `factor`. + Implemented as average pooling. + """ + def __init__(self, factor: Union[int, Tuple[int, ...], List[int]]): + super(SparseDownsample, self).__init__() + self.factor = tuple(factor) if isinstance(factor, (list, tuple)) else factor + + def forward(self, input: SparseTensor) -> SparseTensor: + DIM = input.coords.shape[-1] - 1 + factor = self.factor if isinstance(self.factor, tuple) else (self.factor,) * DIM + assert DIM == len(factor), 'Input coordinates must have the same dimension as the downsample factor.' + + coord = list(input.coords.unbind(dim=-1)) + for i, f in enumerate(factor): + coord[i+1] = coord[i+1] // f + + MAX = [coord[i+1].max().item() + 1 for i in range(DIM)] + OFFSET = torch.cumprod(torch.tensor(MAX[::-1]), 0).tolist()[::-1] + [1] + code = sum([c * o for c, o in zip(coord, OFFSET)]) + code, idx = code.unique(return_inverse=True) + + new_feats = torch.scatter_reduce( + torch.zeros(code.shape[0], input.feats.shape[1], device=input.feats.device, dtype=input.feats.dtype), + dim=0, + index=idx.unsqueeze(1).expand(-1, input.feats.shape[1]), + src=input.feats, + reduce='mean' + ) + new_coords = torch.stack( + [code // OFFSET[0]] + + [(code // OFFSET[i+1]) % MAX[i] for i in range(DIM)], + dim=-1 + ) + out = SparseTensor(new_feats, new_coords, input.shape,) + out._scale = tuple([s // f for s, f in zip(input._scale, factor)]) + out._spatial_cache = input._spatial_cache + + out.register_spatial_cache(f'upsample_{factor}_coords', input.coords) + out.register_spatial_cache(f'upsample_{factor}_layout', input.layout) + out.register_spatial_cache(f'upsample_{factor}_idx', idx) + + return out + + +class SparseUpsample(nn.Module): + """ + Upsample a sparse tensor by a factor of `factor`. + Implemented as nearest neighbor interpolation. + """ + def __init__(self, factor: Union[int, Tuple[int, int, int], List[int]]): + super(SparseUpsample, self).__init__() + self.factor = tuple(factor) if isinstance(factor, (list, tuple)) else factor + + def forward(self, input: SparseTensor) -> SparseTensor: + DIM = input.coords.shape[-1] - 1 + factor = self.factor if isinstance(self.factor, tuple) else (self.factor,) * DIM + assert DIM == len(factor), 'Input coordinates must have the same dimension as the upsample factor.' + + new_coords = input.get_spatial_cache(f'upsample_{factor}_coords') + new_layout = input.get_spatial_cache(f'upsample_{factor}_layout') + idx = input.get_spatial_cache(f'upsample_{factor}_idx') + if any([x is None for x in [new_coords, new_layout, idx]]): + raise ValueError('Upsample cache not found. SparseUpsample must be paired with SparseDownsample.') + new_feats = input.feats[idx] + out = SparseTensor(new_feats, new_coords, input.shape, new_layout) + out._scale = tuple([s * f for s, f in zip(input._scale, factor)]) + out._spatial_cache = input._spatial_cache + return out + +class SparseSubdivide(nn.Module): + """ + Upsample a sparse tensor by a factor of `factor`. + Implemented as nearest neighbor interpolation. + """ + def __init__(self): + super(SparseSubdivide, self).__init__() + + def forward(self, input: SparseTensor) -> SparseTensor: + DIM = input.coords.shape[-1] - 1 + # upsample scale=2^DIM + n_cube = torch.ones([2] * DIM, device=input.device, dtype=torch.int) + n_coords = torch.nonzero(n_cube) + n_coords = torch.cat([torch.zeros_like(n_coords[:, :1]), n_coords], dim=-1) + factor = n_coords.shape[0] + assert factor == 2 ** DIM + # print(n_coords.shape) + new_coords = input.coords.clone() + new_coords[:, 1:] *= 2 + new_coords = new_coords.unsqueeze(1) + n_coords.unsqueeze(0).to(new_coords.dtype) + + new_feats = input.feats.unsqueeze(1).expand(input.feats.shape[0], factor, *input.feats.shape[1:]) + out = SparseTensor(new_feats.flatten(0, 1), new_coords.flatten(0, 1), input.shape) + out._scale = input._scale * 2 + out._spatial_cache = input._spatial_cache + return out + diff --git a/anigen/modules/sparse/transformer/__init__.py b/anigen/modules/sparse/transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b792df201123792b8c60bac7260e99e5b9d8bfca --- /dev/null +++ b/anigen/modules/sparse/transformer/__init__.py @@ -0,0 +1,3 @@ +from .blocks import * +from .modulated import * +from .anigen_modulated import * \ No newline at end of file diff --git a/anigen/modules/sparse/transformer/anigen_modulated.py b/anigen/modules/sparse/transformer/anigen_modulated.py new file mode 100644 index 0000000000000000000000000000000000000000..991cb68f87d4a25ba57b1245367993a1e8c9abee --- /dev/null +++ b/anigen/modules/sparse/transformer/anigen_modulated.py @@ -0,0 +1,155 @@ +from typing import * +import torch +import torch.nn as nn +from ..basic import SparseTensor +from ..attention import SparseMultiHeadAttention, SerializeMode +from ...norm import LayerNorm32 +from .blocks import SparseFeedForwardNet + + +class AniGenModulatedSparseTransformerCrossBlock(nn.Module): + """ + AniGen Sparse Transformer cross-attention block (MSA + MCA + FFN) with adaptive layer norm conditioning. + """ + def __init__( + self, + channels: int, + channels_skl: int, + ctx_channels: int, + num_heads: int, + num_heads_skl: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + share_mod: bool = False, + + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm1_skl = LayerNorm32(channels_skl, elementwise_affine=False, eps=1e-6) + self.norm2_skl = LayerNorm32(channels_skl, elementwise_affine=True, eps=1e-6) + self.norm3_skl = LayerNorm32(channels_skl, elementwise_affine=False, eps=1e-6) + self.attn = SparseMultiHeadAttention( + channels, + ctx_channels=channels_skl, + num_heads=num_heads, + type="cross", + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.attn_skl = SparseMultiHeadAttention( + channels_skl, + ctx_channels=channels, + num_heads=num_heads_skl, + type="cross", + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.context_cross_attn = SparseMultiHeadAttention( + channels, + ctx_channels=ctx_channels, + num_heads=num_heads, + type="cross", + attn_mode="full", + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + ) + self.context_cross_attn_skl = SparseMultiHeadAttention( + channels_skl, + ctx_channels=ctx_channels, + num_heads=num_heads_skl, + type="cross", + attn_mode="full", + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + ) + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + self.mlp_skl = SparseFeedForwardNet( + channels_skl, + mlp_ratio=mlp_ratio, + ) + if not share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(channels, 6 * channels, bias=True) + ) + self.adaLN_modulation_skl = nn.Sequential( + nn.SiLU(), + nn.Linear(channels_skl, 6 * channels_skl, bias=True) + ) + + def _forward(self, x: SparseTensor, x_skl: SparseTensor, mod: torch.Tensor, mod_skl: torch.Tensor, context: torch.Tensor) -> SparseTensor: + if self.share_mod: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1) + shift_msa_skl, scale_msa_skl, gate_msa_skl, shift_mlp_skl, scale_mlp_skl, gate_mlp_skl = mod_skl.chunk(6, dim=1) + else: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1) + shift_msa_skl, scale_msa_skl, gate_msa_skl, shift_mlp_skl, scale_mlp_skl, gate_mlp_skl = self.adaLN_modulation_skl(mod_skl).chunk(6, dim=1) + # Input Norm + h = x.replace(self.norm1(x.feats)) + h_skl = x_skl.replace(self.norm1_skl(x_skl.feats)) + # AdaLN (By Time Step) + h = h * (1 + scale_msa) + shift_msa + h_skl = h_skl * (1 + scale_msa_skl) + shift_msa_skl + # Self Attn (Cross shape and skeleton) + h = self.attn(h, h_skl) + h_skl = self.attn_skl(h_skl, h) + # Gated Residual (By Time Step) + h = h * gate_msa + h_skl = h_skl * gate_msa_skl + x = x + h + x_skl = x_skl + h_skl + # Context Cross Attention + h = x.replace(self.norm2(x.feats)) + h_skl = x_skl.replace(self.norm2_skl(x_skl.feats)) + h = self.context_cross_attn(h, context) + h_skl = self.context_cross_attn_skl(h_skl, context) + x = x + h + x_skl = x_skl + h_skl + # Re-Centered + h = x.replace(self.norm3(x.feats)) + h_skl = x_skl.replace(self.norm3_skl(x_skl.feats)) + h = h * (1 + scale_mlp) + shift_mlp + h_skl = h_skl * (1 + scale_mlp_skl) + shift_mlp_skl + # Output MLP + h = self.mlp(h) + h_skl = self.mlp_skl(h_skl) + # Gated Residual (By Time Step) + h = h * gate_mlp + h_skl = h_skl * gate_mlp_skl + x = x + h + x_skl = x_skl + h_skl + return x, x_skl + + def forward(self, x: SparseTensor, x_skl: SparseTensor, mod: torch.Tensor, mod_skl: torch.Tensor, context: torch.Tensor) -> SparseTensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, x_skl, mod, mod_skl, context, use_reentrant=False) + else: + return self._forward(x, x_skl, mod, mod_skl, context) diff --git a/anigen/modules/sparse/transformer/blocks.py b/anigen/modules/sparse/transformer/blocks.py new file mode 100644 index 0000000000000000000000000000000000000000..14e13f4536255a51879a1f64ca359ce0f03ecdad --- /dev/null +++ b/anigen/modules/sparse/transformer/blocks.py @@ -0,0 +1,259 @@ +from typing import * +import torch +import torch.nn as nn +from ..basic import SparseTensor +from ..linear import SparseLinear +from ..nonlinearity import SparseGELU +from ..attention import SparseMultiHeadAttention, SerializeMode +from ...norm import LayerNorm32 + + +class SparseFeedForwardNet(nn.Module): + def __init__(self, channels: int, mlp_ratio: float = 4.0): + super().__init__() + self.mlp = nn.Sequential( + SparseLinear(channels, int(channels * mlp_ratio)), + SparseGELU(approximate="tanh"), + SparseLinear(int(channels * mlp_ratio), channels), + ) + + def forward(self, x: SparseTensor) -> SparseTensor: + return self.mlp(x) + + +class SparseTransformerBlock(nn.Module): + """ + Sparse Transformer block (MSA + FFN). + """ + def __init__( + self, + channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.attn = SparseMultiHeadAttention( + channels, + num_heads=num_heads, + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + + def _forward(self, x: SparseTensor) -> SparseTensor: + # Self-attention + h = x.replace(self.norm1(x.feats)) + h = self.attn(h) + x = x + h + # Feed-forward network + h = x.replace(self.norm2(x.feats)) + h = self.mlp(h) + x = x + h + return x + + def forward(self, x: SparseTensor) -> SparseTensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, use_reentrant=False) + else: + return self._forward(x) + + +class SparseTransformerCrossBlock(nn.Module): + """ + Sparse Transformer cross-attention block (MSA + MCA + FFN). + """ + def __init__( + self, + channels: int, + ctx_channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "serialized", "windowed"] = "full", + attn_mode_cross: Literal["full", "serialized", "windowed"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + context_is_dual: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.context_is_dual = context_is_dual + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + if context_is_dual: + self.norm4 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.self_attn = SparseMultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.cross_attn = SparseMultiHeadAttention( + channels, + ctx_channels=ctx_channels, + num_heads=num_heads, + type="cross", + attn_mode=attn_mode_cross, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + ) + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + + def _forward(self, x: SparseTensor, context: SparseTensor): + # Self-attention + h = x.replace(self.norm1(x.feats)) + h = self.self_attn(h) + x = x + h + # Cross-attention + h = x.replace(self.norm2(x.feats)) + if self.context_is_dual: + context = context.replace(self.norm4(context.feats)) + h = self.cross_attn(h, context) + x = x + h + # Feed-forward network + h = x.replace(self.norm3(x.feats)) + h = self.mlp(h) + x = x + h + return x + + def forward(self, x: SparseTensor, context: SparseTensor): + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, context, use_reentrant=False) + else: + return self._forward(x, context) + + +class SparseTransformerMultiContextCrossBlock(nn.Module): + """ + Sparse Transformer cross-attention block (MSA + MCA + FFN). + """ + def __init__( + self, + channels: int, + ctx_channels: List[int], + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "serialized", "windowed"] = "full", + attn_mode_cross: Literal["full", "serialized", "windowed"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + cross_attn_cache_suffix: str = '', + ): + super().__init__() + self.context_num = len(ctx_channels) + self.use_checkpoint = use_checkpoint + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + if self.context_num > 0: + self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + + self.self_attn = SparseMultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + for i in range(self.context_num): + setattr(self, f'cross_attn_{i}', SparseMultiHeadAttention( + channels, + ctx_channels=ctx_channels[i], + num_heads=num_heads, + type="cross", + attn_mode=attn_mode_cross, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + cross_attn_cache_suffix=cross_attn_cache_suffix + f'_modality_{i}' + )) + setattr(self, f'ctx_norm_{i}', LayerNorm32(ctx_channels[i], elementwise_affine=True, eps=1e-6)) + + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + + def _forward(self, x: SparseTensor, contexts: List[SparseTensor]) -> SparseTensor: + # Self-attention + h = x.replace(self.norm1(x.feats)) + h = self.self_attn(h) + x = x + h + # Cross-attention + if self.context_num > 0 and len(contexts) > 0: + h_norm = x.replace(self.norm2(x.feats)) + for i, context in enumerate(contexts): + context = context.replace(getattr(self, f'ctx_norm_{i}')(context.feats)) + h = getattr(self, f'cross_attn_{i}')(h_norm, context) + x = x + h + # Feed-forward network + h = x.replace(self.norm3(x.feats)) + h = self.mlp(h) + x = x + h + return x + + def forward(self, x: SparseTensor, contexts: List[SparseTensor]) -> SparseTensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, contexts, use_reentrant=False) + else: + return self._forward(x, contexts) diff --git a/anigen/modules/sparse/transformer/modulated.py b/anigen/modules/sparse/transformer/modulated.py new file mode 100644 index 0000000000000000000000000000000000000000..0e9d1b2bc5c85a101ce09604671d98755a710c27 --- /dev/null +++ b/anigen/modules/sparse/transformer/modulated.py @@ -0,0 +1,174 @@ +from typing import * +import torch +import torch.nn as nn +from ..basic import SparseTensor +from ..attention import SparseMultiHeadAttention, SerializeMode +from ...norm import LayerNorm32 +from .blocks import SparseFeedForwardNet + + +class ModulatedSparseTransformerBlock(nn.Module): + """ + Sparse Transformer block (MSA + FFN) with adaptive layer norm conditioning. + """ + def __init__( + self, + channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qkv_bias: bool = True, + share_mod: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.attn = SparseMultiHeadAttention( + channels, + num_heads=num_heads, + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + if not share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(channels, 6 * channels, bias=True) + ) + + def _forward(self, x: SparseTensor, mod: torch.Tensor) -> SparseTensor: + if self.share_mod: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1) + else: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1) + h = x.replace(self.norm1(x.feats)) + h = h * (1 + scale_msa) + shift_msa + h = self.attn(h) + h = h * gate_msa + x = x + h + h = x.replace(self.norm2(x.feats)) + h = h * (1 + scale_mlp) + shift_mlp + h = self.mlp(h) + h = h * gate_mlp + x = x + h + return x + + def forward(self, x: SparseTensor, mod: torch.Tensor) -> SparseTensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, mod, use_reentrant=False) + else: + return self._forward(x, mod) + + +class ModulatedSparseTransformerCrossBlock(nn.Module): + """ + Sparse Transformer cross-attention block (MSA + MCA + FFN) with adaptive layer norm conditioning. + """ + def __init__( + self, + channels: int, + ctx_channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "shift_window", "shift_sequence", "shift_order", "swin"] = "full", + window_size: Optional[int] = None, + shift_sequence: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + serialize_mode: Optional[SerializeMode] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + share_mod: bool = False, + norm_for_context: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm_for_context = norm_for_context + if self.norm_for_context: + self.context_norm = LayerNorm32(ctx_channels, elementwise_affine=True, eps=1e-6) + self.self_attn = SparseMultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode=attn_mode, + window_size=window_size, + shift_sequence=shift_sequence, + shift_window=shift_window, + serialize_mode=serialize_mode, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.cross_attn = SparseMultiHeadAttention( + channels, + ctx_channels=ctx_channels, + num_heads=num_heads, + type="cross", + attn_mode="full", + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + ) + self.mlp = SparseFeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + if not share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(channels, 6 * channels, bias=True) + ) + + def _forward(self, x: SparseTensor, mod: torch.Tensor, context: torch.Tensor) -> SparseTensor: + if self.share_mod: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1) + else: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1) + h = x.replace(self.norm1(x.feats)) + h = h * (1 + scale_msa) + shift_msa + h = self.self_attn(h) + h = h * gate_msa + x = x + h + h = x.replace(self.norm2(x.feats)) + if self.norm_for_context: + if isinstance(context, SparseTensor): + context = context.replace(self.context_norm(context.feats)) + else: + context = self.context_norm(context) + h = self.cross_attn(h, context) + x = x + h + h = x.replace(self.norm3(x.feats)) + h = h * (1 + scale_mlp) + shift_mlp + h = self.mlp(h) + h = h * gate_mlp + x = x + h + return x + + def forward(self, x: SparseTensor, mod: torch.Tensor, context: torch.Tensor) -> SparseTensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, mod, context, use_reentrant=False) + else: + return self._forward(x, mod, context) diff --git a/anigen/modules/spatial.py b/anigen/modules/spatial.py new file mode 100644 index 0000000000000000000000000000000000000000..79e268d36c2ba49b0275744022a1a1e19983dae3 --- /dev/null +++ b/anigen/modules/spatial.py @@ -0,0 +1,48 @@ +import torch + + +def pixel_shuffle_3d(x: torch.Tensor, scale_factor: int) -> torch.Tensor: + """ + 3D pixel shuffle. + """ + B, C, H, W, D = x.shape + C_ = C // scale_factor**3 + x = x.reshape(B, C_, scale_factor, scale_factor, scale_factor, H, W, D) + x = x.permute(0, 1, 5, 2, 6, 3, 7, 4) + x = x.reshape(B, C_, H*scale_factor, W*scale_factor, D*scale_factor) + return x + + +def patchify(x: torch.Tensor, patch_size: int): + """ + Patchify a tensor. + + Args: + x (torch.Tensor): (N, C, *spatial) tensor + patch_size (int): Patch size + """ + DIM = x.dim() - 2 + for d in range(2, DIM + 2): + assert x.shape[d] % patch_size == 0, f"Dimension {d} of input tensor must be divisible by patch size, got {x.shape[d]} and {patch_size}" + + x = x.reshape(*x.shape[:2], *sum([[x.shape[d] // patch_size, patch_size] for d in range(2, DIM + 2)], [])) + x = x.permute(0, 1, *([2 * i + 3 for i in range(DIM)] + [2 * i + 2 for i in range(DIM)])) + x = x.reshape(x.shape[0], x.shape[1] * (patch_size ** DIM), *(x.shape[-DIM:])) + return x + + +def unpatchify(x: torch.Tensor, patch_size: int): + """ + Unpatchify a tensor. + + Args: + x (torch.Tensor): (N, C, *spatial) tensor + patch_size (int): Patch size + """ + DIM = x.dim() - 2 + assert x.shape[1] % (patch_size ** DIM) == 0, f"Second dimension of input tensor must be divisible by patch size to unpatchify, got {x.shape[1]} and {patch_size ** DIM}" + + x = x.reshape(x.shape[0], x.shape[1] // (patch_size ** DIM), *([patch_size] * DIM), *(x.shape[-DIM:])) + x = x.permute(0, 1, *(sum([[2 + DIM + i, 2 + i] for i in range(DIM)], []))) + x = x.reshape(x.shape[0], x.shape[1], *[x.shape[2 + 2 * i] * patch_size for i in range(DIM)]) + return x diff --git a/anigen/modules/transformer/__init__.py b/anigen/modules/transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b08b0d4e5bc24060a2cdc8df75d06dce122972bd --- /dev/null +++ b/anigen/modules/transformer/__init__.py @@ -0,0 +1,2 @@ +from .blocks import * +from .modulated import * \ No newline at end of file diff --git a/anigen/modules/transformer/blocks.py b/anigen/modules/transformer/blocks.py new file mode 100644 index 0000000000000000000000000000000000000000..79afa37a8c1331452eaf816a427564f06bd0365a --- /dev/null +++ b/anigen/modules/transformer/blocks.py @@ -0,0 +1,285 @@ +from typing import * +import torch +import torch.nn as nn +from ..attention import MultiHeadAttention +from ..norm import LayerNorm32 + + +class AbsolutePositionEmbedder(nn.Module): + """ + Embeds spatial positions into vector representations. + """ + def __init__(self, channels: int, in_channels: int = 3): + super().__init__() + self.channels = channels + self.in_channels = in_channels + self.freq_dim = channels // in_channels // 2 + self.freqs = torch.arange(self.freq_dim, dtype=torch.float32) / self.freq_dim + self.freqs = 1.0 / (10000 ** self.freqs) + + def _sin_cos_embedding(self, x: torch.Tensor) -> torch.Tensor: + """ + Create sinusoidal position embeddings. + + Args: + x: a 1-D Tensor of N indices + + Returns: + an (N, D) Tensor of positional embeddings. + """ + self.freqs = self.freqs.to(x.device) + out = torch.outer(x, self.freqs) + out = torch.cat([torch.sin(out), torch.cos(out)], dim=-1) + return out + + def forward(self, x: torch.Tensor) -> torch.Tensor: + """ + Args: + x (torch.Tensor): (N, D) tensor of spatial positions + """ + N, D = x.shape + assert D == self.in_channels, "Input dimension must match number of input channels" + embed = self._sin_cos_embedding(x.reshape(-1)) + embed = embed.reshape(N, -1) + if embed.shape[1] < self.channels: + embed = torch.cat([embed, torch.zeros(N, self.channels - embed.shape[1], device=embed.device)], dim=-1) + return embed + + +class FeedForwardNet(nn.Module): + def __init__(self, channels: int, mlp_ratio: float = 4.0, out_channels: Optional[int] = None): + super().__init__() + if out_channels is None: + out_channels = channels + self.mlp = nn.Sequential( + nn.Linear(channels, int(channels * mlp_ratio)), + nn.GELU(approximate="tanh"), + nn.Linear(int(channels * mlp_ratio), out_channels), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.mlp(x) + + +class TransformerBlock(nn.Module): + """ + Transformer block (MSA + FFN). + """ + def __init__( + self, + channels: int, + num_heads: int, + out_channels: Optional[int] = None, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "windowed"] = "full", + window_size: Optional[int] = None, + shift_window: Optional[int] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.attn = MultiHeadAttention( + channels, + num_heads=num_heads, + attn_mode=attn_mode, + window_size=window_size, + shift_window=shift_window, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.channels = channels + self.out_channels = out_channels if out_channels is not None else channels + self.mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=mlp_ratio, + ) + if self.out_channels != self.channels: + self.res_mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=1.0, + ) + + def _forward(self, x: torch.Tensor) -> torch.Tensor: + h = self.norm1(x) + h = self.attn(h) + x = x + h + h = self.norm2(x) + h = self.mlp(h) + if self.out_channels != self.channels: + x = self.res_mlp(x) + x = x + h + return x + + def forward(self, x: torch.Tensor) -> torch.Tensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, use_reentrant=False) + else: + return self._forward(x) + + +class SkinTransformerCrossBlock(nn.Module): + """ + Transformer block (MSA + FFN). + """ + def __init__( + self, + channels: int, + num_heads: int, + out_channels: Optional[int] = None, + mlp_ratio: float = 4.0, + use_checkpoint: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.to_v = nn.Linear(channels, channels, bias=qkv_bias) + self.channels = channels + self.out_channels = out_channels if out_channels is not None else channels + self.mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=mlp_ratio, + ) + self.joint_attn = MultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode="full", + qkv_bias=qkv_bias, + ) + self.joint_mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=mlp_ratio, + ) + if self.out_channels != self.channels: + self.res_mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=1.0, + ) + self.res_joint_mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=1.0, + ) + + def _forward(self, x: torch.Tensor, j: torch.Tensor, skin: torch.Tensor) -> torch.Tensor: + v = self.to_v(self.norm1(j)) + h = skin @ v + x = x + h + h = self.norm2(x) + h = self.mlp(h) + if self.out_channels != self.channels: + x = self.res_mlp(x) + x = x + h + + h_j = self.norm3(j) + h_j = self.joint_attn(h_j) + h_j = j + h_j + h_j = self.joint_mlp(h_j) + if self.out_channels != self.channels: + j = self.res_joint_mlp(j) + j = j + h_j + return x, j + + +class TransformerCrossBlock(nn.Module): + """ + Transformer cross-attention block (MSA + MCA + FFN). + """ + def __init__( + self, + channels: int, + ctx_channels: int, + num_heads: int, + out_channels: Optional[int] = None, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "windowed"] = "full", + window_size: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + ln_affine: bool = False, + x_is_query: bool = False, + no_self: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.norm1 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) if not no_self else nn.Identity() + self.norm2 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=ln_affine, eps=1e-6) + if no_self: + self.self_attn = lambda x: 0 + else: + self.self_attn = MultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode=attn_mode, + window_size=window_size, + shift_window=shift_window, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.cross_attn = MultiHeadAttention( + channels, + ctx_channels=ctx_channels, + num_heads=num_heads, + type="cross", + attn_mode="full", + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + x_is_query=x_is_query, + ) + self.channels = channels + self.out_channels = out_channels if out_channels is not None else channels + self.mlp = FeedForwardNet( + channels, + out_channels=self.out_channels, + mlp_ratio=mlp_ratio, + ) + if self.out_channels != self.channels: + self.res_mlp = FeedForwardNet( + self.channels, + out_channels=self.out_channels, + mlp_ratio=1.0, + ) + + def _forward(self, x: torch.Tensor, context: torch.Tensor): + h = self.norm1(x) + h = self.self_attn(h) + x = x + h + h = self.norm2(x) + h = self.cross_attn(h, context) + x = x + h + h = self.norm3(x) + h = self.mlp(h) + if self.out_channels != self.channels: + x = self.res_mlp(x) + x = x + h + return x + + def forward(self, x: torch.Tensor, context: torch.Tensor): + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, context, use_reentrant=False) + else: + return self._forward(x, context) + \ No newline at end of file diff --git a/anigen/modules/transformer/modulated.py b/anigen/modules/transformer/modulated.py new file mode 100644 index 0000000000000000000000000000000000000000..58714589b0187961511a5e0d1967669e416b9fbd --- /dev/null +++ b/anigen/modules/transformer/modulated.py @@ -0,0 +1,175 @@ +from typing import * +import torch +import torch.nn as nn +from ..attention import MultiHeadAttention +from ..norm import LayerNorm32 +from .blocks import FeedForwardNet + + +class ModulatedTransformerBlock(nn.Module): + """ + Transformer block (MSA + FFN) with adaptive layer norm conditioning. + """ + def __init__( + self, + channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "windowed"] = "full", + window_size: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qkv_bias: bool = True, + share_mod: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.attn = MultiHeadAttention( + channels, + num_heads=num_heads, + attn_mode=attn_mode, + window_size=window_size, + shift_window=shift_window, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + ) + self.mlp = FeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + if not share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(channels, 6 * channels, bias=True) + ) + + def _forward(self, x: torch.Tensor, mod: torch.Tensor) -> torch.Tensor: + if self.share_mod: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1) + else: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1) + h = self.norm1(x) + h = h * (1 + scale_msa.unsqueeze(1)) + shift_msa.unsqueeze(1) + h = self.attn(h) + h = h * gate_msa.unsqueeze(1) + x = x + h + h = self.norm2(x) + h = h * (1 + scale_mlp.unsqueeze(1)) + shift_mlp.unsqueeze(1) + h = self.mlp(h) + h = h * gate_mlp.unsqueeze(1) + x = x + h + return x + + def forward(self, x: torch.Tensor, mod: torch.Tensor) -> torch.Tensor: + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, mod, use_reentrant=False) + else: + return self._forward(x, mod) + + +class ModulatedTransformerCrossBlock(nn.Module): + """ + Transformer cross-attention block (MSA + MCA + FFN) with adaptive layer norm conditioning. + """ + def __init__( + self, + channels: int, + ctx_channels: int, + num_heads: int, + mlp_ratio: float = 4.0, + attn_mode: Literal["full", "windowed"] = "full", + window_size: Optional[int] = None, + shift_window: Optional[Tuple[int, int, int]] = None, + use_checkpoint: bool = False, + use_rope: bool = False, + qk_rms_norm: bool = False, + qk_rms_norm_cross: bool = False, + qkv_bias: bool = True, + share_mod: bool = False, + + use_lora_self: bool = False, + lora_rank_self: int = 4, + use_lora_cross: bool = False, + lora_rank_cross: int = 4, + lora_lr_rate: float = 1.0, + use_context_norm: bool = False, + ): + super().__init__() + self.use_checkpoint = use_checkpoint + self.share_mod = share_mod + self.norm1 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.norm2 = LayerNorm32(channels, elementwise_affine=True, eps=1e-6) + self.norm3 = LayerNorm32(channels, elementwise_affine=False, eps=1e-6) + self.use_context_norm = use_context_norm + if self.use_context_norm: + self.context_norm = LayerNorm32(ctx_channels, elementwise_affine=True, eps=1e-6) + self.self_attn = MultiHeadAttention( + channels, + num_heads=num_heads, + type="self", + attn_mode=attn_mode, + window_size=window_size, + shift_window=shift_window, + qkv_bias=qkv_bias, + use_rope=use_rope, + qk_rms_norm=qk_rms_norm, + use_lora=use_lora_self, + lora_rank=lora_rank_self, + lora_lr_rate=lora_lr_rate, + ) + self.cross_attn = MultiHeadAttention( + channels, + ctx_channels=ctx_channels, + num_heads=num_heads, + type="cross", + attn_mode="full", + qkv_bias=qkv_bias, + qk_rms_norm=qk_rms_norm_cross, + use_lora=use_lora_cross, + lora_rank=lora_rank_cross, + lora_lr_rate=lora_lr_rate, + ) + self.mlp = FeedForwardNet( + channels, + mlp_ratio=mlp_ratio, + ) + if not share_mod: + self.adaLN_modulation = nn.Sequential( + nn.SiLU(), + nn.Linear(channels, 6 * channels, bias=True) + ) + + def _forward(self, x: torch.Tensor, mod: torch.Tensor, context: torch.Tensor): + if self.share_mod: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1) + else: + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1) + h = self.norm1(x) + h = h * (1 + scale_msa.unsqueeze(1)) + shift_msa.unsqueeze(1) + h = self.self_attn(h) + h = h * gate_msa.unsqueeze(1) + x = x + h + h = self.norm2(x) + if self.use_context_norm: + context = self.context_norm(context) + h = self.cross_attn(h, context) + x = x + h + h = self.norm3(x) + h = h * (1 + scale_mlp.unsqueeze(1)) + shift_mlp.unsqueeze(1) + h = self.mlp(h) + h = h * gate_mlp.unsqueeze(1) + x = x + h + return x + + def forward(self, x: torch.Tensor, mod: torch.Tensor, context: torch.Tensor): + if self.use_checkpoint: + return torch.utils.checkpoint.checkpoint(self._forward, x, mod, context, use_reentrant=False) + else: + return self._forward(x, mod, context) + \ No newline at end of file diff --git a/anigen/modules/utils.py b/anigen/modules/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..f0afb1b6c767aa2ad00bad96649fb30315e696ea --- /dev/null +++ b/anigen/modules/utils.py @@ -0,0 +1,54 @@ +import torch.nn as nn +from ..modules import sparse as sp + +FP16_MODULES = ( + nn.Conv1d, + nn.Conv2d, + nn.Conv3d, + nn.ConvTranspose1d, + nn.ConvTranspose2d, + nn.ConvTranspose3d, + nn.Linear, + sp.SparseConv3d, + sp.SparseInverseConv3d, + sp.SparseLinear, +) + +def convert_module_to_f16(l): + """ + Convert primitive modules to float16. + """ + if isinstance(l, FP16_MODULES): + for p in l.parameters(): + p.data = p.data.half() + + +def convert_module_to_f32(l): + """ + Convert primitive modules to float32, undoing convert_module_to_f16(). + """ + if isinstance(l, FP16_MODULES): + for p in l.parameters(): + p.data = p.data.float() + + +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module + + +def scale_module(module, scale): + """ + Scale the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().mul_(scale) + return module + + +def modulate(x, shift, scale): + return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1) diff --git a/anigen/pipelines/__init__.py b/anigen/pipelines/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e46f35cb645aecb61735adde910750c4940a558e --- /dev/null +++ b/anigen/pipelines/__init__.py @@ -0,0 +1,24 @@ +from . import samplers +from .anigen_image_to_3d import AnigenImageTo3DPipeline + + +def from_pretrained(path: str): + """ + Load a pipeline from a model folder or a Hugging Face model hub. + + Args: + path: The path to the model. Can be either local path or a Hugging Face model name. + """ + import os + import json + is_local = os.path.exists(f"{path}/pipeline.json") + + if is_local: + config_file = f"{path}/pipeline.json" + else: + from huggingface_hub import hf_hub_download + config_file = hf_hub_download(path, "pipeline.json") + + with open(config_file, 'r') as f: + config = json.load(f) + return globals()[config['name']].from_pretrained(path) diff --git a/anigen/pipelines/anigen_image_to_3d.py b/anigen/pipelines/anigen_image_to_3d.py new file mode 100644 index 0000000000000000000000000000000000000000..fb1c8749abcf3e6ef3b8a0c17ab12894bf11f07a --- /dev/null +++ b/anigen/pipelines/anigen_image_to_3d.py @@ -0,0 +1,470 @@ +from typing import * +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from PIL import Image +import os +import sys +import trimesh +from easydict import EasyDict as edict + +from anigen import models +from .base import Pipeline +from . import samplers +from ..modules import sparse as sp +from ..utils.model_utils import load_model_from_path, load_decoder +from ..utils.image_utils import load_dsine, preprocess_image, encode_image +from ..utils.skin_utils import repair_skeleton_parents, smooth_skin_weights_on_mesh, filter_skinning_weights +from ..utils.export_utils import convert_to_glb_from_data, _extract_vertex_rgb, visualize_skeleton_as_mesh +from ..utils.postprocessing_utils import ( + postprocess_mesh, + barycentric_transfer_attributes, + parametrize_mesh, + bake_texture, +) +from ..utils.general_utils import _keep_largest_connected_component_3d + +class AnigenImageTo3DPipeline(Pipeline): + """ + Pipeline for inferring Anigen image-to-3D models. + """ + def __init__( + self, + models: dict[str, nn.Module] = None, + ss_config: edict = None, + slat_config: edict = None, + ): + if models is None: + return + super().__init__(models) + self.ss_config = ss_config + self.slat_config = slat_config + # self.device is handled by the base Pipeline class property + + @staticmethod + def from_pretrained( + ss_flow_path: str = 'ckpts/anigen/ss_flow_solo', + slat_flow_path: str = 'ckpts/anigen/slat_flow_control', + device: str = 'cuda', + use_ema: bool = False + ) -> "AnigenImageTo3DPipeline": + """ + Load pretrained models from paths. + """ + print("Loading models...") + + # Image Cond Model (DINOv2) + dinov2_model = torch.hub.load('./ckpts/dinov2', 'dinov2_vitl14_reg', pretrained=True, source='local') + dinov2_model.to(device).eval() + + # DSINE Model + print("Loading DSINE...") + dsine_model = load_dsine(device) + + # SLat Flow Model + slat_model, slat_config = load_model_from_path(slat_flow_path, model_name_in_config='denoiser', device=device, use_ema=use_ema) + + # SLat Decoder + slat_dec_path = slat_config.dataset.args.get('slat_dec_path') + slat_dec_ckpt = slat_config.dataset.args.get('slat_dec_ckpt') + print(f"Loading SLat Decoder from {slat_dec_path}...") + slat_decoder = load_decoder(slat_dec_path, slat_dec_ckpt, device) + + # SS Flow Model + ss_model, ss_config = load_model_from_path(ss_flow_path, model_name_in_config='denoiser', device=device, use_ema=use_ema) + + # SS Decoder + ss_dec_path = ss_config.dataset.args.get('ss_dec_path') + ss_dec_ckpt = ss_config.dataset.args.get('ss_dec_ckpt') + print(f"Loading SS Decoder from {ss_dec_path}...") + ss_decoder = load_decoder(ss_dec_path, ss_dec_ckpt, device) + + models_dict = { + 'image_cond_model': dinov2_model, + 'dsine': dsine_model, + 'slat_flow_model': slat_model, + 'slat_decoder': slat_decoder, + 'ss_flow_model': ss_model, + 'ss_decoder': ss_decoder, + } + + pipeline = AnigenImageTo3DPipeline(models_dict, ss_config, slat_config) + return pipeline + + def load_ss_flow_model(self, ss_flow_path: str, device: str = 'cuda', use_ema: bool = False): + """ + Hot-swap the SS flow model (and its config) without reloading decoders or shared models. + """ + print(f"Loading SS flow model from {ss_flow_path}...") + ss_model, ss_config = load_model_from_path(ss_flow_path, model_name_in_config='denoiser', device=device, use_ema=use_ema) + ss_model.to(device).eval() + self.models['ss_flow_model'] = ss_model + self.ss_config = ss_config + + def load_slat_flow_model(self, slat_flow_path: str, device: str = 'cuda', use_ema: bool = False): + """ + Hot-swap the SLAT flow model (and its config) without reloading decoders or shared models. + """ + print(f"Loading SLAT flow model from {slat_flow_path}...") + slat_model, slat_config = load_model_from_path(slat_flow_path, model_name_in_config='denoiser', device=device, use_ema=use_ema) + slat_model.to(device).eval() + self.models['slat_flow_model'] = slat_model + self.slat_config = slat_config + + def preprocess_image(self, image: Image.Image) -> Tuple[Image.Image, Image.Image]: + """ + Preprocess the input image using DSINE model for normal estimation. + Returns (processed_rgb, processed_normal). + """ + image, normal_image = preprocess_image(image, self.models['dsine'], str(self.device)) + return image, normal_image + + def get_cond(self, image: Image.Image, normal_image: Image.Image) -> dict: + """ + Get conditioning for SS and SLat models. + """ + cond_rgb = encode_image(image, self.models['image_cond_model'], self.device) + cond_normal = encode_image(normal_image, self.models['image_cond_model'], self.device) + + # Conditioning tensors for flow models + normal_tensor = torch.from_numpy(np.array(normal_image)).float() / 255.0 + normal_tensor = normal_tensor.permute(2, 0, 1).unsqueeze(0).to(self.device) + + rgb_tensor = torch.from_numpy(np.array(image.convert('RGB'))).float() / 255.0 + rgb_tensor = rgb_tensor.permute(2, 0, 1).unsqueeze(0).to(self.device) + + cond_dict_ss = { + 'cond': cond_normal, + 'neg_cond': torch.zeros_like(cond_rgb), + 'normal': normal_tensor + } + + cond_dict_slat_rgb = { + 'cond': cond_rgb, + 'neg_cond': torch.zeros_like(cond_rgb), + 'normal': rgb_tensor + } + + return cond_dict_ss, cond_dict_slat_rgb + + def sample_sparse_structure( + self, + cond_dict_ss: dict, + strength: float = 7.5, + steps: int = 50, + skl_mainland_only: bool = True, + progress_callback=None, + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Sample sparse structure (SS) and skeleton (SS_skl). + Returns (coords, coords_skl). + """ + ss_model = self.models['ss_flow_model'] + ss_decoder = self.models['ss_decoder'] + + print("Sampling Sparse Structure...") + ss_sampler = samplers.AniGenFlowEulerCfgSampler(sigma_min=1e-5) + reso = ss_model.resolution + + noise = torch.randn(1, ss_model.in_channels, reso, reso, reso).to(self.device) + if ss_model.z_is_global: + noise = torch.randn(1, ss_model.global_token_num, ss_model.in_channels).to(self.device) + + noise_skl = torch.randn(1, ss_model.in_channels_skl, reso, reso, reso).to(self.device) + if ss_model.z_skl_is_global: + noise_skl = torch.randn(1, ss_model.global_token_num_skl, ss_model.in_channels_skl).to(self.device) + + z_s_out = ss_sampler.sample( + ss_model, + noise, + noise_skl, + **cond_dict_ss, + steps=steps, + cfg_strength=strength, + verbose=True, + progress_callback=progress_callback, + ) + + z_s = z_s_out.samples + z_s_skl = z_s_out.samples_skl + + decoded_ss, decoded_ss_skl = ss_decoder(z_s, z_s_skl) + + if skl_mainland_only: + bsz, ch, d, h, w = decoded_ss_skl.shape + for b in range(bsz): + occ_3d = (decoded_ss_skl[b] > 0).any(dim=0).detach().cpu().numpy() + if not np.any(occ_3d): + continue + mainland_3d = _keep_largest_connected_component_3d(occ_3d) + mainland_t = torch.from_numpy(mainland_3d).to(device=decoded_ss_skl.device) + mainland_cd = mainland_t.unsqueeze(0).expand(ch, -1, -1, -1) + decoded_ss_skl[b] = torch.where( + mainland_cd, + decoded_ss_skl[b], + torch.full_like(decoded_ss_skl[b], -1e9), + ) + coords = torch.argwhere(decoded_ss > 0)[:, [0, 2, 3, 4]].int() + coords_skl = torch.argwhere(decoded_ss_skl > 0)[:, [0, 2, 3, 4]].int() + + return coords, coords_skl, decoded_ss, decoded_ss_skl + + def sample_slat( + self, + cond_dict_slat: dict, + coords: torch.Tensor, + coords_skl: torch.Tensor, + strength: float = 3.0, + steps: int = 50, + joint_density: int = 1, + progress_callback=None, + ) -> Tuple[sp.SparseTensor, sp.SparseTensor]: + """ + Sample Structured Latent (SLat) features. + """ + slat_model = self.models['slat_flow_model'] + + print("Sampling Structured Latent...") + slat_sampler = samplers.AniGenFlowEulerCfgSampler(sigma_min=1e-5) + + noise_slat = sp.SparseTensor( + feats=torch.randn(coords.shape[0], slat_model.in_channels + slat_model.in_channels_vert_skin).to(self.device), + coords=coords, + ) + noise_skl = sp.SparseTensor( + feats=torch.randn(coords_skl.shape[0], slat_model.in_channels_skl).to(self.device), + coords=coords_skl, + ) + + # Prepare conditioning + cond = cond_dict_slat.copy() + + # Check for joint density conditioning support + use_joint_num_cond = bool(getattr(slat_model, 'use_joint_num_cond', False)) + + if use_joint_num_cond: + joints_num = {0: 0, 1: 10, 2: 15, 3: 25, 4: 35}.get(joint_density, 10) + cond['joints_num'] = joints_num + cond['neg_joints_num'] = 0 + + out = slat_sampler.sample( + slat_model, + noise_slat, + noise_skl, + **cond, + steps=steps, + cfg_strength=strength, + verbose=True, + progress_callback=progress_callback, + ) + + slat = out.samples + slat_skl = out.samples_skl + + # Normalization + if 'dataset' in self.slat_config and 'args' in self.slat_config.dataset and 'normalization' in self.slat_config.dataset.args: + norm_stats = self.slat_config.dataset.args.normalization + + def denormalize(tensor, mean, std): + if tensor is None: return None + mean = torch.tensor(mean).to(tensor.device) + std = torch.tensor(std).to(tensor.device) + return tensor * std + mean + + if 'slat' in norm_stats: + slat = slat.replace(feats=denormalize(slat.feats, norm_stats['slat']['mean'], norm_stats['slat']['std'])) + elif 'mean' in norm_stats and 'std' in norm_stats: + slat = slat.replace(feats=denormalize(slat.feats, norm_stats['mean'], norm_stats['std'])) + + if 'slat_skl' in norm_stats: + slat_skl = slat_skl.replace(feats=denormalize(slat_skl.feats, norm_stats['slat_skl']['mean'], norm_stats['slat_skl']['std'])) + elif 'slat_skel' in norm_stats: + slat_skl = slat_skl.replace(feats=denormalize(slat_skl.feats, norm_stats['slat_skel']['mean'], norm_stats['slat_skel']['std'])) + elif 'mean_skl' in norm_stats and 'std_skl' in norm_stats: + slat_skl = slat_skl.replace(feats=denormalize(slat_skl.feats, norm_stats['mean_skl'], norm_stats['std_skl'])) + + return slat, slat_skl + + def decode_slat(self, slat: sp.SparseTensor, slat_skl: sp.SparseTensor): + slat_decoder = self.models['slat_decoder'] + meshes, skeletons = slat_decoder(slat, slat_skl) + return meshes[0], skeletons[0] + + @torch.no_grad() + def run( + self, + image: Image.Image, + seed: int = 42, + cfg_scale_ss: float = 7.5, + cfg_scale_slat: float = 3.0, + ss_steps: int = 25, + slat_steps: int = 25, + joints_density: int = 1, + simplify_ratio: float = 0.95, + fill_holes: bool = True, + no_smooth_skin_weights: bool = False, + no_filter_skin_weights: bool = False, + smooth_skin_weights_iters: int = 100, + smooth_skin_weights_alpha: float = 1.0, + texture_size: int = 1024, + output_glb: str = None, + ss_progress_callback=None, + slat_progress_callback=None, + postprocess_progress_callback=None, + ) -> dict: + + def _pp_progress(frac, desc): + if postprocess_progress_callback is not None: + postprocess_progress_callback(frac, desc) + + # Set seed + torch.manual_seed(seed) + np.random.seed(seed) + + # Preprocess + processed_image, processed_normal = self.preprocess_image(image) + + # Get conditioning + cond_dict_ss, cond_dict_slat_rgb = self.get_cond(processed_image, processed_normal) + + # Sample SS + coords, coords_skl, _, _ = self.sample_sparse_structure( + cond_dict_ss, + strength=cfg_scale_ss, + steps=ss_steps, + progress_callback=ss_progress_callback, + ) + + # Sample SLat + slat, slat_skl = self.sample_slat( + cond_dict_slat_rgb, + coords, + coords_skl, + strength=cfg_scale_slat, + steps=slat_steps, + joint_density=joints_density, + progress_callback=slat_progress_callback, + ) + + # Decode + mesh_result, skeleton_result = self.decode_slat(slat, slat_skl) + + # ---------- Post-processing ---------- + _pp_progress(0.0, "Post-processing...") + + joints = skeleton_result.joints_grouped.cpu().numpy() + parents = skeleton_result.parents_grouped.cpu().numpy().astype(np.int32) + parents = repair_skeleton_parents(joints=joints, parents=parents, verbose=False).astype(np.int32) + + skin_weights = skeleton_result.skin_pred.cpu().numpy() + vertex_colors = _extract_vertex_rgb(getattr(mesh_result, 'vertex_attrs', None)) + + orig_vertices = mesh_result.vertices.cpu().numpy() + orig_faces = mesh_result.faces.cpu().numpy() + + _pp_progress(0.05, "Simplification...") + + new_vertices, new_faces = postprocess_mesh( + orig_vertices, orig_faces, + simplify=(simplify_ratio > 0), + simplify_ratio=simplify_ratio, + fill_holes=fill_holes, + verbose=True, + ) + + # Transfer skin weights via barycentric interpolation + if new_vertices.shape[0] != orig_vertices.shape[0]: + orig_mesh = trimesh.Trimesh(vertices=orig_vertices, faces=orig_faces, process=False) + skin_weights = barycentric_transfer_attributes(orig_mesh, skin_weights, new_vertices) + + mesh = trimesh.Trimesh(vertices=new_vertices, faces=new_faces, process=False) + + if not no_filter_skin_weights: + skin_weights = filter_skinning_weights( + mesh, + skin_weights, + joints, + parents, + ) + + if not no_smooth_skin_weights: + skin_weights = smooth_skin_weights_on_mesh( + mesh, + skin_weights, + iterations=smooth_skin_weights_iters, + alpha=smooth_skin_weights_alpha, + ) + + # UV parametrize and bake texture via multiview rendering (mesh-based teacher) + texture_image = None + if texture_size > 0: + _pp_progress(0.20, "Baking texture...") + + uv_vertices, uv_faces, uvs, vmapping = parametrize_mesh( + new_vertices, new_faces + ) + skin_weights = skin_weights[vmapping] + + # Teacher: dense mesh with vertex colors rendered by MeshRenderer + from ..utils.render_utils import render_multiview + + observations, extrinsics_mv, intrinsics_mv = render_multiview( + mesh_result, resolution=1024, nviews=100, + ) + masks = [np.any(obs > 0, axis=-1) for obs in observations] + extrinsics_np = [e.cpu().numpy() for e in extrinsics_mv] + intrinsics_np = [i.cpu().numpy() for i in intrinsics_mv] + + with torch.enable_grad(): + texture = bake_texture( + uv_vertices, uv_faces, uvs, + observations, masks, extrinsics_np, intrinsics_np, + texture_size=texture_size, mode='opt', + lambda_tv=0.01, + verbose=True, + ) + texture_image = texture + + mesh = trimesh.Trimesh( + vertices=uv_vertices, + faces=uv_faces, + visual=trimesh.visual.TextureVisuals(uv=uvs), + process=False, + ) + + _pp_progress(0.90, "Exporting...") + + skeleton_mesh = visualize_skeleton_as_mesh(joints, parents) + + ret = { + 'mesh': mesh, + 'skeleton_mesh': skeleton_mesh, + 'joints': joints, + 'parents': parents, + 'skin_weights': skin_weights, + 'vertex_colors': vertex_colors, + 'texture_image': texture_image, + 'processed_image': processed_image, + 'processed_normal': processed_normal, + 'coords': coords.cpu(), + 'coords_skl': coords_skl.cpu(), + } + + if output_glb: + convert_to_glb_from_data( + mesh, + joints, + parents, + skin_weights, + output_glb, + vertex_colors=vertex_colors, + texture_image=texture_image, + ) + if skeleton_mesh is not None and len(skeleton_mesh.vertices) > 0: + skeleton_glb_path = os.path.join(os.path.dirname(output_glb), "skeleton.glb") + skeleton_mesh.export(skeleton_glb_path) + + _pp_progress(1.0, "Done!") + + return ret diff --git a/anigen/pipelines/base.py b/anigen/pipelines/base.py new file mode 100644 index 0000000000000000000000000000000000000000..9d214e41b9422846decf1c2ec9d075ed3d08b5e7 --- /dev/null +++ b/anigen/pipelines/base.py @@ -0,0 +1,68 @@ +from typing import * +import torch +import torch.nn as nn +from .. import models + + +class Pipeline: + """ + A base class for pipelines. + """ + def __init__( + self, + models: dict[str, nn.Module] = None, + ): + if models is None: + return + self.models = models + for model in self.models.values(): + model.eval() + + @staticmethod + def from_pretrained(path: str) -> "Pipeline": + """ + Load a pretrained model. + """ + import os + import json + is_local = os.path.exists(f"{path}/pipeline.json") + + if is_local: + config_file = f"{path}/pipeline.json" + else: + from huggingface_hub import hf_hub_download + config_file = hf_hub_download(path, "pipeline.json") + + with open(config_file, 'r') as f: + args = json.load(f)['args'] + + _models = {} + for k, v in args['models'].items(): + try: + _models[k] = models.from_pretrained(f"{path}/{v}") + except: + _models[k] = models.from_pretrained(v) + + new_pipeline = Pipeline(_models) + new_pipeline._pretrained_args = args + return new_pipeline + + @property + def device(self) -> torch.device: + for model in self.models.values(): + if hasattr(model, 'device'): + return model.device + for model in self.models.values(): + if hasattr(model, 'parameters'): + return next(model.parameters()).device + raise RuntimeError("No device found.") + + def to(self, device: torch.device) -> None: + for model in self.models.values(): + model.to(device) + + def cuda(self) -> None: + self.to(torch.device("cuda")) + + def cpu(self) -> None: + self.to(torch.device("cpu")) diff --git a/anigen/pipelines/samplers/__init__.py b/anigen/pipelines/samplers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aaef4a5393a598fbd55232fa3e3ec16aae4c7e92 --- /dev/null +++ b/anigen/pipelines/samplers/__init__.py @@ -0,0 +1,3 @@ +from .base import Sampler +from .flow_euler import FlowEulerSampler, FlowEulerCfgSampler, FlowEulerGuidanceIntervalSampler +from .anigen_flow_euler import AniGenFlowEulerSampler, AniGenFlowEulerCfgSampler, AniGenFlowEulerGuidanceIntervalSampler \ No newline at end of file diff --git a/anigen/pipelines/samplers/anigen_flow_euler.py b/anigen/pipelines/samplers/anigen_flow_euler.py new file mode 100644 index 0000000000000000000000000000000000000000..e07119abc5616b794fd8ae2babe5859bf63d62f6 --- /dev/null +++ b/anigen/pipelines/samplers/anigen_flow_euler.py @@ -0,0 +1,332 @@ +from typing import * +import torch +import numpy as np +from tqdm import tqdm +from easydict import EasyDict as edict +from .base import Sampler +from .classifier_free_guidance_mixin import AniGenClassifierFreeGuidanceSamplerMixin +from .guidance_interval_mixin import AniGenGuidanceIntervalSamplerMixin + + +class AniGenFlowEulerSampler(Sampler): + """ + Generate samples from a flow-matching model using Euler sampling. + + Args: + sigma_min: The minimum scale of noise in flow. + """ + def __init__( + self, + sigma_min: float, + ): + self.sigma_min = sigma_min + + def _eps_to_xstart(self, x_t, t, eps): + assert x_t.shape == eps.shape + return (x_t - (self.sigma_min + (1 - self.sigma_min) * t) * eps) / (1 - t) + + def _xstart_to_eps(self, x_t, t, x_0): + assert x_t.shape == x_0.shape + return (x_t - (1 - t) * x_0) / (self.sigma_min + (1 - self.sigma_min) * t) + + def _v_to_xstart_eps(self, x_t, t, v): + assert x_t.shape == v.shape + eps = (1 - t) * v + x_t + x_0 = (1 - self.sigma_min) * x_t - (self.sigma_min + (1 - self.sigma_min) * t) * v + return x_0, eps + + def _x0_eps_to_xt(self, x_0, eps, t: float): + """Forward noising: x_t = (1-t)*x_0 + (sigma(t))*eps. + + Notes: + - With this parameterization, at t=1 we have x_1 = eps. + - This helper is used by `sample_inpaint` to build the known (masked) x_t from + a known x_0 and a known noise/eps. + """ + t = float(t) + a = 1.0 - t + b = float(self.sigma_min + (1.0 - self.sigma_min) * t) + return a * x_0 + b * eps + + def _inference_model(self, model, x_t, x_t_skl, t, cond=None, **kwargs): + t = torch.tensor([1000 * t] * x_t.shape[0], device=x_t.device, dtype=torch.float32) + if cond is not None and cond.shape[0] == 1 and x_t.shape[0] > 1: + cond = cond.repeat(x_t.shape[0], *([1] * (len(cond.shape) - 1))) + return model(x_t, x_t_skl, t, cond, **kwargs) + + def _get_model_prediction(self, model, x_t, x_t_skl, t, cond=None, **kwargs): + pred_v, pred_v_skl = self._inference_model(model, x_t, x_t_skl, t, cond, **kwargs) + pred_x_0, pred_eps = self._v_to_xstart_eps(x_t=x_t, t=t, v=pred_v) + pred_x_0_skl, pred_eps_skl = self._v_to_xstart_eps(x_t=x_t_skl, t=t, v=pred_v_skl) + return pred_x_0, pred_eps, pred_v, pred_x_0_skl, pred_eps_skl, pred_v_skl + + @torch.no_grad() + def sample_once( + self, + model, + x_t, + x_t_skl, + t: float, + t_prev: float, + cond: Optional[Any] = None, + **kwargs + ): + """ + Sample x_{t-1} from the model using Euler method. + + Args: + model: The model to sample from. + x_t: The [N x C x ...] tensor of noisy inputs at time t. + t: The current timestep. + t_prev: The previous timestep. + cond: conditional information. + **kwargs: Additional arguments for model inference. + + Returns: + a dict containing the following + - 'pred_x_prev': x_{t-1}. + - 'pred_x_0': a prediction of x_0. + """ + pred_x_0, pred_eps, pred_v, pred_x_0_skl, pred_eps_skl, pred_v_skl = self._get_model_prediction(model, x_t, x_t_skl, t, cond, **kwargs) + pred_x_prev = x_t - (t - t_prev) * pred_v + pred_x_prev_skl = x_t_skl - (t - t_prev) * pred_v_skl + return edict({"pred_x_prev": pred_x_prev, "pred_x_0": pred_x_0, "pred_x_prev_skl": pred_x_prev_skl, "pred_x_0_skl": pred_x_0_skl}) + + @torch.no_grad() + def sample( + self, + model, + noise, + noise_skl, + cond: Optional[Any] = None, + steps: int = 50, + rescale_t: float = 1.0, + verbose: bool = True, + progress_callback: Optional[Callable[[int, int], None]] = None, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + verbose: If True, show a progress bar. + progress_callback: Optional callback(step_index, total_steps) invoked after each step. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + sample = noise + sample_skl = noise_skl + t_seq = np.linspace(1, 0, steps + 1) + t_seq = rescale_t * t_seq / (1 + (rescale_t - 1) * t_seq) + t_pairs = list((t_seq[i], t_seq[i + 1]) for i in range(steps)) + ret = edict({"samples": None, "samples_skl": None, "pred_x_t": [], "pred_x_0": [], "pred_x_t_skl": [], "pred_x_0_skl": []}) + for step_idx, (t, t_prev) in enumerate(tqdm(t_pairs, desc="Sampling", disable=not verbose)): + out = self.sample_once(model, sample, sample_skl, t, t_prev, cond, **kwargs) + sample = out.pred_x_prev + sample_skl = out.pred_x_prev_skl + ret.pred_x_t.append(out.pred_x_prev) + ret.pred_x_0.append(out.pred_x_0) + ret.pred_x_t_skl.append(out.pred_x_prev_skl) + ret.pred_x_0_skl.append(out.pred_x_0_skl) + if progress_callback is not None: + progress_callback(step_idx, steps) + ret.samples = sample + ret.samples_skl = sample_skl + return ret + + @torch.no_grad() + def sample_inpaint( + self, + model, + noise, + noise_skl, + cond: Optional[Any] = None, + *, + # Standard sampling parameters + steps: int = 50, + rescale_t: float = 1.0, + verbose: bool = True, + progress_callback: Optional[Callable[[int, int], None]] = None, + # Inpainting option A (dense tensors): known x0 + known noise(eps) + mask + known_x0: Optional[torch.Tensor] = None, + known_noise: Optional[torch.Tensor] = None, + inpaint_mask: Optional[torch.Tensor] = None, + known_x0_skl: Optional[torch.Tensor] = None, + known_noise_skl: Optional[torch.Tensor] = None, + inpaint_mask_skl: Optional[torch.Tensor] = None, + # Inpainting option B (generic): user hook for SparseTensor / custom blending + inpaint_fn: Optional[Callable[[Any, Any, float], Tuple[Any, Any]]] = None, + **kwargs, + ): + """Euler sampling with inpainting-style constraints. + + This is useful when part of the latent (or sparse features) is known (GT) and + should stay consistent during denoising, similar to diffusion inpainting. + + Two usage modes: + 1) Dense tensors (torch.Tensor): + Provide `known_x0` (GT clean target), `known_noise` (eps; note x_1 == eps), + and `inpaint_mask` (1 keeps GT region, 0 keeps sampled region). The sampler + will, after every Euler step (at t_prev), blend: + x_{t_prev} <- mask * known_x_{t_prev} + (1-mask) * x_{t_prev} + where known_x_t is computed from (known_x0, known_noise) via forward noising. + + 2) Generic hook (recommended for SparseTensor): + Provide `inpaint_fn(sample, sample_skl, t_prev) -> (sample, sample_skl)`. + This hook runs after every Euler step. You can implement coord-based GT + overwrites there. + + All CFG-related kwargs (e.g. neg_cond/cfg_strength/cfg_interval) are passed + through to `sample_once`. + """ + + def _blend_dense(x, known_x, mask): + if mask is None or known_x is None: + return x + if not isinstance(x, torch.Tensor): + raise TypeError("Dense inpainting mode requires torch.Tensor states; use `inpaint_fn` for SparseTensor.") + m = mask + if not isinstance(m, torch.Tensor): + m = torch.as_tensor(m) + if m.dtype != torch.float32 and m.dtype != torch.float16 and m.dtype != torch.bfloat16: + m = m.float() + m = m.to(device=x.device) + known_x = known_x.to(device=x.device, dtype=x.dtype) + return x * (1.0 - m) + known_x * m + + sample = noise + sample_skl = noise_skl + t_seq = np.linspace(1, 0, int(steps) + 1) + t_seq = rescale_t * t_seq / (1 + (rescale_t - 1) * t_seq) + t_pairs = list((float(t_seq[i]), float(t_seq[i + 1])) for i in range(int(steps))) + ret = edict({"samples": None, "samples_skl": None, "pred_x_t": [], "pred_x_0": [], "pred_x_t_skl": [], "pred_x_0_skl": []}) + + for step_idx, (t, t_prev) in enumerate(tqdm(t_pairs, desc="Sampling", disable=not verbose)): + out = self.sample_once(model, sample, sample_skl, t, t_prev, cond, **kwargs) + sample = out.pred_x_prev + sample_skl = out.pred_x_prev_skl + + # Apply inpainting constraint at the *new* time (t_prev). + if inpaint_fn is not None: + sample, sample_skl = inpaint_fn(sample, sample_skl, float(t_prev)) + else: + if known_x0 is not None or known_noise is not None or inpaint_mask is not None: + if known_x0 is None or known_noise is None or inpaint_mask is None: + raise ValueError("Dense inpainting requires `known_x0`, `known_noise`, and `inpaint_mask`.") + known_xt = self._x0_eps_to_xt(known_x0.to(device=sample.device, dtype=sample.dtype), known_noise.to(device=sample.device, dtype=sample.dtype), float(t_prev)) + sample = _blend_dense(sample, known_xt, inpaint_mask) + + if known_x0_skl is not None or known_noise_skl is not None or inpaint_mask_skl is not None: + if known_x0_skl is None or known_noise_skl is None or inpaint_mask_skl is None: + raise ValueError("Dense inpainting for skl requires `known_x0_skl`, `known_noise_skl`, and `inpaint_mask_skl`.") + known_xt_skl = self._x0_eps_to_xt(known_x0_skl.to(device=sample_skl.device, dtype=sample_skl.dtype), known_noise_skl.to(device=sample_skl.device, dtype=sample_skl.dtype), float(t_prev)) + sample_skl = _blend_dense(sample_skl, known_xt_skl, inpaint_mask_skl) + + ret.pred_x_t.append(sample) + ret.pred_x_0.append(out.pred_x_0) + ret.pred_x_t_skl.append(sample_skl) + ret.pred_x_0_skl.append(out.pred_x_0_skl) + if progress_callback is not None: + progress_callback(step_idx, int(steps)) + + ret.samples = sample + ret.samples_skl = sample_skl + return ret + + +class AniGenFlowEulerCfgSampler(AniGenClassifierFreeGuidanceSamplerMixin, AniGenFlowEulerSampler): + """ + Generate samples from a flow-matching model using Euler sampling with classifier-free guidance. + """ + @torch.no_grad() + def sample( + self, + model, + noise, + noise_skl, + cond, + neg_cond, + steps: int = 50, + rescale_t: float = 1.0, + cfg_strength: float = 3.0, + verbose: bool = True, + progress_callback: Optional[Callable[[int, int], None]] = None, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + neg_cond: negative conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + cfg_strength: The strength of classifier-free guidance. + verbose: If True, show a progress bar. + progress_callback: Optional callback(step_index, total_steps) invoked after each step. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + return super().sample(model, noise, noise_skl, cond, steps, rescale_t, verbose, progress_callback=progress_callback, neg_cond=neg_cond, cfg_strength=cfg_strength, **kwargs) + + +class AniGenFlowEulerGuidanceIntervalSampler(AniGenGuidanceIntervalSamplerMixin, AniGenFlowEulerSampler): + """ + Generate samples from a flow-matching model using Euler sampling with classifier-free guidance and interval. + """ + @torch.no_grad() + def sample( + self, + model, + noise, + noise_skl, + cond, + neg_cond, + steps: int = 50, + rescale_t: float = 1.0, + cfg_strength: float = 3.0, + cfg_interval: Tuple[float, float] = (0.0, 1.0), + verbose: bool = True, + progress_callback: Optional[Callable[[int, int], None]] = None, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + neg_cond: negative conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + cfg_strength: The strength of classifier-free guidance. + cfg_interval: The interval for classifier-free guidance. + verbose: If True, show a progress bar. + progress_callback: Optional callback(step_index, total_steps) invoked after each step. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + return super().sample(model, noise, noise_skl, cond, steps, rescale_t, verbose, progress_callback=progress_callback, neg_cond=neg_cond, cfg_strength=cfg_strength, cfg_interval=cfg_interval, **kwargs) diff --git a/anigen/pipelines/samplers/base.py b/anigen/pipelines/samplers/base.py new file mode 100644 index 0000000000000000000000000000000000000000..1966ce787009a5ee0c1ed06dce491525ff1dbcbf --- /dev/null +++ b/anigen/pipelines/samplers/base.py @@ -0,0 +1,20 @@ +from typing import * +from abc import ABC, abstractmethod + + +class Sampler(ABC): + """ + A base class for samplers. + """ + + @abstractmethod + def sample( + self, + model, + **kwargs + ): + """ + Sample from a model. + """ + pass + \ No newline at end of file diff --git a/anigen/pipelines/samplers/classifier_free_guidance_mixin.py b/anigen/pipelines/samplers/classifier_free_guidance_mixin.py new file mode 100644 index 0000000000000000000000000000000000000000..3baa06d7a34717846355aac96b0760f054d16ddd --- /dev/null +++ b/anigen/pipelines/samplers/classifier_free_guidance_mixin.py @@ -0,0 +1,35 @@ +from typing import * + + +class ClassifierFreeGuidanceSamplerMixin: + """ + A mixin class for samplers that apply classifier-free guidance. + """ + + def _inference_model(self, model, x_t, t, cond, neg_cond, cfg_strength, **kwargs): + pred = super()._inference_model(model, x_t, t, cond, **kwargs) + neg_pred = super()._inference_model(model, x_t, t, neg_cond, **kwargs) + return (1 + cfg_strength) * pred - cfg_strength * neg_pred + + +class AniGenClassifierFreeGuidanceSamplerMixin: + """ + A mixin class for samplers that apply classifier-free guidance. + """ + + def _inference_model(self, model, x_t, x_t_skl, t, cond, neg_cond, cfg_strength, **kwargs): + # Allow per-branch kwargs for the negative/unconditional pass via `neg_`. + # Example: pass `joints_num=J` and `neg_joints_num=0` to apply CFG on joints number. + neg_overrides = {} + shared_kwargs = {} + for k, v in kwargs.items(): + if k.startswith('neg_'): + neg_overrides[k[4:]] = v + else: + shared_kwargs[k] = v + + pred, pred_skl = super()._inference_model(model, x_t, x_t_skl, t, cond, **shared_kwargs) + neg_kwargs = dict(shared_kwargs) + neg_kwargs.update(neg_overrides) + neg_pred, neg_pred_skl = super()._inference_model(model, x_t, x_t_skl, t, neg_cond, **neg_kwargs) + return (1 + cfg_strength) * pred - cfg_strength * neg_pred, (1 + cfg_strength) * pred_skl - cfg_strength * neg_pred_skl diff --git a/anigen/pipelines/samplers/flow_euler.py b/anigen/pipelines/samplers/flow_euler.py new file mode 100644 index 0000000000000000000000000000000000000000..2be478c5d6646fde8327bd05fbb083ee936ecda1 --- /dev/null +++ b/anigen/pipelines/samplers/flow_euler.py @@ -0,0 +1,264 @@ +from typing import * +import torch +import numpy as np +from tqdm import tqdm +from easydict import EasyDict as edict +from .base import Sampler +from .classifier_free_guidance_mixin import ClassifierFreeGuidanceSamplerMixin +from .guidance_interval_mixin import GuidanceIntervalSamplerMixin + + +class FlowEulerSampler(Sampler): + """ + Generate samples from a flow-matching model using Euler sampling. + + Args: + sigma_min: The minimum scale of noise in flow. + """ + def __init__( + self, + sigma_min: float, + ): + self.sigma_min = sigma_min + + def _eps_to_xstart(self, x_t, t, eps): + assert x_t.shape == eps.shape + return (x_t - (self.sigma_min + (1 - self.sigma_min) * t) * eps) / (1 - t) + + def _xstart_to_eps(self, x_t, t, x_0): + assert x_t.shape == x_0.shape + return (x_t - (1 - t) * x_0) / (self.sigma_min + (1 - self.sigma_min) * t) + + def _v_to_xstart_eps(self, x_t, t, v): + assert x_t.shape == v.shape + eps = (1 - t) * v + x_t + x_0 = (1 - self.sigma_min) * x_t - (self.sigma_min + (1 - self.sigma_min) * t) * v + return x_0, eps + + def _inference_model(self, model, x_t, t, cond=None, **kwargs): + t = torch.tensor([1000 * t] * x_t.shape[0], device=x_t.device, dtype=torch.float32) + if cond is not None and cond.shape[0] == 1 and x_t.shape[0] > 1: + cond = cond.repeat(x_t.shape[0], *([1] * (len(cond.shape) - 1))) + return model(x_t, t, cond, **kwargs) + + def _get_model_prediction(self, model, x_t, t, cond=None, **kwargs): + pred_v = self._inference_model(model, x_t, t, cond, **kwargs) + pred_x_0, pred_eps = self._v_to_xstart_eps(x_t=x_t, t=t, v=pred_v) + return pred_x_0, pred_eps, pred_v + + @torch.no_grad() + def sample_once( + self, + model, + x_t, + t: float, + t_prev: float, + cond: Optional[Any] = None, + **kwargs + ): + """ + Sample x_{t-1} from the model using Euler method. + + Args: + model: The model to sample from. + x_t: The [N x C x ...] tensor of noisy inputs at time t. + t: The current timestep. + t_prev: The previous timestep. + cond: conditional information. + **kwargs: Additional arguments for model inference. + + Returns: + a dict containing the following + - 'pred_x_prev': x_{t-1}. + - 'pred_x_0': a prediction of x_0. + """ + pred_x_0, pred_eps, pred_v = self._get_model_prediction(model, x_t, t, cond, **kwargs) + pred_x_prev = x_t - (t - t_prev) * pred_v + return edict({"pred_x_prev": pred_x_prev, "pred_x_0": pred_x_0}) + + @torch.no_grad() + def inpaint_sample_once( + self, + model, + x_t, + x_0, + x_0_mask, + t: float, + t_prev: float, + cond: Optional[Any] = None, + **kwargs + ): + pred_x_0, pred_eps, pred_v = self._get_model_prediction(model, x_t, t, cond, **kwargs) + pred_x_0 = x_0_mask * x_0 + (1 - x_0_mask) * pred_x_0 + pred_v = x_0_mask * (x_t - x_0) / t + (1 - x_0_mask) * pred_v + pred_x_prev = x_t - (t - t_prev) * pred_v + # pred_x_prev = x_0_mask * ((x_t - x_0) / t * t_prev + x_0) + (1 - x_0_mask) * pred_x_prev + return edict({"pred_x_prev": pred_x_prev, "pred_x_0": pred_x_0}) + + @torch.no_grad() + def sample( + self, + model, + noise, + cond: Optional[Any] = None, + steps: int = 50, + rescale_t: float = 1.0, + verbose: bool = True, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + verbose: If True, show a progress bar. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + sample = noise + t_seq = np.linspace(1, 0, steps + 1) + t_seq = rescale_t * t_seq / (1 + (rescale_t - 1) * t_seq) + t_pairs = list((t_seq[i], t_seq[i + 1]) for i in range(steps)) + ret = edict({"samples": None, "pred_x_t": [], "pred_x_0": []}) + for t, t_prev in tqdm(t_pairs, desc="Sampling", disable=not verbose): + out = self.sample_once(model, sample, t, t_prev, cond, **kwargs) + sample = out.pred_x_prev + ret.pred_x_t.append(out.pred_x_prev) + ret.pred_x_0.append(out.pred_x_0) + ret.samples = sample + return ret + + @torch.no_grad() + def inpaint_sample( + self, + model, + noise, + z0, + z0_mask, + cond: Optional[Any] = None, + steps: int = 50, + rescale_t: float = 1.0, + verbose: bool = True, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + verbose: If True, show a progress bar. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + sample = noise + t_seq = np.linspace(1, 0, steps + 1) + t_seq = rescale_t * t_seq / (1 + (rescale_t - 1) * t_seq) + t_pairs = list((t_seq[i], t_seq[i + 1]) for i in range(steps)) + ret = edict({"samples": None, "pred_x_t": [], "pred_x_0": []}) + for t, t_prev in tqdm(t_pairs, desc="Sampling", disable=not verbose): + out = self.inpaint_sample_once(model, sample, z0, z0_mask, t, t_prev, cond, **kwargs) + sample = out.pred_x_prev + ret.pred_x_t.append(out.pred_x_prev) + ret.pred_x_0.append(out.pred_x_0) + ret.samples = sample + return ret + + +class FlowEulerCfgSampler(ClassifierFreeGuidanceSamplerMixin, FlowEulerSampler): + """ + Generate samples from a flow-matching model using Euler sampling with classifier-free guidance. + """ + @torch.no_grad() + def sample( + self, + model, + noise, + cond, + neg_cond, + steps: int = 50, + rescale_t: float = 1.0, + cfg_strength: float = 3.0, + verbose: bool = True, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + neg_cond: negative conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + cfg_strength: The strength of classifier-free guidance. + verbose: If True, show a progress bar. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + return super().sample(model, noise, cond, steps, rescale_t, verbose, neg_cond=neg_cond, cfg_strength=cfg_strength, **kwargs) + + +class FlowEulerGuidanceIntervalSampler(GuidanceIntervalSamplerMixin, FlowEulerSampler): + """ + Generate samples from a flow-matching model using Euler sampling with classifier-free guidance and interval. + """ + @torch.no_grad() + def sample( + self, + model, + noise, + cond, + neg_cond, + steps: int = 50, + rescale_t: float = 1.0, + cfg_strength: float = 3.0, + cfg_interval: Tuple[float, float] = (0.0, 1.0), + verbose: bool = True, + **kwargs + ): + """ + Generate samples from the model using Euler method. + + Args: + model: The model to sample from. + noise: The initial noise tensor. + cond: conditional information. + neg_cond: negative conditional information. + steps: The number of steps to sample. + rescale_t: The rescale factor for t. + cfg_strength: The strength of classifier-free guidance. + cfg_interval: The interval for classifier-free guidance. + verbose: If True, show a progress bar. + **kwargs: Additional arguments for model_inference. + + Returns: + a dict containing the following + - 'samples': the model samples. + - 'pred_x_t': a list of prediction of x_t. + - 'pred_x_0': a list of prediction of x_0. + """ + return super().sample(model, noise, cond, steps, rescale_t, verbose, neg_cond=neg_cond, cfg_strength=cfg_strength, cfg_interval=cfg_interval, **kwargs) diff --git a/anigen/pipelines/samplers/guidance_interval_mixin.py b/anigen/pipelines/samplers/guidance_interval_mixin.py new file mode 100644 index 0000000000000000000000000000000000000000..53f981bf0ff631a9a6224cdadb0ab9c7a4443f68 --- /dev/null +++ b/anigen/pipelines/samplers/guidance_interval_mixin.py @@ -0,0 +1,29 @@ +from typing import * + + +class GuidanceIntervalSamplerMixin: + """ + A mixin class for samplers that apply classifier-free guidance with interval. + """ + + def _inference_model(self, model, x_t, t, cond, neg_cond, cfg_strength, cfg_interval, **kwargs): + if cfg_interval[0] <= t <= cfg_interval[1]: + pred = super()._inference_model(model, x_t, t, cond, **kwargs) + neg_pred = super()._inference_model(model, x_t, t, neg_cond, **kwargs) + return (1 + cfg_strength) * pred - cfg_strength * neg_pred + else: + return super()._inference_model(model, x_t, t, cond, **kwargs) + + +class AniGenGuidanceIntervalSamplerMixin: + """ + A mixin class for samplers that apply classifier-free guidance with interval. + """ + + def _inference_model(self, model, x_t, x_t_skl, t, cond, neg_cond, cfg_strength, cfg_interval, **kwargs): + if cfg_interval[0] <= t <= cfg_interval[1]: + pred, pred_skl = super()._inference_model(model, x_t, x_t_skl, t, cond, **kwargs) + neg_pred, neg_pred_skl = super()._inference_model(model, x_t, x_t_skl, t, neg_cond, **kwargs) + return (1 + cfg_strength) * pred - cfg_strength * neg_pred, (1 + cfg_strength) * pred_skl - cfg_strength * neg_pred_skl + else: + return super()._inference_model(model, x_t, x_t_skl, t, cond, **kwargs) diff --git a/anigen/renderers/__init__.py b/anigen/renderers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0339355c56b8d17f72e926650d140a658452fbe9 --- /dev/null +++ b/anigen/renderers/__init__.py @@ -0,0 +1,31 @@ +import importlib + +__attributes = { + 'OctreeRenderer': 'octree_renderer', + 'GaussianRenderer': 'gaussian_render', + 'MeshRenderer': 'mesh_renderer', +} + +__submodules = [] + +__all__ = list(__attributes.keys()) + __submodules + +def __getattr__(name): + if name not in globals(): + if name in __attributes: + module_name = __attributes[name] + module = importlib.import_module(f".{module_name}", __name__) + globals()[name] = getattr(module, name) + elif name in __submodules: + module = importlib.import_module(f".{name}", __name__) + globals()[name] = module + else: + raise AttributeError(f"module {__name__} has no attribute {name}") + return globals()[name] + + +# For Pylance +if __name__ == '__main__': + from .octree_renderer import OctreeRenderer + from .gaussian_render import GaussianRenderer + from .mesh_renderer import MeshRenderer \ No newline at end of file diff --git a/anigen/renderers/gaussian_render.py b/anigen/renderers/gaussian_render.py new file mode 100644 index 0000000000000000000000000000000000000000..57108e3cccf6aab8e3059431557c461de46aff1a --- /dev/null +++ b/anigen/renderers/gaussian_render.py @@ -0,0 +1,231 @@ +# +# Copyright (C) 2023, Inria +# GRAPHDECO research group, https://team.inria.fr/graphdeco +# All rights reserved. +# +# This software is free for non-commercial, research and evaluation use +# under the terms of the LICENSE.md file. +# +# For inquiries contact george.drettakis@inria.fr +# + +import torch +import math +from easydict import EasyDict as edict +import numpy as np +from ..representations.gaussian import Gaussian +from .sh_utils import eval_sh +import torch.nn.functional as F +from easydict import EasyDict as edict + + +def intrinsics_to_projection( + intrinsics: torch.Tensor, + near: float, + far: float, + ) -> torch.Tensor: + """ + OpenCV intrinsics to OpenGL perspective matrix + + Args: + intrinsics (torch.Tensor): [3, 3] OpenCV intrinsics matrix + near (float): near plane to clip + far (float): far plane to clip + Returns: + (torch.Tensor): [4, 4] OpenGL perspective matrix + """ + fx, fy = intrinsics[0, 0], intrinsics[1, 1] + cx, cy = intrinsics[0, 2], intrinsics[1, 2] + ret = torch.zeros((4, 4), dtype=intrinsics.dtype, device=intrinsics.device) + ret[0, 0] = 2 * fx + ret[1, 1] = 2 * fy + ret[0, 2] = 2 * cx - 1 + ret[1, 2] = - 2 * cy + 1 + ret[2, 2] = far / (far - near) + ret[2, 3] = near * far / (near - far) + ret[3, 2] = 1. + return ret + + +def render(viewpoint_camera, pc : Gaussian, pipe, bg_color : torch.Tensor, scaling_modifier = 1.0, override_color = None): + """ + Render the scene. + + Background tensor (bg_color) must be on GPU! + """ + # lazy import + if 'GaussianRasterizer' not in globals(): + from diff_gaussian_rasterization import GaussianRasterizer, GaussianRasterizationSettings + + # Create zero tensor. We will use it to make pytorch return gradients of the 2D (screen-space) means + screenspace_points = torch.zeros_like(pc.get_xyz, dtype=pc.get_xyz.dtype, requires_grad=True, device="cuda") + 0 + try: + screenspace_points.retain_grad() + except: + pass + # Set up rasterization configuration + tanfovx = math.tan(viewpoint_camera.FoVx * 0.5) + tanfovy = math.tan(viewpoint_camera.FoVy * 0.5) + + kernel_size = pipe.kernel_size + subpixel_offset = torch.zeros((int(viewpoint_camera.image_height), int(viewpoint_camera.image_width), 2), dtype=torch.float32, device="cuda") + + raster_settings = GaussianRasterizationSettings( + image_height=int(viewpoint_camera.image_height), + image_width=int(viewpoint_camera.image_width), + tanfovx=tanfovx, + tanfovy=tanfovy, + kernel_size=kernel_size, + subpixel_offset=subpixel_offset, + bg=bg_color, + scale_modifier=scaling_modifier, + viewmatrix=viewpoint_camera.world_view_transform, + projmatrix=viewpoint_camera.full_proj_transform, + sh_degree=pc.active_sh_degree, + campos=viewpoint_camera.camera_center, + prefiltered=False, + debug=pipe.debug + ) + + rasterizer = GaussianRasterizer(raster_settings=raster_settings) + + means3D = pc.get_xyz + means2D = screenspace_points + opacity = pc.get_opacity + + # If precomputed 3d covariance is provided, use it. If not, then it will be computed from + # scaling / rotation by the rasterizer. + scales = None + rotations = None + cov3D_precomp = None + if pipe.compute_cov3D_python: + cov3D_precomp = pc.get_covariance(scaling_modifier) + else: + scales = pc.get_scaling + rotations = pc.get_rotation + + # If precomputed colors are provided, use them. Otherwise, if it is desired to precompute colors + # from SHs in Python, do it. If not, then SH -> RGB conversion will be done by rasterizer. + shs = None + colors_precomp = None + if override_color is None: + if pipe.convert_SHs_python: + shs_view = pc.get_features.transpose(1, 2).view(-1, 3, (pc.max_sh_degree+1)**2) + dir_pp = (pc.get_xyz - viewpoint_camera.camera_center.repeat(pc.get_features.shape[0], 1)) + dir_pp_normalized = dir_pp/dir_pp.norm(dim=1, keepdim=True) + sh2rgb = eval_sh(pc.active_sh_degree, shs_view, dir_pp_normalized) + colors_precomp = torch.clamp_min(sh2rgb + 0.5, 0.0) + else: + shs = pc.get_features + else: + colors_precomp = override_color + + # Rasterize visible Gaussians to image, obtain their radii (on screen). + rendered_image, radii = rasterizer( + means3D = means3D, + means2D = means2D, + shs = shs, + colors_precomp = colors_precomp, + opacities = opacity, + scales = scales, + rotations = rotations, + cov3D_precomp = cov3D_precomp + ) + + # Those Gaussians that were frustum culled or had a radius of 0 were not visible. + # They will be excluded from value updates used in the splitting criteria. + return edict({"render": rendered_image, + "viewspace_points": screenspace_points, + "visibility_filter" : radii > 0, + "radii": radii}) + + +class GaussianRenderer: + """ + Renderer for the Voxel representation. + + Args: + rendering_options (dict): Rendering options. + """ + + def __init__(self, rendering_options={}) -> None: + self.pipe = edict({ + "kernel_size": 0.1, + "convert_SHs_python": False, + "compute_cov3D_python": False, + "scale_modifier": 1.0, + "debug": False + }) + self.rendering_options = edict({ + "resolution": None, + "near": None, + "far": None, + "ssaa": 1, + "bg_color": 'random', + }) + self.rendering_options.update(rendering_options) + self.bg_color = None + + def render( + self, + gausssian: Gaussian, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + colors_overwrite: torch.Tensor = None + ) -> edict: + """ + Render the gausssian. + + Args: + gaussian : gaussianmodule + extrinsics (torch.Tensor): (4, 4) camera extrinsics + intrinsics (torch.Tensor): (3, 3) camera intrinsics + colors_overwrite (torch.Tensor): (N, 3) override color + + Returns: + edict containing: + color (torch.Tensor): (3, H, W) rendered color image + """ + resolution = self.rendering_options["resolution"] + near = self.rendering_options["near"] + far = self.rendering_options["far"] + ssaa = self.rendering_options["ssaa"] + + if self.rendering_options["bg_color"] == 'random': + self.bg_color = torch.zeros(3, dtype=torch.float32, device="cuda") + if np.random.rand() < 0.5: + self.bg_color += 1 + else: + self.bg_color = torch.tensor(self.rendering_options["bg_color"], dtype=torch.float32, device="cuda") + + view = extrinsics + perspective = intrinsics_to_projection(intrinsics, near, far) + camera = torch.inverse(view)[:3, 3] + focalx = intrinsics[0, 0] + focaly = intrinsics[1, 1] + fovx = 2 * torch.atan(0.5 / focalx) + fovy = 2 * torch.atan(0.5 / focaly) + + camera_dict = edict({ + "image_height": resolution * ssaa, + "image_width": resolution * ssaa, + "FoVx": fovx, + "FoVy": fovy, + "znear": near, + "zfar": far, + "world_view_transform": view.T.contiguous(), + "projection_matrix": perspective.T.contiguous(), + "full_proj_transform": (perspective @ view).T.contiguous(), + "camera_center": camera + }) + + # Render + render_ret = render(camera_dict, gausssian, self.pipe, self.bg_color, override_color=colors_overwrite, scaling_modifier=self.pipe.scale_modifier) + + if ssaa > 1: + render_ret.render = F.interpolate(render_ret.render[None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + + ret = edict({ + 'color': render_ret['render'] + }) + return ret diff --git a/anigen/renderers/mesh_renderer.py b/anigen/renderers/mesh_renderer.py new file mode 100644 index 0000000000000000000000000000000000000000..03ab4219073e6fb182045b011dd3826bbf0971b5 --- /dev/null +++ b/anigen/renderers/mesh_renderer.py @@ -0,0 +1,139 @@ +import torch +import nvdiffrast.torch as dr +from easydict import EasyDict as edict +from ..representations.mesh import MeshExtractResult +import torch.nn.functional as F + + +def intrinsics_to_projection( + intrinsics: torch.Tensor, + near: float, + far: float, + ) -> torch.Tensor: + """ + OpenCV intrinsics to OpenGL perspective matrix + + Args: + intrinsics (torch.Tensor): [3, 3] OpenCV intrinsics matrix + near (float): near plane to clip + far (float): far plane to clip + Returns: + (torch.Tensor): [4, 4] OpenGL perspective matrix + """ + fx, fy = intrinsics[0, 0], intrinsics[1, 1] + cx, cy = intrinsics[0, 2], intrinsics[1, 2] + ret = torch.zeros((4, 4), dtype=intrinsics.dtype, device=intrinsics.device) + ret[0, 0] = 2 * fx + ret[1, 1] = 2 * fy + ret[0, 2] = 2 * cx - 1 + ret[1, 2] = - 2 * cy + 1 + ret[2, 2] = far / (far - near) + ret[2, 3] = near * far / (near - far) + ret[3, 2] = 1. + return ret + + +class MeshRenderer: + """ + Renderer for the Mesh representation. + + Args: + rendering_options (dict): Rendering options. + glctx (nvdiffrast.torch.RasterizeGLContext): RasterizeGLContext object for CUDA/OpenGL interop. + """ + def __init__(self, rendering_options={}, device='cuda'): + self.rendering_options = edict({ + "resolution": None, + "near": None, + "far": None, + "ssaa": 1 + }) + self.rendering_options.update(rendering_options) + self.glctx = dr.RasterizeCudaContext(device=device) + self.device=device + + def render( + self, + mesh : MeshExtractResult, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + return_types = ["mask", "normal", "depth"], + specified_color: torch.Tensor = None, + *args, + **kwargs, + ) -> edict: + """ + Render the mesh. + + Args: + mesh : meshmodel + extrinsics (torch.Tensor): (4, 4) camera extrinsics + intrinsics (torch.Tensor): (3, 3) camera intrinsics + return_types (list): list of return types, can be "mask", "depth", "normal_map", "normal", "color" + + Returns: + edict based on return_types containing: + color (torch.Tensor): [3, H, W] rendered color image + depth (torch.Tensor): [H, W] rendered depth image + normal (torch.Tensor): [3, H, W] rendered normal image + normal_map (torch.Tensor): [3, H, W] rendered normal map image + mask (torch.Tensor): [H, W] rendered mask image + """ + resolution = self.rendering_options["resolution"] + near = self.rendering_options["near"] + far = self.rendering_options["far"] + ssaa = self.rendering_options["ssaa"] + + if mesh.vertices.shape[0] == 0 or mesh.faces.shape[0] == 0: + default_img = torch.zeros((1, resolution, resolution, 3), dtype=torch.float32, device=self.device).permute(0, 3, 1, 2).squeeze() + ret_dict = {k : default_img if k in ['normal', 'normal_map', 'color'] else default_img[0] for k in return_types} + return ret_dict + + perspective = intrinsics_to_projection(intrinsics, near, far) + + RT = extrinsics.unsqueeze(0) + full_proj = (perspective @ extrinsics).unsqueeze(0) + + vertices = mesh.vertices.unsqueeze(0) + + vertices_homo = torch.cat([vertices, torch.ones_like(vertices[..., :1])], dim=-1) + vertices_camera = torch.bmm(vertices_homo, RT.transpose(-1, -2)) + vertices_clip = torch.bmm(vertices_homo, full_proj.transpose(-1, -2)) + faces_int = mesh.faces.int() + rast, _ = dr.rasterize( + self.glctx, vertices_clip, faces_int, (resolution * ssaa, resolution * ssaa)) + + out_dict = edict() + for type in return_types: + img = None + if type == "mask" : + img = dr.antialias((rast[..., -1:] > 0).float(), rast, vertices_clip, faces_int) + elif type == "depth": + img = dr.interpolate(vertices_camera[..., 2:3].contiguous(), rast, faces_int)[0] + img = dr.antialias(img, rast, vertices_clip, faces_int) + elif type == "normal" : + img = dr.interpolate( + mesh.face_normal.reshape(1, -1, 3), rast, + torch.arange(mesh.faces.shape[0] * 3, device=self.device, dtype=torch.int).reshape(-1, 3) + )[0] + img = dr.antialias(img, rast, vertices_clip, faces_int) + # normalize norm pictures + img = (img + 1) / 2 + elif type == "normal_map" : + img = dr.interpolate(mesh.vertex_attrs[:, 3:].contiguous(), rast, faces_int)[0] + img = dr.antialias(img, rast, vertices_clip, faces_int) + elif type == "color" : + img = dr.interpolate(mesh.vertex_attrs[:, :3].contiguous(), rast, faces_int)[0] + img = dr.antialias(img, rast, vertices_clip, faces_int) + elif type == "specified" and specified_color is not None: + img = dr.interpolate(specified_color.unsqueeze(0).contiguous(), rast, faces_int)[0] + img = dr.antialias(img, rast, vertices_clip, faces_int) + + if ssaa > 1: + img = F.interpolate(img.permute(0, 3, 1, 2), (resolution, resolution), mode='bilinear', align_corners=False, antialias=True) + img = img.squeeze() + else: + img = img.permute(0, 3, 1, 2).squeeze() + out_dict[type] = img + + return out_dict diff --git a/anigen/renderers/octree_renderer.py b/anigen/renderers/octree_renderer.py new file mode 100644 index 0000000000000000000000000000000000000000..e0a81d3cf8a151d9243d2b782752995f5a12a85e --- /dev/null +++ b/anigen/renderers/octree_renderer.py @@ -0,0 +1,307 @@ +import numpy as np +import torch +import torch.nn.functional as F +import math +import cv2 +from scipy.stats import qmc +from easydict import EasyDict as edict +from ..representations.octree import DfsOctree + + +def intrinsics_to_projection( + intrinsics: torch.Tensor, + near: float, + far: float, + ) -> torch.Tensor: + """ + OpenCV intrinsics to OpenGL perspective matrix + + Args: + intrinsics (torch.Tensor): [3, 3] OpenCV intrinsics matrix + near (float): near plane to clip + far (float): far plane to clip + Returns: + (torch.Tensor): [4, 4] OpenGL perspective matrix + """ + fx, fy = intrinsics[0, 0], intrinsics[1, 1] + cx, cy = intrinsics[0, 2], intrinsics[1, 2] + ret = torch.zeros((4, 4), dtype=intrinsics.dtype, device=intrinsics.device) + ret[0, 0] = 2 * fx + ret[1, 1] = 2 * fy + ret[0, 2] = 2 * cx - 1 + ret[1, 2] = - 2 * cy + 1 + ret[2, 2] = far / (far - near) + ret[2, 3] = near * far / (near - far) + ret[3, 2] = 1. + return ret + + +def render(viewpoint_camera, octree : DfsOctree, pipe, bg_color : torch.Tensor, scaling_modifier = 1.0, used_rank = None, colors_overwrite = None, aux=None, halton_sampler=None): + """ + Render the scene. + + Background tensor (bg_color) must be on GPU! + """ + # lazy import + if 'OctreeTrivecRasterizer' not in globals(): + from diffoctreerast import OctreeVoxelRasterizer, OctreeGaussianRasterizer, OctreeTrivecRasterizer, OctreeDecoupolyRasterizer + + # Set up rasterization configuration + tanfovx = math.tan(viewpoint_camera.FoVx * 0.5) + tanfovy = math.tan(viewpoint_camera.FoVy * 0.5) + + raster_settings = edict( + image_height=int(viewpoint_camera.image_height), + image_width=int(viewpoint_camera.image_width), + tanfovx=tanfovx, + tanfovy=tanfovy, + bg=bg_color, + scale_modifier=scaling_modifier, + viewmatrix=viewpoint_camera.world_view_transform, + projmatrix=viewpoint_camera.full_proj_transform, + sh_degree=octree.active_sh_degree, + campos=viewpoint_camera.camera_center, + with_distloss=pipe.with_distloss, + jitter=pipe.jitter, + debug=pipe.debug, + ) + + positions = octree.get_xyz + if octree.primitive == "voxel": + densities = octree.get_density + elif octree.primitive == "gaussian": + opacities = octree.get_opacity + elif octree.primitive == "trivec": + trivecs = octree.get_trivec + densities = octree.get_density + raster_settings.density_shift = octree.density_shift + elif octree.primitive == "decoupoly": + decoupolys_V, decoupolys_g = octree.get_decoupoly + densities = octree.get_density + raster_settings.density_shift = octree.density_shift + else: + raise ValueError(f"Unknown primitive {octree.primitive}") + depths = octree.get_depth + + # If precomputed colors are provided, use them. Otherwise, if it is desired to precompute colors + # from SHs in Python, do it. If not, then SH -> RGB conversion will be done by rasterizer. + colors_precomp = None + shs = octree.get_features + if octree.primitive in ["voxel", "gaussian"] and colors_overwrite is not None: + colors_precomp = colors_overwrite + shs = None + + ret = edict() + + if octree.primitive == "voxel": + renderer = OctreeVoxelRasterizer(raster_settings=raster_settings) + rgb, depth, alpha, distloss = renderer( + positions = positions, + densities = densities, + shs = shs, + colors_precomp = colors_precomp, + depths = depths, + aabb = octree.aabb, + aux = aux, + ) + ret['rgb'] = rgb + ret['depth'] = depth + ret['alpha'] = alpha + ret['distloss'] = distloss + elif octree.primitive == "gaussian": + renderer = OctreeGaussianRasterizer(raster_settings=raster_settings) + rgb, depth, alpha = renderer( + positions = positions, + opacities = opacities, + shs = shs, + colors_precomp = colors_precomp, + depths = depths, + aabb = octree.aabb, + aux = aux, + ) + ret['rgb'] = rgb + ret['depth'] = depth + ret['alpha'] = alpha + elif octree.primitive == "trivec": + raster_settings.used_rank = used_rank if used_rank is not None else trivecs.shape[1] + renderer = OctreeTrivecRasterizer(raster_settings=raster_settings) + rgb, depth, alpha, percent_depth = renderer( + positions = positions, + trivecs = trivecs, + densities = densities, + shs = shs, + colors_precomp = colors_precomp, + colors_overwrite = colors_overwrite, + depths = depths, + aabb = octree.aabb, + aux = aux, + halton_sampler = halton_sampler, + ) + ret['percent_depth'] = percent_depth + ret['rgb'] = rgb + ret['depth'] = depth + ret['alpha'] = alpha + elif octree.primitive == "decoupoly": + raster_settings.used_rank = used_rank if used_rank is not None else decoupolys_V.shape[1] + renderer = OctreeDecoupolyRasterizer(raster_settings=raster_settings) + rgb, depth, alpha = renderer( + positions = positions, + decoupolys_V = decoupolys_V, + decoupolys_g = decoupolys_g, + densities = densities, + shs = shs, + colors_precomp = colors_precomp, + depths = depths, + aabb = octree.aabb, + aux = aux, + ) + ret['rgb'] = rgb + ret['depth'] = depth + ret['alpha'] = alpha + + return ret + + +class OctreeRenderer: + """ + Renderer for the Voxel representation. + + Args: + rendering_options (dict): Rendering options. + """ + + def __init__(self, rendering_options={}) -> None: + try: + import diffoctreerast + except ImportError: + print("\033[93m[WARNING] diffoctreerast is not installed. The renderer will be disabled.\033[0m") + self.unsupported = True + else: + self.unsupported = False + + self.pipe = edict({ + "with_distloss": False, + "with_aux": False, + "scale_modifier": 1.0, + "used_rank": None, + "jitter": False, + "debug": False, + }) + self.rendering_options = edict({ + "resolution": None, + "near": None, + "far": None, + "ssaa": 1, + "bg_color": 'random', + }) + self.halton_sampler = qmc.Halton(2, scramble=False) + self.rendering_options.update(rendering_options) + self.bg_color = None + + def render( + self, + octree: DfsOctree, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + colors_overwrite: torch.Tensor = None, + ) -> edict: + """ + Render the octree. + + Args: + octree (Octree): octree + extrinsics (torch.Tensor): (4, 4) camera extrinsics + intrinsics (torch.Tensor): (3, 3) camera intrinsics + colors_overwrite (torch.Tensor): (N, 3) override color + + Returns: + edict containing: + color (torch.Tensor): (3, H, W) rendered color + depth (torch.Tensor): (H, W) rendered depth + alpha (torch.Tensor): (H, W) rendered alpha + distloss (Optional[torch.Tensor]): (H, W) rendered distance loss + percent_depth (Optional[torch.Tensor]): (H, W) rendered percent depth + aux (Optional[edict]): auxiliary tensors + """ + resolution = self.rendering_options["resolution"] + near = self.rendering_options["near"] + far = self.rendering_options["far"] + ssaa = self.rendering_options["ssaa"] + + if self.unsupported: + image = np.zeros((512, 512, 3), dtype=np.uint8) + text_bbox = cv2.getTextSize("Unsupported", cv2.FONT_HERSHEY_SIMPLEX, 2, 3)[0] + origin = (512 - text_bbox[0]) // 2, (512 - text_bbox[1]) // 2 + image = cv2.putText(image, "Unsupported", origin, cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 3, cv2.LINE_AA) + return { + 'color': torch.tensor(image, dtype=torch.float32).permute(2, 0, 1) / 255, + } + + if self.rendering_options["bg_color"] == 'random': + self.bg_color = torch.zeros(3, dtype=torch.float32, device="cuda") + if np.random.rand() < 0.5: + self.bg_color += 1 + else: + self.bg_color = torch.tensor(self.rendering_options["bg_color"], dtype=torch.float32, device="cuda") + + if self.pipe["with_aux"]: + aux = { + 'grad_color2': torch.zeros((octree.num_leaf_nodes, 3), dtype=torch.float32, requires_grad=True, device="cuda") + 0, + 'contributions': torch.zeros((octree.num_leaf_nodes, 1), dtype=torch.float32, requires_grad=True, device="cuda") + 0, + } + for k in aux.keys(): + aux[k].requires_grad_() + aux[k].retain_grad() + else: + aux = None + + view = extrinsics + perspective = intrinsics_to_projection(intrinsics, near, far) + camera = torch.inverse(view)[:3, 3] + focalx = intrinsics[0, 0] + focaly = intrinsics[1, 1] + fovx = 2 * torch.atan(0.5 / focalx) + fovy = 2 * torch.atan(0.5 / focaly) + + camera_dict = edict({ + "image_height": resolution * ssaa, + "image_width": resolution * ssaa, + "FoVx": fovx, + "FoVy": fovy, + "znear": near, + "zfar": far, + "world_view_transform": view.T.contiguous(), + "projection_matrix": perspective.T.contiguous(), + "full_proj_transform": (perspective @ view).T.contiguous(), + "camera_center": camera + }) + + # Render + render_ret = render(camera_dict, octree, self.pipe, self.bg_color, aux=aux, colors_overwrite=colors_overwrite, scaling_modifier=self.pipe.scale_modifier, used_rank=self.pipe.used_rank, halton_sampler=self.halton_sampler) + + if ssaa > 1: + try: + # data_cpu = render_ret.rgb[None].cpu() + F.interpolate(render_ret.rgb[None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + except: + # print(data_cpu.max(), render_ret.rgb[None].max(), data_cpu.min(), render_ret.rgb[None].min()) + # print('The first time interpolation failed but the second time should be fine') + pass + render_ret.rgb = F.interpolate(render_ret.rgb[None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + render_ret.depth = F.interpolate(render_ret.depth[None, None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + render_ret.alpha = F.interpolate(render_ret.alpha[None, None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + if hasattr(render_ret, 'percent_depth'): + render_ret.percent_depth = F.interpolate(render_ret.percent_depth[None, None], size=(resolution, resolution), mode='bilinear', align_corners=False, antialias=True).squeeze() + + ret = edict({ + 'color': render_ret.rgb, + 'depth': render_ret.depth, + 'alpha': render_ret.alpha, + }) + if self.pipe["with_distloss"] and 'distloss' in render_ret: + ret['distloss'] = render_ret.distloss + if self.pipe["with_aux"]: + ret['aux'] = aux + if hasattr(render_ret, 'percent_depth'): + ret['percent_depth'] = render_ret.percent_depth + return ret diff --git a/anigen/renderers/sh_utils.py b/anigen/renderers/sh_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..bbca7d192aa3a7edf8c5b2d24dee535eac765785 --- /dev/null +++ b/anigen/renderers/sh_utils.py @@ -0,0 +1,118 @@ +# Copyright 2021 The PlenOctree Authors. +# 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 above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. + +import torch + +C0 = 0.28209479177387814 +C1 = 0.4886025119029199 +C2 = [ + 1.0925484305920792, + -1.0925484305920792, + 0.31539156525252005, + -1.0925484305920792, + 0.5462742152960396 +] +C3 = [ + -0.5900435899266435, + 2.890611442640554, + -0.4570457994644658, + 0.3731763325901154, + -0.4570457994644658, + 1.445305721320277, + -0.5900435899266435 +] +C4 = [ + 2.5033429417967046, + -1.7701307697799304, + 0.9461746957575601, + -0.6690465435572892, + 0.10578554691520431, + -0.6690465435572892, + 0.47308734787878004, + -1.7701307697799304, + 0.6258357354491761, +] + + +def eval_sh(deg, sh, dirs): + """ + Evaluate spherical harmonics at unit directions + using hardcoded SH polynomials. + Works with torch/np/jnp. + ... Can be 0 or more batch dimensions. + Args: + deg: int SH deg. Currently, 0-3 supported + sh: jnp.ndarray SH coeffs [..., C, (deg + 1) ** 2] + dirs: jnp.ndarray unit directions [..., 3] + Returns: + [..., C] + """ + assert deg <= 4 and deg >= 0 + coeff = (deg + 1) ** 2 + assert sh.shape[-1] >= coeff + + result = C0 * sh[..., 0] + if deg > 0: + x, y, z = dirs[..., 0:1], dirs[..., 1:2], dirs[..., 2:3] + result = (result - + C1 * y * sh[..., 1] + + C1 * z * sh[..., 2] - + C1 * x * sh[..., 3]) + + if deg > 1: + xx, yy, zz = x * x, y * y, z * z + xy, yz, xz = x * y, y * z, x * z + result = (result + + C2[0] * xy * sh[..., 4] + + C2[1] * yz * sh[..., 5] + + C2[2] * (2.0 * zz - xx - yy) * sh[..., 6] + + C2[3] * xz * sh[..., 7] + + C2[4] * (xx - yy) * sh[..., 8]) + + if deg > 2: + result = (result + + C3[0] * y * (3 * xx - yy) * sh[..., 9] + + C3[1] * xy * z * sh[..., 10] + + C3[2] * y * (4 * zz - xx - yy)* sh[..., 11] + + C3[3] * z * (2 * zz - 3 * xx - 3 * yy) * sh[..., 12] + + C3[4] * x * (4 * zz - xx - yy) * sh[..., 13] + + C3[5] * z * (xx - yy) * sh[..., 14] + + C3[6] * x * (xx - 3 * yy) * sh[..., 15]) + + if deg > 3: + result = (result + C4[0] * xy * (xx - yy) * sh[..., 16] + + C4[1] * yz * (3 * xx - yy) * sh[..., 17] + + C4[2] * xy * (7 * zz - 1) * sh[..., 18] + + C4[3] * yz * (7 * zz - 3) * sh[..., 19] + + C4[4] * (zz * (35 * zz - 30) + 3) * sh[..., 20] + + C4[5] * xz * (7 * zz - 3) * sh[..., 21] + + C4[6] * (xx - yy) * (7 * zz - 1) * sh[..., 22] + + C4[7] * xz * (xx - 3 * yy) * sh[..., 23] + + C4[8] * (xx * (xx - 3 * yy) - yy * (3 * xx - yy)) * sh[..., 24]) + return result + +def RGB2SH(rgb): + return (rgb - 0.5) / C0 + +def SH2RGB(sh): + return sh * C0 + 0.5 \ No newline at end of file diff --git a/anigen/representations/__init__.py b/anigen/representations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..93edb4cb260a73ee35232aecc7c30c2b824f8f09 --- /dev/null +++ b/anigen/representations/__init__.py @@ -0,0 +1,5 @@ +from .radiance_field import Strivec +from .octree import DfsOctree as Octree +from .gaussian import Gaussian +from .mesh import MeshExtractResult +from .mesh import AniGenMeshExtractResult \ No newline at end of file diff --git a/anigen/representations/gaussian/__init__.py b/anigen/representations/gaussian/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e3de6e180bd732836af876d748255595be2d4d74 --- /dev/null +++ b/anigen/representations/gaussian/__init__.py @@ -0,0 +1 @@ +from .gaussian_model import Gaussian \ No newline at end of file diff --git a/anigen/representations/gaussian/gaussian_model.py b/anigen/representations/gaussian/gaussian_model.py new file mode 100644 index 0000000000000000000000000000000000000000..54ba16f1550e8edb1728605202cc31b6dd805d90 --- /dev/null +++ b/anigen/representations/gaussian/gaussian_model.py @@ -0,0 +1,209 @@ +import torch +import numpy as np +from plyfile import PlyData, PlyElement +from .general_utils import inverse_sigmoid, strip_symmetric, build_scaling_rotation +import utils3d + + +class Gaussian: + def __init__( + self, + aabb : list, + sh_degree : int = 0, + mininum_kernel_size : float = 0.0, + scaling_bias : float = 0.01, + opacity_bias : float = 0.1, + scaling_activation : str = "exp", + device='cuda' + ): + self.init_params = { + 'aabb': aabb, + 'sh_degree': sh_degree, + 'mininum_kernel_size': mininum_kernel_size, + 'scaling_bias': scaling_bias, + 'opacity_bias': opacity_bias, + 'scaling_activation': scaling_activation, + } + + self.sh_degree = sh_degree + self.active_sh_degree = sh_degree + self.mininum_kernel_size = mininum_kernel_size + self.scaling_bias = scaling_bias + self.opacity_bias = opacity_bias + self.scaling_activation_type = scaling_activation + self.device = device + self.aabb = torch.tensor(aabb, dtype=torch.float32, device=device) + self.setup_functions() + + self._xyz = None + self._features_dc = None + self._features_rest = None + self._scaling = None + self._rotation = None + self._opacity = None + + def setup_functions(self): + def build_covariance_from_scaling_rotation(scaling, scaling_modifier, rotation): + L = build_scaling_rotation(scaling_modifier * scaling, rotation) + actual_covariance = L @ L.transpose(1, 2) + symm = strip_symmetric(actual_covariance) + return symm + + if self.scaling_activation_type == "exp": + self.scaling_activation = torch.exp + self.inverse_scaling_activation = torch.log + elif self.scaling_activation_type == "softplus": + self.scaling_activation = torch.nn.functional.softplus + self.inverse_scaling_activation = lambda x: x + torch.log(-torch.expm1(-x)) + + self.covariance_activation = build_covariance_from_scaling_rotation + + self.opacity_activation = torch.sigmoid + self.inverse_opacity_activation = inverse_sigmoid + + self.rotation_activation = torch.nn.functional.normalize + + self.scale_bias = self.inverse_scaling_activation(torch.tensor(self.scaling_bias)).cuda() + self.rots_bias = torch.zeros((4)).cuda() + self.rots_bias[0] = 1 + self.opacity_bias = self.inverse_opacity_activation(torch.tensor(self.opacity_bias)).cuda() + + @property + def get_scaling(self): + scales = self.scaling_activation(self._scaling + self.scale_bias) + scales = torch.square(scales) + self.mininum_kernel_size ** 2 + scales = torch.sqrt(scales) + return scales + + @property + def get_rotation(self): + return self.rotation_activation(self._rotation + self.rots_bias[None, :]) + + @property + def get_xyz(self): + return self._xyz * self.aabb[None, 3:] + self.aabb[None, :3] + + @property + def get_features(self): + return torch.cat((self._features_dc, self._features_rest), dim=2) if self._features_rest is not None else self._features_dc + + @property + def get_opacity(self): + return self.opacity_activation(self._opacity + self.opacity_bias) + + def get_covariance(self, scaling_modifier = 1): + return self.covariance_activation(self.get_scaling, scaling_modifier, self._rotation + self.rots_bias[None, :]) + + def from_scaling(self, scales): + scales = torch.sqrt(torch.square(scales) - self.mininum_kernel_size ** 2) + self._scaling = self.inverse_scaling_activation(scales) - self.scale_bias + + def from_rotation(self, rots): + self._rotation = rots - self.rots_bias[None, :] + + def from_xyz(self, xyz): + self._xyz = (xyz - self.aabb[None, :3]) / self.aabb[None, 3:] + + def from_features(self, features): + self._features_dc = features + + def from_opacity(self, opacities): + self._opacity = self.inverse_opacity_activation(opacities) - self.opacity_bias + + def construct_list_of_attributes(self): + l = ['x', 'y', 'z', 'nx', 'ny', 'nz'] + # All channels except the 3 DC + for i in range(self._features_dc.shape[1]*self._features_dc.shape[2]): + l.append('f_dc_{}'.format(i)) + l.append('opacity') + for i in range(self._scaling.shape[1]): + l.append('scale_{}'.format(i)) + for i in range(self._rotation.shape[1]): + l.append('rot_{}'.format(i)) + return l + + def save_ply(self, path, transform=[[1, 0, 0], [0, 0, -1], [0, 1, 0]]): + xyz = self.get_xyz.detach().cpu().numpy() + normals = np.zeros_like(xyz) + f_dc = self._features_dc.detach().transpose(1, 2).flatten(start_dim=1).contiguous().cpu().numpy() + opacities = inverse_sigmoid(self.get_opacity).detach().cpu().numpy() + scale = torch.log(self.get_scaling).detach().cpu().numpy() + rotation = (self._rotation + self.rots_bias[None, :]).detach().cpu().numpy() + + if transform is not None: + transform = np.array(transform) + xyz = np.matmul(xyz, transform.T) + rotation = utils3d.numpy.quaternion_to_matrix(rotation) + rotation = np.matmul(transform, rotation) + rotation = utils3d.numpy.matrix_to_quaternion(rotation) + + dtype_full = [(attribute, 'f4') for attribute in self.construct_list_of_attributes()] + + elements = np.empty(xyz.shape[0], dtype=dtype_full) + attributes = np.concatenate((xyz, normals, f_dc, opacities, scale, rotation), axis=1) + elements[:] = list(map(tuple, attributes)) + el = PlyElement.describe(elements, 'vertex') + PlyData([el]).write(path) + + def load_ply(self, path, transform=[[1, 0, 0], [0, 0, -1], [0, 1, 0]]): + plydata = PlyData.read(path) + + xyz = np.stack((np.asarray(plydata.elements[0]["x"]), + np.asarray(plydata.elements[0]["y"]), + np.asarray(plydata.elements[0]["z"])), axis=1) + opacities = np.asarray(plydata.elements[0]["opacity"])[..., np.newaxis] + + features_dc = np.zeros((xyz.shape[0], 3, 1)) + features_dc[:, 0, 0] = np.asarray(plydata.elements[0]["f_dc_0"]) + features_dc[:, 1, 0] = np.asarray(plydata.elements[0]["f_dc_1"]) + features_dc[:, 2, 0] = np.asarray(plydata.elements[0]["f_dc_2"]) + + if self.sh_degree > 0: + extra_f_names = [p.name for p in plydata.elements[0].properties if p.name.startswith("f_rest_")] + extra_f_names = sorted(extra_f_names, key = lambda x: int(x.split('_')[-1])) + assert len(extra_f_names)==3*(self.sh_degree + 1) ** 2 - 3 + features_extra = np.zeros((xyz.shape[0], len(extra_f_names))) + for idx, attr_name in enumerate(extra_f_names): + features_extra[:, idx] = np.asarray(plydata.elements[0][attr_name]) + # Reshape (P,F*SH_coeffs) to (P, F, SH_coeffs except DC) + features_extra = features_extra.reshape((features_extra.shape[0], 3, (self.max_sh_degree + 1) ** 2 - 1)) + + scale_names = [p.name for p in plydata.elements[0].properties if p.name.startswith("scale_")] + scale_names = sorted(scale_names, key = lambda x: int(x.split('_')[-1])) + scales = np.zeros((xyz.shape[0], len(scale_names))) + for idx, attr_name in enumerate(scale_names): + scales[:, idx] = np.asarray(plydata.elements[0][attr_name]) + + rot_names = [p.name for p in plydata.elements[0].properties if p.name.startswith("rot")] + rot_names = sorted(rot_names, key = lambda x: int(x.split('_')[-1])) + rots = np.zeros((xyz.shape[0], len(rot_names))) + for idx, attr_name in enumerate(rot_names): + rots[:, idx] = np.asarray(plydata.elements[0][attr_name]) + + if transform is not None: + transform = np.array(transform) + xyz = np.matmul(xyz, transform) + rotation = utils3d.numpy.quaternion_to_matrix(rotation) + rotation = np.matmul(rotation, transform) + rotation = utils3d.numpy.matrix_to_quaternion(rotation) + + # convert to actual gaussian attributes + xyz = torch.tensor(xyz, dtype=torch.float, device=self.device) + features_dc = torch.tensor(features_dc, dtype=torch.float, device=self.device).transpose(1, 2).contiguous() + if self.sh_degree > 0: + features_extra = torch.tensor(features_extra, dtype=torch.float, device=self.device).transpose(1, 2).contiguous() + opacities = torch.sigmoid(torch.tensor(opacities, dtype=torch.float, device=self.device)) + scales = torch.exp(torch.tensor(scales, dtype=torch.float, device=self.device)) + rots = torch.tensor(rots, dtype=torch.float, device=self.device) + + # convert to _hidden attributes + self._xyz = (xyz - self.aabb[None, :3]) / self.aabb[None, 3:] + self._features_dc = features_dc + if self.sh_degree > 0: + self._features_rest = features_extra + else: + self._features_rest = None + self._opacity = self.inverse_opacity_activation(opacities) - self.opacity_bias + self._scaling = self.inverse_scaling_activation(torch.sqrt(torch.square(scales) - self.mininum_kernel_size ** 2)) - self.scale_bias + self._rotation = rots - self.rots_bias[None, :] + \ No newline at end of file diff --git a/anigen/representations/gaussian/general_utils.py b/anigen/representations/gaussian/general_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..541c0825229a2d86e84460b765879f86f724a59d --- /dev/null +++ b/anigen/representations/gaussian/general_utils.py @@ -0,0 +1,133 @@ +# +# Copyright (C) 2023, Inria +# GRAPHDECO research group, https://team.inria.fr/graphdeco +# All rights reserved. +# +# This software is free for non-commercial, research and evaluation use +# under the terms of the LICENSE.md file. +# +# For inquiries contact george.drettakis@inria.fr +# + +import torch +import sys +from datetime import datetime +import numpy as np +import random + +def inverse_sigmoid(x): + return torch.log(x/(1-x)) + +def PILtoTorch(pil_image, resolution): + resized_image_PIL = pil_image.resize(resolution) + resized_image = torch.from_numpy(np.array(resized_image_PIL)) / 255.0 + if len(resized_image.shape) == 3: + return resized_image.permute(2, 0, 1) + else: + return resized_image.unsqueeze(dim=-1).permute(2, 0, 1) + +def get_expon_lr_func( + lr_init, lr_final, lr_delay_steps=0, lr_delay_mult=1.0, max_steps=1000000 +): + """ + Copied from Plenoxels + + Continuous learning rate decay function. Adapted from JaxNeRF + The returned rate is lr_init when step=0 and lr_final when step=max_steps, and + is log-linearly interpolated elsewhere (equivalent to exponential decay). + If lr_delay_steps>0 then the learning rate will be scaled by some smooth + function of lr_delay_mult, such that the initial learning rate is + lr_init*lr_delay_mult at the beginning of optimization but will be eased back + to the normal learning rate when steps>lr_delay_steps. + :param conf: config subtree 'lr' or similar + :param max_steps: int, the number of steps during optimization. + :return HoF which takes step as input + """ + + def helper(step): + if step < 0 or (lr_init == 0.0 and lr_final == 0.0): + # Disable this parameter + return 0.0 + if lr_delay_steps > 0: + # A kind of reverse cosine decay. + delay_rate = lr_delay_mult + (1 - lr_delay_mult) * np.sin( + 0.5 * np.pi * np.clip(step / lr_delay_steps, 0, 1) + ) + else: + delay_rate = 1.0 + t = np.clip(step / max_steps, 0, 1) + log_lerp = np.exp(np.log(lr_init) * (1 - t) + np.log(lr_final) * t) + return delay_rate * log_lerp + + return helper + +def strip_lowerdiag(L): + uncertainty = torch.zeros((L.shape[0], 6), dtype=torch.float, device="cuda") + + uncertainty[:, 0] = L[:, 0, 0] + uncertainty[:, 1] = L[:, 0, 1] + uncertainty[:, 2] = L[:, 0, 2] + uncertainty[:, 3] = L[:, 1, 1] + uncertainty[:, 4] = L[:, 1, 2] + uncertainty[:, 5] = L[:, 2, 2] + return uncertainty + +def strip_symmetric(sym): + return strip_lowerdiag(sym) + +def build_rotation(r): + norm = torch.sqrt(r[:,0]*r[:,0] + r[:,1]*r[:,1] + r[:,2]*r[:,2] + r[:,3]*r[:,3]) + + q = r / norm[:, None] + + R = torch.zeros((q.size(0), 3, 3), device='cuda') + + r = q[:, 0] + x = q[:, 1] + y = q[:, 2] + z = q[:, 3] + + R[:, 0, 0] = 1 - 2 * (y*y + z*z) + R[:, 0, 1] = 2 * (x*y - r*z) + R[:, 0, 2] = 2 * (x*z + r*y) + R[:, 1, 0] = 2 * (x*y + r*z) + R[:, 1, 1] = 1 - 2 * (x*x + z*z) + R[:, 1, 2] = 2 * (y*z - r*x) + R[:, 2, 0] = 2 * (x*z - r*y) + R[:, 2, 1] = 2 * (y*z + r*x) + R[:, 2, 2] = 1 - 2 * (x*x + y*y) + return R + +def build_scaling_rotation(s, r): + L = torch.zeros((s.shape[0], 3, 3), dtype=torch.float, device="cuda") + R = build_rotation(r) + + L[:,0,0] = s[:,0] + L[:,1,1] = s[:,1] + L[:,2,2] = s[:,2] + + L = R @ L + return L + +def safe_state(silent): + old_f = sys.stdout + class F: + def __init__(self, silent): + self.silent = silent + + def write(self, x): + if not self.silent: + if x.endswith("\n"): + old_f.write(x.replace("\n", " [{}]\n".format(str(datetime.now().strftime("%d/%m %H:%M:%S"))))) + else: + old_f.write(x) + + def flush(self): + old_f.flush() + + sys.stdout = F(silent) + + random.seed(0) + np.random.seed(0) + torch.manual_seed(0) + torch.cuda.set_device(torch.device("cuda:0")) diff --git a/anigen/representations/mesh/__init__.py b/anigen/representations/mesh/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..921de9cca886e59d0bf6f9eb494e85d9d701cb8b --- /dev/null +++ b/anigen/representations/mesh/__init__.py @@ -0,0 +1,2 @@ +from .cube2mesh import SparseFeatures2Mesh, MeshExtractResult +from .cube2mesh_skeleton import AniGenSparseFeatures2Mesh, AniGenMeshExtractResult, AniGenSklFeatures2Skeleton \ No newline at end of file diff --git a/anigen/representations/mesh/cube2mesh.py b/anigen/representations/mesh/cube2mesh.py new file mode 100644 index 0000000000000000000000000000000000000000..44e8776fafbc21d787e2ba855e4c99bd191a0762 --- /dev/null +++ b/anigen/representations/mesh/cube2mesh.py @@ -0,0 +1,143 @@ +import torch +from ...modules.sparse import SparseTensor +from easydict import EasyDict as edict +from .utils_cube import * +from .flexicubes.flexicubes import FlexiCubes + + +class MeshExtractResult: + def __init__(self, + vertices, + faces, + vertex_attrs=None, + res=64 + ): + self.vertices = vertices + self.faces = faces.long() + self.vertex_attrs = vertex_attrs + self.face_normal = self.comput_face_normals(vertices, faces) + self.res = res + self.success = (vertices.shape[0] != 0 and faces.shape[0] != 0) + + # training only + self.tsdf_v = None + self.tsdf_s = None + self.reg_loss = None + + def comput_face_normals(self, verts, faces): + i0 = faces[..., 0].long() + i1 = faces[..., 1].long() + i2 = faces[..., 2].long() + + v0 = verts[i0, :] + v1 = verts[i1, :] + v2 = verts[i2, :] + face_normals = torch.cross(v1 - v0, v2 - v0, dim=-1) + face_normals = torch.nn.functional.normalize(face_normals, dim=1) + # print(face_normals.min(), face_normals.max(), face_normals.shape) + return face_normals[:, None, :].repeat(1, 3, 1) + + def comput_v_normals(self, verts, faces): + i0 = faces[..., 0].long() + i1 = faces[..., 1].long() + i2 = faces[..., 2].long() + + v0 = verts[i0, :] + v1 = verts[i1, :] + v2 = verts[i2, :] + face_normals = torch.cross(v1 - v0, v2 - v0, dim=-1) + v_normals = torch.zeros_like(verts) + v_normals.scatter_add_(0, i0[..., None].repeat(1, 3), face_normals) + v_normals.scatter_add_(0, i1[..., None].repeat(1, 3), face_normals) + v_normals.scatter_add_(0, i2[..., None].repeat(1, 3), face_normals) + + v_normals = torch.nn.functional.normalize(v_normals, dim=1) + return v_normals + + +class SparseFeatures2Mesh: + def __init__(self, device="cuda", res=64, use_color=True): + ''' + a model to generate a mesh from sparse features structures using flexicube + ''' + super().__init__() + self.device=device + self.res = res + self.mesh_extractor = FlexiCubes(device=device) + self.sdf_bias = -1.0 / res + verts, cube = construct_dense_grid(self.res, self.device) + self.reg_c = cube.to(self.device) + self.reg_v = verts.to(self.device) + self.use_color = use_color + self._calc_layout() + + def _calc_layout(self): + LAYOUTS = { + 'sdf': {'shape': (8, 1), 'size': 8}, + 'deform': {'shape': (8, 3), 'size': 8 * 3}, + 'weights': {'shape': (21,), 'size': 21} + } + if self.use_color: + ''' + 6 channel color including normal map + ''' + LAYOUTS['color'] = {'shape': (8, 6,), 'size': 8 * 6} + self.layouts = edict(LAYOUTS) + start = 0 + for k, v in self.layouts.items(): + v['range'] = (start, start + v['size']) + start += v['size'] + self.feats_channels = start + + def get_layout(self, feats : torch.Tensor, name : str): + if name not in self.layouts: + return None + return feats[:, self.layouts[name]['range'][0]:self.layouts[name]['range'][1]].reshape(-1, *self.layouts[name]['shape']) + + def __call__(self, cubefeats : SparseTensor, training=False): + """ + Generates a mesh based on the specified sparse voxel structures. + Args: + cube_attrs [Nx21] : Sparse Tensor attrs about cube weights + verts_attrs [Nx10] : [0:1] SDF [1:4] deform [4:7] color [7:10] normal + Returns: + return the success tag and ni you loss, + """ + # add sdf bias to verts_attrs + coords = cubefeats.coords[:, 1:] + feats = cubefeats.feats + + sdf, deform, color, weights = [self.get_layout(feats, name) for name in ['sdf', 'deform', 'color', 'weights']] + sdf += self.sdf_bias + v_attrs = [sdf, deform, color] if self.use_color else [sdf, deform] + v_pos, v_attrs, reg_loss = sparse_cube2verts(coords, torch.cat(v_attrs, dim=-1), training=training) + v_attrs_d = get_dense_attrs(v_pos, v_attrs, res=self.res+1, sdf_init=True) + weights_d = get_dense_attrs(coords, weights, res=self.res, sdf_init=False) + if self.use_color: + sdf_d, deform_d, colors_d = v_attrs_d[..., 0], v_attrs_d[..., 1:4], v_attrs_d[..., 4:] + else: + sdf_d, deform_d = v_attrs_d[..., 0], v_attrs_d[..., 1:4] + colors_d = None + + x_nx3 = get_defomed_verts(self.reg_v, deform_d, self.res) + + vertices, faces, L_dev, colors = self.mesh_extractor( + voxelgrid_vertices=x_nx3, + scalar_field=sdf_d, + cube_idx=self.reg_c, + resolution=self.res, + beta=weights_d[:, :12], + alpha=weights_d[:, 12:20], + gamma_f=weights_d[:, 20], + voxelgrid_colors=colors_d, + training=training) + + mesh = MeshExtractResult(vertices=vertices, faces=faces, vertex_attrs=colors, res=self.res) + if training: + if mesh.success: + reg_loss += L_dev.mean() * 0.5 + reg_loss += (weights[:,:20]).abs().mean() * 0.2 + mesh.reg_loss = reg_loss + mesh.tsdf_v = get_defomed_verts(v_pos, v_attrs[:, 1:4], self.res) + mesh.tsdf_s = v_attrs[:, 0] + return mesh diff --git a/anigen/representations/mesh/cube2mesh_skeleton.py b/anigen/representations/mesh/cube2mesh_skeleton.py new file mode 100644 index 0000000000000000000000000000000000000000..f6f4a8f0eb1bbf91bd76b3c603ea38ed06bd3c3f --- /dev/null +++ b/anigen/representations/mesh/cube2mesh_skeleton.py @@ -0,0 +1,498 @@ +import math +import torch +from typing import Optional +from ...modules.sparse import SparseTensor +from easydict import EasyDict as edict +from .utils_cube import * +from .flexicubes.flexicubes import FlexiCubes +from pytorch3d.ops import knn_points + + +class AniGenMeshExtractResult: + def __init__(self, + vertices, + faces, + vertex_attrs=None, + vertex_skin_feats=None, + grid_positions=None, + grid_skin_feats=None, + res=64, + ): + self.vertices = vertices + self.faces = faces.long() + self.vertex_attrs = vertex_attrs + self.vertex_skin_feats = vertex_skin_feats + self.grid_positions = grid_positions + self.grid_skin_feats = grid_skin_feats + self.face_normal = self.comput_face_normals(vertices, faces) + self.res = res + self.success = (vertices.shape[0] != 0 and faces.shape[0] != 0) + + # training only + self.tsdf_v = None + self.tsdf_s = None + self.reg_loss = None + + def comput_face_normals(self, verts, faces): + i0 = faces[..., 0].long() + i1 = faces[..., 1].long() + i2 = faces[..., 2].long() + + v0 = verts[i0, :] + v1 = verts[i1, :] + v2 = verts[i2, :] + face_normals = torch.cross(v1 - v0, v2 - v0, dim=-1) + face_normals = torch.nn.functional.normalize(face_normals, dim=1) + # print(face_normals.min(), face_normals.max(), face_normals.shape) + return face_normals[:, None, :].repeat(1, 3, 1) + + def comput_v_normals(self, verts, faces): + i0 = faces[..., 0].long() + i1 = faces[..., 1].long() + i2 = faces[..., 2].long() + + v0 = verts[i0, :] + v1 = verts[i1, :] + v2 = verts[i2, :] + face_normals = torch.cross(v1 - v0, v2 - v0, dim=-1) + v_normals = torch.zeros_like(verts) + v_normals.scatter_add_(0, i0[..., None].repeat(1, 3), face_normals) + v_normals.scatter_add_(0, i1[..., None].repeat(1, 3), face_normals) + v_normals.scatter_add_(0, i2[..., None].repeat(1, 3), face_normals) + + v_normals = torch.nn.functional.normalize(v_normals, dim=1) + return v_normals + + +class AniGenSparseFeatures2Mesh: + def __init__( + self, + device="cuda", + res=64, + use_color=True, + skin_feat_channels=32, + predict_skin=True, + interpolate_skin_sparse=False, + use_nearest_skin_feat=False, + vertex_skin_feat_interp_sparse: Optional[bool] = None, + vertex_skin_feat_interp_nearest: Optional[bool] = None, + vertex_skin_feat_interp_use_deformed_grid: bool = False, + vertex_skin_feat_interp_trilinear: bool = False, + flexicube_disable_deform: bool = False, + vertex_skin_feat_nodeform_trilinear: bool = False, + ): + ''' + a model to generate a mesh from sparse features structures using flexicube + ''' + super().__init__() + self.device=device + self.res = res + self.mesh_extractor = FlexiCubes(device=device, use_color=use_color) + self.sdf_bias = -1.0 / res + verts, cube = construct_dense_grid(self.res, self.device) + self.reg_c = cube.to(self.device) + self.reg_v = verts.to(self.device) + self.use_color = use_color + self.skin_feat_channels = skin_feat_channels if predict_skin else 0 + self.predict_skin = predict_skin + + # Backward-compatible aliasing. + if vertex_skin_feat_interp_sparse is None: + vertex_skin_feat_interp_sparse = interpolate_skin_sparse + if vertex_skin_feat_interp_nearest is None: + vertex_skin_feat_interp_nearest = use_nearest_skin_feat + + self.vertex_skin_feat_interp_sparse = bool(vertex_skin_feat_interp_sparse) + self.vertex_skin_feat_interp_nearest = bool(vertex_skin_feat_interp_nearest) + self.vertex_skin_feat_interp_use_deformed_grid = bool(vertex_skin_feat_interp_use_deformed_grid) + self.vertex_skin_feat_interp_trilinear = bool(vertex_skin_feat_interp_trilinear) + self.flexicube_disable_deform = bool(flexicube_disable_deform) + self.vertex_skin_feat_nodeform_trilinear = bool(vertex_skin_feat_nodeform_trilinear) + + # Combined mode overrides individual toggles. + if self.vertex_skin_feat_nodeform_trilinear: + # Force deform off and use strict trilinear interpolation. + self.flexicube_disable_deform = True + self.vertex_skin_feat_interp_trilinear = True + self.vertex_skin_feat_interp_use_deformed_grid = False + self.vertex_skin_feat_interp_nearest = False + # Ensure we take the sparse-interp branch (i.e., don't read skin from FlexiCubes colors). + self.vertex_skin_feat_interp_sparse = True + + self.interpolate_skin_sparse = self.vertex_skin_feat_interp_sparse and predict_skin and self.skin_feat_channels > 0 + self.use_nearest_skin_feat = self.vertex_skin_feat_interp_nearest + self._calc_layout() + + def _calc_layout(self): + LAYOUTS = [ + ('sdf', {'shape': (8, 1), 'size': 8}), + ('deform', {'shape': (8, 3), 'size': 8 * 3}), + ('weights', {'shape': (21,), 'size': 21}), + ] + if self.use_color: + # 6 channel color including normal map + LAYOUTS.append(('color', {'shape': (8, 6,), 'size': 8 * 6})) + if self.predict_skin: + # Ensure skin_feat is always at the end + LAYOUTS.append(('skin_feat', {'shape': (8, self.skin_feat_channels,), 'size': 8*self.skin_feat_channels})) + self.layouts = edict() + start = 0 + for k, v in LAYOUTS: + v['range'] = (start, start + v['size']) + self.layouts[k] = v + start += v['size'] + # Do not include skin_feat in feats_channels if not predicting skin + self.feats_channels = start - 8*self.skin_feat_channels if self.predict_skin else start + self.skin_feat_channels = self.skin_feat_channels * 8 if self.predict_skin else 0 + + def get_layout(self, feats : torch.Tensor, name : str): + if name not in self.layouts: + return None + return feats[:, self.layouts[name]['range'][0]:self.layouts[name]['range'][1]].reshape(-1, *self.layouts[name]['shape']) + + def _interpolate_skin_features(self, vertices, grid_points, grid_features, res): + if grid_features is None or grid_features.shape[1] == 0: + return None + device = vertices.device + feat_dtype = grid_features.dtype + + grid_points = grid_points.to(device=device, dtype=torch.float32) + # Backward compatibility: if integer grid coords are passed, normalize to [-0.5, 0.5]. + if grid_points.dtype in (torch.int8, torch.int16, torch.int32, torch.int64) or grid_points.abs().max() > 1.5: + grid_points = (grid_points + 0.5) / res - 0.5 + # IMPORTANT for training stability: do not backprop through coordinates/distances. + grid_points = grid_points.detach() + vertex_points = vertices.to(device=device, dtype=torch.float32).detach() + + k = 1 if self.use_nearest_skin_feat else min(8, grid_points.shape[0]) + if k == 0: + return torch.zeros(vertices.shape[0], grid_features.shape[1], device=device, dtype=feat_dtype) + + dist2, idx, _ = knn_points(vertex_points.unsqueeze(0), grid_points.unsqueeze(0), K=k, return_nn=False) + + if self.use_nearest_skin_feat: + idx = idx[0, :, 0] + return grid_features[idx].to(device=device, dtype=feat_dtype) + + dist = torch.sqrt(dist2[0]).clamp_min(1e-12) + idx = idx[0] + + feats = grid_features.to(device=device, dtype=feat_dtype) + neighbor_feats = feats[idx] + # Smooth kernel weights to reduce jitter from neighbor swaps. + # Grid spacing in normalized coords is ~ 1/res. + sigma = (1.5 / res) + weights = torch.exp(-(dist ** 2) / (2.0 * (sigma ** 2))) + weights = weights / weights.sum(dim=-1, keepdim=True).clamp_min(1e-12) + weights = weights.to(dtype=neighbor_feats.dtype) + + vertex_skin_feats = torch.sum(neighbor_feats * weights.unsqueeze(-1), dim=1) + return vertex_skin_feats + + def _interpolate_skin_features_trilinear(self, vertices, grid_features_dense, res: int): + """Trilinear interpolation from regular (res+1)^3 grid vertices. + + This is deform-independent as long as `vertices` are in the same canonical + coordinate system as `get_defomed_verts(..., deform=0)` i.e. v/res - 0.5. + """ + if grid_features_dense is None or grid_features_dense.shape[-1] == 0: + return None + device = vertices.device + feat_dtype = grid_features_dense.dtype + + # grid_features_dense: [(res+1)^3, C] -> [res+1, res+1, res+1, C] + C = grid_features_dense.shape[-1] + grid = grid_features_dense.view(res + 1, res + 1, res + 1, C).to(device=device) + + # vertices are in [-0.5, 0.5]; map to grid coordinate in [0, res] + v = vertices.to(device=device, dtype=torch.float32).detach() + g = (v + 0.5) * float(res) + # Clamp so that i0+1 is always valid. + eps = 1e-6 + g = torch.clamp(g, 0.0, float(res) - eps) + + i0 = torch.floor(g[:, 0]).to(torch.long) + j0 = torch.floor(g[:, 1]).to(torch.long) + k0 = torch.floor(g[:, 2]).to(torch.long) + i1 = i0 + 1 + j1 = j0 + 1 + k1 = k0 + 1 + + tx = (g[:, 0] - i0.to(g.dtype)).unsqueeze(-1) + ty = (g[:, 1] - j0.to(g.dtype)).unsqueeze(-1) + tz = (g[:, 2] - k0.to(g.dtype)).unsqueeze(-1) + + def gather(ii, jj, kk): + return grid[ii, jj, kk] + + c000 = gather(i0, j0, k0) + c100 = gather(i1, j0, k0) + c010 = gather(i0, j1, k0) + c110 = gather(i1, j1, k0) + c001 = gather(i0, j0, k1) + c101 = gather(i1, j0, k1) + c011 = gather(i0, j1, k1) + c111 = gather(i1, j1, k1) + + wx0 = 1.0 - tx + wy0 = 1.0 - ty + wz0 = 1.0 - tz + + out = ( + c000 * (wx0 * wy0 * wz0) + + c100 * (tx * wy0 * wz0) + + c010 * (wx0 * ty * wz0) + + c110 * (tx * ty * wz0) + + c001 * (wx0 * wy0 * tz ) + + c101 * (tx * wy0 * tz ) + + c011 * (wx0 * ty * tz ) + + c111 * (tx * ty * tz ) + ) + return out.to(dtype=feat_dtype) + + def __call__(self, cubefeats : SparseTensor, training=False): + """ + Generates a mesh based on the specified sparse voxel structures. + Args: + cube_attrs [Nx21] : Sparse Tensor attrs about cube weights + verts_attrs [Nx10] : [0:1] SDF [1:4] deform [4:7] color [7:10] normal + Returns: + return the success tag and ni you loss, + """ + + skin_feat_channels = self.skin_feat_channels // 8 if self.predict_skin else 0 + + # add sdf bias to verts_attrs + coords = cubefeats.coords[:, 1:] + feats = cubefeats.feats + + sdf, deform, color, weights = [self.get_layout(feats, name) for name in ['sdf', 'deform', 'color', 'weights']] + sdf += self.sdf_bias + v_attrs = [sdf, deform] + if self.predict_skin: + skin_feat = self.get_layout(feats, 'skin_feat') + v_attrs.append(skin_feat) + if self.use_color: + v_attrs.append(torch.sigmoid(color)) + v_pos, v_attrs, reg_loss = sparse_cube2verts(coords, torch.cat(v_attrs, dim=-1), training=training) + # Grid-vertex canonical coordinates in [-0.5, 0.5] (consistent with deform=0). + v_pos_normalized = v_pos / self.res - 0.5 + grid_skin_feats = v_attrs[:, 4:4+skin_feat_channels] if self.predict_skin and skin_feat_channels > 0 else None + if self.predict_skin and self.interpolate_skin_sparse and skin_feat_channels > 0: + v_attrs_for_dense = torch.cat([v_attrs[:, :4], v_attrs[:, 4+skin_feat_channels:]], dim=-1) + else: + v_attrs_for_dense = v_attrs + v_attrs_d = get_dense_attrs(v_pos, v_attrs_for_dense, res=self.res+1, sdf_init=True) + weights_d = get_dense_attrs(coords, weights, res=self.res, sdf_init=False) + + sdf_d, deform_d, colors_d = v_attrs_d[..., 0], v_attrs_d[..., 1:4], v_attrs_d[..., 4:] + deform_d_eff = deform_d if not self.flexicube_disable_deform else (deform_d * 0.0) + x_nx3 = get_defomed_verts(self.reg_v, deform_d_eff, self.res).type(sdf_d.dtype) + vertices, faces, L_dev, colors = self.mesh_extractor( + voxelgrid_vertices=x_nx3, + scalar_field=sdf_d, + cube_idx=self.reg_c, + resolution=self.res, + beta=weights_d[:, :12], + alpha=weights_d[:, 12:20], + gamma_f=weights_d[:, 20], + voxelgrid_colors=colors_d, + training=training, + no_sigmoid=True) + + rgbnormal_colors = None + vertex_skin_feats = None + start = 0 + if self.predict_skin and skin_feat_channels > 0: + if self.interpolate_skin_sparse: + # Deform-independent trilinear interpolation from 8 grid-vertex features. + if self.vertex_skin_feat_nodeform_trilinear: + grid_features_dense = get_dense_attrs(v_pos, grid_skin_feats, res=self.res+1, sdf_init=False) + vertex_skin_feats = self._interpolate_skin_features_trilinear( + vertices=vertices, + grid_features_dense=grid_features_dense, + res=self.res, + ) + # Backward-compatible: allow trilinear if explicitly enabled alongside deform-disable. + elif self.vertex_skin_feat_interp_trilinear and self.flexicube_disable_deform: + grid_features_dense = get_dense_attrs(v_pos, grid_skin_feats, res=self.res+1, sdf_init=False) + vertex_skin_feats = self._interpolate_skin_features_trilinear( + vertices=vertices, + grid_features_dense=grid_features_dense, + res=self.res, + ) + else: + # Choose the coordinate space used for KNN distances. + # - Regular grid space: stable, independent of predicted deformation. + # - Deformed space: matches mesh vertices but depends on deformation prediction. + if self.vertex_skin_feat_interp_use_deformed_grid: + grid_points_for_skin = get_defomed_verts(v_pos, v_attrs[:, 1:4], self.res) + else: + grid_points_for_skin = v_pos / self.res - 0.5 + grid_features_for_skin = grid_skin_feats + + vertex_skin_feats = self._interpolate_skin_features( + vertices=vertices, + grid_points=grid_points_for_skin, + grid_features=grid_features_for_skin, + res=self.res, + ) + else: + vertex_skin_feats = colors[:, start: start + skin_feat_channels] + start += skin_feat_channels + if self.use_color: + if colors is not None and colors.shape[1] >= start + 6: + rgbnormal_colors = colors[:, start: start + 6] + elif colors is not None and colors.shape[1] >= 6: + rgbnormal_colors = colors[:, -6:] + else: + rgbnormal_colors = None + + mesh = AniGenMeshExtractResult(vertices=vertices, faces=faces, vertex_attrs=rgbnormal_colors, vertex_skin_feats=vertex_skin_feats, grid_positions=v_pos_normalized, grid_skin_feats=grid_skin_feats, res=self.res) + if training: + if mesh.success: + reg_loss += L_dev.mean() * 0.5 + reg_loss += (weights[:,:20]).abs().mean() * 0.2 + mesh.reg_loss = reg_loss + mesh.tsdf_v = get_defomed_verts(v_pos, v_attrs[:, 1:4], self.res) + mesh.tsdf_s = v_attrs[:, 0] + + return mesh + + +class AniGenSklFeatures2Skeleton: + def __init__(self, skin_feat_channels=32, device="cuda", res=64, use_conf_jp=False, use_conf_skin=False, predict_skin=True, defined_on_center=False, jp_hyper_continuous=False, jp_residual_fields=False): + self.device=device + self.res = res + self.use_conf_jp = use_conf_jp or jp_hyper_continuous + self.jp_hyper_continuous = jp_hyper_continuous + self.jp_residual_fields = jp_residual_fields + self.use_conf_skin = use_conf_skin and not jp_hyper_continuous + self.predict_skin = predict_skin + self.skin_feat_channels = skin_feat_channels if predict_skin else 0 + self.defined_on_center = defined_on_center + self._calc_layout() + + def _calc_layout(self): + if self.defined_on_center: + LAYOUTS = { + 'joint': {'shape': (3,), 'size': 3}, + 'parent': {'shape': (3,), 'size': 3}, + } + if self.use_conf_jp: + LAYOUTS['conf_j'] = {'shape': (1,), 'size': 1} + LAYOUTS['conf_p'] = {'shape': (1,), 'size': 1} + if self.use_conf_skin: + LAYOUTS['conf_skin'] = {'shape': (1,), 'size': 1} + # Define skin features at the end + if self.predict_skin: + LAYOUTS['skin_feat'] = {'shape': (self.skin_feat_channels,), 'size': self.skin_feat_channels} + else: + LAYOUTS = { + 'joint': {'shape': (8, 3), 'size': 8*3}, + 'parent': {'shape': (8, 3), 'size': 8*3}, + } + if self.use_conf_jp: + LAYOUTS['conf_j'] = {'shape': (8, 1), 'size': 8} + LAYOUTS['conf_p'] = {'shape': (8, 1), 'size': 8} + if self.use_conf_skin: + LAYOUTS['conf_skin'] = {'shape': (8, 1), 'size': 8} + # Define skin features at the end + if self.predict_skin: + LAYOUTS['skin_feat'] = {'shape': (8, self.skin_feat_channels), 'size': 8*self.skin_feat_channels} + self.skin_feat_channels = 8 * self.skin_feat_channels + self.layouts = edict(LAYOUTS) + start = 0 + for k, v in self.layouts.items(): + v['range'] = (start, start + v['size']) + start += v['size'] + self.feats_channels = start - (self.skin_feat_channels if self.predict_skin else 0) + + def get_layout(self, feats : torch.Tensor, name : str): + if name not in self.layouts: + return None + return feats[:, self.layouts[name]['range'][0]:self.layouts[name]['range'][1]].reshape(-1, *self.layouts[name]['shape']) + + def __call__(self, cubefeats : SparseTensor, training=False): + """ + Generates a skeleton based on the specified sparse voxel structures. + Args: + cubefeats [SparseTensor] : Sparse Tensor attrs about cube weights + Returns: + return s a dictionary with joints, parents, skin features, and positions. + """ + coords = cubefeats.coords[:, 1:] + joints, parents, skin_feats, conf_j, conf_p, conf_skin = [self.get_layout(cubefeats.feats, name) for name in ['joint', 'parent', 'skin_feat', 'conf_j', 'conf_p', 'conf_skin']] + if conf_skin is not None: + conf_skin = torch.sigmoid(conf_skin) + if self.defined_on_center: + positions = (coords + 0.5) / self.res - 0.5 + if self.jp_hyper_continuous: + conf_j = torch.sigmoid(conf_j) + conf_p = torch.sigmoid(conf_p) + conf_skin = conf_j + if self.jp_residual_fields: + joints = joints + positions + parents = parents + positions + results = { + 'joints': joints, + 'parents': parents, + 'skin_feats': skin_feats, + 'positions': positions, + 'reg_loss': 0, # No reg loss for skeleton extraction + 'conf_j': conf_j, + 'conf_p': conf_p, + 'conf_skin': conf_skin, + 'skin_pred': None, + 'skin_feats_joints_var_loss': None, + 'jp_hyper_continuous': self.jp_hyper_continuous, + 'jp_residual_fields': self.jp_residual_fields, + 'joints_grouped': None, + 'parents_grouped': None, + } + else: + results = {} + skin_feat_channels = self.skin_feat_channels // 8 if self.predict_skin else 0 + v_attrs = [joints, parents] + if self.predict_skin: + v_attrs.append(skin_feats) + if self.use_conf_jp: + v_attrs.append(conf_j) + v_attrs.append(conf_p) + if self.use_conf_skin: + v_attrs.append(conf_skin) + v_pos, v_attrs, reg_loss = sparse_cube2verts(coords, torch.cat(v_attrs, dim=-1), training=training) + positions = ((v_pos + 0.5) / self.res - 0.5) + joints_grid, parents_grid = v_attrs[:, :3], v_attrs[:, 3:6] + skin_feats_grid, conf_j_grid, conf_p_grid, conf_skin_grid = None, None, None, None + if self.predict_skin: + skin_feats_grid = v_attrs[:, 6:6+skin_feat_channels] + if self.use_conf_jp: + conf_j_grid = v_attrs[:, 6+skin_feat_channels:7+skin_feat_channels] + conf_p_grid = v_attrs[:, 7+skin_feat_channels:8+skin_feat_channels] + if self.use_conf_skin: + conf_skin_grid = v_attrs[:, 8+skin_feat_channels:9+skin_feat_channels] if self.use_conf_jp else v_attrs[:, 6+skin_feat_channels:7+skin_feat_channels] + if self.jp_hyper_continuous: + conf_j_grid = torch.sigmoid(conf_j_grid) + conf_p_grid = torch.sigmoid(conf_p_grid) + conf_skin_grid = conf_j_grid + if self.jp_residual_fields: + joints_grid = joints_grid + positions + parents_grid = parents_grid + positions + results.update({ + 'joints': joints_grid, + 'parents': parents_grid, + 'skin_feats': skin_feats_grid, + 'positions': positions, + 'reg_loss': reg_loss if training else 0, + 'conf_j': conf_j_grid, + 'conf_p': conf_p_grid, + 'conf_skin': conf_skin_grid, + 'skin_pred': None, + 'skin_feats_joints_var_loss': None, + 'jp_hyper_continuous': self.jp_hyper_continuous, + 'jp_residual_fields': self.jp_residual_fields, + 'joints_grouped': None, + 'parents_grouped': None, + }) + return edict(results) diff --git a/anigen/representations/mesh/flexicubes/LICENSE.txt b/anigen/representations/mesh/flexicubes/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..40e8f765ee25d88128e7b5cd769389c633ba86bb --- /dev/null +++ b/anigen/representations/mesh/flexicubes/LICENSE.txt @@ -0,0 +1,90 @@ +Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + +NVIDIA Source Code License for FlexiCubes + + +======================================================================= + +1. Definitions + +โ€œLicensorโ€ means any person or entity that distributes its Work. + +โ€œWorkโ€ means (a) the original work of authorship made available under +this license, which may include software, documentation, or other files, +and (b) any additions to or derivative works thereof that are made +available under this license. + +The terms โ€œreproduce,โ€ โ€œreproduction,โ€ โ€œderivative works,โ€ and +โ€œdistributionโ€ have the meaning as provided under U.S. copyright law; +provided, however, that for the purposes of this license, derivative works +shall not include works that remain separable from, or merely link +(or bind by name) to the interfaces of, the Work. + +Works are โ€œmade availableโ€ under this license by including in or with +the Work either (a) a copyright notice referencing the applicability of +this license to the Work, or (b) a copy of this license. + +2. License Grant + + 2.1 Copyright Grant. Subject to the terms and conditions of this license, + each Licensor grants to you a perpetual, worldwide, non-exclusive, + royalty-free, copyright license to use, reproduce, prepare derivative + works of, publicly display, publicly perform, sublicense and distribute + its Work and any resulting derivative works in any form. + +3. Limitations + + 3.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. + + 3.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 3.3 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. + + 3.3 Use Limitation. The Work and any derivative works thereof only may be + used or intended for use non-commercially. Notwithstanding the foregoing, + NVIDIA Corporation and its affiliates may use the Work and any derivative + works commercially. As used herein, โ€œnon-commerciallyโ€ means for research + or evaluation purposes only. + + 3.4 Patent Claims. If you bring or threaten to bring a patent claim against + any Licensor (including any claim, cross-claim or counterclaim in a lawsuit) + to enforce any patents that you allege are infringed by any Work, then your + rights under this license from such Licensor (including the grant in + Section 2.1) will terminate immediately. + + 3.5 Trademarks. This license does not grant any rights to use any Licensorโ€™s + or its affiliatesโ€™ names, logos, or trademarks, except as necessary to + reproduce the notices described in this license. + + 3.6 Termination. If you violate any term of this license, then your rights + under this license (including the grant in Section 2.1) will terminate + immediately. + +4. Disclaimer of Warranty. + +THE WORK IS PROVIDED โ€œAS ISโ€ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT. +YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER THIS LICENSE. + +5. Limitation of Liability. + +EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY, +WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE SHALL ANY +LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, +INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATED TO THIS LICENSE, +THE USE OR INABILITY TO USE THE WORK (INCLUDING BUT NOT LIMITED TO LOSS OF +GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR DATA, COMPUTER FAILURE OR +MALFUNCTION, OR ANY OTHER DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +======================================================================= \ No newline at end of file diff --git a/anigen/representations/mesh/flexicubes/README.md b/anigen/representations/mesh/flexicubes/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8f8b460651edef71c9636d62868c239defaa73ce --- /dev/null +++ b/anigen/representations/mesh/flexicubes/README.md @@ -0,0 +1,110 @@ +## Flexible Isosurface Extraction for Gradient-Based Mesh Optimization (FlexiCubes)
Official PyTorch implementation + +![Teaser image]() + +FlexiCubes is a high-quality isosurface representation specifically designed for gradient-based mesh optimization with respect to geometric, visual, or even physical objectives. For more details, please refer to our [paper](https://arxiv.org/abs/2308.05371) and [project page](https://research.nvidia.com/labs/toronto-ai/flexicubes/). + +## Highlights +* [Getting started](https://github.com/nv-tlabs/FlexiCubes#getting-started) +* [Basic workflow](https://github.com/nv-tlabs/FlexiCubes#example-usage) +* [nvdiffrec: image-based reconstruction example](https://github.com/NVlabs/nvdiffrec#news) +* [GET3D: generative AI example](https://github.com/nv-tlabs/GET3D#employing-flexicubes) +* [Bibtex](https://github.com/nv-tlabs/FlexiCubes#citation) + +## Getting Started + +The core functions of FlexiCubes are now in [Kaolin](https://github.com/NVIDIAGameWorks/kaolin/) starting from v0.15.0. See installation instructions [here](https://kaolin.readthedocs.io/en/latest/notes/installation.html) and API documentations [here](https://kaolin.readthedocs.io/en/latest/modules/kaolin.non_commercial.html#kaolin.non_commercial.FlexiCubes) + +The original code of the paper is still visible in `flexicube.py`. + +## Example Usage + +### Gradient-Based Mesh Optimization +We provide examples demonstrating how to use FlexiCubes for reconstructing unknown meshes through gradient-based optimization. Specifically, starting from randomly initialized SDF, we optimize the shape towards the reference mesh by minimizing their geometric difference, measured by multiview mask and depth losses. This workflow is a simplified version of `nvdiffrec` with code largely borrowed from the [nvdiffrec GitHub](https://github.com/NVlabs/nvdiffrec). We use the same pipeline to conduct the analysis in Section 3 and the main experiments described in Section 5 of our paper. We provide a detailed tutorial in `examples/optimization.ipynb`, along with an optimization script in `examples/optimize.py` which accepts command-line arguments. + + +To run the examples, it is suggested to install the Conda environment as detailed below: +```sh +conda create -n flexicubes python=3.9 +conda activate flexicubes +conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cudatoolkit=11.3 -c pytorch +pip install imageio trimesh tqdm matplotlib torch_scatter ninja +pip install git+https://github.com/NVlabs/nvdiffrast/ +pip install kaolin==0.15.0 -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-1.12.0_cu113.html +``` + +Then download the dataset collected by [Myles et al.](https://vcg.isti.cnr.it/Publications/2014/MPZ14/) as follows. We include one shape in 'examples/data/inputmodels/block.obj' if you want to test without downloading the full dataset. + +```sh +cd examples +python download_data.py +``` + +After downloading the data, run shape optimization with the following example command: +```sh +python optimize.py --ref_mesh data/inputmodels/block.obj --out_dir out/block +``` +You can find visualization and output meshes in the `out/block`. Below, we show the initial and final shapes during optimization, with the reference shape on the right. + +block_init + +block_final + + +To further demonstrate the flexibility of our FlexiCubes representation, which can accommodates both reconstruction objectives and regularizers defined on the extracted mesh, you can add a developability regularizer (proposed by [Stein et al.](https://www.cs.cmu.edu/~kmcrane/Projects/DiscreteDevelopable/)) to the previous reconstruction pipeline to encourage fabricability from panels: +```sh +python optimize.py --ref_mesh data/inputmodels/david.obj --out_dir out/david_dev --develop_reg True --iter=1250 +``` + +### Extract mesh from known signed distance field +While not its designated use case, our function can extract a mesh from a known Signed Distance Field (SDF) without optimization. Please refer to the tutorial found in `examples/extraction.ipynb` for details. + +## Tips for using FlexiCubes +### Regularization losses: +We commonly use three regularizers in our mesh optimization pipelines, referenced in lines `L104-L106` in `examples/optimize.py`. The weights of these regularizers should be scaled according to the your application objectives. Initially, it is suggested to employ low weights because strong regularization can hinder convergence. You can incrementally increase the weights if you notice artifacts appearing in the optimized meshes. Specifically: + +* The loss function at `L104` helps to remove floaters in areas of the shape that are not supervised by the application objective, such as internal faces when using image supervision only. +* The L_dev loss at `L105` can be increased if you observe artifacts in flat areas, as illustrated in the image below. +* Generally, the L1 regularizer on flexible weights at `L106` does not have a significant impact during the optimization of a single shape. However, we found it to be effective in stabilizing training in generative pipelines such as GET3D. +Ablating L_dev + +### Resolution of voxel grid vs. tetrahedral grid: +If you are switching from our previous work, DMTet, it's important to note the difference in grid resolution when compared to FlexiCubes. In both implementations, the resolution is defined by the edge length: a grid resolution of `n` means the grid edge length is 1/n for both the voxel and tetrahedral grids. However, a tetrahedral grid with a resolution of `n` contains only `(n/2+1)ยณ` grid vertices, in contrast to the `(n+1)ยณ` vertices in a voxel grid. Consequently, if you are switching from DMTet to FlexiCubes while maintaining the same resolution, you will notice not only a denser output mesh but also a substantial increase in computational cost. To align the triangle count in the output meshes more closely, we recommend adopting a 4:5 resolution ratio between the voxel grid and the tetrahedral grid. For instance, in our paper, `64ยณ` FlexiCubes generate approximately the same number of triangles as `80ยณ` DMTet. + +## Applications +FlexiCubes is now integrated into NVIDIA applications as a drop-in replacement for DMTet. You can visit their GitHub pages to see how FlexiCubes is used in advanced photogrammetry and 3D generative pipelines. + +[Extracting Triangular 3D Models, Materials, and Lighting From Images (nvdiffrec)](https://github.com/NVlabs/nvdiffrec#news) + +[GET3D: A Generative Model of High Quality 3D Textured Shapes Learned from Images](https://github.com/nv-tlabs/GET3D#employing-flexicubes) + + + +## License +Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + +This work is made available under the [Nvidia Source Code License](LICENSE.txt). + +For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). + +## Citation +```bibtex +@article{shen2023flexicubes, +author = {Shen, Tianchang and Munkberg, Jacob and Hasselgren, Jon and Yin, Kangxue and Wang, Zian + and Chen, Wenzheng and Gojcic, Zan and Fidler, Sanja and Sharp, Nicholas and Gao, Jun}, +title = {Flexible Isosurface Extraction for Gradient-Based Mesh Optimization}, +year = {2023}, +issue_date = {August 2023}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {42}, +number = {4}, +issn = {0730-0301}, +url = {https://doi.org/10.1145/3592430}, +doi = {10.1145/3592430}, +journal = {ACM Trans. Graph.}, +month = {jul}, +articleno = {37}, +numpages = {16} +} +``` diff --git a/anigen/representations/mesh/flexicubes/examples/download_data.py b/anigen/representations/mesh/flexicubes/examples/download_data.py new file mode 100644 index 0000000000000000000000000000000000000000..3d0ea2d006ab5919b442d29bc019792927f90b10 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/download_data.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +import requests +from zipfile import ZipFile +from tqdm import tqdm +import os + +def download_file(url, output_path): + response = requests.get(url, stream=True) + response.raise_for_status() + total_size_in_bytes = int(response.headers.get('content-length', 0)) + block_size = 1024 #1 Kibibyte + progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True) + + with open(output_path, 'wb') as file: + for data in response.iter_content(block_size): + progress_bar.update(len(data)) + file.write(data) + progress_bar.close() + if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes: + raise Exception("ERROR, something went wrong") + + +url = "https://vcg.isti.cnr.it/Publications/2014/MPZ14/inputmodels.zip" +zip_file_path = './data/inputmodels.zip' + +os.makedirs('./data', exist_ok=True) + +download_file(url, zip_file_path) + +with ZipFile(zip_file_path, 'r') as zip_ref: + zip_ref.extractall('./data') + +os.remove(zip_file_path) + +print("Download and extraction complete.") diff --git a/anigen/representations/mesh/flexicubes/examples/extraction.ipynb b/anigen/representations/mesh/flexicubes/examples/extraction.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..650ee0d300e936764bf72d0839bd8bc1574284fb --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/extraction.ipynb @@ -0,0 +1,1668 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mesh Extraction from a fixed Signed Distance Field (SDF)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, we demonstrate how to use FlexiCubes to extract a mesh from a fixed signed distance field (SDF) **without** optimization. Note that in this case, the extraction scheme used is the original Dual Marching Cubes [Nielson 2004] algorithm, with minor improvements in splitting. To begin with, we will establish two functions: one for calculating the SDF of a cube, and another for determining its analytic gradient. In your specific application, the SDF might be predicted by a network, with gradients computed through methods such as finite differences or autograd." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import kaolin as kal\n", + "from matplotlib import pyplot as plt\n", + "\n", + "import render" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def cube_sdf(x_nx3):\n", + " sdf_values = 0.5 - torch.abs(x_nx3)\n", + " sdf_values = torch.clamp(sdf_values, min=0.0)\n", + " sdf_values = sdf_values[:, 0] * sdf_values[:, 1] * sdf_values[:, 2]\n", + " sdf_values = -1.0 * sdf_values\n", + "\n", + " return sdf_values\n", + "\n", + "\n", + "def cube_sdf_gradient(x_nx3):\n", + " gradients = []\n", + " for i in range(x_nx3.shape[0]):\n", + " x, y, z = x_nx3[i]\n", + " grad_x, grad_y, grad_z = 0, 0, 0\n", + "\n", + " max_val = max(abs(x) - 0.5, abs(y) - 0.5, abs(z) - 0.5)\n", + "\n", + " if max_val == abs(x) - 0.5:\n", + " grad_x = 1.0 if x > 0 else -1.0\n", + " if max_val == abs(y) - 0.5:\n", + " grad_y = 1.0 if y > 0 else -1.0\n", + " if max_val == abs(z) - 0.5:\n", + " grad_z = 1.0 if z > 0 else -1.0\n", + "\n", + " gradients.append(torch.tensor([grad_x, grad_y, grad_z]))\n", + "\n", + " return torch.stack(gradients).to(x_nx3.device)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, let's call upon FlexiCubes to extract the mesh from this SDF, both with and without providing the gradient information." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "res = 5\n", + "device='cuda'\n", + "fc = kal.non_commercial.FlexiCubes(device)\n", + "voxelgrid_vertices, cube_idx = fc.construct_voxel_grid(res)\n", + "voxelgrid_vertices *= 1.1 # add small margin to boundary\n", + "scalar_field = cube_sdf(voxelgrid_vertices)\n", + "\n", + "mesh_with_grad_v, mesh_with_grad_f, _ = fc(\n", + " voxelgrid_vertices, scalar_field, cube_idx, res, grad_func=cube_sdf_gradient)\n", + "\n", + "mesh_with_grad = kal.rep.SurfaceMesh(vertices=mesh_with_grad_v, faces=mesh_with_grad_f)\n", + "mesh_no_grad_v, mesh_no_grad_f, _ = fc(\n", + " voxelgrid_vertices, scalar_field, cube_idx, res)\n", + "\n", + "mesh_no_grad = kal.rep.SurfaceMesh(vertices=mesh_no_grad_v, faces=mesh_no_grad_f)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we visualize the two meshes. Without the gradient information (left), the extracted vertex locations are positioned at the centroids of the primal (Marching Cubes) mesh. Consequently, this method fails to reconstruct the sharp features present in the cube." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "camera = render.get_rotate_camera(0, iter_res=[512, 512], device=device)\n", + "f, ax = plt.subplots(1, 2)\n", + "output = render.render_mesh(mesh_no_grad, camera, [512, 512], return_types=['normals'])\n", + "ax[0].imshow(((output['normals'][0] + 1) / 2.).cpu())\n", + "output = render.render_mesh(mesh_with_grad, camera, [512, 512], return_types=['normals'])\n", + "ax[1].imshow(((output['normals'][0] + 1) / 2.).cpu())\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also visualize interactively with [kaolin's interactive visualizer](https://kaolin.readthedocs.io/en/latest/modules/kaolin.visualize.html), by moving around the camera and adjusting a wireframe to see the topology of the meshes." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9adcd325a6664219aeb6a2a4843ede3b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Canvas(height=512, width=1024), interactive(children=(FloatLogSlider(value=0.3981071705534972, โ€ฆ" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "95aa177aef744427b5061f5cd1547f5c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render.SplitVisualizer(mesh_no_grad, mesh_with_grad, 512, 512).show(camera)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "0310e1f1b5744d52bad42a93c0b4cacd": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_8fd21a1694e34e89aed7c2a8d9e706c4" + } + }, + "0623f93c57da497993e106b73e986ef7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "076373e179904a4ea7bb68807ef129a9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "08a6bc9e8c2441998aa15ebc4c69667d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "09357156e94142fe8abc1f70c30e70ec": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "0e971676622b4e24b3b7b4a4bbf82af8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "0f1e78a70fe049bfaab18c58610eb2aa": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_cad2738b444c452ebf92880dbd7c86f1" + } + }, + "0fc858ce475b4c5b854ee31d1ff0ce35": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_2e7fc70235424294be5f51f4ba00c6a8" + } + }, + "10785ebff0264da2a584b1cbdc280d7c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "13907e82d9bf42198fb63f62b7b8962b": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoqRU7tV0xRkYKL+Ap1Iumk5Lc2o0XVvZ7GdRV/7PF/d/U0z7JH6t+dZe0Ro8JURToq2bQZ4cge4pptDj5XBPuMU+eJDw1VdCtRU5tZMdVP4037PL/d/UU+ZdyXRqL7LIqKeYpAcbG/KkZWX7ykfUU7kOLW6G0UUUyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiilAJOBTSbdkAdacxjhQyTOqKOpY4AqG7vLbTot9w+C2doAyW+grkNS1S41F/3jbYgcrGOg/xP/166lGNFXlrLsTub1vrjXmsxW1uALck5Yj5nwp/IdPfj8K3dV/5BN5/1wf/ANBNcT4e/wCQ1b/8C/8AQTXbar/yCbz/AK4P/wCgmubETlOMXLu/0O7CaKf9dzgf7Tv/APn+uf8Av63+NTw67qcCFUvHIJz84Dn8zms6iosjlU5LZmvF4m1RJAzTrIB/C0Ywfywasf8ACXX/APzxtv8Avlv/AIqsCilyrsWq1RdTqE8YsEUPYgtjkiXAJ+mKmg8YW7bvtFrKnpsYPn88VyNFLkiWsTVXU7VPFuns6qY7hQTgsVGB78GrP/CR6T/z9/8AkN/8K4Gil7NFLF1F2PRY9W02eIMLyDaezuFP5HmpYbiyuHKQS28rAZIRlY4/CvNaKPZ+ZX1tveKPTvs8X939TTTaxk8ZH0NeaIzI6ujFWU5BBwQatpqOou6ol5dMzHAAlYkn86OWXcPb0nvA742i4+ViD780htOOH5+lQ6NbXltZKL64aWU87WIOz2z1J/yPfQqOdrqdSoU5K7jYp/ZJPVfzpptpQeFB9wavVnazqUumQJMtoZ4ycOwfbs9M8Hr/AJ601OTM54alFXdxWhkXqh/DmmlHAyVYD3FZ0Pi+1ZCZ7aZGzwEIYY+pxU0XivTnkCss8YP8TIMD8iTVc0uxh7Ki9plmik/4SPSf+fv/AMhv/hU66jpkihxd2vzDPzOoP4g0c77B9Wi9pohoq1E9ndFjBJFLt6+W4OPripDbRkcAj6Gj2iD6pPdNFGirn2SP1b86b9k/2/0p88SHhaq6FWirBtHzwyke9Na2kHQA/Q0+ZEOh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91LtKqeq4zkfTmtyssYnGME99f0O7BK/OvT9TnvDOitZobu6jAncfIpHMY/xP6fiRWlq+pRaZZtIzDzWBESddzf4etWbqY29tJKsbSsikhFBJY9hwDXFT6drWrTvdS2z7icYfCbR6AE9K4l7zuzom/Yw5KauzLnnluZ3mncvI5yzHvUda8XhnVHkCtAsYP8AE0gwPyyasf8ACI3/APz2tv8Avpv/AImteZHB7Go9bMwKK6hPBzFFL3wDY5AiyAfrmpoPB9uu77RdSv6bFCY/PNLniWsNVfQ5Giu1Twlp6urGS4YA5Klhg+3Aqz/wjmk/8+n/AJEf/Gl7RFLCVH2OBor0WPSdNgiCizg2ju6Bj+Z5qWG3srdy8EVvExGCUVVOPwo9p5FfVGt5I82RWd1RFLMxwABkk1Z/sy//AOfG5/79N/hXon2iL+9+hppuoweMn6Cjml2D2FJbzOFi0DVJYw62jAH+8wU/kTmup8M2VxYafJFdR+W5lLAbgeMD0+lXzdrj5VJPvxSG744Tn60nzSWxcPYUpXUtS1WdrOmy6nAkK3ZgjBy6hN2/0zyOn+elS/a5PRfyppuZSeGA9gKShJFzxNKSs7mVD4QtVQie5mds8FAFGPoc1NF4U05JAzNPIB/CzjB/IA1daaRurn8OKaXcjBZiPc1XLLuYe1oraAz/AIRzSf8An0/8iP8A41OunaZGoQWlr8ox8yKT+JNQ0Ucj7h9ZitoItRJZ2pYQRxRbuvloBn64qQ3MYHBJ+gqjRR7NB9bnski59rj9G/Km/a/9j9aq0U+SJDxVV9Swbt88KoHvTWuZD0IH0FQ0U+VEOvUfUe8ruMM2R9KZRRVWsZuTk7thRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAkV+zVdMsYGS6/gazqKdSTqJKT2NqNZ0r2W5f+0Rf3v0NM+1x+jflVOisvZo0eLqMtm7GeEJHuaabs4+VAD7nNVqKfJEh4mq+pObqTHRR+FN+0S/3v0FRUU+VdiXWqP7THmWQnO9vzpGZm+8xP1NNop2Icm92FFFFMkKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_8d390a6198e14de3abb4c02f86eed6e8" + } + }, + "14a8486500314b69a09ca2bb973b049e": { + "model_module": "ipyevents", + "model_module_version": "2.0.2", + "model_name": "EventModel", + "state": { + "_supported_key_events": [ + "keydown", + "keyup" + ], + "_supported_mouse_events": [ + "click", + "auxclick", + "dblclick", + "mouseenter", + "mouseleave", + "mousedown", + "mouseup", + "mousemove", + "wheel", + "contextmenu", + "dragstart", + "drag", + "dragend", + "dragenter", + "dragover", + "dragleave", + "drop" + ], + "_supported_touch_events": [ + "touchstart", + "touchend", + "touchmove", + "touchcancel" + ], + "_view_module": "@jupyter-widgets/controls", + "prevent_default_action": true, + "source": "IPY_MODEL_16a9d12b4d66495e937287d81d98ed86", + "throttle_or_debounce": "throttle", + "wait": 41, + "watched_events": [ + "wheel", + "mousedown", + "mouseup", + "mousemove", + "mouseleave", + "mouseenter", + "contextmenu" + ], + "xy_coordinate_system": "" + } + }, + "16a9d12b4d66495e937287d81d98ed86": { + "model_module": "ipycanvas", + "model_module_version": "^0.13", + "model_name": "CanvasModel", + "state": { + "_canvas_manager": "IPY_MODEL_74bbe62a9d604bc1902ed8de1ede91da", + "_model_module_version": "^0.13", + "_view_count": 2, + "_view_module_version": "^0.13", + "height": 512, + "layout": "IPY_MODEL_3593de689d2e4b278450682ae1cfbb80", + "width": 1024 + } + }, + "1cb8550bf1d948c599386ef05c6e3849": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQhhj6nFTReK9OeQKyzxg/xMgwPyJNcTRR7NFLFVEd9/wkek/8/f8A5Df/AAqymq6e6KwvbfDDIzIAfyPSvOKKXs0WsZPqkenRTQXMZaGSOZM4JRgwzTvLj/uL+VeX0+KWSGQSRO0bjoynBH40vZ+ZX1tPeJ6X9ni/u/qaabWMnjcPYGvPf7Tv/wDn+uf+/rf41ZTxDqqIqi7OFGBlFJ/Mjmjll3F7ai94nbm0XHysQffmkNpxw/P0rkIPFOpxbt7RTZ6b0xj/AL5xUyeL70OpeC3K55ADAkfXNFphzYZ9DpXt3RCxK4HpUNX7n/UN+H86oVUG2tTLEU405WiFFFFWc4UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRTZJEiQvIwVR1JNY994gjjylqvmN03noP8AGmkNI2iQoyxAHqapz6jFHGZFIKAZ3np/9esSCSfUCZrxz5K8hein1/DiqmoXxuD5ceREP/Hq2UYxjzS+R0RhCEeefyOqgvI5FG4hc9Dng1YrirK8a1fBy0bfeX+orat72SJPMtm8+3HBixyv+6f6H8KhxUleIOnGouanv2/yNuioLS9gvIw8EgJxkqeq/UVPWZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFSImeT0q4QdR8sQbsNVC30qjqusw6dmJB5lxjIUdF9N3+H8qz9X8QfftrE+xmB/Pb/j/APrrnWZnYsxLMxySTkk10OpGiuWnq+5Nr7nbaTdtPpttJcPullLKDjGSC3p7CuOu4GtbqWBs5jYrkjGR2P41uwXH2XQtLmLbVW5+Y4z8uXB/TNVPFEHl6mJQGxKgJJ6ZHGB+AH51Vb3qafVW/FAtzHoooriKNLw9/wAhq3/4F/6Ca9Brz7w9/wAhq3/4F/6Ca9BpVfgj6v8AQ7sFvL5fqeWUUUUzhCiiigAooooAKKKKACiiigAooqSCCW5nSGBC8jnCqO9AbhBBLczpDAheRzhVHeu70TRotLgycPcOPnk/oPb+f8jRNGi0uDJw9w4+eT+g9v5/yuX17BYWzT3DbUHQDqx9B71jKV9EenQoKmuee/5BfXsFhbNPcNtQdAOrH0HvXA6pqc+qXPmy/Kg4SMHhB/j70apqc+qXPmy/Kg4SMHhB/j71Sq4xscteu6jstjqfBP8Ay+/9s/8A2auqrlfBP/L7/wBs/wD2auqrKfxHdhv4SPNtV/5C15/13f8A9CNdf4e1v+0ozBOMXMa5JA4cevsfb/I5DVf+Qtef9d3/APQjUME8ttOk0DlJEOVYdq1ceZHnwqunNvod9relrqln5YYJKh3RsR39D7H/AA9K4CWN4ZXikG10Yqwz0I616DpGpRanZrIrDzVAEqdNrf4elUPEmireQNd28Z+1IOQo/wBYP8QP8PSohKzszqr0lUj7SBxVFFFbHnBRRRQAUUUUAFFFFABRRRQB6dc/6hvw/nVCr9z/AKhvw/nVCs6ex14z416BRRRWhyBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRUNzeQWqFppAuO3esO+8Qu2UtF2jpvbr+A/Kq5XuyuV7s3priKBd0sioPc1i3viIDK2aZ/wBtx/T86wZZpZm3SyM5yTyaZRdLYLpbE091PcnM0rP9ansbLz/3svywrySeM/8A1qLCxNwwkkBEQ/8AHqk1G9V1+zwY8scEjvjsPatYxsuefyN4QSXtKny8yO+vfO/dQ/LCvpxu/wDrVSoorKUnJ3ZhObm7sKmtbl7WXcnIP3l7GoaKSbTuhRk4u6NfYlyPtVgxjuFOSM4Jq7Y698yw36GN+nmYwPxHaufgme3lEkZwR+R9q0v3WqQ9kuUH5/8A1v5VpZT23On3a22kvz/4J1COrqGRgynkEHINLXH293d6TOUB+XOSh+63uK6LT9Vt74BQfLl/55sev09ayOZpp2L1FFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArO8SLIdHBTO1ZAXwccc/nzitGqF8RO13ZlXctaCRFHTIZv1zt/Kt6Ora7oTOPooorAZt3X/ACKVn/12P83qfVib/wAPWt7tLOhAdjx7Nx7sBUF1/wAilZ/9dj/N6n0NRfaLd2JyWByu4/KMjj9Rmu1avk7xRJztFFFcRRpeHv8AkNW//Av/AEE16DXn3h7/AJDVv/wL/wBBNeg0qvwR9X+h3YLeXy/U8sooopnCFFFFABRRRQAUUUUAFFFSQQS3M6QwIXkc4VR3oDcIIJbmdIYELyOcKo713eiaNFpcGTh7hx88n9B7fz/kaJo0WlwZOHuHHzyf0Ht/P+WhPPFbQPNO4SNBlmPasJSvoj06FBU1zS3/ACI769gsLZp7htqDoB1Y+g964HVNTn1S582X5UHCRg8IP8fejVNTn1S582X5UHCRg8IP8feqVaRjY5a9d1HZbBRRRVnMdT4J/wCX3/tn/wCzV1Vcr4J/5ff+2f8A7NXVVzz+I9fDfwkebar/AMha8/67v/6Eaq1a1X/kLXn/AF3f/wBCNVa3Wx5UviZa02+k069S5jG7bwy5wGB6j/PfFehWd1Fe2sdxCTskGRkYI7EfnXmdauhavJplyFZs20jDzFP8P+0Pf+f5VM431OjD1vZvlexpeJ9EcSSahbDch5lQD7v+0Pb1/P6cxXqH7ueL+GSORfqGB/mK4bxDpH9m3IeFW+zSfdJ52n+7n/P44NKEujLxNG3vx2MiiiitDiCiiigAooooAKKKKAPTrn/UN+H86oVfuf8AUN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiig1UIuclFDiuZ2RBPdxQKScsR2UZ/lWDf69cMxjhQwD1YfN2/KtW+vrG0nSCeJgWAbcijAGSOec9qYs+k3O4LcqoAwQx2g/99da7PYQWilqb8tPZOzOUZmdizsWJ7k5pK6t9EtpkVkEbA8gqNoI/DrVSbw8MsUDDjjawI/XmolhKm61E6LezRz9W7C0NzKCwPlL949M+1XBoUnmIpZjk8jZgke1aR0yeS2MECGJcYOV7fjUxouLvM1o4aTfNJaL8THv74FTb25AjHBYd/Ye1Z1dLF4X+VS7nPcFuv5D+tWf7G0yzYG4ljTcCAHYDP/fRNRO8neTLnh6tR802kcjUy2dy7BRA+T6rgfrXUi60O1zF56nb/dBI/AqMVXk8R2MaqbeyZnB/jAXHvnnmotBdSPYUo/FMx4dHvJs4jxj3z/LNXYvDVwyqzMcdxgD+Z/pT5vFdyWHk28SLjo5LHP1GKoz67qUwZTcFFY5wgC49gev60XiugXw0ejZsReF41f8AePuX3b/ACrdro1hE7ojKZUOW2kZXI75yRXN2dve6zcLG00jqnLPIxYID9e/HSuoY2mjWG1fkiT8Wdv6n/PQVUZN7aHTRlGXvKNkuol1ptpPHteLOP4s81j3Ph1gxe0mwRyFbt+NbOnXf2+yWchQxLAqDnbzwPyxXN6q01hq0rQO8QkIkG1uG+o+uetRVvzXRVd0+RTlG/wCZdt9RvdPKx6lE7Rk4EvUj8eh/nW1b3EVzGJIJA6eornLfxFcRjE8aTDHUfKc/y/SrlveaXK+6Fms5TwCPk4HPPVfzrO7W5xeypz+CX3m3RTUYMoYMGB5BHQinU00zKpRnT+JBRRRTMgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKyri48jxNaZbaskPltxnOS2B+eK1a5zxDK0Gr20ygFo41YA9Mhia0py5Xf+txMybuJYLyeFSSscjKCeuAcVDWr4kRRqhlVw6zRq4I6Yxj8emfxrKpVI8smho27r/kUrP/AK7H+b1H4YnaLVBFyVmUqRngEDOf0I/GpLr/AJFKz/67H+b1kW0vkXMU23d5bhsZxnBzW0pcs4y8kIn1WD7NqdxFhQA5IC9ADyB+RqpW/wCKot0tvdo26N025AyPUc++f0rArKtHlm0C2NLw9/yGrf8A4F/6Ca9Brz7w9/yGrf8A4F/6Ca9BrKr8EfV/od+C3l8v1PLKKKKZwhRRRQAUUUUAFFFKis7qiKWZjgADJJoAEVndURSzMcAAZJNd14e0j+zbYvMq/aZPvEc7R/dz/n8cCo/D+hLp6C4uAGumH1EY9B7+p/D67E88VtA807hI0GWY9qxnK+iPSw9Dk9+W4TzxW0DzTuEjQZZj2rg9b1mXVJ8DKW6H5I/6n3/l/M1vWZdUnwMpbofkj/qff+X88yqhC2rMMRiOf3Y7BRRRWhyBRRRQB1Pgn/l9/wC2f/s1dVXK+Cf+X3/tn/7NXVVzz+I9fDfwkebar/yFrz/ru/8A6Eaq1a1X/kLXn/Xd/wD0I1VrdbHlS+JhRRRTJOi8M62lp/od0cQs2UkJ4QnsfQfyP146u6t47u2kt5RlJFKn29x715lXY+Gdbe7/ANDujmZVykhPLgdj6n+Y+nOU49Ud+GrX/dyOb1TTJ9LufKl+ZDykgHDj/H2qlXo2qaZBqlt5UvyuOUkA5Q/4e1eezwS207wzoUkQ4ZT2qoSujCvR9m9NiOiiirOcKKKKACiiigD065/1Dfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACsjW9SNpJBHHnduDuAcZUHp+P8AT3rVlkWKNpHOFUEk+gFcRd3DXV1JO/Bc5x6DsPyraL5I83Vmi92N+rN3xJAJbWG6jwwU7SVGcqehz6f41zldTY41LQfIO3cEMfcAMPu/0NctV4hXamuo6q1v3HRyPE4eN2Rh0ZTgirkGsX8GALhnGckSfNn2yeao0VhGUo7MzvY7nRLma8sxcTiMFidoTPTOOc+4NYF74ivWupPs0ypCGITag5GeCc98Vu6KBaaJG8zAKqGQkc4By38jXEVpWbcteyOuc5QpRSdrlie/u7gMJrmV1c5Klzt9enSq9FFYnI23uFFFFAgqeztJr64WCBcsepPRR6n2os7Sa+uFggXLHqT0Uep9q7C2t7XR7FgGAAGZZW6sf89BVRjc6KFB1Hd7DY1ttC00qXJUHLN3dj6D8P8APWuU1G/l1CfzJOFHCIOij/PepNW1BtRut4BWNRhFJ7ep9zVGnKXRbDr1ub3IfCjpfCsubaeHb91w2c9cjH/stQ+KYgHglCnJypbt6gfzqt4alWPVNpBzIhUY9ev9K2PEMHm6a5AYmMhwB+R/QmiWsU+x0w/eYZrt+mpyNFFFQeaSwXM1s26CV4zkE7Twceo71p2/iK4jGJ40mAHUfKc/y/Sseik0maQqzh8LOwttZsrgcTCNsZ2yfLj8en61fzXAV12j2w0/TjJMWUkeZJnPy8en061Enyq510uXENqUbea0NKkpW60lWndXOKceWTj2CiiimSFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVzPij/kIRf9cR/6E1dNXM+KP+QhF/1xH/oTVS2YCaovn6Jp10FVdoMLepxwPw+U/nWPWvZItz4dvIQhaSGQTA5wAMY/kGrIq6utpd1/wBI27r/kUrP/AK7H+b1iVt3X/IpWf/XY/wA3rEp1t16IEdHN/p3hKN+rwY4TttO3n/gJzXOV0XheVJoLqxlAKsN2OckEYbn8vzrn5I2ileOQYdCVYehFVW96MZ+X5AjQ8Pf8hq3/AOBf+gmvQa8+8Pf8hq3/AOBf+gmvQa5qvwR9X+h34LeXy/U8sooopnCFFFFABRRSorO6oilmY4AAySaABFZ3VEUszHAAGSTXbeH9CXT0FxcANdMPqIx6D39T+H1PD+hLp6C4uAGumH1EY9B7+p/D67TsqIzuwVVGSScACsZzvoj0sPh+X3pbjZ54raB5p3CRoMsx7Vwet6zLqk+BlLdD8kf9T7/y/nJ4h1f+0rkJCzfZo/ug8bj/AHsf5/DJrIqoQtqzDEV+d8sdgooorQ5AooooAKKKKAOp8E/8vv8A2z/9mrqq5XwT/wAvv/bP/wBmrqq55/Eevhv4SPNtV/5C15/13f8A9CNVatar/wAha8/67v8A+hGqtbrY8qXxMKKKKZIUqMyOroxVlOQQcEGkooA77QtXj1O2Cs2LmNR5in+L/aHt/L8qj8RaMdTgWSDAuIgdoOBvHpn+X4+ua4uzupbK6juISN8ZyMjIPYj8q9C02+j1GyS5jG3dwy5yVI6j/PbFYyXK7o9KjUVaPJPc84dWR2R1KspwQRgg0ldX4o0VdjX9rGd2czKo4x/e/wAfz9a5StYu6ucNSm6crMKKKKZmFFFFAHp1z/qG/D+dUKv3P+ob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUU2WRYo2kc4VQST6AVUY8zshxV3YxfEt5siS1U8yfM/0HT9f5VzlTXdw11dSTvwXOceg7D8qhp1Jcz02HJ3eht+GbjZPLbk8ONy5buPQfT+VU9btzb6pLwdsh8xST1z1/XNQ6dcC1v4ZjgKrfMSM4B4P6GtnxRDmKCcBflJQnuc8j8OD+dbr36DXYven6HO0UVJbxefcxQ7tvmOFzjOMnFcqV9DI7O4AtPDkiTMBtt/LyOQTt2j9a4iu08RSLHociscGQqq+5zn+QNcXWlX42dOI05V5BRRRWZzBUttA91cRwRDLu2B7e/0psEMlxMsUKF5HOAorsdM06HSbdmZlMxGZJT0Ueg9B/n6VGLbN6FF1X5Eltb2ujWLAMBgZllbqx/z0H9a5fVtUk1CXAykCn5E/qff+VLrGpvfzlVOLdD8gHf8A2j/nis6nJ9EaV66a5IbIKKKKg5Cazn+zXkM2WARwTt6kdx+VdxcxLNA8bEhXUqcdcEVwNdzYT/atPhlLbiyDccY+Ydf1zVrWLR6OBlvFnDUVc1aLydUuFznL7unrz/WqdQjglHlk4voFFFFBJf0Wz+13y7lzFH8z5HB9B+P8s1reJrvy4Es1PzSfO/0HT9f5e9WdHtV0/TjJMNrEeZISOQMdPXgdvXNcveXLXd3JO/Bc5x6DsPyrL4peh3z/AHFBR6yOt0abz9KgYlcoNhA7Y4H6Y/OrlYXha4BSe2JGQfMXjk9j/T863aqOl0c1XW0u6/LQKKKKsxCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK5nxR/yEIv+uI/9CaumrmfFH/IQi/64j/0JqpbMBvhx1e5ns5HKpcxFcAck/wD6t1ZLKyMVYFWU4IIwQataVP8AZtTt5cqAHAJboAeCfyNO1qLydWuV3bsvuzjH3uf61b1pryYupeuv+RSs/wDrsf5vWJW3df8AIpWf/XY/zesSnW3XogRpeH7jyNWhy21ZMxtxnOeg/PFL4hthb6rIVACygSAA+vX9Qazo5GilSSM4dCGU+hFdB4mVbizs71AArDHI+bDDI/kfzqo+9Sa7ah1M/wAPf8hq3/4F/wCgmvQa8+8Pf8hq3/4F/wCgmvQa5qvwR9X+h34LeXy/U8sooopnCFFFFACorO6oilmY4AAySa7bw/oS6eguLgBrph9RGPQe/qfw+rPDOjfY4vtV1Fi5f7gbqi/TsT/L8a3XZURndgqqMkk4AFYznfRHo4ehy+/LcHZURndgqqMkk4AFcT4g11tQc29uStqp+hkPqfb0H4/Q8Qa62oObe3JW1U/QyH1Pt6D8fpiVUIW1ZliMRze7HYKKKK0OMKKKKACiiigAooooA6nwT/y+/wDbP/2auqrlfBP/AC+/9s//AGauqrnn8R6+G/hI821X/kLXn/Xd/wD0I1Vq1qv/ACFrz/ru/wD6Eaq1utjypfEwooopkhRRRQAVe0jUpdMvFkVj5TECVOu5f8fSqNFDVxxk4u6PT4J4rmBJoHDxuMqw71x3iTRWs52u7eMfZXPIUf6s/wCBP+HpUfh7W/7NkME4zbSNkkDlD6+49v8AJ7WeCK5geGdA8bjDKe9YawZ6Xu4mn5nmFFX9Z0x9MvWi+YwtzG7D7w/xHT/9dUK3TuebKLi7MKKKKBHp1z/qG/D+dUKv3P8AqG/D+dUKzp7HXjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFY3iS7EdqLYYLynJ9lB/wAf61sOwRSzEBQMkk8AVxWoXRvLySY52k4UHsvato+5By6vT/M0Xuxv3K1FFFYmYV1cJOp6AUyWkKbcbsksvTJPrgfnXKV0Hhi4G2a3OMg+YvHJ7H+ldOGfvcr2ZrS35e5z9XNHi87VbZd2MPuzj05/pRq9t9l1KZAMITuXC4GDzx7Dp+FWfDcPm6srbseWpbp17f1rOEbVFF9yEvesa3i2RV0+CIn52k3AewBz/MVyldH4wkUy2sYPzqrMR7HGP5GucrOTu7m2Kf7xrsFPghkuJlihQvI5wFFNVWdgqKWZjgADJJrstI09NLs/MmCrcMuZHJyEHpn+f/6qErsmjRdWVug7TdNh0m2LMymcjMkh6KPQegrA1nV2vWMMBK24P0Ln1Pt7f5BrWsNesYYSRbg/i59T7e3+Rk1TlZWRtWrK3s6ewUUUVBxhRRRQAV1fhiUvpzRlgTG5AXuAef55rlK2/C0+y8lhJUCRMjPUkdh+BP5VdN2kdOFly1V5h4oi23MMu77ylcY9D/8AXrErqvEsG+w8wBcxsDk9cHjj8SPyrlai1tB4uNqrfcK0tEsReXe5/wDVRYZhgHJ7D+f5Vm12FhCmlaVum4KgvJz1b0649BUTlZBhaanO8tkVPE135cCWan5pPmf6A8fr/L3rmqluriS7uHnlxvc5OBgVFThHlRnXq+1m5GhodwbfVIjztkPlsAOuen64rsD1rgFZkYMpKsDkEHBBrvIZfPt4ptu3zEDYznGRmltL1Be9Tfk/zHUUUVZiFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVzPij/kIRf9cR/wChNXTVzPij/kIRf9cR/wChNVLZgY1bfiT999ivOnnw/c/u9+v/AAL9KxK2nVbjwrGygbrWUhiRzgnt/wB9L+VaU9Yyj/WgmLdf8ilZ/wDXY/zesStu6/5FKz/67H+b1iUVt16IEFdNbN9t8JTRlmDQgglufuncAPbGBXM1v+EpcXNxDt++gbOemDj/ANm/Snh37/K+ugMpeHv+Q1b/APAv/QTXoNcJpcH2bxOsGGAR3A3dSNpwfyru656ytBLzf6HfgvtfL9TyyiiimcIV13h3QPI23l6n73rHGf4Pc+/t2+vQ8O6B5G28vU/e9Y4z/B7n39u316dLWM59Eehh8Pb35jXZURndgqqMkk4AFcT4g11tQc29uStqp+hkPqfb0H4/Sx4k11boNZWhDQ5/eSdd5B6D2z37/TrzlVCHVkYmvf3I7BRRRWhxBRRRQAUUUUAFFFFABRRRQB1Pgn/l9/7Z/wDs1dVXK+Cf+X3/ALZ/+zV1Vc8/iPXw38JHm2q/8ha8/wCu7/8AoRqrVrVf+Qtef9d3/wDQjVWt1seVL4mFFFFMkKKKKACiiigArqPC+tNvWwupBtxiFmPOf7v+H5elcvRSaurGlOo6cuZHpOoWUWoWclvKB8w+ViM7W7EV59fWU9hctBcLtcdCOjD1HtXXeHdbS9iW1nO25RcAk/6wDv8AX1/P6WNd0iPU7Ysq4uY1PlsP4v8AZPt/L86yi+V2Z3VYKvDnhucDRSurI7I6lWU4IIwQaStjzT065/1Dfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopHYIpZiAoGSSeAKqEXKSSHFczsZHiK98m2FujfPL1wei/wD1/wDGuYqzqF0by8kmOdpOFB7L2qtVVJKUtNkVN3emwUUUVmQFXNKuPs2owuThSdrfNgYPHP06/hVOinF8rTQ07O50HiiDiC4C+qM2fxA/nTfCUO67ml3fcULjHXJz/wCy1enA1TQiwALsm8YXPzDqAPwIqPwjDiGebd95guMdMD/7KuypH95zrZq/4HQo3rLzKPiuRX1UKpyUiCt7HJP8iKxlVnYKilmY4AAySa0NcYXGuXAhy5LBAAOSQACPzFb+i6OunIJ5wGumHA6iMeg9/f8AyeNK70H7KVarK21xNG0hdPQTTgNdMPqIx6D39/8AJzdc1nzt1rat+76PIP4vYe38/p1Nc1rzi1tat+76PIP4vYe38/p1wqttJWRdatGMfZ09gooorM4gooooAKKKKACrmjy+Tqts23OX24z68f1qnRTTs7lRlytM7u+h+0WksWFJdCBu6Z7frXCV3sMvn2sU23bvQPjOcZGa4y/gaPUpoVjwTIdqKOxPGMexFOorT9TvxsbqMkWdAtPtN8JGHyQ4Y/Xt/j+FXvE15gJZRt/tyYP5D+v5VfsIU0rSt03BUF5OerenXHoK5O4ne5neaQ5dzk+3tWC96V+xNT9zRVPq9yOiiitTgCus8OzrLpYjGA0LEEZ5wec/r+lcnW14YuBHeSQMQBMvHHOR/wDWzUT2v2NqOsuXvp/XzOloooqzEKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArmfFH/IQi/64j/0Jq6auZ8Uf8hCL/riP/QmqlswMatrQ1FzY6hZHLM8YeOPOBkd/TrtrFrT8OzGLV4hvCrICjZ78cD8wKui7TVxMsXX/ACKVn/12P83rErodXg+zeH4YMMAlywG7qRl8H8q56nXVml5IEFXNInW21S3lbG0NtJJwACMZ/DOap0VlF8rTQzrLm38vxVaTBcLKjZOerBSD+m2unrFhUXyafe/IXQFmIPAypBA/HH5VtVrjVazXVt/kduB+18v1PLK67w7oHkbby9T971jjP8Huff27fXoeHdA8jbeXqfvescZ/g9z7+3b69OlrjnPoi8Ph7e/MK5DxFr/n7rOyf910kkH8fsPb37/TqeItf8/dZ2T/ALrpJIP4/Ye3v3+nXm6cIdWTiMRf3IBRRRWpwhRRRQAUUUUAFFFFABRRRQAUUUUAdT4J/wCX3/tn/wCzV1Vcr4J/5ff+2f8A7NXVVzz+I9fDfwkebar/AMha8/67v/6Eaq1a1X/kLXn/AF3f/wBCNVa3Wx5UviYUUUUyQooooAKKKKACiiigCSCeW2nSaBykiHKsO1d/o2ppqdksvyiZeJEU/dP+B6//AKq88qzp97Lp95HcRE/KfmUHG5e4NRKN0b0KzpvyOp8TaK14gu7WMGdB86gcyD/Efr+AFcbXpdjewX9ss9u25D1B6qfQ+9ct4m0RLT/TLUYhZsPGBwhPceg/kfrxMJdGb4mimvaROsuf9Q34fzqhV+5/1Dfh/OqFOnsRjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVj+Ir3ybYW6N88vXB6L/9f/Gtg1nXmjwXlwZpZZtxAGAwwB7cV1UqUnByjuzenBuLaORorp/+Ecs/+ek//fQ/wo/4Ryz/AOek/wD30P8ACl9VqC9jM5iiun/4Ryz/AOek/wD30P8ACj/hHLP/AJ6T/wDfQ/wo+q1A9jM5iiun/wCEcs/+ek//AH0P8KP+Ecs/+ek//fQ/wo+q1A9jMj8MXO6GS3Y8ody5bseuB9f51r6RY/YY5kBG1pGdQP4Qeg/IVUsdJgsZjLE8hYrt+YjGOPb2rVibahP4V0Sg40bS3OqhB80b9DL0/SxFfzahNnfJI7RJyNoJPJ98Hp2+vSl4h1UFWs4HJbOJWB4x/d/x/L1rdnQzRMnmPGWGNyHBH0rJ/wCEas/+es//AH0P8K5eRpWRvUpzUOSmt9zlaK6r/hGrP/nrP/30P8KP+Eas/wDnrP8A99D/AAqPZyOL6pVOVorqv+Eas/8AnrP/AN9D/Cj/AIRqz/56z/8AfQ/wo9nIPqlU5Wiuq/4Rqz/56z/99D/Cj/hGrP8A56z/APfQ/wAKPZyD6pVOVorqv+Eas/8AnrP/AN9D/Cj/AIRqz/56z/8AfQ/wo9nIPqlU5Wiuq/4Rqz/56z/99D/Cj/hGrP8A56z/APfQ/wAKPZyD6pVJvD03naUiksTGShJ/MfoRTW04PrQuyo2KgPXOX6dPYY/SrOn6dFp6usMkrK5Bw5BAPtx/nFWgvzE1Fe8YJnp04XglPp+hz/ia8wEso2/25MH8h/X8q56umuPDr3M7zSXuXc5P7vp7feqL/hF/+nz/AMhf/XrCM4RVrnBWo1qk3K35HPUV0P8Awi//AE+f+Qv/AK9H/CL/APT5/wCQv/r1XtYdzL6rW7fkc9U9jcG0vYZ+cI2TgZOO/wCma2v+EX/6fP8AyF/9ej/hF/8Ap8/8hf8A16TqQfUaw1ZO6X5G+etJSRxtHBGjOXZVClz1YgdaWqg7xRnXjy1GgoooqzEKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuZ8Uf8AIQi/64j/ANCaumqKfTLO9ZZLiHe4G0HcRxk+h961pU3UbihN2OFqS2l8i5im27vLcNjOM4Oa7H+wdM/59v8AyI3+NSRaNp0LFltUJIx8+WH5HNbrCTT3QuZFLxX/AMgyP/rsP/QWrk69De3gkiWKSGNo1+6rKCB9BUX9n2X/AD52/wD36X/Ctq2HdSXNcSdjgaK9Ajs7WJw8VtCjjoyoARU9ZrBPrIfMYvhe5EunGAkboWxgDseR+ufyrpqp1crDHR5Ywi/P9DvwP2vl+oVyPiXXWkeSwtSVRSVlfoWPdR7evr9OvXUV58XZ3O2pBzjZOx5ZRXqdFae08jk+pf3vwPLKK9Too9p5B9S/vfgeWUV6nRR7TyD6l/e/A8sor1Oij2nkH1L+9+B5ZRXqdFHtPIPqX978DyyivU6KPaeQfUv734HllFep0Ue08g+pf3vwOV8E/wDL7/2z/wDZq6qiis5O7uddKHs4qJ5tqv8AyFrz/ru//oRqrXqEsUc0ZjlRZEPVWGQfwqv/AGZYf8+Nt/36X/CtFUOSWDbd0zzeivSP7MsP+fG2/wC/S/4Uf2ZYf8+Nt/36X/Cj2iJ+py7nm9Fekf2ZYf8APjbf9+l/wo/syw/58bb/AL9L/hR7RB9Tl3PN6K9I/syw/wCfG2/79L/hR/Zlh/z423/fpf8ACj2iD6nLueb0V6R/Zlh/z423/fpf8KP7MsP+fG2/79L/AIUe0QfU5dzzeivSP7MsP+fG2/79L/hR/Zlh/wA+Nt/36X/Cj2iD6nLucVomsy6XPg5e3c/PH/Ue/wDP+Xe/u54v4ZI5F+oYH+Yqv/Zlh/z423/fpf8ACrEUUcMYjiRY0HRVGAPwqJNPU6qNOVNcrd0Nuf8AUN+H86oVfuf9Q34fzqhWlPY48Z8a9AooorQ5AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKALNlJsm2no/H49qdq17Pp9sbiK0+0IvMgD7So9ehyPX0/lUpbrVG0+WG5nJaznPlynqYpAOGHsR1AHGM9TzvTnZWFexl/8Jr/1D/8AyN/9jR/wmv8A1D//ACN/9jUHiLQFjQ6hpwDW7Dc6JyFH95f9n+X06c1SlOcXZsq51n/Ca/8AUP8A/I3/ANjR/wAJr/1D/wDyN/8AY1ydFT7WfcLnWf8ACa/9Q/8A8jf/AGNH/Ca/9Q//AMjf/Y1ydFHtZ9wudZ/wmv8A1D//ACN/9jXXx9DXklepaXK82n20sh3PJCjMcYySBmq5nKLuaUn7xh33i5rK9mtn04kxOVyZcZHY429xzVf/AITj/qHf+R//ALGsrxajL4huCykBghUkdRtAyPxB/KsasRyqTTaudd/wnH/UO/8AI/8A9jR/wnH/AFDv/I//ANjXI0UE+1n3Ou/4Tj/qHf8Akf8A+xo/4Tj/AKh3/kf/AOxrkaKA9rPudd/wnH/UO/8AI/8A9jR/wnH/AFDv/I//ANjXI0UB7Wfc67/hOP8AqHf+R/8A7Gj/AITj/qHf+R//ALGuRooD2s+513/Ccf8AUO/8j/8A2NX9I8Rz6tdeTDp21F5kkM3CD/vnr6Cue0Hw5Lqo8+VjDbA4DY5fnkD/AB9fXmu1nuLDQrBRIUhijU+XEp+Zseg7nn9cmk3Y2g5vWT0Lyrnr0rN1jWLXSBGbgSMZCQqoMnjqeeO4/Oo/Dmp3GrwXF3NsSMSeXHEo+6AM5J7k7gO3T3rmvG9wZNThhEgZYos7Rj5WJOc/gFrmqL2k1BjlP3eZGr/wmenf88br/vlf/iqP+Ez07/njdf8AfK//ABVcNRT+q0zH20juf+Ez07/njdf98r/8VR/wmenf88br/vlf/iq4aij6rTD20juf+Ez07/njdf8AfK//ABVXdL1+31WcxW1vc4UZZ2VQq/U5rgrCxn1G6W3tk3O3JJ6KPU+1dfK8dgtpoWnPi4lYee8fDBcZZsk8MQMjrgfhWVSjTXux3NITlLV7GrqMmdiA+5H+fxqjU102+4frgHHNQ11Uo8sEjKq7zYUUUVoZhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVFPqdnZMsdxNscjcBtJ4yfQe1S1zPij/kIRf8AXEf+hNWtKo6bckJq5uf29pn/AD8/+Q2/wqSLWdOmYqt0gIGfnyo/M4rhqktovPuYod23zHC5xnGTit1i5t7IXKj0HzE8rzd6+Xjduzxj1z6VB/aFl/z+W/8A39X/ABqaZY5IzFLjbKCmCcbuDkflmvPGVkYqwKspwQRgg1016zpWshJXO/jvLWVwkVzC7noquCTU9ecUVgsa+sR8p6PVyvPvD3/Iat/+Bf8AoJr0GuXF1faxi7W3/Q9DAq3N8v1CivLKK5vZ+Y/rv938T1OivLKKPZ+YfXf7v4nqdFeWUUez8w+u/wB38T1OivLKKPZ+YfXf7v4nqdFeWUUez8w+u/3fxPU6K8soo9n5h9d/u/iep0V5ZRR7PzD67/d/E9TorzCCCW5nSGBC8jnCqO9d9omlrpdn5ZYPK53SMB39B7D/AB9amUeXqbUa7qv4dDRoooqDpGSyxwxmSV1jQdWY4A/Gq/8Aadh/z/W3/f1f8a4HVf8AkLXn/Xd//QjVWtVTOCWMadkj0j+07D/n+tv+/q/40f2nYf8AP9bf9/V/xrzeij2aJ+uS7HpH9p2H/P8AW3/f1f8AGj+07D/n+tv+/q/415vRR7NB9cl2PSP7TsP+f62/7+r/AI0f2nYf8/1t/wB/V/xrzeij2aD65Lsekf2nYf8AP9bf9/V/xo/tOw/5/rb/AL+r/jXm9FHs0H1yXY9I/tOw/wCf62/7+r/jR/adh/z/AFt/39X/ABrzeij2aD65Lsekf2nYf8/1t/39X/GrEUsc0YkidZEPRlOQfxrgtE0aXVJ8nKW6H55P6D3/AJfz7393BF/DHHGv0CgfyFRJJaHVRqSqLmashtz/AKhvw/nVCr9z/qG/D+dUK0p7HHjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUrwJd281nKcJOu3P91uqn8DSUU07MDA0PWpdHuWsb7Jt1cqw6mJs84x1Geo/Ee8viLQFjQ6hpwDW7De6JyFH95f9n+X06N8WWeWi1FBxL+7l/3wOD+IHYdveovDuvtpzi2uiWtGP1MR9R7eo/Ee+ia+GWwjBorpfEWgLGh1DTgGt2G90TkKP7y/7P8AL6dOaqJRcXZjCiiipAK9G8MSvLodo0hydpXOOwJA/QCvOa7rwXK76OVY5EczKox0GAf5k1pT6ryLg7SRk+OUYarA5U7TAAGxwSGbI/UfnXN12Hj1GKWLhTtBcFscAnbgfofyrj6zHVXvsKKKKDMKKKKACiiprW1nvJhDbRPLIeyjp2yfQc9aAIkRpHVEUszHAUDJJ9K6/wAP+FVKR3WpIS+dyQHoB/tf4fn6VqaD4bg0zbO582624Ln7qeu3+Wf5ZxVDX/FiQr9n0mQNJn558ZC4PQZ4P16Y6e0t9EbqCgryNLXPENtpKPEhEt7gYj5wue7H+nXp65rgL29udQuDPdymWTAGTxgegA4FQu7SOzuxZ2OWZjkk+ppYYnnmjhiXdJIwVRnGSTgU0rGc5uTPSPDVt9k8PWqkIGkXzCVHXdyM++MD8K4LXLn7XrN3NlCDIVUp0IHAP5AV6RqEn2LTZngRB5ELMiY+UbRwMDtxXlNYU9akpGlXRJBRRRXQYBUlvby3U6QQIZJHOFUd6YiNI6oilmY4CgZJPpXX2VvB4VsTeXp33sy7ViVug4O3+WT27e+dSfKrLcuEeZ+QrvD4U0hrdZBJqFwN2VA4OMA9Pujtnqc++KHhGEzahcX0x3mBCcsxyXbPPvxu6+tYd3cyXl1LcTHLyMWPt7D2FdX4bh8jQDIQm65lJBHXaOMH8QfzqOTljZ7s0Uru62ReooorcwCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK5nxR/yEIv+uI/9CaumrmfFH/IQi/64j/0JqpbMDGrT8OwmXV4jsDLGC7Z7ccH8yKzK2tDYW1jqF6cqyRhI5MZGT29Ou2roq81cTNP7Yz2mn3K5PmXpA39QrFx+gNYWuweRq04Aba53gt3zyce2c/lVu6/5FKz/AOux/m9HiT999ivOnnw/c/u9+v8AwL9K3qvmhr5MSMSiiiuMo0vD3/Iat/8AgX/oJr0GvPvD3/Iat/8AgX/oJr0GlV+CPq/0O7Bby+X6nllFFFM4QooooAKKKKACiiigAooooAKKKKAClRWd1RFLMxwABkk0ldp4Z0b7HF9quosXL/cDdUX6dif5fjUylZGtKk6krIn8PaR/ZtsXmVftMn3iOdo/u5/z+OBVzVNQi0yzNxKC3O1FH8Tent0qW8uorK1kuJidkYycDJPYD864DVNTn1S582X5UHCRg8IP8fesopyd2d9WpGhDljudJ4WvZ7+5v57htzny8AdFHzcD2roq5XwT/wAvv/bP/wBmrqqU9y8O26ab/rU821X/AJC15/13f/0I1Vq1qv8AyFrz/ru//oRqrW62PKl8TCiiimSFFFFABRRRQAUUUUAFWdPspdQvI7eIH5j8zAZ2r3JqKCCW5nSGBC8jnCqO9d/o2mJplksXymZuZHUfeP8AgOn/AOuolKyN6FF1H5FixsoLC2WC3Xag6k9WPqfeuW8Ta2l3/odqcwq2XkB4cjsPUfzP050PE2tNZoLS1kAncfOwPMY/xP6fiDXG1MI9Wb4mskvZxPTrn/UN+H86oVfuf9Q34fzqhTp7EYz416BRRRWhyBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFACvAl3bzWcpwk67c/wB1uqn8DXBTRPBM8Ug2vGxVhnOCODXeVh+LLPLRaig4l/dy/wC+BwfxA7Dt71W6F1IvDuvtpzi2uiWtGP1MR9R7eo/Ee8/iLQFjQ6hpwDW7De6JyFH95f8AZ/l9OnNVuaB4hfTMwXAeW1OSAv3kPtnsfT8fXNRkmuWQGHRXR67okTQf2ppWJLVxuZE/h9SB6eo7fTpzlTKLi7MYV1/gaVzFdxE/IjIwGOhOc/yFchXReCXYapMgY7TCSVzwSGGD+p/Oqp/Ehrc2vG6M2ixlVJCzqWIHQYYZP4kfnXB16P4oVpPDt0FUscKcAZ4DAk/lXnFZmtb4rhRRRQYhRRXQaF4Ym1DbPdh4bVlypGNz+mPQd8n2x1zQOMXJ2Rn6Ro91qs6pEpWLPzzEfKvr9Tz0/wD113tlYWGgWEjhvLiHzSSyHLN6Zx+QA/maW7vLDw9YRh12Rj5Y4oxlm9cZ/Mk/zNcFrGs3WrXDPM5WHPyQhvlX0+p5PP8A+qpu3sb+7T9S/wCIPE8upHybMyQWoHIzhpMjnOO3t+ftz9FFNKxg227sK2PCdr9q1+3ym9IcytzjGOh/7621j113gG1zNd3ZDjaojU/wnJyfxGF/OlJ2Q4K8kafjS48rRHTbnzpFTOen8Wf/AB3H4159XUeO5997awbcbIy+7PXccY/8d/WuXrOgvcv3Kqu8goorovDGjR3O6/v1xaxcoHwFcjqT7D8vyIrSc1BXZMYuTsifQtNt9P0/+29RBIUboo9vTnAOO5J6du/0wtW1KXVL1riUBeNqKP4V9M9+tWdd1uXVp8DKWyH5I/6n3/l+ZOVUQg780typyVuWOwqI0jqiKWZjgKBkk+lehPH9nht7XfvEESpnGMkDGf5VyPhq0N3rcAwdsR81iCBjb0/XA/GutlbfIzc8nvVbz9AWkPUZRRRVmYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXM+KP8AkIRf9cR/6E1dNXM+KP8AkIRf9cR/6E1UtmBjVtOy2/hWNVI3XUpLAnnAPb/vlfzrFrb8SfufsVn18iH7/wDe7dP+A/rWlPSMpf1qJhdf8ilZ/wDXY/zenTE3PhKIh9xt5Pn3ZyOSAB+DLTbr/kUrP/rsf5vTtBzcadqFn8rlk3RxnHLYIz+YX6cVstZcveP6CMKiiiuMo0vD3/Iat/8AgX/oJr0GvPvD3/Iat/8AgX/oJr0GlV+CPq/0O7Bby+X6nllFFFM4QooooAKKKKACiiigAooooAKKK6LwzoiXf+mXQzCrYSMjhyO59R/M/TlN2Vy6cHOXKiz4X0Vdi391Gd2cwqw4x/e/w/P0rpJ54raB5p3CRoMsx7U52VEZ3YKqjJJOABXE+INdbUHNvbkraqfoZD6n29B+P0xV5s9JuOHhZblfW9Zl1SfAyluh+SP+p9/5fzzKKK2SseZKTk7s6nwT/wAvv/bP/wBmrqq5XwT/AMvv/bP/ANmrqqwn8R6uG/hI821X/kLXn/Xd/wD0I1Vq1qv/ACFrz/ru/wD6Eaq1utjypfEwooopkhRRRQAUUUUAFFFdR4X0Vt6391GNuMwqw5z/AHv8Pz9KTdlc0p03UlyoveHdESyiW6nG65dcgEf6sHt9fX8vrY13V49Mtiqtm5kU+Wo/h/2j7fz/ADq3qF7Fp9nJcSkfKPlUnG5uwFefX17Pf3LT3DbnPQDoo9B7VlFczuzuqzVCHJDcgdmd2d2LMxySTkk0lFFbHmnp1z/qG/D+dUKv3P8AqG/D+dUKzp7HXjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFK8CXdvNZynCTrtz/dbqp/A0lFNOzA4OaJ4JnikG142KsM5wRwaZXR+LLPLRaig4l/dy/74HB/EDsO3vXOUNWYkauha3LpM+DmS2c/vI/T/AGh7/wA/yxf1rQkljXUdHHnW8vJjjGce6j09R2/lzdauha3LpM+DmS2c/vI/T/aHv/P8sVGStyy2GZVa/hV2XX7cKxAYMGAPUbScH8QK1td0SLUIP7U0rEhcbmRP+WnqQP73qP69ee0d2TWLMoxU+cgyDjgkAj8qfK4yQHo2pK0mkXaIpZ2gcKoGSTtPFeW162n3a8ldGjdkdSrKcFSMEH0qZq0mbVdosSlRGkdURSzMcBQMkn0qazsri/nEFrEZJME4HGB6kngV32heHbfTESVwJLvB3S9lz2Uf169fXFQ3YiEHIzdA8KLGPP1SMNJn5Ic5C4PU44P06Y/TR17xHDpB8iFRPdEZK5wI+OCf049PTiszxB4swJbPTD/stcg/nt/+K+uOxrjqVubc0lNRXLEmu7u4vZjNdTPLIe7HpznA9Bz0FQ0UVRgFFFFABXong6FYfDsbqSTM7O2exzt4/BRXndeq4XTNIRXJdbWAZIGCwVfT8Kxru0Daitbnn3iW5+1a7dMC+1G8sBu23g49s5P41l0ru0js7sWZjksTkk+tXdI0qfVrryoflReZJCOEH+PoKtWhHXoZ6yZa8OaM2qXYeVD9kjP7xs43Hso/TPt+FT+JdZ+1SGxs2RbKLA/d9HI/oOw6cZ9MWvEuqRW0C6RpjCOJAVl2dv8AZz+ef59a5as4JzfPL5FyfIuVfMKKKK3MjqPCFvtt727ZM8CJGz68sMf981r1DpcP2XQbOMhN0gMrFe+eRn8CB+FTVENbs0npZBRRRVmYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXM+KP+QhF/wBcR/6E1dNXM+KP+QhF/wBcR/6E1UtmBR0qD7TqdvFhSC4JDdCByR+Qp2tS+dq1y23bh9uM5+7x/SrXhxFS5nvJELJbRFsg8g//AKt1ZLMzsWYlmY5JJySat6U15sXU2rr/AJFKz/67H+b1D4alaPV0UAYkVlOfTGf6VNdf8ilZ/wDXY/zesi2l8i5im27vLcNjOM4OauUuWcX5ICS/hFvf3EQQoqyEKD6Z4/Sq9a/ieJY9V3AnMkasc+vI/pWRWVSPLNoEaXh7/kNW/wDwL/0E16DXn3h7/kNW/wDwL/0E16DWdX4I+r/Q78FvL5fqeWUUUUzhCiiigAooooAKKKKACiitPRNGl1SfJyluh+eT+g9/5fzTdioxcnZFjw/oTag4uLgFbVT9DIfQe3qfw+nbIqoioihVUYAAwAKbBBFbQJDAgSNBhVHaud8S66saSWFqQzsCsr9Qo7qPf19Pr0xbc2enFQw8LsreItf8/dZ2T/uukkg/j9h7e/f6deboorZJJHm1KjqO7CiiimQdT4J/5ff+2f8A7NXVVyvgn/l9/wC2f/s1dVXPP4j18N/CR5tqv/IWvP8Aru//AKEaq1a1X/kLXn/Xd/8A0I1VrdbHlS+JhRRRTJCiiigAooq9pGmy6neLGqnylIMr9Nq/4+lDdhxi5OyLnh7RP7SkM85xbRtggHlz6ew9/wDI7WeeK2geadwkaDLMe1EEEVtAkMCBI0GFUdq47xJrTXk7WlvIPsqHkqf9Yf8AAH/H0rDWbPS93DU/Moazqb6netL8whXiNGP3R/iev/6qoUUVulY82UnJ3YUUUUCPTrn/AFDfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAFeBLu3ms5ThJ125/ut1U/ga4KaJ4JnikG142KsM5wRwa7ysPxZZ5aLUUHEv7uX/fA4P4gdh296rdC6nOUUUVIzV0LW5dJnwcyWzn95H6f7Q9/5/lja1rR0vY11bR2y5+ciPjf/tL6N6j+vXAg0PVJ3KJYzAgZ+ddg/NsV0nh3StY01wZDCLeQ/vIGcll/2hgEZ/Hnv7bQu1ytaCukdNH3rhH0K91PXr0JGY4hctvlcYCgkngd+MdPUdM13aAhsVKVYIxQBnx8oY4BPueazrNRkzqilOCuZtta6b4fsmbKQRn7zu3zOQP1PB4HvgVxuveJLjVt0EY8m0DZCD7zjtu/nj+eM1Y1uw8Rag/2m8syVQYWOJgwX6KCT9f8BWFcWlza7ftNvLDuzt8xCufpmslrqyJzeyVkQ0UUVZiFFFFABRRRQBo+HoGuNeskQgESh+fRfmP6Cu08X3Ag0OcbyjSFY1xnnJyR+QNYXgO18zUZ7khCsMe0Z6hmPBH4Aj8at+M3lu7mz062zJI5MhjA69lOf++v61z1dZxRvHSDZythYz6jdLb2ybnbkk9FHqfaul1S8h8P6UNKsZSbojLyLgFc8kn3I4HcDHPTL99v4S04oGE+oXABIzxxnH/ARz7n+XHu7SOzuxZmOSxOST601+9d3svxF/DXmJRUkFvNcuUghklYDJVFLHHrxW3aeEr6X5rp47ZATnJ3NjHXA4/WtZTjHdmcYSlsjAqxYWcl9eRwRqx3MAzKu7YMgFj7DNdda6BpNngy77qQYPzH5cj0A4x7HNaK3AijEVvFHDGOiqOB9O1RzyfwovkjH4mJdvvuG5yBwKgpSSTknJNJWkVZJESfM2wooopkhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcz4o/wCQhF/1xH/oTV01cz4o/wCQhF/1xH/oTVS2YDbJ1tvDt5MHKyTSCEDGQRjP8i1ZFbGqN5GiadahlbcDM3qM8j8PmP5Vj1dXS0ey/wCCJG3df8ilZ/8AXY/zesStu6/5FKz/AOux/m9YlOtuvRAjd1hvtWh6fd7mJX92d3Vjjk5+q/rWFW7ZH7X4ZuoCVL253qGH3V68H1+9WFRW1al3QI0vD3/Iat/+Bf8AoJr0GvPvD3/Iat/+Bf8AoJr0GsKvwR9X+h34LeXy/U8sooopnCFFFFABRRRQAUUVYsbKe/uVgt13OepPRR6n2oGk27Il0vTJ9UufKi+VBy8hHCD/AB9q7+ztYrK1jt4QdkYwMnJPcn86j02xj06yS2jO7byzYwWJ6n/PbFVtb1mLS4MDD3Dj5I/6n2/n/LCTcnZHp0qcaEeaW5W8Ra2llE1rAd1y64JB/wBWD3+vp+f14mldmd2d2LMxySTkk0laxjyo4KtV1JXYUUUVRkFFFFAHU+Cf+X3/ALZ/+zV1Vcr4J/5ff+2f/s1dVXPP4j18N/CR5tqv/IWvP+u7/wDoRqrVrVf+Qtef9d3/APQjVWt1seVL4mFFFFMkKKKVFZ3VEUszHAAGSTQBLZ2st7dR28IG+Q4GTgDuT+VehabYx6dZJbRndt5ZsYLE9T/ntiquhaRHplsGZc3MijzGP8P+yPb+f5VH4i1k6ZAscGDcSg7ScHYPXH8vx9MVjJ8zsj0qNNUY889yh4o1pdjWFrId2cTMp4x/d/x/L1rlKV2Z3Z3YszHJJOSTSVrFWVjhqVHUldhRRRTMwooooA9Ouf8AUN+H86oVfuf9Q34fzqhWdPY68Z8a9AooorQ5AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKd5MV3FJaXGfKnG04OCDnIP502imnZ3BkMWneHLBUdminZSRud/MJznqo4/Spxrek2SlLaIiM/MfJjCrn8cc8VUutOguQSQUc/xLx+dYN9oVzES8LGdf8Ax7tWvtLbIfLD1NqfxfhR5UMatnqzlxj8MVn3Hiq8kLhZSqsMYRAB07E8iufIKnBBB9DSVLqSHdLZGkdaumkR2lm3JnDeaSVz1x6Vej13UbeJpIbuSQHk7zu49t2cVz9TW83lPgn5D1pKV/iLjN7M6KHxpeJGqukTt3Zk5/Qj+VacHjW1dyJrdkXHVWzz+IFcbcW+B5kfKnkgVWqZRXVDc5Rdmd8NQ8N3qSPNbQo0hO4tB8zZ6ncufzzmmPoXhu7SNYJliZyCPLn+Y57YbP8ALNcJTxNIDkO34nNTyx6XF7RPdHYzeBYjKTDfukfZXiDEfiCP5VmzeDNUjiLo1vKw6IjnJ/MAfrWRb6neW27yZ3TdjO1iufyrQh8VanFGqCdiB3YBj+ZGaOV9GH7tlWfQdVt3CPYTkkZ/drvH5rkVQdGjdkdSrqcMrDBB9DXVw+N5vMHnQRFO4AKk/jk/yrQh8X2FzEyXFu/zZUoMOGGO+cfyotLsHJF7MTwPa+TpEtyybWnkOGzncq8Dj67qs36xWN0+pyRyXV0wEVvEiZK8E4GPX5iT6cfUPiHR7SyUQsI1A4hSLbjPXA6d6xL3xjK7FLG3C5yA78k+hA//AF1zTpVJTvbQ2ThGNmyFtD1jWbo3V8VgDYxvPRfRVHTHocfzqa003RLSRczPqU6gHZEMp14PHA+hb+lQRWeo6qRJqtxKIs5ER4ycdcdB/Oti3t4raIRwRhE64Fbcj6v7jJzindL7y4tyIohFbwpCgJwFAwOfToKheR3OXYn602iqjCMdkRKcpbsKKKKogKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuc8QxNPq9tCpAaSNVBPTJYiujrKuLfz/E1pldyxw+Y3OMYLYP54rSnHmdv63EzK8SOp1QxKgRYY1QAdMYz+HXH4VlVNdyrPeTzKCFkkZgD1wTmoaVSXNJsaNu6/5FKz/67H+b1iVt3X/IpWf/AF2P83rEq6269EJG54XIknurV1Biliy3rwcf+zGsWSNopXjkGHQlWHoRVvRZfJ1a2bbuy+3Gcfe4/rUmvwiHV5wqFVYhxnvkcn880PWkn2YdRfD3/Iat/wDgX/oJr0GvPvD3/Iat/wDgX/oJr0GsKvwR9X+h34LeXy/U8sooopnCFFFFABRRSorO6oilmY4AAySaAHwQS3M6QwIXkc4VR3rv9G0xNMsli+UzNzI6j7x/wHT/APXUPh/SF021DyoPtUg+c5zgf3R/X3/Cr19ewWFs09w21B0A6sfQe9YzlfRHp0KKprnlv+RFqmpwaXbebL8znhIweXP+HvXns88tzO807l5HOWY96l1C9l1C8kuJSfmPyqTnavYCq1XGPKcles6j8goooqznCiiigAooooA6nwT/AMvv/bP/ANmrqq5XwT/y+/8AbP8A9mrqq55/Eevhv4SPNtV/5C15/wBd3/8AQjVWrWq/8ha8/wCu7/8AoRqrW62PKl8TCiiimSFdj4Z0R7T/AEy6GJmXCRkcoD3Pof5D68UPDOiJd/6ZdDMKthIyOHI7n1H8z9OeruriO0tpLiU4SNSx9/Ye9ZTl0R34ajb95Ig1TU4NLtvNl+ZzwkYPLn/D3rz2eeW5neady8jnLMe9WdU1OfVLnzZflQcJGDwg/wAfeqVVCNkYV63tHpsFFFFWc4UUUUAFFFFAHp1z/qG/D+dUKv3P+ob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBWu7C3u1IljGf7w4NYl94fljy9q3mL12nqP8a6SigdzgpI3iYrIjKQcYIptd1cWsFyMTRK/1rEvfDpGWs3z/sOf6/nTDToY9vceWdr8of0p1zAFHmJjaeoqKaCWBtssbIfQin28+z5H5Q/pVJ9GWndcsiCip7iDy/nTlD+lQVLViGmnZhRRT4omlbA6dz6UJXFuIiNIwVRzVr5LSPn5pGH+fwpyjY3kWymSZjjAGTWrY6B8wmvn3t18sH+Z71ppD1L+H1Mm1srnU5souEzgufur7V0en6Tb2IDD95N/z0YdPoO1XkRY0CIoVR0AGAKWs27kBRRRSAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKoXwEDXd4WdCtoI0YdMlm/XO386v1neJGkGjgJna0gD4GeOfy5xW9HRt9kJnI0UUVgM27r/kUrP/rsf5vWJW3df8ilZ/8AXY/zesStq269EJCqzIwZSVZTkEHBBrc8T7JvsV2m4edH0PYcEfj81YVb8zfbPCUbGTLWzgMNvocAfkwop6xlH5/cDKXh7/kNW/8AwL/0E16DXn3h7/kNW/8AwL/0E16DWFX4I+r/AEO/Bby+X6nllFFFM4QooooAK7bw7oiWUS3U43XLrkAj/Vg9vr6/l9a3hrQljSO/ugGdgGiTqFHZj7+np9enSOyojO7BVUZJJwAKxnLoj0MNQt78hs88VtA807hI0GWY9q8+1fUpdTvGkZj5SkiJOm1f8fWp9d1eTU7kqrYto2PlqP4v9o+/8vzrKqoRtqzHEV+d8sdgooorQ5QooooAKKKKACiiigDqfBP/AC+/9s//AGauqrlfBP8Ay+/9s/8A2auqrnn8R6+G/hI821X/AJC15/13f/0I1Vq1qv8AyFrz/ru//oRqrW62PKl8TCtXQtIk1O5DMuLaNh5jH+L/AGR7/wAvyqpptjJqN6ltGdu7lmxkKB1P+e+K9Cs7WKytY7eEHZGMDJyT3J/OpnK2h0Yej7R8z2JP3cEX8Mcca/QKB/IVw3iHV/7SuQkLN9mj+6DxuP8Aex/n8MmtDxPrbmSTT7Y7UHErg/e/2R7ev5fXmKUI9WXia1/cjsFFFFaHEFFFFABRRRQAUUUUAenXP+ob8P51Qq/c/wCob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFADZYo5kKSoHU9iKxb7w8jZe0baeuxun4H8q3KKB3OQ8iezJiuo2VDwGI496rXFuYjuX7n8q7dlV1KuoZT2IyKzbrRopEIgIUdNjdP8A61WmmrMu6aszmIITK3oo6mtez0yacARr5MJ58w9T9B/WtWz0yKBQZAJH+nAq9Vcyivd3JvbRFe0srezTbBGAcYLH7x+pqxRRWRIUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUiPjg9Kjoq4TdN80QauYer+H/v3NiPcwgfnt/w/wD1VzrKyMVYFWU4IIwQa9AVyv0qjqujQ6jmVD5dxjAYdG9N3+P866HTjWXNT0fYm9tzHuv+RSs/+ux/m9Ylb+pW8tr4ZtYZl2yLNyMg/wB49qwKyrKzSfZDQVv+H/8AStOvrE+XlhuQN6kYz9AQtYFa3hmXy9WVdufNRlznp3/pRQdqiv1B7Efh7/kNW/8AwL/0E16DXD6fb/ZfFQhC7VV32jOfl2kj9MV3FY11aCT7v9DvwX2vl+p5ZRRRQcIV0nh3QPP23l6n7rrHGf4/c+3t3+nWt4f0JtQcXFwCtqp+hkPoPb1P4fTtkVURURQqqMAAYAFZTn0R24ahf35bDq4rxJrTXk7WlvIPsqHkqf8AWH/AH/H0qz4n1tzJJp9sdqDiVwfvf7I9vX8vrzFEI9WPE17+5EKKKK1OEKKKKACiiigAooooAKKKKAOp8E/8vv8A2z/9mrqq5XwT/wAvv/bP/wBmrqq55/Eevhv4SPNtV/5C15/13f8A9CNQwQS3M6QwIXkc4VR3qbVf+Qtef9d3/wDQjXX+HtE/s2MzznNzIuCAeEHp7n3/AMnVy5UefCk6k2uhb0jTYtMs1jVR5rAGV+u5v8PSqHiTWls4GtLeQ/anHJU/6sf4kf4+lXdb1RdLs/MCh5XO2NSe/qfYf4etcBLI80ryyHc7sWY46k9aiEbu7OqvVVOPs4DKKKK2POCiiigAooooAKKKKACiiigD065/1Dfh/OqFX7n/AFDfh/OqFZ09jrxnxr0CiiitDkCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKxU8U2imm4u6AS7tINQt/KnUlc5GDgg4xn9a4/U9Kn01gZMPExwsi9PofQ12QODkU9hHOhjlRXU9VYZBrrUoV1aWkidjzyprSVYLyCZgSscisQOuAc1raxoLWqvcWpLwg5ZO6D+o/wA+9Ydc8oSpysx7nVTweX4ttpQGxKhJJ6ZCkYH4AfnXU1zsTfazpF4ZNzDcrfLjLFDn9VNdFRjEtGurb/BHfgftfL9TyytPRNGl1SfJyluh+eT+g9/5fzh0vTJ9UufKi+VBy8hHCD/H2r0C1t47S2jt4hhI1Cj39z71hOVtEZ4ehzvmlsPijSGJIoxtRFCqM9AOlYHibW3tP9DtTiZly8gPKA9h6H+Q+vFjxDrf9mxiCAZuZFyCRwg9fc+3+Tw7szuzuxZmOSSckmohG+rN8RX5VyR3EooorY84KKKKACiiigAooooAKKKKACiiigDqfBP/AC+/9s//AGauqrlfBP8Ay+/9s/8A2auqrnn8R6+G/hIwdL0Vf7Tur+6jO77Q5hVhxjd97/D8/Sta+vYLC2ae4bag6AdWPoPerFcvqunatrV4N0KW8EYPl+Y4Pp1255P5cfmL3nqEv3UbQV2c7qF7LqF5JcSk/MflUnO1ewFVq3/+ERv/APntbf8AfTf/ABNWv+EN/wCn/wD8g/8A2Va80Uef7CrJ3sctRXYQ+ELVUInuZnbPBQBRj6HNTReFNOSQMzTyAfws4wfyANHtEUsLUZxNFd9/wjmk/wDPp/5Ef/GrKaVp6Iqiyt8KMDMYJ/M9aXtEWsHPq0ecU+KKSaQRxI0jnoqjJP4V6XFDBbRlYY44UzkhFCjNO8yP++v50vaeRX1RLeR5z/Zl/wD8+Nz/AN+m/wAKsp4e1V0VhaHDDIy6g/kTxXd/aIv736Gmm6jB43H3Ao5pdhexoreRxsHhbU5d29YocdN75z/3zmpk8IXpdQ89uFzyQWJA+mK6o3a4+VST78Uhu+OE5+tF5hy4ZdSW5/1Dfh/OqFTPcO6FSFwfSoaqCaWpliKkakrxCiiirOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAClpKKAJEfs351kaxoKXXmXFr8lweSvRX9fof8+9adPR8cHpXXTrKa5Kv3ktdjO8Nu409reVdkkDkbCMMAeQSPxNdFVIBdxcAbiACcckf5Jq7WeOXLGC9f0O/A/a+X6lexsoLC2WC3Xag6k9WPqfeqet6zFpcGBh7hx8kf9T7fz/lqVj33h22v7lp7i4uWc9AGXCj0HHSvPVr6nbNSUbUziJ55bmd5p3LyOcsx71HXff8I5pP/Pp/5Ef/ABqaHRtNgQqllCQTn513n8zmtfaI4fqc29Wed0V6ZDZ2tu5eC2hiYjBKIFOPwqel7TyKWCfWR5t/Zl//AM+Nz/36b/Cp4dC1OdCyWbgA4+chD+RxXf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_a487eb84e8204ecb917d2b7cd9b32355" + } + }, + "1f4281270d7047fcb9290b1d738ed731": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_d19ff89eddb544b9a3265ad5d782bd1b" + } + }, + "203326cb43394e3eb0a75166ddccf87d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "221ece0acf7e48c4a9e3cf24ee8d3cbf": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFVo7+3lvXtI33yoCWwOFxjjPrz+hr1KdOFJW6kN3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FFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU5WK02iqjJxd0BbF0gQDDZApPtf8AsfrVWis3FN3Z0fWalrJlg3b54VQPemtcyHoQPoKhoo5UQ69R9SUzykYLn8Kb5kn99vzplFOyJc5Pdik5OT1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_d7995ce46a94421881e055f652521fac" + } + }, + "23d0f8680d6d4eecb025638aba77cc8f": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_3174998fe35e41c69a38a0ef6d559cea" + } + }, + "25be8dd0b3c94728b96f4776197809fa": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "28cdb449c5ad4da7958d7b5c08e3efe4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "29a459cc6d794822ac02e5a849d426e4": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_36dac2661efa48f88a15361d15230877" + } + }, + "2e7fc70235424294be5f51f4ba00c6a8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "2ef59014e10f48b7a0b0c97c17de548e": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UF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qMzRqMlx+HNJ9oi/vfoadmQ6kFu0S0VX+1x+jflSG7GeEJHuafJIh4imupZoqo1238KgfXmmm6kx0UfhT9myHiqZdoqh9ol/vfoKaZZCc72/On7NkPGQ6JmjSEgDJIA96zSxY5Ykn3pKfs/Mh43tE0fMj/vr+dN+0Rf3v0NUKKfs0Q8ZPoi6bqMHjcfcCmm7XHyqSffiqlFP2aIeKqMtG744Tn6037XJ6L+VV6KfJEh4iq+pMbiXP3sfhTWmkbq5/Dio6KfKiHUm92xxdyMFmI9zTaKKZLbe4UUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKxWm0VUZOLugLYukCAYbIFJ9r/2P1qrRWbim7s6PrNS1kywbt88KoHvTWuZD0IH0FQ0UcqIdeo+pKZ5SMFz+FN8yT++350yinZEucnuxScnJ60lFFMgKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_6897285225264a61a60351eb926c2b31" + } + }, + "3174998fe35e41c69a38a0ef6d559cea": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "31ab19682de744dd9f4ee5f995fbf14f": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_3fdfab044d404ec8b21a1eed31705844" + } + }, + "331d1e10b4d3476297f4f5d27508aeba": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_203326cb43394e3eb0a75166ddccf87d" + } + }, + "3354964add124253b5397b24cbd2f38e": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_e046c6442bc34b1eb9dfa1629f4552c3" + } + }, + "348d6a5be9d84dde93e2a7c996db64fb": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_dfefc663d1aa478eb813d24a111499bf" + } + }, + "35405d21bb3a405b9e23e6a3e8fd013d": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_55ccf38b8e654cbba4f8834766f734c5" + } + }, + "3593de689d2e4b278450682ae1cfbb80": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "365398449b8a4739988051896039fa3a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "36dac2661efa48f88a15361d15230877": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "3e67b0173c7d4d0aa14f17cfe314c0ee": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "3fdfab044d404ec8b21a1eed31705844": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "450886f5f96a463bb730ab2e08679b0f": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_b8a5514c3ef6441eabe6b134805c6bdd" + } + }, + "45a32f90ecdc4264ba917e6a77b5be84": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "4887c0e8468349cbafcbd8b3d8aa6fbd": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "4b50d7e87a99479785b52622467fb5b3": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "children": [ + "IPY_MODEL_16a9d12b4d66495e937287d81d98ed86", + "IPY_MODEL_9b59d44ffb7d4b238d06150e744f3b4d" + ], + "layout": "IPY_MODEL_0623f93c57da497993e106b73e986ef7" + } + }, + "4b8009c5e65a43919a112a502f7133ad": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_9bcec2011f0c486fb924fa7172df1eb4" + } + }, + "4cbc7bc2e74b498fbbc0308029da8556": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_b29d1852b22d4b8085ba983605d04c94" + } + }, + "52219eab5a534c5eafd9e66fdc6c3f3c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "53598e9732c04146a6e652fd09275431": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFQ3V1DaQ+bcSBEzjJ7msS01qbUNagiQeXb5Yhe7fK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AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_cfed2b9aa96e4204aa505002deb6e0fe" + } + }, + "53fd909a138245578e6033ab51e712e0": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK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6iivZQ2Ox8Jf8gS4/wCurf8AoK1eqj4S/wCQJcf9dW/9BWr1OO7M6vww9AoooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAjurVb+0ltGwDIPkY/wuPunofofYmuFdGjdkdSrKcFSMEH0rvq53xRZbLhL6NcJPw+BwJB17Y5HP1zT3QitousPpsjRyr51nLxLEefbIz3/n/KXWtHS3jW/wBPbzrCXkMOfL9j7dv0PPXGrU0XWH02Ro5V86zl4liPPtkZ7/z/AJUmmrMDLrvvBs/m6KqbceU7JnPX+LP/AI9+lc/q2gIlr/aOmSefZt820dUX+oHOe479zWp4Fnza3MG37kgfdnruGMf+O/rTUWm0+xpB2kjndfha31y8RyCTKX49G+Yfoaz63PGELRa/I7EETIrrjsMbefxU1S0jSp9WuvJhG1F5kkI4Qf4+grMJRfM0ipb28t1OkECGSVzhVHeu50rRbLw9Eb2/uIzLjAduAvHIUdSevuR2608NpvhPTSpYSXLAErkB5Tzg+y9fp7nrxuq6tdatcCW6YfKMKicKvrge9Te+xelP1LuveI59V3QRjybQNkIPvP6bv54/njNYlFFNKxk227sKfDE880cMS7pJGCqM4yScCmVq+F7X7Vr9qpDlY28wle23kZ9s4H40PRAld2Op8Xsln4dW1iT92xSFRn7oHI+v3cVwNdT48uN99bQbfuRl92eu44x/47+tYmk6VPqt15UPyovMkhHCD/H0FZU2lByZpU96VkT6FpDahP502EsoTumkY4BA5K5+n5D8MprWsPqcixxr5NpFxFEOMDpk47/y/nPrupqyLpdg4FjbgLlf+WpHUn8fzPPpjEpxTk+aXyFJ8q5UFdf4ctxBo3nHG+5kJyCfurwAfxzXIV6D5AtIYbVcbYIwuQMBjjk496qWrSFHRNjaKKKsgKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOR1/8A5DE/0X/0EU5wIPDsY3APczluOrIoxg/Q8496br//ACGJ/ov/AKCKXWP3P2WzHHkQjen9125bnv29q225mIP+Za/7fP8A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AB+59vbv9OvRapqcGl23my/M54SMHlz/AIe9TOV9Ea0KKivaTINb1mLS4MDD3Dj5I/6n2/n/AC4F2Z3Z3YszHJJOSTUl1cSXdzJcSnLyMWPt7D2qKrjHlRz1qzqPyCiiiqMQooooAKKKKALWlf8AIWs/+u6f+hCvSa820r/kLWf/AF3T/wBCFek1jU3PRwfws821X/kLXn/Xd/8A0I1d8PaR/aVyXmVvs0f3iONx/u5/z+GRR/Zk+qa/eRRfKgncvIRwg3H9fauwmmtNH08EgRQRjCqvUn0HqT/9c1UpWVkZUqPNJzlsiLV9Qi0jT9yBA+NsMXQH8B2A/wAO9cDPPLczvNO5eRzlmPeptSvpNRvXuZBt3cKuchQOg/z3zVWnGNkZV63tHpsFFFFWYBRRRQAUUUUAdj4S/wCQJcf9dW/9BWr1UfCX/IEuP+urf+grV6ojuzoq/DD0CiiirOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApaSigBZEjuIWhnUOjDBB71yuq6FNY/vId00PJJA5T6+2O/8q6mno+OD0rpjUjUXLU+8VrbHntdpZb5tWtLt9o86zHA7HcpP4fNVDVfDwfM2nj5icmLIA/4D6fT/wDVV3wyd1givFtkgkaPJHPUE/Tr09quFOUG4vsOL95DvGX/ACCYv+u4/wDQWrG8P6E2oOLi4BW1U/QyH0Ht6n8Pp1Gsab/akEMBfYiyh3I64APA9+ass0FhZ5ZhFBCgGSegHA+teYpWVkepKipVOeWwy7urbTbMyykRxINqqo6+igV5/qF7LqF5JcSk/MflUnO1ewFTazqb6netL8whXiNGP3R/iev/AOqqFaQjY5MRW9o7LYKKKKs5goqxFY3k0YkitZ5EPRljJB/GpodG1KdyqWUwIGfnXYPzOKV0UoSeyKNFav8Awjmrf8+n/kRP8atf8Ijf/wDPa2/76b/4mlzLuWqNR/ZMCiulh8HzMhM94iNngIhYY+pxU8Xg6MSAy3rMncLHtJ/HJ/lS54lLDVX0Od0r/kLWf/XdP/QhXpNYdv4Xsre4imSW4LRuHALLjIOfStsnAyelZzknsd2Hpypp8xWgtbaxE8qgJ5jtLLIx9yeT6CuL13V5NTuSqti2jY+Wo/i/2j7/AMvzruZfImjMcvlyIeqtgg/hVYWumxSBltbZXU5DLEOD7HFEXZ3sKslKPKpJI86qymnXrorpZ3DKwyCImII/KvRGuYx0JP0FNN2mOFYn3q+aXY5fY0lvM4ODRNTn3bLOUbeu8bP/AELGanTw1qrOqm2CgnBYyLge/Brs/tf+x+tNN2+eFXFO8+wcuHX2mcv/AMIjf/8APa2/76b/AOJqxF4OkMYMt6qv3Cx7gPxyP5VvG5kJ4IH0FNM8jDBc/hxRaYc2HXRsyYfB8KuTPeO644CIFOfqc1P/AMIjYf8APa5/76X/AOJq95kn99vzplHLLuHtaS2gWILW1sLaSG2URqcsV3E849z7Cq9FFOMbGVWr7S2lrBRRRVGQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAOVitSwoglMijBcjd74/r/8AW9KgpVYqcg4Nb067iuV6oFumadZ+p6TFqmwTzzqidERgBn16daX7RL/e/QU3zJP77fnXEqbR6EsVTkrWIIvDOlpGFaBpCP4mkOT+WBU0Wh6VbNvFpHyMfvCWH5MTSEknJJJ96Sq5H3MvrEFtBE5sdMAz9ktP+/a/4VY+0Rf3v0NUKKPZoPrclskXTdR56MfwprXa/wAKk/XiqlFP2aJeKqFk3ZxwgB9zSfa5PRfyqvRT5IkPEVH1JftEv979BSGaRjkufw4qOinZEOpN7tji7MMMxI9zTaKKZLbe4UUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_94b84a1da7284751a57189c75db9083e" + } + }, + "55164477924b4245b737ef500a432be0": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "55ccf38b8e654cbba4f8834766f734c5": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "570818bdbfe7490abbd09a27602e7dde": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "572f59892959494ca9ebeefdfd5c80af": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "5e1d0da65fef47868fe59005668870da": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "5ea918db99614846aeb2aa171b2c2e1d": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_28cdb449c5ad4da7958d7b5c08e3efe4" + } + }, + "687d435e027b48e984eb2789ad6f2d03": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "6897285225264a61a60351eb926c2b31": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "6b08c8cf4c0046aa99e174fcb251a576": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "71edaa99e18f4145b2b988e1a2963fb9": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK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6iivZQ2Ox8Jf8gS4/wCurf8AoK1eqj4S/wCQJcf9dW/9BWr1OO7M6vww9AoooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAjurVb+0ltGwDIPkY/wuPunofofYmuFdGjdkdSrKcFSMEH0rvq53xRZbLhL6NcJPw+BwJB17Y5HP1zT3QitousPpsjRyr51nLxLEefbIz3/n/KXWtHS3jW/wBPbzrCXkMOfL9j7dv0PPXGrU0XWH02Ro5V86zl4liPPtkZ7/z/AJUmmrMDLrvvBs/m6KqbceU7JnPX+LP/AI9+lc/q2gIlr/aOmSefZt820dUX+oHOe479zWp4Fnza3MG37kgfdnruGMf+O/rTUWm0+xpB2kjndfha31y8RyCTKX49G+Yfoaz63PGELRa/I7EETIrrjsMbefxU1S0jSp9WuvJhG1F5kkI4Qf4+grMJRfM0ipb28t1OkECGSVzhVHeu50rRbLw9Eb2/uIzLjAduAvHIUdSevuR2608NpvhPTSpYSXLAErkB5Tzg+y9fp7nrxuq6tdatcCW6YfKMKicKvrge9Te+xelP1LuveI59V3QRjybQNkIPvP6bv54/njNYlFFNKxk227sKfDE880cMS7pJGCqM4yScCmVq+F7X7Vr9qpDlY28wle23kZ9s4H40PRAld2Op8Xsln4dW1iT92xSFRn7oHI+v3cVwNdT48uN99bQbfuRl92eu44x/47+tYmk6VPqt15UPyovMkhHCD/H0FZU2lByZpU96VkT6FpDahP502EsoTumkY4BA5K5+n5D8MprWsPqcixxr5NpFxFEOMDpk47/y/nPrupqyLpdg4FjbgLlf+WpHUn8fzPPpjEpxTk+aXyFJ8q5UFdf4ctxBo3nHG+5kJyCfurwAfxzXIV6D5AtIYbVcbYIwuQMBjjk496qWrSFHRNjaKKKsgKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOR1/8A5DE/0X/0EU5wIPDsY3APczluOrIoxg/Q8496br//ACGJ/ov/AKCKXWP3P2WzHHkQjen9125bnv29q225mIP+Za/7fP8A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AB+59vbv9OvRapqcGl23my/M54SMHlz/AIe9TOV9Ea0KKivaTINb1mLS4MDD3Dj5I/6n2/n/AC4F2Z3Z3YszHJJOSTUl1cSXdzJcSnLyMWPt7D2qKrjHlRz1qzqPyCiiiqMQooooAKKKKALWlf8AIWs/+u6f+hCvSa820r/kLWf/AF3T/wBCFek1jU3PRwfws821X/kLXn/Xd/8A0I1d8PaR/aVyXmVvs0f3iONx/u5/z+GRR/Zk+qa/eRRfKgncvIRwg3H9fauwmmtNH08EgRQRjCqvUn0HqT/9c1UpWVkZUqPNJzlsiLV9Qi0jT9yBA+NsMXQH8B2A/wAO9cDPPLczvNO5eRzlmPeptSvpNRvXuZBt3cKuchQOg/z3zVWnGNkZV63tHpsFFFFWYBRRRQAUUUUAdj4S/wCQJcf9dW/9BWr1UfCX/IEuP+urf+grV6ojuzoq/DD0CiiirOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApaSigBZEjuIWhnUOjDBB71yuq6FNY/vId00PJJA5T6+2O/8q6mno+OD0rpjUjUXLU+8VrbHntdpZb5tWtLt9o86zHA7HcpP4fNVDVfDwfM2nj5icmLIA/4D6fT/wDVV3wyd1givFtkgkaPJHPUE/Tr09quFOUG4vsOL95DvGX/ACCYv+u4/wDQWrG8P6E2oOLi4BW1U/QyH0Ht6n8Pp1Gsab/akEMBfYiyh3I64APA9+ass0FhZ5ZhFBCgGSegHA+teYpWVkepKipVOeWwy7urbTbMyykRxINqqo6+igV5/qF7LqF5JcSk/MflUnO1ewFTazqb6netL8whXiNGP3R/iev/AOqqFaQjY5MRW9o7LYKKKKs5goqxFY3k0YkitZ5EPRljJB/GpodG1KdyqWUwIGfnXYPzOKV0UoSeyKNFav8Awjmrf8+n/kRP8atf8Ijf/wDPa2/76b/4mlzLuWqNR/ZMCiulh8HzMhM94iNngIhYY+pxU8Xg6MSAy3rMncLHtJ/HJ/lS54lLDVX0Od0r/kLWf/XdP/QhXpNYdv4Xsre4imSW4LRuHALLjIOfStsnAyelZzknsd2Hpypp8xWgtbaxE8qgJ5jtLLIx9yeT6CuL13V5NTuSqti2jY+Wo/i/2j7/AMvzruZfImjMcvlyIeqtgg/hVYWumxSBltbZXU5DLEOD7HFEXZ3sKslKPKpJI86qymnXrorpZ3DKwyCImII/KvRGuYx0JP0FNN2mOFYn3q+aXY5fY0lvM4ODRNTn3bLOUbeu8bP/AELGanTw1qrOqm2CgnBYyLge/Brs/tf+x+tNN2+eFXFO8+wcuHX2mcv/AMIjf/8APa2/76b/AOJqxF4OkMYMt6qv3Cx7gPxyP5VvG5kJ4IH0FNM8jDBc/hxRaYc2HXRsyYfB8KuTPeO644CIFOfqc1P/AMIjYf8APa5/76X/AOJq95kn99vzplHLLuHtaS2gWILW1sLaSG2URqcsV3E849z7Cq9FFOMbGVWr7S2lrBRRRVGQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAOVitSwoglMijBcjd74/r/8AW9KgpVYqcg4Nb067iuV6oFumadZ+p6TFqmwTzzqidERgBn16daX7RL/e/QU3zJP77fnXEqbR6EsVTkrWIIvDOlpGFaBpCP4mkOT+WBU0Wh6VbNvFpHyMfvCWH5MTSEknJJJ96Sq5H3MvrEFtBE5sdMAz9ktP+/a/4VY+0Rf3v0NUKKPZoPrclskXTdR56MfwprXa/wAKk/XiqlFP2aJeKqFk3ZxwgB9zSfa5PRfyqvRT5IkPEVH1JftEv979BSGaRjkufw4qOinZEOpN7tji7MMMxI9zTaKKZLbe4UUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_747776a93eb041ae85ec7aee3c06b451" + } + }, + "7239f0f8f3f64b128c986fbd360a309a": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_0e971676622b4e24b3b7b4a4bbf82af8" + } + }, + "747776a93eb041ae85ec7aee3c06b451": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "74bbe62a9d604bc1902ed8de1ede91da": { + "model_module": "ipycanvas", + "model_module_version": "^0.13", + "model_name": "CanvasManagerModel", + "state": { + "_model_module_version": "^0.13", + "_view_module": null, + "_view_module_version": "" + } + }, + "763434d108c943ec963e572182f71412": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQhhj6nFTReK9OeQKyzxg/xMgwPyJNcTRR7NFLFVEd9/wkek/8/f8A5Df/AAqymq6e6KwvbfDDIzIAfyPSvOKKXs0WsZPqkenRTQXMZaGSOZM4JRgwzTvLj/uL+VeX0+KWSGQSRO0bjoynBH40vZ+ZX1tPeJ6X9ni/u/qaabWMnjcPYGvPf7Tv/wDn+uf+/rf41ZTxDqqIqi7OFGBlFJ/Mjmjll3F7ai94nbm0XHysQffmkNpxw/P0rkIPFOpxbt7RTZ6b0xj/AL5xUyeL70OpeC3K55ADAkfXNFphzYZ9DpXt3RCxK4HpUNX7n/UN+H86oVUG2tTLEU405WiFFFFWc4UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRTZJEiQvIwVR1JNY994gjjylqvmN03noP8AGmkNI2iQoyxAHqapz6jFHGZFIKAZ3np/9esSCSfUCZrxz5K8hein1/DiqmoXxuD5ceREP/Hq2UYxjzS+R0RhCEeefyOqgvI5FG4hc9Dng1YrirK8a1fBy0bfeX+orat72SJPMtm8+3HBixyv+6f6H8KhxUleIOnGouanv2/yNuioLS9gvIw8EgJxkqeq/UVPWZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFSImeT0q4QdR8sQbsNVC30qjqusw6dmJB5lxjIUdF9N3+H8qz9X8QfftrE+xmB/Pb/j/APrrnWZnYsxLMxySTkk10OpGiuWnq+5Nr7nbaTdtPpttJcPullLKDjGSC3p7CuOu4GtbqWBs5jYrkjGR2P41uwXH2XQtLmLbVW5+Y4z8uXB/TNVPFEHl6mJQGxKgJJ6ZHGB+AH51Vb3qafVW/FAtzHoooriKNLw9/wAhq3/4F/6Ca9Brz7w9/wAhq3/4F/6Ca9BpVfgj6v8AQ7sFvL5fqeWUUUUzhCiiigAooooAKKKKACiiigAooqSCCW5nSGBC8jnCqO9AbhBBLczpDAheRzhVHeu70TRotLgycPcOPnk/oPb+f8jRNGi0uDJw9w4+eT+g9v5/yuX17BYWzT3DbUHQDqx9B71jKV9EenQoKmuee/5BfXsFhbNPcNtQdAOrH0HvXA6pqc+qXPmy/Kg4SMHhB/j70apqc+qXPmy/Kg4SMHhB/j71Sq4xscteu6jstjqfBP8Ay+/9s/8A2auqrlfBP/L7/wBs/wD2auqrKfxHdhv4SPNtV/5C15/13f8A9CNdf4e1v+0ozBOMXMa5JA4cevsfb/I5DVf+Qtef9d3/APQjUME8ttOk0DlJEOVYdq1ceZHnwqunNvod9relrqln5YYJKh3RsR39D7H/AA9K4CWN4ZXikG10Yqwz0I616DpGpRanZrIrDzVAEqdNrf4elUPEmireQNd28Z+1IOQo/wBYP8QP8PSohKzszqr0lUj7SBxVFFFbHnBRRRQAUUUUAFFFFABRRRQB6dc/6hvw/nVCr9z/AKhvw/nVCs6ex14z416BRRRWhyBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRUNzeQWqFppAuO3esO+8Qu2UtF2jpvbr+A/Kq5XuyuV7s3priKBd0sioPc1i3viIDK2aZ/wBtx/T86wZZpZm3SyM5yTyaZRdLYLpbE091PcnM0rP9ansbLz/3svywrySeM/8A1qLCxNwwkkBEQ/8AHqk1G9V1+zwY8scEjvjsPatYxsuefyN4QSXtKny8yO+vfO/dQ/LCvpxu/wDrVSoorKUnJ3ZhObm7sKmtbl7WXcnIP3l7GoaKSbTuhRk4u6NfYlyPtVgxjuFOSM4Jq7Y698yw36GN+nmYwPxHaufgme3lEkZwR+R9q0v3WqQ9kuUH5/8A1v5VpZT23On3a22kvz/4J1COrqGRgynkEHINLXH293d6TOUB+XOSh+63uK6LT9Vt74BQfLl/55sev09ayOZpp2L1FFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArO8SLIdHBTO1ZAXwccc/nzitGqF8RO13ZlXctaCRFHTIZv1zt/Kt6Ora7oTOPooorAZt3X/ACKVn/12P83qfVib/wAPWt7tLOhAdjx7Nx7sBUF1/wAilZ/9dj/N6n0NRfaLd2JyWByu4/KMjj9Rmu1avk7xRJztFFFcRRpeHv8AkNW//Av/AEE16DXn3h7/AJDVv/wL/wBBNeg0qvwR9X+h3YLeXy/U8sooopnCFFFFABRRRQAUUUUAFFFSQQS3M6QwIXkc4VR3oDcIIJbmdIYELyOcKo713eiaNFpcGTh7hx88n9B7fz/kaJo0WlwZOHuHHzyf0Ht/P+WhPPFbQPNO4SNBlmPasJSvoj06FBU1zS3/ACI769gsLZp7htqDoB1Y+g964HVNTn1S582X5UHCRg8IP8fejVNTn1S582X5UHCRg8IP8feqVaRjY5a9d1HZbBRRRVnMdT4J/wCX3/tn/wCzV1Vcr4J/5ff+2f8A7NXVVzz+I9fDfwkebar/AMha8/67v/6Eaq1a1X/kLXn/AF3f/wBCNVa3Wx5UviZa02+k069S5jG7bwy5wGB6j/PfFehWd1Fe2sdxCTskGRkYI7EfnXmdauhavJplyFZs20jDzFP8P+0Pf+f5VM431OjD1vZvlexpeJ9EcSSahbDch5lQD7v+0Pb1/P6cxXqH7ueL+GSORfqGB/mK4bxDpH9m3IeFW+zSfdJ52n+7n/P44NKEujLxNG3vx2MiiiitDiCiiigAooooAKKKKAPTrn/UN+H86oVfuf8AUN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiig1UIuclFDiuZ2RBPdxQKScsR2UZ/lWDf69cMxjhQwD1YfN2/KtW+vrG0nSCeJgWAbcijAGSOec9qYs+k3O4LcqoAwQx2g/99da7PYQWilqb8tPZOzOUZmdizsWJ7k5pK6t9EtpkVkEbA8gqNoI/DrVSbw8MsUDDjjawI/XmolhKm61E6LezRz9W7C0NzKCwPlL949M+1XBoUnmIpZjk8jZgke1aR0yeS2MECGJcYOV7fjUxouLvM1o4aTfNJaL8THv74FTb25AjHBYd/Ye1Z1dLF4X+VS7nPcFuv5D+tWf7G0yzYG4ljTcCAHYDP/fRNRO8neTLnh6tR802kcjUy2dy7BRA+T6rgfrXUi60O1zF56nb/dBI/AqMVXk8R2MaqbeyZnB/jAXHvnnmotBdSPYUo/FMx4dHvJs4jxj3z/LNXYvDVwyqzMcdxgD+Z/pT5vFdyWHk28SLjo5LHP1GKoz67qUwZTcFFY5wgC49gev60XiugXw0ejZsReF41f8AePuX3b/ACrdro1hE7ojKZUOW2kZXI75yRXN2dve6zcLG00jqnLPIxYID9e/HSuoY2mjWG1fkiT8Wdv6n/PQVUZN7aHTRlGXvKNkuol1ptpPHteLOP4s81j3Ph1gxe0mwRyFbt+NbOnXf2+yWchQxLAqDnbzwPyxXN6q01hq0rQO8QkIkG1uG+o+uetRVvzXRVd0+RTlG/wCZdt9RvdPKx6lE7Rk4EvUj8eh/nW1b3EVzGJIJA6eornLfxFcRjE8aTDHUfKc/y/SrlveaXK+6Fms5TwCPk4HPPVfzrO7W5xeypz+CX3m3RTUYMoYMGB5BHQinU00zKpRnT+JBRRRTMgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKyri48jxNaZbaskPltxnOS2B+eK1a5zxDK0Gr20ygFo41YA9Mhia0py5Xf+txMybuJYLyeFSSscjKCeuAcVDWr4kRRqhlVw6zRq4I6Yxj8emfxrKpVI8smho27r/kUrP/AK7H+b1H4YnaLVBFyVmUqRngEDOf0I/GpLr/AJFKz/67H+b1kW0vkXMU23d5bhsZxnBzW0pcs4y8kIn1WD7NqdxFhQA5IC9ADyB+RqpW/wCKot0tvdo26N025AyPUc++f0rArKtHlm0C2NLw9/yGrf8A4F/6Ca9Brz7w9/yGrf8A4F/6Ca9BrKr8EfV/od+C3l8v1PLKKKKZwhRRRQAUUUUAFFFKis7qiKWZjgADJJoAEVndURSzMcAAZJNd14e0j+zbYvMq/aZPvEc7R/dz/n8cCo/D+hLp6C4uAGumH1EY9B7+p/D67E88VtA807hI0GWY9qxnK+iPSw9Dk9+W4TzxW0DzTuEjQZZj2rg9b1mXVJ8DKW6H5I/6n3/l/M1vWZdUnwMpbofkj/qff+X88yqhC2rMMRiOf3Y7BRRRWhyBRRRQB1Pgn/l9/wC2f/s1dVXK+Cf+X3/tn/7NXVVzz+I9fDfwkebar/yFrz/ru/8A6Eaq1a1X/kLXn/Xd/wD0I1VrdbHlS+JhRRRTJOi8M62lp/od0cQs2UkJ4QnsfQfyP146u6t47u2kt5RlJFKn29x715lXY+Gdbe7/ANDujmZVykhPLgdj6n+Y+nOU49Ud+GrX/dyOb1TTJ9LufKl+ZDykgHDj/H2qlXo2qaZBqlt5UvyuOUkA5Q/4e1eezwS207wzoUkQ4ZT2qoSujCvR9m9NiOiiirOcKKKKACiiigD065/1Dfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACsjW9SNpJBHHnduDuAcZUHp+P8AT3rVlkWKNpHOFUEk+gFcRd3DXV1JO/Bc5x6DsPyraL5I83Vmi92N+rN3xJAJbWG6jwwU7SVGcqehz6f41zldTY41LQfIO3cEMfcAMPu/0NctV4hXamuo6q1v3HRyPE4eN2Rh0ZTgirkGsX8GALhnGckSfNn2yeao0VhGUo7MzvY7nRLma8sxcTiMFidoTPTOOc+4NYF74ivWupPs0ypCGITag5GeCc98Vu6KBaaJG8zAKqGQkc4By38jXEVpWbcteyOuc5QpRSdrlie/u7gMJrmV1c5Klzt9enSq9FFYnI23uFFFFAgqeztJr64WCBcsepPRR6n2os7Sa+uFggXLHqT0Uep9q7C2t7XR7FgGAAGZZW6sf89BVRjc6KFB1Hd7DY1ttC00qXJUHLN3dj6D8P8APWuU1G/l1CfzJOFHCIOij/PepNW1BtRut4BWNRhFJ7ep9zVGnKXRbDr1ub3IfCjpfCsubaeHb91w2c9cjH/stQ+KYgHglCnJypbt6gfzqt4alWPVNpBzIhUY9ev9K2PEMHm6a5AYmMhwB+R/QmiWsU+x0w/eYZrt+mpyNFFFQeaSwXM1s26CV4zkE7Twceo71p2/iK4jGJ40mAHUfKc/y/Sseik0maQqzh8LOwttZsrgcTCNsZ2yfLj8en61fzXAV12j2w0/TjJMWUkeZJnPy8en061Enyq510uXENqUbea0NKkpW60lWndXOKceWTj2CiiimSFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVzPij/kIRf9cR/6E1dNXM+KP+QhF/1xH/oTVS2YCaovn6Jp10FVdoMLepxwPw+U/nWPWvZItz4dvIQhaSGQTA5wAMY/kGrIq6utpd1/wBI27r/kUrP/AK7H+b1iVt3X/IpWf/XY/wA3rEp1t16IEdHN/p3hKN+rwY4TttO3n/gJzXOV0XheVJoLqxlAKsN2OckEYbn8vzrn5I2ileOQYdCVYehFVW96MZ+X5AjQ8Pf8hq3/AOBf+gmvQa8+8Pf8hq3/AOBf+gmvQa5qvwR9X+h34LeXy/U8sooopnCFFFFABRRSorO6oilmY4AAySaABFZ3VEUszHAAGSTXbeH9CXT0FxcANdMPqIx6D39T+H1PD+hLp6C4uAGumH1EY9B7+p/D67TsqIzuwVVGSScACsZzvoj0sPh+X3pbjZ54raB5p3CRoMsx7Vwet6zLqk+BlLdD8kf9T7/y/nJ4h1f+0rkJCzfZo/ug8bj/AHsf5/DJrIqoQtqzDEV+d8sdgooorQ5AooooAKKKKAOp8E/8vv8A2z/9mrqq5XwT/wAvv/bP/wBmrqq55/Eevhv4SPNtV/5C15/13f8A9CNVatar/wAha8/67v8A+hGqtbrY8qXxMKKKKZIUqMyOroxVlOQQcEGkooA77QtXj1O2Cs2LmNR5in+L/aHt/L8qj8RaMdTgWSDAuIgdoOBvHpn+X4+ua4uzupbK6juISN8ZyMjIPYj8q9C02+j1GyS5jG3dwy5yVI6j/PbFYyXK7o9KjUVaPJPc84dWR2R1KspwQRgg0ldX4o0VdjX9rGd2czKo4x/e/wAfz9a5StYu6ucNSm6crMKKKKZmFFFFAHp1z/qG/D+dUKv3P+ob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUU2WRYo2kc4VQST6AVUY8zshxV3YxfEt5siS1U8yfM/0HT9f5VzlTXdw11dSTvwXOceg7D8qhp1Jcz02HJ3eht+GbjZPLbk8ONy5buPQfT+VU9btzb6pLwdsh8xST1z1/XNQ6dcC1v4ZjgKrfMSM4B4P6GtnxRDmKCcBflJQnuc8j8OD+dbr36DXYven6HO0UVJbxefcxQ7tvmOFzjOMnFcqV9DI7O4AtPDkiTMBtt/LyOQTt2j9a4iu08RSLHociscGQqq+5zn+QNcXWlX42dOI05V5BRRRWZzBUttA91cRwRDLu2B7e/0psEMlxMsUKF5HOAorsdM06HSbdmZlMxGZJT0Ueg9B/n6VGLbN6FF1X5Eltb2ujWLAMBgZllbqx/z0H9a5fVtUk1CXAykCn5E/qff+VLrGpvfzlVOLdD8gHf8A2j/nis6nJ9EaV66a5IbIKKKKg5Cazn+zXkM2WARwTt6kdx+VdxcxLNA8bEhXUqcdcEVwNdzYT/atPhlLbiyDccY+Ydf1zVrWLR6OBlvFnDUVc1aLydUuFznL7unrz/WqdQjglHlk4voFFFFBJf0Wz+13y7lzFH8z5HB9B+P8s1reJrvy4Es1PzSfO/0HT9f5e9WdHtV0/TjJMNrEeZISOQMdPXgdvXNcveXLXd3JO/Bc5x6DsPyrL4peh3z/AHFBR6yOt0abz9KgYlcoNhA7Y4H6Y/OrlYXha4BSe2JGQfMXjk9j/T863aqOl0c1XW0u6/LQKKKKsxCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK5nxR/yEIv+uI/9CaumrmfFH/IQi/64j/0JqpbMBvhx1e5ns5HKpcxFcAck/wD6t1ZLKyMVYFWU4IIwQataVP8AZtTt5cqAHAJboAeCfyNO1qLydWuV3bsvuzjH3uf61b1pryYupeuv+RSs/wDrsf5vWJW3df8AIpWf/XY/zesSnW3XogRpeH7jyNWhy21ZMxtxnOeg/PFL4hthb6rIVACygSAA+vX9Qazo5GilSSM4dCGU+hFdB4mVbizs71AArDHI+bDDI/kfzqo+9Sa7ah1M/wAPf8hq3/4F/wCgmvQa8+8Pf8hq3/4F/wCgmvQa5qvwR9X+h34LeXy/U8sooopnCFFFFACorO6oilmY4AAySa7bw/oS6eguLgBrph9RGPQe/qfw+rPDOjfY4vtV1Fi5f7gbqi/TsT/L8a3XZURndgqqMkk4AFYznfRHo4ehy+/LcHZURndgqqMkk4AFcT4g11tQc29uStqp+hkPqfb0H4/Q8Qa62oObe3JW1U/QyH1Pt6D8fpiVUIW1ZliMRze7HYKKKK0OMKKKKACiiigAooooA6nwT/y+/wDbP/2auqrlfBP/AC+/9s//AGauqrnn8R6+G/hI821X/kLXn/Xd/wD0I1Vq1qv/ACFrz/ru/wD6Eaq1utjypfEwooopkhRRRQAVe0jUpdMvFkVj5TECVOu5f8fSqNFDVxxk4u6PT4J4rmBJoHDxuMqw71x3iTRWs52u7eMfZXPIUf6s/wCBP+HpUfh7W/7NkME4zbSNkkDlD6+49v8AJ7WeCK5geGdA8bjDKe9YawZ6Xu4mn5nmFFX9Z0x9MvWi+YwtzG7D7w/xHT/9dUK3TuebKLi7MKKKKBHp1z/qG/D+dUKv3P8AqG/D+dUKzp7HXjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFY3iS7EdqLYYLynJ9lB/wAf61sOwRSzEBQMkk8AVxWoXRvLySY52k4UHsvato+5By6vT/M0Xuxv3K1FFFYmYV1cJOp6AUyWkKbcbsksvTJPrgfnXKV0Hhi4G2a3OMg+YvHJ7H+ldOGfvcr2ZrS35e5z9XNHi87VbZd2MPuzj05/pRq9t9l1KZAMITuXC4GDzx7Dp+FWfDcPm6srbseWpbp17f1rOEbVFF9yEvesa3i2RV0+CIn52k3AewBz/MVyldH4wkUy2sYPzqrMR7HGP5GucrOTu7m2Kf7xrsFPghkuJlihQvI5wFFNVWdgqKWZjgADJJrstI09NLs/MmCrcMuZHJyEHpn+f/6qErsmjRdWVug7TdNh0m2LMymcjMkh6KPQegrA1nV2vWMMBK24P0Ln1Pt7f5BrWsNesYYSRbg/i59T7e3+Rk1TlZWRtWrK3s6ewUUUVBxhRRRQAV1fhiUvpzRlgTG5AXuAef55rlK2/C0+y8lhJUCRMjPUkdh+BP5VdN2kdOFly1V5h4oi23MMu77ylcY9D/8AXrErqvEsG+w8wBcxsDk9cHjj8SPyrlai1tB4uNqrfcK0tEsReXe5/wDVRYZhgHJ7D+f5Vm12FhCmlaVum4KgvJz1b0649BUTlZBhaanO8tkVPE135cCWan5pPmf6A8fr/L3rmqluriS7uHnlxvc5OBgVFThHlRnXq+1m5GhodwbfVIjztkPlsAOuen64rsD1rgFZkYMpKsDkEHBBrvIZfPt4ptu3zEDYznGRmltL1Be9Tfk/zHUUUVZiFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVzPij/kIRf9cR/wChNXTVzPij/kIRf9cR/wChNVLZgY1bfiT999ivOnnw/c/u9+v/AAL9KxK2nVbjwrGygbrWUhiRzgnt/wB9L+VaU9Yyj/WgmLdf8ilZ/wDXY/zesStu6/5FKz/67H+b1iUVt16IEFdNbN9t8JTRlmDQgglufuncAPbGBXM1v+EpcXNxDt++gbOemDj/ANm/Snh37/K+ugMpeHv+Q1b/APAv/QTXoNcJpcH2bxOsGGAR3A3dSNpwfyru656ytBLzf6HfgvtfL9TyyiiimcIV13h3QPI23l6n73rHGf4Pc+/t2+vQ8O6B5G28vU/e9Y4z/B7n39u316dLWM59Eehh8Pb35jXZURndgqqMkk4AFcT4g11tQc29uStqp+hkPqfb0H4/Sx4k11boNZWhDQ5/eSdd5B6D2z37/TrzlVCHVkYmvf3I7BRRRWhxBRRRQAUUUUAFFFFABRRRQB1Pgn/l9/7Z/wDs1dVXK+Cf+X3/ALZ/+zV1Vc8/iPXw38JHm2q/8ha8/wCu7/8AoRqrVrVf+Qtef9d3/wDQjVWt1seVL4mFFFFMkKKKKACiiigArqPC+tNvWwupBtxiFmPOf7v+H5elcvRSaurGlOo6cuZHpOoWUWoWclvKB8w+ViM7W7EV59fWU9hctBcLtcdCOjD1HtXXeHdbS9iW1nO25RcAk/6wDv8AX1/P6WNd0iPU7Ysq4uY1PlsP4v8AZPt/L86yi+V2Z3VYKvDnhucDRSurI7I6lWU4IIwQaStjzT065/1Dfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopHYIpZiAoGSSeAKqEXKSSHFczsZHiK98m2FujfPL1wei/wD1/wDGuYqzqF0by8kmOdpOFB7L2qtVVJKUtNkVN3emwUUUVmQFXNKuPs2owuThSdrfNgYPHP06/hVOinF8rTQ07O50HiiDiC4C+qM2fxA/nTfCUO67ml3fcULjHXJz/wCy1enA1TQiwALsm8YXPzDqAPwIqPwjDiGebd95guMdMD/7KuypH95zrZq/4HQo3rLzKPiuRX1UKpyUiCt7HJP8iKxlVnYKilmY4AAySa0NcYXGuXAhy5LBAAOSQACPzFb+i6OunIJ5wGumHA6iMeg9/f8AyeNK70H7KVarK21xNG0hdPQTTgNdMPqIx6D39/8AJzdc1nzt1rat+76PIP4vYe38/p1Nc1rzi1tat+76PIP4vYe38/p1wqttJWRdatGMfZ09gooorM4gooooAKKKKACrmjy+Tqts23OX24z68f1qnRTTs7lRlytM7u+h+0WksWFJdCBu6Z7frXCV3sMvn2sU23bvQPjOcZGa4y/gaPUpoVjwTIdqKOxPGMexFOorT9TvxsbqMkWdAtPtN8JGHyQ4Y/Xt/j+FXvE15gJZRt/tyYP5D+v5VfsIU0rSt03BUF5OerenXHoK5O4ne5neaQ5dzk+3tWC96V+xNT9zRVPq9yOiiitTgCus8OzrLpYjGA0LEEZ5wec/r+lcnW14YuBHeSQMQBMvHHOR/wDWzUT2v2NqOsuXvp/XzOloooqzEKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArmfFH/IQi/64j/0Jq6auZ8Uf8hCL/riP/QmqlswMatrQ1FzY6hZHLM8YeOPOBkd/TrtrFrT8OzGLV4hvCrICjZ78cD8wKui7TVxMsXX/ACKVn/12P83rErodXg+zeH4YMMAlywG7qRl8H8q56nXVml5IEFXNInW21S3lbG0NtJJwACMZ/DOap0VlF8rTQzrLm38vxVaTBcLKjZOerBSD+m2unrFhUXyafe/IXQFmIPAypBA/HH5VtVrjVazXVt/kduB+18v1PLK67w7oHkbby9T971jjP8Huff27fXoeHdA8jbeXqfvescZ/g9z7+3b69OlrjnPoi8Ph7e/MK5DxFr/n7rOyf910kkH8fsPb37/TqeItf8/dZ2T/ALrpJIP4/Ye3v3+nXm6cIdWTiMRf3IBRRRWpwhRRRQAUUUUAFFFFABRRRQAUUUUAdT4J/wCX3/tn/wCzV1Vcr4J/5ff+2f8A7NXVVzz+I9fDfwkebar/AMha8/67v/6Eaq1a1X/kLXn/AF3f/wBCNVa3Wx5UviYUUUUyQooooAKKKKACiiigCSCeW2nSaBykiHKsO1d/o2ppqdksvyiZeJEU/dP+B6//AKq88qzp97Lp95HcRE/KfmUHG5e4NRKN0b0KzpvyOp8TaK14gu7WMGdB86gcyD/Efr+AFcbXpdjewX9ss9u25D1B6qfQ+9ct4m0RLT/TLUYhZsPGBwhPceg/kfrxMJdGb4mimvaROsuf9Q34fzqhV+5/1Dfh/OqFOnsRjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVj+Ir3ybYW6N88vXB6L/9f/Gtg1nXmjwXlwZpZZtxAGAwwB7cV1UqUnByjuzenBuLaORorp/+Ecs/+ek//fQ/wo/4Ryz/AOek/wD30P8ACl9VqC9jM5iiun/4Ryz/AOek/wD30P8ACj/hHLP/AJ6T/wDfQ/wo+q1A9jM5iiun/wCEcs/+ek//AH0P8KP+Ecs/+ek//fQ/wo+q1A9jMj8MXO6GS3Y8ody5bseuB9f51r6RY/YY5kBG1pGdQP4Qeg/IVUsdJgsZjLE8hYrt+YjGOPb2rVibahP4V0Sg40bS3OqhB80b9DL0/SxFfzahNnfJI7RJyNoJPJ98Hp2+vSl4h1UFWs4HJbOJWB4x/d/x/L1rdnQzRMnmPGWGNyHBH0rJ/wCEas/+es//AH0P8K5eRpWRvUpzUOSmt9zlaK6r/hGrP/nrP/30P8KP+Eas/wDnrP8A99D/AAqPZyOL6pVOVorqv+Eas/8AnrP/AN9D/Cj/AIRqz/56z/8AfQ/wo9nIPqlU5Wiuq/4Rqz/56z/99D/Cj/hGrP8A56z/APfQ/wAKPZyD6pVOVorqv+Eas/8AnrP/AN9D/Cj/AIRqz/56z/8AfQ/wo9nIPqlU5Wiuq/4Rqz/56z/99D/Cj/hGrP8A56z/APfQ/wAKPZyD6pVJvD03naUiksTGShJ/MfoRTW04PrQuyo2KgPXOX6dPYY/SrOn6dFp6usMkrK5Bw5BAPtx/nFWgvzE1Fe8YJnp04XglPp+hz/ia8wEso2/25MH8h/X8q56umuPDr3M7zSXuXc5P7vp7feqL/hF/+nz/AMhf/XrCM4RVrnBWo1qk3K35HPUV0P8Awi//AE+f+Qv/AK9H/CL/APT5/wCQv/r1XtYdzL6rW7fkc9U9jcG0vYZ+cI2TgZOO/wCma2v+EX/6fP8AyF/9ej/hF/8Ap8/8hf8A16TqQfUaw1ZO6X5G+etJSRxtHBGjOXZVClz1YgdaWqg7xRnXjy1GgoooqzEKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuZ8Uf8AIQi/64j/ANCaumqKfTLO9ZZLiHe4G0HcRxk+h961pU3UbihN2OFqS2l8i5im27vLcNjOM4Oa7H+wdM/59v8AyI3+NSRaNp0LFltUJIx8+WH5HNbrCTT3QuZFLxX/AMgyP/rsP/QWrk69De3gkiWKSGNo1+6rKCB9BUX9n2X/AD52/wD36X/Ctq2HdSXNcSdjgaK9Ajs7WJw8VtCjjoyoARU9ZrBPrIfMYvhe5EunGAkboWxgDseR+ufyrpqp1crDHR5Ywi/P9DvwP2vl+oVyPiXXWkeSwtSVRSVlfoWPdR7evr9OvXUV58XZ3O2pBzjZOx5ZRXqdFae08jk+pf3vwPLKK9Too9p5B9S/vfgeWUV6nRR7TyD6l/e/A8sor1Oij2nkH1L+9+B5ZRXqdFHtPIPqX978DyyivU6KPaeQfUv734HllFep0Ue08g+pf3vwOV8E/wDL7/2z/wDZq6qiis5O7uddKHs4qJ5tqv8AyFrz/ru//oRqrXqEsUc0ZjlRZEPVWGQfwqv/AGZYf8+Nt/36X/CtFUOSWDbd0zzeivSP7MsP+fG2/wC/S/4Uf2ZYf8+Nt/36X/Cj2iJ+py7nm9Fekf2ZYf8APjbf9+l/wo/syw/58bb/AL9L/hR7RB9Tl3PN6K9I/syw/wCfG2/79L/hR/Zlh/z423/fpf8ACj2iD6nLueb0V6R/Zlh/z423/fpf8KP7MsP+fG2/79L/AIUe0QfU5dzzeivSP7MsP+fG2/79L/hR/Zlh/wA+Nt/36X/Cj2iD6nLucVomsy6XPg5e3c/PH/Ue/wDP+Xe/u54v4ZI5F+oYH+Yqv/Zlh/z423/fpf8ACrEUUcMYjiRY0HRVGAPwqJNPU6qNOVNcrd0Nuf8AUN+H86oVfuf9Q34fzqhWlPY48Z8a9AooorQ5AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKALNlJsm2no/H49qdq17Pp9sbiK0+0IvMgD7So9ehyPX0/lUpbrVG0+WG5nJaznPlynqYpAOGHsR1AHGM9TzvTnZWFexl/8Jr/1D/8AyN/9jR/wmv8A1D//ACN/9jUHiLQFjQ6hpwDW7Dc6JyFH95f9n+X06c1SlOcXZsq51n/Ca/8AUP8A/I3/ANjR/wAJr/1D/wDyN/8AY1ydFT7WfcLnWf8ACa/9Q/8A8jf/AGNH/Ca/9Q//AMjf/Y1ydFHtZ9wudZ/wmv8A1D//ACN/9jXXx9DXklepaXK82n20sh3PJCjMcYySBmq5nKLuaUn7xh33i5rK9mtn04kxOVyZcZHY429xzVf/AITj/qHf+R//ALGsrxajL4huCykBghUkdRtAyPxB/KsasRyqTTaudd/wnH/UO/8AI/8A9jR/wnH/AFDv/I//ANjXI0UE+1n3Ou/4Tj/qHf8Akf8A+xo/4Tj/AKh3/kf/AOxrkaKA9rPudd/wnH/UO/8AI/8A9jR/wnH/AFDv/I//ANjXI0UB7Wfc67/hOP8AqHf+R/8A7Gj/AITj/qHf+R//ALGuRooD2s+513/Ccf8AUO/8j/8A2NX9I8Rz6tdeTDp21F5kkM3CD/vnr6Cue0Hw5Lqo8+VjDbA4DY5fnkD/AB9fXmu1nuLDQrBRIUhijU+XEp+Zseg7nn9cmk3Y2g5vWT0Lyrnr0rN1jWLXSBGbgSMZCQqoMnjqeeO4/Oo/Dmp3GrwXF3NsSMSeXHEo+6AM5J7k7gO3T3rmvG9wZNThhEgZYos7Rj5WJOc/gFrmqL2k1BjlP3eZGr/wmenf88br/vlf/iqP+Ez07/njdf8AfK//ABVcNRT+q0zH20juf+Ez07/njdf98r/8VR/wmenf88br/vlf/iq4aij6rTD20juf+Ez07/njdf8AfK//ABVXdL1+31WcxW1vc4UZZ2VQq/U5rgrCxn1G6W3tk3O3JJ6KPU+1dfK8dgtpoWnPi4lYee8fDBcZZsk8MQMjrgfhWVSjTXux3NITlLV7GrqMmdiA+5H+fxqjU102+4frgHHNQ11Uo8sEjKq7zYUUUVoZhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVFPqdnZMsdxNscjcBtJ4yfQe1S1zPij/kIRf8AXEf+hNWtKo6bckJq5uf29pn/AD8/+Q2/wqSLWdOmYqt0gIGfnyo/M4rhqktovPuYod23zHC5xnGTit1i5t7IXKj0HzE8rzd6+Xjduzxj1z6VB/aFl/z+W/8A39X/ABqaZY5IzFLjbKCmCcbuDkflmvPGVkYqwKspwQRgg1016zpWshJXO/jvLWVwkVzC7noquCTU9ecUVgsa+sR8p6PVyvPvD3/Iat/+Bf8AoJr0GuXF1faxi7W3/Q9DAq3N8v1CivLKK5vZ+Y/rv938T1OivLKKPZ+YfXf7v4nqdFeWUUez8w+u/wB38T1OivLKKPZ+YfXf7v4nqdFeWUUez8w+u/3fxPU6K8soo9n5h9d/u/iep0V5ZRR7PzD67/d/E9TorzCCCW5nSGBC8jnCqO9d9omlrpdn5ZYPK53SMB39B7D/AB9amUeXqbUa7qv4dDRoooqDpGSyxwxmSV1jQdWY4A/Gq/8Aadh/z/W3/f1f8a4HVf8AkLXn/Xd//QjVWtVTOCWMadkj0j+07D/n+tv+/q/40f2nYf8AP9bf9/V/xrzeij2aJ+uS7HpH9p2H/P8AW3/f1f8AGj+07D/n+tv+/q/415vRR7NB9cl2PSP7TsP+f62/7+r/AI0f2nYf8/1t/wB/V/xrzeij2aD65Lsekf2nYf8AP9bf9/V/xo/tOw/5/rb/AL+r/jXm9FHs0H1yXY9I/tOw/wCf62/7+r/jR/adh/z/AFt/39X/ABrzeij2aD65Lsekf2nYf8/1t/39X/GrEUsc0YkidZEPRlOQfxrgtE0aXVJ8nKW6H55P6D3/AJfz7393BF/DHHGv0CgfyFRJJaHVRqSqLmashtz/AKhvw/nVCr9z/qG/D+dUK0p7HHjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUrwJd281nKcJOu3P91uqn8DSUU07MDA0PWpdHuWsb7Jt1cqw6mJs84x1Geo/Ee8viLQFjQ6hpwDW7De6JyFH95f9n+X06N8WWeWi1FBxL+7l/3wOD+IHYdveovDuvtpzi2uiWtGP1MR9R7eo/Ee+ia+GWwjBorpfEWgLGh1DTgGt2G90TkKP7y/7P8AL6dOaqJRcXZjCiiipAK9G8MSvLodo0hydpXOOwJA/QCvOa7rwXK76OVY5EczKox0GAf5k1pT6ryLg7SRk+OUYarA5U7TAAGxwSGbI/UfnXN12Hj1GKWLhTtBcFscAnbgfofyrj6zHVXvsKKKKDMKKKKACiiprW1nvJhDbRPLIeyjp2yfQc9aAIkRpHVEUszHAUDJJ9K6/wAP+FVKR3WpIS+dyQHoB/tf4fn6VqaD4bg0zbO582624Ln7qeu3+Wf5ZxVDX/FiQr9n0mQNJn558ZC4PQZ4P16Y6e0t9EbqCgryNLXPENtpKPEhEt7gYj5wue7H+nXp65rgL29udQuDPdymWTAGTxgegA4FQu7SOzuxZ2OWZjkk+ppYYnnmjhiXdJIwVRnGSTgU0rGc5uTPSPDVt9k8PWqkIGkXzCVHXdyM++MD8K4LXLn7XrN3NlCDIVUp0IHAP5AV6RqEn2LTZngRB5ELMiY+UbRwMDtxXlNYU9akpGlXRJBRRRXQYBUlvby3U6QQIZJHOFUd6YiNI6oilmY4CgZJPpXX2VvB4VsTeXp33sy7ViVug4O3+WT27e+dSfKrLcuEeZ+QrvD4U0hrdZBJqFwN2VA4OMA9Pujtnqc++KHhGEzahcX0x3mBCcsxyXbPPvxu6+tYd3cyXl1LcTHLyMWPt7D2FdX4bh8jQDIQm65lJBHXaOMH8QfzqOTljZ7s0Uru62ReooorcwCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK5nxR/yEIv+uI/9CaumrmfFH/IQi/64j/0JqpbMDGrT8OwmXV4jsDLGC7Z7ccH8yKzK2tDYW1jqF6cqyRhI5MZGT29Ou2roq81cTNP7Yz2mn3K5PmXpA39QrFx+gNYWuweRq04Aba53gt3zyce2c/lVu6/5FKz/AOux/m9HiT999ivOnnw/c/u9+v8AwL9K3qvmhr5MSMSiiiuMo0vD3/Iat/8AgX/oJr0GvPvD3/Iat/8AgX/oJr0GlV+CPq/0O7Bby+X6nllFFFM4QooooAKKKKACiiigAooooAKKKKAClRWd1RFLMxwABkk0ldp4Z0b7HF9quosXL/cDdUX6dif5fjUylZGtKk6krIn8PaR/ZtsXmVftMn3iOdo/u5/z+OBVzVNQi0yzNxKC3O1FH8Tent0qW8uorK1kuJidkYycDJPYD864DVNTn1S582X5UHCRg8IP8fesopyd2d9WpGhDljudJ4WvZ7+5v57htzny8AdFHzcD2roq5XwT/wAvv/bP/wBmrqqU9y8O26ab/rU821X/AJC15/13f/0I1Vq1qv8AyFrz/ru//oRqrW62PKl8TCiiimSFFFFABRRRQAUUUUAFWdPspdQvI7eIH5j8zAZ2r3JqKCCW5nSGBC8jnCqO9d/o2mJplksXymZuZHUfeP8AgOn/AOuolKyN6FF1H5FixsoLC2WC3Xag6k9WPqfeuW8Ta2l3/odqcwq2XkB4cjsPUfzP050PE2tNZoLS1kAncfOwPMY/xP6fiDXG1MI9Wb4mskvZxPTrn/UN+H86oVfuf9Q34fzqhTp7EYz416BRRRWhyBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFACvAl3bzWcpwk67c/wB1uqn8DXBTRPBM8Ug2vGxVhnOCODXeVh+LLPLRaig4l/dy/wC+BwfxA7Dt71W6F1IvDuvtpzi2uiWtGP1MR9R7eo/Ee8/iLQFjQ6hpwDW7De6JyFH95f8AZ/l9OnNVuaB4hfTMwXAeW1OSAv3kPtnsfT8fXNRkmuWQGHRXR67okTQf2ppWJLVxuZE/h9SB6eo7fTpzlTKLi7MYV1/gaVzFdxE/IjIwGOhOc/yFchXReCXYapMgY7TCSVzwSGGD+p/Oqp/Ehrc2vG6M2ixlVJCzqWIHQYYZP4kfnXB16P4oVpPDt0FUscKcAZ4DAk/lXnFZmtb4rhRRRQYhRRXQaF4Ym1DbPdh4bVlypGNz+mPQd8n2x1zQOMXJ2Rn6Ro91qs6pEpWLPzzEfKvr9Tz0/wD113tlYWGgWEjhvLiHzSSyHLN6Zx+QA/maW7vLDw9YRh12Rj5Y4oxlm9cZ/Mk/zNcFrGs3WrXDPM5WHPyQhvlX0+p5PP8A+qpu3sb+7T9S/wCIPE8upHybMyQWoHIzhpMjnOO3t+ftz9FFNKxg227sK2PCdr9q1+3ym9IcytzjGOh/7621j113gG1zNd3ZDjaojU/wnJyfxGF/OlJ2Q4K8kafjS48rRHTbnzpFTOen8Wf/AB3H4159XUeO5997awbcbIy+7PXccY/8d/WuXrOgvcv3Kqu8goorovDGjR3O6/v1xaxcoHwFcjqT7D8vyIrSc1BXZMYuTsifQtNt9P0/+29RBIUboo9vTnAOO5J6du/0wtW1KXVL1riUBeNqKP4V9M9+tWdd1uXVp8DKWyH5I/6n3/l+ZOVUQg780typyVuWOwqI0jqiKWZjgKBkk+lehPH9nht7XfvEESpnGMkDGf5VyPhq0N3rcAwdsR81iCBjb0/XA/GutlbfIzc8nvVbz9AWkPUZRRRVmYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXM+KP8AkIRf9cR/6E1dNXM+KP8AkIRf9cR/6E1UtmBjVtOy2/hWNVI3XUpLAnnAPb/vlfzrFrb8SfufsVn18iH7/wDe7dP+A/rWlPSMpf1qJhdf8ilZ/wDXY/zenTE3PhKIh9xt5Pn3ZyOSAB+DLTbr/kUrP/rsf5vTtBzcadqFn8rlk3RxnHLYIz+YX6cVstZcveP6CMKiiiuMo0vD3/Iat/8AgX/oJr0GvPvD3/Iat/8AgX/oJr0GlV+CPq/0O7Bby+X6nllFFFM4QooooAKKKKACiiigAooooAKKK6LwzoiXf+mXQzCrYSMjhyO59R/M/TlN2Vy6cHOXKiz4X0Vdi391Gd2cwqw4x/e/w/P0rpJ54raB5p3CRoMsx7U52VEZ3YKqjJJOABXE+INdbUHNvbkraqfoZD6n29B+P0xV5s9JuOHhZblfW9Zl1SfAyluh+SP+p9/5fzzKKK2SseZKTk7s6nwT/wAvv/bP/wBmrqq5XwT/AMvv/bP/ANmrqqwn8R6uG/hI821X/kLXn/Xd/wD0I1Vq1qv/ACFrz/ru/wD6Eaq1utjypfEwooopkhRRRQAUUUUAFFFdR4X0Vt6391GNuMwqw5z/AHv8Pz9KTdlc0p03UlyoveHdESyiW6nG65dcgEf6sHt9fX8vrY13V49Mtiqtm5kU+Wo/h/2j7fz/ADq3qF7Fp9nJcSkfKPlUnG5uwFefX17Pf3LT3DbnPQDoo9B7VlFczuzuqzVCHJDcgdmd2d2LMxySTkk0lFFbHmnp1z/qG/D+dUKv3P8AqG/D+dUKzp7HXjPjXoFFFFaHIFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFK8CXdvNZynCTrtz/dbqp/A0lFNOzA4OaJ4JnikG142KsM5wRwaZXR+LLPLRaig4l/dy/74HB/EDsO3vXOUNWYkauha3LpM+DmS2c/vI/T/AGh7/wA/yxf1rQkljXUdHHnW8vJjjGce6j09R2/lzdauha3LpM+DmS2c/vI/T/aHv/P8sVGStyy2GZVa/hV2XX7cKxAYMGAPUbScH8QK1td0SLUIP7U0rEhcbmRP+WnqQP73qP69ee0d2TWLMoxU+cgyDjgkAj8qfK4yQHo2pK0mkXaIpZ2gcKoGSTtPFeW162n3a8ldGjdkdSrKcFSMEH0qZq0mbVdosSlRGkdURSzMcBQMkn0qazsri/nEFrEZJME4HGB6kngV32heHbfTESVwJLvB3S9lz2Uf169fXFQ3YiEHIzdA8KLGPP1SMNJn5Ic5C4PU44P06Y/TR17xHDpB8iFRPdEZK5wI+OCf049PTiszxB4swJbPTD/stcg/nt/+K+uOxrjqVubc0lNRXLEmu7u4vZjNdTPLIe7HpznA9Bz0FQ0UVRgFFFFABXong6FYfDsbqSTM7O2exzt4/BRXndeq4XTNIRXJdbWAZIGCwVfT8Kxru0Daitbnn3iW5+1a7dMC+1G8sBu23g49s5P41l0ru0js7sWZjksTkk+tXdI0qfVrryoflReZJCOEH+PoKtWhHXoZ6yZa8OaM2qXYeVD9kjP7xs43Hso/TPt+FT+JdZ+1SGxs2RbKLA/d9HI/oOw6cZ9MWvEuqRW0C6RpjCOJAVl2dv8AZz+ef59a5as4JzfPL5FyfIuVfMKKKK3MjqPCFvtt727ZM8CJGz68sMf981r1DpcP2XQbOMhN0gMrFe+eRn8CB+FTVENbs0npZBRRRVmYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXM+KP+QhF/wBcR/6E1dNXM+KP+QhF/wBcR/6E1UtmBR0qD7TqdvFhSC4JDdCByR+Qp2tS+dq1y23bh9uM5+7x/SrXhxFS5nvJELJbRFsg8g//AKt1ZLMzsWYlmY5JJySat6U15sXU2rr/AJFKz/67H+b1D4alaPV0UAYkVlOfTGf6VNdf8ilZ/wDXY/zesi2l8i5im27vLcNjOM4OauUuWcX5ICS/hFvf3EQQoqyEKD6Z4/Sq9a/ieJY9V3AnMkasc+vI/pWRWVSPLNoEaXh7/kNW/wDwL/0E16DXn3h7/kNW/wDwL/0E16DWdX4I+r/Q78FvL5fqeWUUUUzhCiiigAooooAKKKKACiitPRNGl1SfJyluh+eT+g9/5fzTdioxcnZFjw/oTag4uLgFbVT9DIfQe3qfw+nbIqoioihVUYAAwAKbBBFbQJDAgSNBhVHaud8S66saSWFqQzsCsr9Qo7qPf19Pr0xbc2enFQw8LsreItf8/dZ2T/uukkg/j9h7e/f6deboorZJJHm1KjqO7CiiimQdT4J/5ff+2f8A7NXVVyvgn/l9/wC2f/s1dVXPP4j18N/CR5tqv/IWvP8Aru//AKEaq1a1X/kLXn/Xd/8A0I1VrdbHlS+JhRRRTJCiiigAooq9pGmy6neLGqnylIMr9Nq/4+lDdhxi5OyLnh7RP7SkM85xbRtggHlz6ew9/wDI7WeeK2geadwkaDLMe1EEEVtAkMCBI0GFUdq47xJrTXk7WlvIPsqHkqf9Yf8AAH/H0rDWbPS93DU/Moazqb6netL8whXiNGP3R/iev/6qoUUVulY82UnJ3YUUUUCPTrn/AFDfh/OqFX7n/UN+H86oVnT2OvGfGvQKKKK0OQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAFeBLu3ms5ThJ125/ut1U/ga4KaJ4JnikG142KsM5wRwa7ysPxZZ5aLUUHEv7uX/fA4P4gdh296rdC6nOUUUVIzV0LW5dJnwcyWzn95H6f7Q9/5/lja1rR0vY11bR2y5+ciPjf/tL6N6j+vXAg0PVJ3KJYzAgZ+ddg/NsV0nh3StY01wZDCLeQ/vIGcll/2hgEZ/Hnv7bQu1ytaCukdNH3rhH0K91PXr0JGY4hctvlcYCgkngd+MdPUdM13aAhsVKVYIxQBnx8oY4BPueazrNRkzqilOCuZtta6b4fsmbKQRn7zu3zOQP1PB4HvgVxuveJLjVt0EY8m0DZCD7zjtu/nj+eM1Y1uw8Rag/2m8syVQYWOJgwX6KCT9f8BWFcWlza7ftNvLDuzt8xCufpmslrqyJzeyVkQ0UUVZiFFFFABRRRQBo+HoGuNeskQgESh+fRfmP6Cu08X3Ag0OcbyjSFY1xnnJyR+QNYXgO18zUZ7khCsMe0Z6hmPBH4Aj8at+M3lu7mz062zJI5MhjA69lOf++v61z1dZxRvHSDZythYz6jdLb2ybnbkk9FHqfaul1S8h8P6UNKsZSbojLyLgFc8kn3I4HcDHPTL99v4S04oGE+oXABIzxxnH/ARz7n+XHu7SOzuxZmOSxOST601+9d3svxF/DXmJRUkFvNcuUghklYDJVFLHHrxW3aeEr6X5rp47ZATnJ3NjHXA4/WtZTjHdmcYSlsjAqxYWcl9eRwRqx3MAzKu7YMgFj7DNdda6BpNngy77qQYPzH5cj0A4x7HNaK3AijEVvFHDGOiqOB9O1RzyfwovkjH4mJdvvuG5yBwKgpSSTknJNJWkVZJESfM2wooopkhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcz4o/wCQhF/1xH/oTV01cz4o/wCQhF/1xH/oTVS2YDbJ1tvDt5MHKyTSCEDGQRjP8i1ZFbGqN5GiadahlbcDM3qM8j8PmP5Vj1dXS0ey/wCCJG3df8ilZ/8AXY/zesStu6/5FKz/AOux/m9YlOtuvRAjd1hvtWh6fd7mJX92d3Vjjk5+q/rWFW7ZH7X4ZuoCVL253qGH3V68H1+9WFRW1al3QI0vD3/Iat/+Bf8AoJr0GvPvD3/Iat/+Bf8AoJr0GsKvwR9X+h34LeXy/U8sooopnCFFFFABRRRQAUUVYsbKe/uVgt13OepPRR6n2oGk27Il0vTJ9UufKi+VBy8hHCD/AB9q7+ztYrK1jt4QdkYwMnJPcn86j02xj06yS2jO7byzYwWJ6n/PbFVtb1mLS4MDD3Dj5I/6n2/n/LCTcnZHp0qcaEeaW5W8Ra2llE1rAd1y64JB/wBWD3+vp+f14mldmd2d2LMxySTkk0laxjyo4KtV1JXYUUUVRkFFFFAHU+Cf+X3/ALZ/+zV1Vcr4J/5ff+2f/s1dVXPP4j18N/CR5tqv/IWvP+u7/wDoRqrVrVf+Qtef9d3/APQjVWt1seVL4mFFFFMkKKKVFZ3VEUszHAAGSTQBLZ2st7dR28IG+Q4GTgDuT+VehabYx6dZJbRndt5ZsYLE9T/ntiquhaRHplsGZc3MijzGP8P+yPb+f5VH4i1k6ZAscGDcSg7ScHYPXH8vx9MVjJ8zsj0qNNUY889yh4o1pdjWFrId2cTMp4x/d/x/L1rlKV2Z3Z3YszHJJOSTSVrFWVjhqVHUldhRRRTMwooooA9Ouf8AUN+H86oVfuf9Q34fzqhWdPY68Z8a9AooorQ5AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKd5MV3FJaXGfKnG04OCDnIP502imnZ3BkMWneHLBUdminZSRud/MJznqo4/Spxrek2SlLaIiM/MfJjCrn8cc8VUutOguQSQUc/xLx+dYN9oVzES8LGdf8Ax7tWvtLbIfLD1NqfxfhR5UMatnqzlxj8MVn3Hiq8kLhZSqsMYRAB07E8iufIKnBBB9DSVLqSHdLZGkdaumkR2lm3JnDeaSVz1x6Vej13UbeJpIbuSQHk7zu49t2cVz9TW83lPgn5D1pKV/iLjN7M6KHxpeJGqukTt3Zk5/Qj+VacHjW1dyJrdkXHVWzz+IFcbcW+B5kfKnkgVWqZRXVDc5Rdmd8NQ8N3qSPNbQo0hO4tB8zZ6ncufzzmmPoXhu7SNYJliZyCPLn+Y57YbP8ALNcJTxNIDkO34nNTyx6XF7RPdHYzeBYjKTDfukfZXiDEfiCP5VmzeDNUjiLo1vKw6IjnJ/MAfrWRb6neW27yZ3TdjO1iufyrQh8VanFGqCdiB3YBj+ZGaOV9GH7tlWfQdVt3CPYTkkZ/drvH5rkVQdGjdkdSrqcMrDBB9DXVw+N5vMHnQRFO4AKk/jk/yrQh8X2FzEyXFu/zZUoMOGGO+cfyotLsHJF7MTwPa+TpEtyybWnkOGzncq8Dj67qs36xWN0+pyRyXV0wEVvEiZK8E4GPX5iT6cfUPiHR7SyUQsI1A4hSLbjPXA6d6xL3xjK7FLG3C5yA78k+hA//AF1zTpVJTvbQ2ThGNmyFtD1jWbo3V8VgDYxvPRfRVHTHocfzqa003RLSRczPqU6gHZEMp14PHA+hb+lQRWeo6qRJqtxKIs5ER4ycdcdB/Oti3t4raIRwRhE64Fbcj6v7jJzindL7y4tyIohFbwpCgJwFAwOfToKheR3OXYn602iqjCMdkRKcpbsKKKKogKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuc8QxNPq9tCpAaSNVBPTJYiujrKuLfz/E1pldyxw+Y3OMYLYP54rSnHmdv63EzK8SOp1QxKgRYY1QAdMYz+HXH4VlVNdyrPeTzKCFkkZgD1wTmoaVSXNJsaNu6/5FKz/67H+b1iVt3X/IpWf/AF2P83rEq6269EJG54XIknurV1Biliy3rwcf+zGsWSNopXjkGHQlWHoRVvRZfJ1a2bbuy+3Gcfe4/rUmvwiHV5wqFVYhxnvkcn880PWkn2YdRfD3/Iat/wDgX/oJr0GvPvD3/Iat/wDgX/oJr0GsKvwR9X+h34LeXy/U8sooopnCFFFFABRRSorO6oilmY4AAySaAHwQS3M6QwIXkc4VR3rv9G0xNMsli+UzNzI6j7x/wHT/APXUPh/SF021DyoPtUg+c5zgf3R/X3/Cr19ewWFs09w21B0A6sfQe9YzlfRHp0KKprnlv+RFqmpwaXbebL8znhIweXP+HvXns88tzO807l5HOWY96l1C9l1C8kuJSfmPyqTnavYCq1XGPKcles6j8goooqznCiiigAooooA6nwT/AMvv/bP/ANmrqq5XwT/y+/8AbP8A9mrqq55/Eevhv4SPNtV/5C15/wBd3/8AQjVWrWq/8ha8/wCu7/8AoRqrW62PKl8TCiiimSFdj4Z0R7T/AEy6GJmXCRkcoD3Pof5D68UPDOiJd/6ZdDMKthIyOHI7n1H8z9OeruriO0tpLiU4SNSx9/Ye9ZTl0R34ajb95Ig1TU4NLtvNl+ZzwkYPLn/D3rz2eeW5neady8jnLMe9WdU1OfVLnzZflQcJGDwg/wAfeqVVCNkYV63tHpsFFFFWc4UUUUAFFFFAHp1z/qG/D+dUKv3P+ob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBWu7C3u1IljGf7w4NYl94fljy9q3mL12nqP8a6SigdzgpI3iYrIjKQcYIptd1cWsFyMTRK/1rEvfDpGWs3z/sOf6/nTDToY9vceWdr8of0p1zAFHmJjaeoqKaCWBtssbIfQin28+z5H5Q/pVJ9GWndcsiCip7iDy/nTlD+lQVLViGmnZhRRT4omlbA6dz6UJXFuIiNIwVRzVr5LSPn5pGH+fwpyjY3kWymSZjjAGTWrY6B8wmvn3t18sH+Z71ppD1L+H1Mm1srnU5souEzgufur7V0en6Tb2IDD95N/z0YdPoO1XkRY0CIoVR0AGAKWs27kBRRRSAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKoXwEDXd4WdCtoI0YdMlm/XO386v1neJGkGjgJna0gD4GeOfy5xW9HRt9kJnI0UUVgM27r/kUrP/rsf5vWJW3df8ilZ/8AXY/zesStq269EJCqzIwZSVZTkEHBBrc8T7JvsV2m4edH0PYcEfj81YVb8zfbPCUbGTLWzgMNvocAfkwop6xlH5/cDKXh7/kNW/8AwL/0E16DXn3h7/kNW/8AwL/0E16DWFX4I+r/AEO/Bby+X6nllFFFM4QooooAK7bw7oiWUS3U43XLrkAj/Vg9vr6/l9a3hrQljSO/ugGdgGiTqFHZj7+np9enSOyojO7BVUZJJwAKxnLoj0MNQt78hs88VtA807hI0GWY9q8+1fUpdTvGkZj5SkiJOm1f8fWp9d1eTU7kqrYto2PlqP4v9o+/8vzrKqoRtqzHEV+d8sdgooorQ5QooooAKKKKACiiigDqfBP/AC+/9s//AGauqrlfBP8Ay+/9s/8A2auqrnn8R6+G/hI821X/AJC15/13f/0I1Vq1qv8AyFrz/ru//oRqrW62PKl8TCtXQtIk1O5DMuLaNh5jH+L/AGR7/wAvyqpptjJqN6ltGdu7lmxkKB1P+e+K9Cs7WKytY7eEHZGMDJyT3J/OpnK2h0Yej7R8z2JP3cEX8Mcca/QKB/IVw3iHV/7SuQkLN9mj+6DxuP8Aex/n8MmtDxPrbmSTT7Y7UHErg/e/2R7ev5fXmKUI9WXia1/cjsFFFFaHEFFFFABRRRQAUUUUAenXP+ob8P51Qq/c/wCob8P51QrOnsdeM+NegUUUVocgUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFADZYo5kKSoHU9iKxb7w8jZe0baeuxun4H8q3KKB3OQ8iezJiuo2VDwGI496rXFuYjuX7n8q7dlV1KuoZT2IyKzbrRopEIgIUdNjdP8A61WmmrMu6aszmIITK3oo6mtez0yacARr5MJ58w9T9B/WtWz0yKBQZAJH+nAq9Vcyivd3JvbRFe0srezTbBGAcYLH7x+pqxRRWRIUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUiPjg9Kjoq4TdN80QauYer+H/v3NiPcwgfnt/w/wD1VzrKyMVYFWU4IIwQa9AVyv0qjqujQ6jmVD5dxjAYdG9N3+P866HTjWXNT0fYm9tzHuv+RSs/+ux/m9Ylb+pW8tr4ZtYZl2yLNyMg/wB49qwKyrKzSfZDQVv+H/8AStOvrE+XlhuQN6kYz9AQtYFa3hmXy9WVdufNRlznp3/pRQdqiv1B7Efh7/kNW/8AwL/0E16DXD6fb/ZfFQhC7VV32jOfl2kj9MV3FY11aCT7v9DvwX2vl+p5ZRRRQcIV0nh3QPP23l6n7rrHGf4/c+3t3+nWt4f0JtQcXFwCtqp+hkPoPb1P4fTtkVURURQqqMAAYAFZTn0R24ahf35bDq4rxJrTXk7WlvIPsqHkqf8AWH/AH/H0qz4n1tzJJp9sdqDiVwfvf7I9vX8vrzFEI9WPE17+5EKKKK1OEKKKKACiiigAooooAKKKKAOp8E/8vv8A2z/9mrqq5XwT/wAvv/bP/wBmrqq55/Eevhv4SPNtV/5C15/13f8A9CNQwQS3M6QwIXkc4VR3qbVf+Qtef9d3/wDQjXX+HtE/s2MzznNzIuCAeEHp7n3/AMnVy5UefCk6k2uhb0jTYtMs1jVR5rAGV+u5v8PSqHiTWls4GtLeQ/anHJU/6sf4kf4+lXdb1RdLs/MCh5XO2NSe/qfYf4etcBLI80ryyHc7sWY46k9aiEbu7OqvVVOPs4DKKKK2POCiiigAooooAKKKKACiiigD065/1Dfh/OqFX7n/AFDfh/OqFZ09jrxnxr0CiiitDkCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKxU8U2imm4u6AS7tINQt/KnUlc5GDgg4xn9a4/U9Kn01gZMPExwsi9PofQ12QODkU9hHOhjlRXU9VYZBrrUoV1aWkidjzyprSVYLyCZgSscisQOuAc1raxoLWqvcWpLwg5ZO6D+o/wA+9Ydc8oSpysx7nVTweX4ttpQGxKhJJ6ZCkYH4AfnXU1zsTfazpF4ZNzDcrfLjLFDn9VNdFRjEtGurb/BHfgftfL9TyytPRNGl1SfJyluh+eT+g9/5fzh0vTJ9UufKi+VBy8hHCD/H2r0C1t47S2jt4hhI1Cj39z71hOVtEZ4ehzvmlsPijSGJIoxtRFCqM9AOlYHibW3tP9DtTiZly8gPKA9h6H+Q+vFjxDrf9mxiCAZuZFyCRwg9fc+3+Tw7szuzuxZmOSSckmohG+rN8RX5VyR3EooorY84KKKKACiiigAooooAKKKKACiiigDqfBP/AC+/9s//AGauqrlfBP8Ay+/9s/8A2auqrnn8R6+G/hIwdL0Vf7Tur+6jO77Q5hVhxjd97/D8/Sta+vYLC2ae4bag6AdWPoPerFcvqunatrV4N0KW8EYPl+Y4Pp1255P5cfmL3nqEv3UbQV2c7qF7LqF5JcSk/MflUnO1ewFVq3/+ERv/APntbf8AfTf/ABNWv+EN/wCn/wD8g/8A2Va80Uef7CrJ3sctRXYQ+ELVUInuZnbPBQBRj6HNTReFNOSQMzTyAfws4wfyANHtEUsLUZxNFd9/wjmk/wDPp/5Ef/GrKaVp6Iqiyt8KMDMYJ/M9aXtEWsHPq0ecU+KKSaQRxI0jnoqjJP4V6XFDBbRlYY44UzkhFCjNO8yP++v50vaeRX1RLeR5z/Zl/wD8+Nz/AN+m/wAKsp4e1V0VhaHDDIy6g/kTxXd/aIv736Gmm6jB43H3Ao5pdhexoreRxsHhbU5d29YocdN75z/3zmpk8IXpdQ89uFzyQWJA+mK6o3a4+VST78Uhu+OE5+tF5hy4ZdSW5/1Dfh/OqFTPcO6FSFwfSoaqCaWpliKkakrxCiiirOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAClpKKAJEfs351kaxoKXXmXFr8lweSvRX9fof8+9adPR8cHpXXTrKa5Kv3ktdjO8Nu409reVdkkDkbCMMAeQSPxNdFVIBdxcAbiACcckf5Jq7WeOXLGC9f0O/A/a+X6lexsoLC2WC3Xag6k9WPqfeqet6zFpcGBh7hx8kf9T7fz/lqVj33h22v7lp7i4uWc9AGXCj0HHSvPVr6nbNSUbUziJ55bmd5p3LyOcsx71HXff8I5pP/Pp/5Ef/ABqaHRtNgQqllCQTn513n8zmtfaI4fqc29Wed0V6ZDZ2tu5eC2hiYjBKIFOPwqel7TyKWCfWR5t/Zl//AM+Nz/36b/Cp4dC1OdCyWbgA4+chD+RxXf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_c29eb1dd56b94eac8a8d79fd36b76504" + } + }, + "79e3ab585f4f4eba8404f11b9b8c4e5b": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK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6iivZQ2Ox8Jf8gS4/wCurf8AoK1eqj4S/wCQJcf9dW/9BWr1OO7M6vww9AoooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAjurVb+0ltGwDIPkY/wuPunofofYmuFdGjdkdSrKcFSMEH0rvq53xRZbLhL6NcJPw+BwJB17Y5HP1zT3QitousPpsjRyr51nLxLEefbIz3/n/KXWtHS3jW/wBPbzrCXkMOfL9j7dv0PPXGrU0XWH02Ro5V86zl4liPPtkZ7/z/AJUmmrMDLrvvBs/m6KqbceU7JnPX+LP/AI9+lc/q2gIlr/aOmSefZt820dUX+oHOe479zWp4Fnza3MG37kgfdnruGMf+O/rTUWm0+xpB2kjndfha31y8RyCTKX49G+Yfoaz63PGELRa/I7EETIrrjsMbefxU1S0jSp9WuvJhG1F5kkI4Qf4+grMJRfM0ipb28t1OkECGSVzhVHeu50rRbLw9Eb2/uIzLjAduAvHIUdSevuR2608NpvhPTSpYSXLAErkB5Tzg+y9fp7nrxuq6tdatcCW6YfKMKicKvrge9Te+xelP1LuveI59V3QRjybQNkIPvP6bv54/njNYlFFNKxk227sKfDE880cMS7pJGCqM4yScCmVq+F7X7Vr9qpDlY28wle23kZ9s4H40PRAld2Op8Xsln4dW1iT92xSFRn7oHI+v3cVwNdT48uN99bQbfuRl92eu44x/47+tYmk6VPqt15UPyovMkhHCD/H0FZU2lByZpU96VkT6FpDahP502EsoTumkY4BA5K5+n5D8MprWsPqcixxr5NpFxFEOMDpk47/y/nPrupqyLpdg4FjbgLlf+WpHUn8fzPPpjEpxTk+aXyFJ8q5UFdf4ctxBo3nHG+5kJyCfurwAfxzXIV6D5AtIYbVcbYIwuQMBjjk496qWrSFHRNjaKKKsgKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOR1/8A5DE/0X/0EU5wIPDsY3APczluOrIoxg/Q8496br//ACGJ/ov/AKCKXWP3P2WzHHkQjen9125bnv29q225mIP+Za/7fP8A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AB+59vbv9OvRapqcGl23my/M54SMHlz/AIe9TOV9Ea0KKivaTINb1mLS4MDD3Dj5I/6n2/n/AC4F2Z3Z3YszHJJOSTUl1cSXdzJcSnLyMWPt7D2qKrjHlRz1qzqPyCiiiqMQooooAKKKKALWlf8AIWs/+u6f+hCvSa820r/kLWf/AF3T/wBCFek1jU3PRwfws821X/kLXn/Xd/8A0I1d8PaR/aVyXmVvs0f3iONx/u5/z+GRR/Zk+qa/eRRfKgncvIRwg3H9fauwmmtNH08EgRQRjCqvUn0HqT/9c1UpWVkZUqPNJzlsiLV9Qi0jT9yBA+NsMXQH8B2A/wAO9cDPPLczvNO5eRzlmPeptSvpNRvXuZBt3cKuchQOg/z3zVWnGNkZV63tHpsFFFFWYBRRRQAUUUUAdj4S/wCQJcf9dW/9BWr1UfCX/IEuP+urf+grV6ojuzoq/DD0CiiirOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApaSigBZEjuIWhnUOjDBB71yuq6FNY/vId00PJJA5T6+2O/8q6mno+OD0rpjUjUXLU+8VrbHntdpZb5tWtLt9o86zHA7HcpP4fNVDVfDwfM2nj5icmLIA/4D6fT/wDVV3wyd1givFtkgkaPJHPUE/Tr09quFOUG4vsOL95DvGX/ACCYv+u4/wDQWrG8P6E2oOLi4BW1U/QyH0Ht6n8Pp1Gsab/akEMBfYiyh3I64APA9+ass0FhZ5ZhFBCgGSegHA+teYpWVkepKipVOeWwy7urbTbMyykRxINqqo6+igV5/qF7LqF5JcSk/MflUnO1ewFTazqb6netL8whXiNGP3R/iev/AOqqFaQjY5MRW9o7LYKKKKs5goqxFY3k0YkitZ5EPRljJB/GpodG1KdyqWUwIGfnXYPzOKV0UoSeyKNFav8Awjmrf8+n/kRP8atf8Ijf/wDPa2/76b/4mlzLuWqNR/ZMCiulh8HzMhM94iNngIhYY+pxU8Xg6MSAy3rMncLHtJ/HJ/lS54lLDVX0Od0r/kLWf/XdP/QhXpNYdv4Xsre4imSW4LRuHALLjIOfStsnAyelZzknsd2Hpypp8xWgtbaxE8qgJ5jtLLIx9yeT6CuL13V5NTuSqti2jY+Wo/i/2j7/AMvzruZfImjMcvlyIeqtgg/hVYWumxSBltbZXU5DLEOD7HFEXZ3sKslKPKpJI86qymnXrorpZ3DKwyCImII/KvRGuYx0JP0FNN2mOFYn3q+aXY5fY0lvM4ODRNTn3bLOUbeu8bP/AELGanTw1qrOqm2CgnBYyLge/Brs/tf+x+tNN2+eFXFO8+wcuHX2mcv/AMIjf/8APa2/76b/AOJqxF4OkMYMt6qv3Cx7gPxyP5VvG5kJ4IH0FNM8jDBc/hxRaYc2HXRsyYfB8KuTPeO644CIFOfqc1P/AMIjYf8APa5/76X/AOJq95kn99vzplHLLuHtaS2gWILW1sLaSG2URqcsV3E849z7Cq9FFOMbGVWr7S2lrBRRRVGQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAOVitSwoglMijBcjd74/r/8AW9KgpVYqcg4Nb067iuV6oFumadZ+p6TFqmwTzzqidERgBn16daX7RL/e/QU3zJP77fnXEqbR6EsVTkrWIIvDOlpGFaBpCP4mkOT+WBU0Wh6VbNvFpHyMfvCWH5MTSEknJJJ96Sq5H3MvrEFtBE5sdMAz9ktP+/a/4VY+0Rf3v0NUKKPZoPrclskXTdR56MfwprXa/wAKk/XiqlFP2aJeKqFk3ZxwgB9zSfa5PRfyqvRT5IkPEVH1JftEv979BSGaRjkufw4qOinZEOpN7tji7MMMxI9zTaKKZLbe4UUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_09357156e94142fe8abc1f70c30e70ec" + } + }, + "79f4ad25e79d42a9aa03fcba0d8b7830": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UF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RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFSI/ZvzqOitKdSVN3QmrliiokfHB6VKDkZFerSrRqLQhqxaT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABRRTS6qcMwB9zQDaW46iozNGoyXH4c0n2iL+9+hp2ZDqQW7RLRVf7XH6N+VIbsZ4Qke5p8kiHiKa6lmiqjXbfwqB9eaabqTHRR+FP2bIeKpl2iqH2iX+9+gpplkJzvb86fs2Q8ZDomaNISAMkgD3rNLFjliSfekp+z8yHje0TR8yP8Avr+dN+0Rf3v0NUKKfs0Q8ZPoi6bqMHjcfcCmm7XHyqSffiqlFP2aIeKqMtG744Tn6037XJ6L+VV6KfJEh4iq+pMbiXP3sfhTWmkbq5/Dio6KfKiHUm92xxdyMFmI9zTaKKZLbe4UUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKxWm0VUZOLugLYukCAYbIFJ9r/ANj9aq0Vm4pu7Oj6zUtZMsG7fPCqB701rmQ9CB9BUNFHKiHXqPqSmeUjBc/hTfMk/vt+dMop2RLnJ7sUnJyetJRRTICiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_08a6bc9e8c2441998aa15ebc4c69667d" + } + }, + "7ca0fb1e6ff74f7a86a69ccbd6c1bfea": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_dc65a72c8e16444f9527a674358775f8" + } + }, + "814e3b8b4bcf45cd908972a591dbdb4c": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_52219eab5a534c5eafd9e66fdc6c3f3c" + } + }, + "81f2351b03644df39e2c8dd4342c4097": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_c83af41cbb3542708293e7f95bfed76d" + } + }, + "82717cc25b2c44a4a70742d2ec263435": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_eddd2bdec793468ba5645a5eeb859468" + } + }, + "883050fc8e244613b62e9aee196b7ae4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "8d390a6198e14de3abb4c02f86eed6e8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "8f03211affc24281a3c755e1a413b5b7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "8fd21a1694e34e89aed7c2a8d9e706c4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "92e5a81bd5dc40139cb339813cb39d71": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFQ3V1DaQ+bcSBEzjJ7msS01qbUNagiQeXb5Yhe7fK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AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_a7bd29798fd8472c9efb68a3dd2987cc" + } + }, + "94b84a1da7284751a57189c75db9083e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "9548190091d34d27a44714164b565f8b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "972d52b3c02e41bdb136ed10f38bf44b": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_6b08c8cf4c0046aa99e174fcb251a576" + } + }, + "9874e422848a4c65b459519e84d4f9b4": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_b2604a3c2c8f4e269fd0c322dffc8e0b" + } + }, + "98d90b3d4ebd411a83abaa4cc07986e8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "9b1dd5b7ae08434780df8c2e64a00d65": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "9b59d44ffb7d4b238d06150e744f3b4d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "_dom_classes": [ + "widget-interact" + ], + "children": [ + "IPY_MODEL_b6b39687a287427883c31131a9b9f769", + "IPY_MODEL_972d52b3c02e41bdb136ed10f38bf44b" + ], + "layout": "IPY_MODEL_98d90b3d4ebd411a83abaa4cc07986e8" + } + }, + "9bcec2011f0c486fb924fa7172df1eb4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "9de5d09d2de14559a6e1b30e78020e52": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_365398449b8a4739988051896039fa3a" + } + }, + "9fd4f2bfca9541819bcb629c760281ed": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VISq7VJA3HABPU9f6Gs3VdZhsFaNSJLnHCdhnuf8Ov86w9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RRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU5WK02iqjJxd0BbF0gQDDZApPtf+x+tVaKzcU3dnR9ZqWsmWDdvnhVA96a1zIehA+gqGijlRDr1H1JTPKRgufwpvmSf32/OmUU7Ilzk92KTk5PWkoopkBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_9b1dd5b7ae08434780df8c2e64a00d65" + } + }, + "9fda09fe038f44bda7c14162a767c606": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_4887c0e8468349cbafcbd8b3d8aa6fbd" + } + }, + "a127ce11df8942c49b6bee68d7700778": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VISq7VJA3HABPU9f6Gs3VdZhsFaNSJLnHCdhnuf8Ov86w9Ku5r3xFDNO2WO7A7KNp4HtXdF06LUI6tk6s7lPuL9KzLrxBZWl+1pceajJjL7cqMjPbn9K00+4v0rg/E3/Ieuf8AgP8A6CK8hpObuevVqOnTTidT/wAJHpP/AD9/+Q3/AMKspqunuisL23wwyMyAH8j0rziin7NHOsZPqkemwXVvc7vs88Uu3rscNj8qmryylRmR1dGKspyCDgg0vZ+ZaxveJ6lTSiscsoJ9xXnH9p3/APz/AFz/AN/W/wAasRa/qkUYRbtiB/eUMfzIzS9myvrcHujvTDGwwUH4cUn2eL+7+priYfE+pxOWeRJhjG10AH14xU//AAl1/wD88bb/AL5b/wCKo5ZB7eg9WvwOs+yR+rfnSG0GeHIHuK57/hMv+nD/AMjf/Y1PD4vtWQme2mRs8BCGGPqcUe+F8M9P8zYa0b+FgfrxTTayY6qfxrPi8V6c8gVlnjB/iZBgfkSasf8ACR6T/wA/f/kN/wDCjmmHssO9n+JN9nl/u/qKaYpAcbG/Kp7TULS9ANtcJIcZ2g4YDOOR1FWqPaPqH1SDV4szCpU4YEH3pK1KQgEYIBHvT9p5EvBdpGZRWj5cf9xfypv2eL+7+pp+0RDwc+jKFFXTaxk8bh7A002i4+ViD780/aIh4WoipRVo2nHD8/Sm/ZJPVfzp88SHh6q6Feipjby5+7n8aa0Mi9UP4c0+ZEOnNbpkdFOKOBkqwHuKbTJaa3CiiigQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUEhRkkAepoAKKAQRkciigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAClAycClVSx4qQbU2gkAscDPc9f6V0UaDqa9BN2BU28965/WPEC7Xt7Fjuzhph0x/s/4/l60viyWZEgiWTEUmSygdSMdT6c9P8AI5mta1X2f7uCsJK+rFZmdizEszHJJOSTWj4e/wCQ1b/8C/8AQTWbWl4e/wCQ1b/8C/8AQTXNS/iR9RvY79PuL9K4PxN/yHrn/gP/AKCK7xPuL9K4PxN/yHrn/gP/AKCK51/EZ6WJ/gx+X5GVRRRWh5wUUUUAFFFFABRRRQAUUUUAFWLGynv7lYLddznqT0Uep9qLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8PaolKx0UKDqO72DS9Mg0u28qL5nPLyEcuf8PartRzzxW0DzTuEjQZZj2rC0jWZdU1yUDKW6Qtsj/4EvJ9/5fzxs3qek5Rp2gjoaKKz9Y1L+y4IZym9GlCOB1wQeR78Ukrlykoq7JtQS5ezk+xymOdRlMBTuPoc+tccviTVoJ8SyhihIaOSMDn3wAa7eCeK5gSaBw8bjKsO9YHijRjcI1/BgPGn7xeBuUd/qB+g9ubg1szmrxk1zwZnf8Jdf/8APG2/75b/AOKqynjFgih7EFsckS4BP0xXL0VryROFYiqup10HjC3bd9otZU9NjB8/nip08W6ezqpjuFBOCxUYHvwa4qil7NFrFVDvv+Ej0n/n7/8AIb/4VYi1fTpYw63sAB/vOFP5HmvOaKXs0WsZPqkemQ3lrcOUguYZWAyQjhjj8Knryyil7PzKWNfWJ6h5cf8AcX8qQwRsclB+HFedf2nf/wDP9c/9/W/xrW8OapfS6pDbS3LyROWLB/mP3T3PPak4Na3KjiKc2ouJ1FzEiRgquDn1qtVy8/1Q/wB6qdXB3Rz4mKjUskFFFFWc4UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRTZZY4VLSOFA5yaaV9hpX2HUjuqLliAPesW98QomVtV3npuPQVjPPd6jPtaRmLds4UDNUo62ZSjrZnQy6zEZPKtF86T1zhQPUmql/fmCMeY2+YjgdB9cdhUD+Xpdr8gDSNxz3Pr9Kx5HaRy7sWY9Sa2k1SVludLaoKy+L8jodN1Eyr8pCyAfMh6H3rTt76KZhG37ub+43f6HvXFAlSCCQRyCK1re7ivIhDcHbLn5WHGT2I9DWelT1/MSlGvpLSXfudRRWHFqdxYMkd8PNhPAlX7w+vr/nrWzDNHPEskLh0boRWbTWjOaUHF2Y+iiikSFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU5ULfSm1n63q0mnokUMR3yJkSH7q/T1P/ANbrW1GMHdz2QmWdS1S30xAHBeRhlY16/U+grC0u/uL/AF+2e4fON+1QMBflPSsaSR5XLyuzuerMck1oeHv+Q1b/APAv/QTWntnOcUtFdCtZG7r6/bNHeSPd+5kJIxknaSp/DqfwrkK63S9tw2rWbAhTO+WB5w2R/SuTZWRirAqynBBGCDRidbT7/oCErS8Pf8hq3/4F/wCgms2tLw9/yGrf/gX/AKCaxpfHH1Q3sd+n3F+lcH4m/wCQ9c/8B/8AQRXeJ9xfpXB+Jv8AkPXP/Af/AEEVzr+Iz0sT/Bj8vyMqiiitDzgooooAKKKKACiiigAqSCCW5nSGBC8jnCqO9EEEtzOkMCF5HOFUd67vRNGi0uDJw9w4+eT+g9v5/wAplLlNqNF1H5EmjaYmmWSxfKZm5kdR94/4Dp/+urzsqIzuwVVGSScACh2VEZ3YKqjJJOABXE+INdbUHNvbkraqfoZD6n29B+P0xScmejOpGjGxH4h1f+0rkJCzfZo/ug8bj/ex/n8MmrHg3/kLS/8AXA/+hLWBW/4N/wCQtL/1wP8A6EtayVo2OCnJzrKTO0rA8Zf8gmL/AK7j/wBBat+sDxl/yCYv+u4/9Baso7noV/4bMfw7rb2Uq2s53WztgEn/AFZPf6ev5/Xt68srq/C+tLsWwupDuziFmPGP7v8Ah+XpVzj1Ry4avb3JFTxNoq2bi7tYyIHPzqBxGf8AA/p+IFc/XqLqroyOoZWGCCMgiuA1vSX0q5C7t8MmTGx68dQfcZFOEr6MnE0OV88djNooorQ4wooooAKKKKACtXwz/wAh62/4F/6Cayq1fDP/ACHrb/gX/oJpS2ZpS+OPqjtrz/VD/eqnVy8/1Q/3qp1NPY1xf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooqKe5igUlySR/CoyfyFNJvRDSb0RLUU9zDbLumkVPTJ61g6hr025o4EMeO7DmsaWWSZy8rl2PcmnZLcdktzdvPEXO20X/AIEw/pWHPcTXD75pGdvc1HTo0aRwiAsx6AUXb0QXb0QRo0jhEBZj0ArXjWLS7Ys53SP2Hc+3tSxxR6batK+GkPH1PoKyZ5nuJTJIck/kPatv4K/vfkdKSoK7+J/gE8z3EpkkOSfyHtUdFTR2txIRshc55BIwPzrDWTOa0pvuyGirselXUhxtVT2BOc/lmrsXhy5kXklWHUbeP1IqvZy7Gqw9V7RILW/SWL7Pecg8bj/X/GiaOfS5vtFo5EZPI6gex9RWpH4YXhmJ/wB1m/wFaMekxwoqmU7F4xjn8ya1spK0nqdsaE5xtU+T6lHTtchutsc+Ipj/AN8k+x/xrVrGvPD0MjE28hiPoRkVXt31PSPlmiM9sOu052jHUdwPrxXNdXsclTDVIatHQ0VXsr63vo90D5I6qeCPwqxTOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACsfxSiPZQyhsvHJsIB6ZXPPvwPzrYrLvP9Ig1i3+75YSXd1z8gOMf8A/Wt6Oqku//AA4mcpWl4e/5DVv/AMC/9BNZtaXh7/kNW/8AwL/0E1FL44+qB7FzTZ1g8UXCtjEskiZJxg7sj+WPxqn4gt/I1abC7VkxIvOc56n881DdytBrU8ygFo7hmAPTIbNbPiuJZILa6QoVyV3DqwIyOfTg/nWz96nJdmLqc1Wl4e/5DVv/AMC/9BNZtaXh7/kNW/8AwL/0E1jS+OPqhvY79PuL9K4PxN/yHrn/AID/AOgiu8T7i/SuD8Tf8h65/wCA/wDoIrnX8RnpYn+DH5fkZVFFFaHnBRRRQAUUUUAFSQQS3M6QwIXkc4VR3oggluZ0hgQvI5wqjvXd6Jo0WlwZOHuHHzyf0Ht/P+Uylym1Gi6j8g0TRotLgycPcOPnk/oPb+f8tJ2VEZ3YKqjJJOABTq4fxBrrag5t7clbVT9DIfU+3oPx+mKTkz0ZzjQhoHiDXW1Bzb25K2qn6GQ+p9vQfj9MSiit0raI8qc3N3YVv+Df+QtL/wBcD/6EtYFb/g3/AJC0v/XA/wDoS0pbGlD+IjtKwPGX/IJi/wCu4/8AQWrfrA8Zf8gmL/ruP/QWrGO56Vf+Gzi6KKK6DxzuvDusnU4GjnwLiIDcRgbx64/n+HritG+soL+2aC4Xch6EdVPqPevOIJ5badJoHKSIcqw7V6BpGpRanZrIrDzVAEqdNrf4elYzjbVHp4esqi5JbnCahZS6feSW8oPyn5WIxuXsRVavQtb0tdUs/LDBJUO6NiO/ofY/4elcBLG8MrxSDa6MVYZ6Eda0jK6OOvRdOXkMoooqjAKKKKACtXwz/wAh62/4F/6Cayq1fDP/ACHrb/gX/oJpS2ZpS+OPqjtrz/VD/eqnVy8/1Q/3qp1NPY1xf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec1Tup9OgnSK4ZY3YAgYIGM+o4pt/qKWc9vEdpMr4bJxtXpn8/5GqXia3328Vwo5jO1sL2PTJ9M/wA69GH7qk+XdbnSrwhpuXltrW5VhBcLJj72GDDB9cVBLocLkYSPA9AV/lXKVZh1G8gK+XcygKMBS2QB9DxUfWoy+OIvbt/Fqa02gjllWRc9ApDAf1qaw0mS3GFjdnbqxXHFR6RrN3c3kNtN5bBs5fbhuhPbj9K19bv5dNsY5YVRmLhCHBIxgnsfalKdNJTgjooSg7za2KUugyXcoeZmAXopYY/QVNF4dt05ITd3BBYfqa56TXNSlQo10wB/uqFP5gZqpNcz3GPPmkl29N7FsfnXO6jbvYUsTSvdRuzrxHpFpvBuIV253JvAII68DnNRPrOjQR/uwZsnosZJ/wDHsVyFFS6kn1JeNntFJHUS+K4UIWC0dkA/iYLj8BmqMnie/dCqiGMn+JVOR+ZIrFrY0TRjen7RcAraqfoZD6D29/8AInVkKtWqy5UzW0hNQuxHeahcyCJeY41+Tf7nGMj0/wAOuhNeRLdRW7N+9lztUdgATk/lVfWNSFhbeZgNIx2opP6n2/8ArVylreyLqkV1NKd28F3Izx0P6VrpD1OuVVUbQvd9TrdS3LZTOjsjIhcFeuRz/Suft/EVxGMTxpMMdR8pz/L9K6l+lcFcReTcSxZ3bHK5xjODisqkVzsMXOdPllFnRJfaXeyhyTBPk4c/I3TruHH51qwk+WCZPMU8q2ByMe3B/CuEqWC5mtm3QSvGcgnaeDj1Heo5Wtjl+sRn/Ej81od1RXMW/iK4jGJ40mGOo+U5/l+lbFtrFlOOJhG2M7ZPlx+PT9aLtbh7GnP+HL5Mv0UDmimmnsYVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKyIZVXxTcwOCyTxhSvVSdgPI+gP51r1zV9cfZfFHnFtqqybjjPy7QD+ma1pS5Wn5oTMieJoJ5IWILRsVJHTIOKv+Hv+Q1b/wDAv/QTS+IoTFq8p2BVkAdcd+OT+YNJ4e/5DVv/AMC/9BNOMeWsl5h0K2pf8hO6/wCuz/8AoRrfQrqPhRgxXfAmPu9CnI/Erjn3rA1L/kJ3X/XZ/wD0I1teErj/AI+Lct6SKuPwJz/3zWlF/vHF9biexzlaXh7/AJDVv/wL/wBBNU7uBrW6lgbOY2K5Ixkdj+NXPD3/ACGrf/gX/oJrGmrVEn3G9jv0+4v0rg/E3/Ieuf8AgP8A6CK7xPuL9K4PxN/yHrn/AID/AOgiudfxGelif4Mfl+RlUUUVoecFFFFABUkEEtzOkMCF5HOFUd6Yis7qiKWZjgADJJrvtE0aLS4MnD3Dj55P6D2/n/KZS5TajRdV+QaJo0WlwZOHuHHzyf0Ht/P+WpRXIeItf8/dZ2T/ALrpJIP4/Ye3v3+nXFJyZ6UpQowDxFr/AJ+6zsn/AHXSSQfx+w9vfv8ATrzdFFbpJI8qpUdR3YUUUUyArf8ABv8AyFpf+uB/9CWsCt/wb/yFpf8Argf/AEJamWxtQ/iI7SsDxl/yCYv+u4/9Bat+sDxl/wAgmL/ruP8A0FqxjuelX/hs4uiiiug8cKtabfSadepcxjdt4Zc4DA9R/nviqtFA02ndHplndRXtrHcQk7JBkZGCOxH51keJNFW8ga7t4z9qQchR/rB/iB/h6Vz+havJplyFZs20jDzFP8P+0Pf+f5V3iMrorowZWGQQcgisGnBnqQlHEQszy6iun8T6I4kk1C2G5DzKgH3f9oe3r+f05itk7q551Sm6crMKKKKZmFavhn/kPW3/AAL/ANBNZVavhn/kPW3/AAL/ANBNKWzNKXxx9Udtef6of71U6uXn+qH+9VOpp7GuL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUjsEUsxAUDJJPAFLWP4ivfJthbo3zy9cHov/wBf/GtaSV+Z7IuC1u+hg6hdG8vJJjnaThQey9q6Yf8AEx0PH+seSL6Zcf8A2QrkK6Pwzc7oZLdjyh3Llux64H1/nWuHnebUupdN3bT6nOUVc1e2+y6lMgGEJ3LhcDB549h0/Cqdc0ouLaZi9DW8NRCTVAxzmNCwx68D+tafjCVhBbQgDa7MxPfIGB/6Eaq+Eog1zPLzuVVUDtgnJ/lR4vlY3kEJA2pHuB75Jwf/AEEVpLSEfmdcNKEn3MCiiisjkCiitfQtI/tBzPOcW0ZwQDy59PYf5+gXCDnLliLoejG+YXFwCtqp+hkPoPb3/wAjodRv4NOtgWAAA2xxLxnH8hRqN/Bp1sCwAAG2OJeM4/kK4y7upbydppmyx6DsB6Ctfg9TulKOGjyx+ILu6lvJ2mmbLHoOwHoKhoorI89tt3Z3dlKbiwgkLB2aMFiPXHP61y/iGLy9UZs58xA3Tp2/pWz4an8zTTGSuYnIAHXB5yfxJ/KqniiH5IZwFGGKE9znkfyP51dTpI9St+8w/N6M56iiioPKCpLeF7idIYxlnOB/jUdb/hqyyWu3H+zHkfmf6fnSk7K5rRp+0momzH5NhbRJ0XcsaDjJJOP/AK5/GrB61zPiK/L3iQQuQsBzlT/H+Hp/PNdJHIs0McyghZFDDPXkZrKF07vqdeJkqiaX2RaKKK2PPCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArkdf/AOQxP9F/9BFddXI6/wD8hif6L/6CKr7LAt+ICLm1sL0KC0keHZfug8HH57v8iqvh7/kNW/8AwL/0E1aG248ItkEG2l4wepJ/+z/Sqvh7/kNW/wDwL/0E10PWrGXexPQral/yE7r/AK7P/wChGrGg3JttVhOTtkPlsAOuen64qvqX/ITuv+uz/wDoRqurMjBlJVlOQQcEGseblnfzH0NfxRB5epiUBsSoCSemRxgfgB+dQ+Hv+Q1b/wDAv/QTWv4jRbvSILyND8pDZJwVVh/jtrI8Pf8AIat/+Bf+gmt5xtXXm0Lod+n3F+lcH4m/5D1z/wAB/wDQRXeJ9xfpXB+Jv+Q9c/8AAf8A0EVwL+Iz08T/AAY/L8jKooorQ84KVFZ3VEUszHAAGSTQis7qiKWZjgADJJrtvD+hLp6C4uAGumH1EY9B7+p/D6zKXKa0qTqOyDw/oS6eguLgBrph9RGPQe/qfw+u5RXK+KdZ62FpL6icr/6Dn+f5eorHWTPTbhQgReItf8/dZ2T/ALrpJIP4/Ye3v3+nXm6KK3SSR5VSo6juwooopkBRRRQAVv8Ag3/kLS/9cD/6EtYFb/g3/kLS/wDXA/8AoS1Mtjah/ER2lYHjL/kExf8AXcf+gtW/WB4y/wCQTF/13H/oLVjHc9Kv/DZxdFFFdB44UUUUAFdF4Z1tLT/Q7o4hZspITwhPY+g/kfrxztFJq6sXTm4S5keouqujI6hlYYIIyCK4XxDpH9m3IeFW+zSfdJ52n+7n/P44NbXhnW3u/wDQ7o5mVcpITy4HY+p/mPpzuXVvHd20lvKMpIpU+3uPesU3BnpTjHEQujzKiruqaZPpdz5UvzIeUkA4cf4+1Uq3TueW04uzCtXwz/yHrb/gX/oJrKrV8M/8h62/4F/6CaUtmXS+OPqjtrz/AFQ/3qp1cvP9UP8AeqnU09jXF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAR2CKWYgKBkkngCuK1C6N5eSTHO0nCg9l7VveIr3ybYW6N88vXB6L/8AX/xrmK2qe5FQ+80l7qUQq/oc/k6pFltqvlDxnOeg/PFUKVWKsGUkMDkEHkGs4y5ZJkRdnc6DxRbgpBcjGQfLbnk9x/WuersZgNT0dtg5lj3KFYfeHOM/UYrjq3xUbS5l1NKqtK51XhKNRayyAfMZME+wAx/M1l+J5Wk1mRSBiJVUY9MZ/qa3fDMappUbKMFyxb3OcfyArmdZlabV7pmABEhXj0HA/lWdXZLyNpaYdLuylRRWjo+kyalNk5S3Q/O/9B7/AMqyOaMXN2QaPpMmpTZOUt0Pzv8A0Hv/ACrqria202zHAjgjGFUdSfQeponnttMshwI4IxhVHUn0Hqf/ANdcdqN/LqE/mScKOEQdFH+e9ar3Nep3txwsbLWTE1C9kv7ozSALxhVHYenvVaiism7nntuTuwooooEbvhWXFzPDt+8gbOemDj/2atXXIPO02YALlRvBPbHJx+Ga5nR5fJ1W2bbnL7cZ9eP612kqq6FWAKngg9CKt60/Q9XCe/ScH6Hn9FOkRopGjcYZSVI9CKbUHlE1pbtdXUcCcFzjPoO5/KuuuZYtL01njVVCDbGvqe319T+NZ3hqz2xNdMOZPlT6Dr+v8qq+JL3zroW0bfu4euD1b/63T86xl70uU9Gn+4oOfV/1/wAEx2ZnYsxLMTkknJJrq/Dk4l0sRjAaFiCM8kHnP6n8q5OtrwxcCO8kgYgCZeOOcj/6xNXPa/Y5KDvLlfXQ6WilpKsxCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArkdf8A+QxP9F/9BFddXI6//wAhif6L/wCgiq+ywLfhrbMt9Z5KtNFw2MgDkf8Aswqr4e/5DVv/AMC/9BNHh+48jVocttWTMbcZznoPzxVuzg+zeLfKwoAdyAvQAqSB+RrohqoPs7EmXqX/ACE7r/rs/wD6EarVZ1L/AJCd1/12f/0I1Wrnl8TKOr0jdqHh2S3YAsoaJS5yM4yD7YyPyrG8Pf8AIat/+Bf+gmrnhOdUupoDgGRQwJPcdv1/Si1gW28XeUuNoZmAAwAChOPwziuv4lTl52J7nZp9xfpXB+Jv+Q9c/wDAf/QRXeJ9xfpXB+Jv+Q9c/wDAf/QRXnL+Iz08T/Bj8vyMqlRWd1RFLMxwABkk0IrO6oilmY4AAySa7bw/oS6eguLgBrph9RGPQe/qfw+tSlynHSpOo7IPD+hLp6C4uAGumH1EY9B7+p/D67lFc14i1/yN1nZP+96SSD+D2Hv79vr0x1kz024UIB4i1/yN1nZP+96SSD+D2Hv79vr05Giit4xSR5dSo6juwooopmYUUUUAFFFFABW/4N/5C0v/AFwP/oS1gVv+Df8AkLS/9cD/AOhLUy2NqH8RHaVgeMv+QTF/13H/AKC1b9YHjL/kExf9dx/6C1Yx3PSr/wANnF0UUV0HjhRRRQAUUUUAKjMjq6MVZTkEHBBrvdC1ePU7YKzYuY1HmKf4v9oe38vyrgams7qWyuo7iEjfGcjIyD2I/KplHmRtRqunLyPQNU0yDVLbypflccpIByh/w9q89ngltp3hnQpIhwyntXomm30eo2SXMY27uGXOSpHUf57Yqj4i0Y6nAskGBcRA7QcDePTP8vx9c1nCVnZnbXpKpHnjv+Zwtavhn/kPW3/Av/QTWW6sjsjqVZTggjBBrU8M/wDIetv+Bf8AoJrWWzOCl/Ej6nbXn+qH+9VOrl5/qh/vVTqaexri/wCIFFFFWcwUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFI7BFLMQFAySTwBS1j+Ir3ybYW6N88vXB6L/APX/AMa1pJX5nsi4LW76GDqF0by8kmOdpOFB7L2qtRRWbbbuyW7u4UUUUhHT+Gp99k0RbJifgY6Kf/r5rB1K3FrqE0IwFVsqAc4B5H6GrXh+48nUQhOFlG3lsDPUf4fjVzxRbnMFyM4x5bc8DuP611v36CfY2fvU0+xu6LGsel24QYBjU/iRk/qa4aeVp55JnADSMWIHTJOa71z9j0yVoVAEMRKA8jgcfyri9M06bUrjy4uFHLuRwo/x9qyrfG0bVotwhBC6Vp8mo3SxqD5SkGR+m1f8fSuyZrextMDbDbxD8v8AP60xEtdLsSiERwxjLMepPqfU1yerapJqEuBlIFPyJ/U+/wDKkrQV3ubLlwsNdZMi1O/kv7ppGJ8sEiNemB/j61UoorNu550pOTuwooopCCiiigBVZkYMpKsDkEHBBrvopFnt0lXIV1DDPXBGa4Cuy0Gfz9Kiy25o8oeMYx0H5YrSnrdHdgZWk0c5rkHk6pLhdqvhxznOep/PNVrS3a6uo4E4LnGfQdz+VbHiiIB4JQpycozdvUD+dWfDtl5VsZ3GHm6ZHRf/AK/X8qwvaIOhzYhx6bl66nj03TmkUAbFCRqT1PQDrz/gK4tmZ2LMSzE5JJySa2PEl7510LaNv3cPXB6t/wDW6fnWNSprS76kYurzzstkFWNPn+zX8ExbaFcbjjPy9D+mar0VbV9DlTs7o9AbrSVX02b7RptvLliSgBLdSRwT+YqxUwfumlZJTduuv3hRRRVmQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVyOv/8AIYn+i/8AoIrrq5HX/wDkMT/Rf/QRVfZYFGCVoJ45lALRsGAPTIOa6iaFR4os7iMApPGTvByGIU/021yldhp+Lm00m4EZ3RFkyOcAKyk/iVFdGH1930f4ks5jUv8AkJ3X/XZ//QjVarOpf8hO6/67P/6EarVzy+JlFvSp/s2p28uVADgEt0APBP5Gunu4GHiGwuOSrK6HjgEKx6++T+VcbXeWki39paXRPzD5/l4G7BUjntya68L7ycfNMmRqp9xfpXCeJFZ/ENwiKWZigAAySdoru0+4v0qhDpaprVxqMjBmcBY1x90bQCfrx+X1rzW7TbPXqU3UhGKKnh/Ql09BcXADXTD6iMeg9/U/h9dyisPxBrq6eht7chrph9RGPU+/oPx+uesmae5Rh5FbxFr/AJG6zsn/AHvSSQfwew9/ft9enI0UV0RikjyqlR1HdhRRRTMwooooAKKKKACiiigArf8ABv8AyFpf+uB/9CWsCt/wb/yFpf8Argf/AEJamWxtQ/iI7SsDxl/yCYv+u4/9Bat+sDxl/wAgmL/ruP8A0FqxjuelX/hs4uiiiug8cKKKKACiiigAooooAvaRqUumXiyKx8piBKnXcv8Aj6V6DBPFcwJNA4eNxlWHevMK2PDusjTJ2jnybeUjcRk7D64/n+Hpis5xvqjrw1fkfLLY0/FGirsa/tYzuzmZVHGP73+P5+tZPhn/AJD1t/wL/wBBNd9XOx6I9l4kguoButnZyQB/qyVPH09Py+sxlpZm9Shaopx7m1ef6of71U6uXn+qH+9VOrp7HNi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAGuL1O6F5fySqSUzhMnsP8AOfxrr7iIXEDxFmUONpK4zj8azP8AhHLP/npP/wB9D/Cu10J8iivVnS6UuVJHMUV0/wDwjln/AM9J/wDvof4Uf8I5Z/8APSf/AL6H+FZ/VahHsZnMUV0//COWf/PSf/vof4Uq+HbMMCXmYA9Cwwf0o+q1A9jM5mN2ikWRDhlIYH0IrtZoIdRtFVsNG5VwSO2QfwyOPxqt/Yun/wDPv/4+3+NXoI0gjWOMEIowASTgfjXVQoyhdS2ZrCk4ppk11DJPYSQRsqtIu0lhkAHqfrjNRRRW+m2RjiGyKMFnbqT6k+tWXbACg/Wq1zbRXUXlTqWQnJAYjP5Vy2vJyPSULK63sclq2qSahLgZSBT8if1Pv/Ks+uy/sPTf+fb/AMfb/Gj+w9N/59v/AB9v8azdOT1ZwSwlWbu2jjaK7L+w9N/59v8Ax9v8aP7D03/n2/8AH2/xo9kyfqVTujjaK7L+w9N/59v/AB9v8aP7D03/AJ9v/H2/xo9kw+pVO6ONorsv7D03/n2/8fb/ABo/sPTf+fb/AMfb/Gj2TD6lU7o42ui8KSnbcQlhgEOq9/Qn+VaH9h6b/wA+3/j7f41Na6baWchkt4tjkbSdxPH4n2pxg07mtHDTpzUm0M1SyF9CsTMVw6twccdD+hNOvbhNPsHlAUbRtjXtnsMf54FWmGSKq6hp0WoKiyySqqEkBCACffj/ADmuOvZTs9jumnZuG7OJZmdizEsxOSSckmkrqv8AhGrL/nrP/wB9D/CkbwzaFTtmnDY4JIIB/Kn7aJ5f1OqctRXQ/wDCL/8AT5/5C/8Ar0f8Iv8A9Pn/AJC/+vT9rDuT9VrdvyH+Fp1NvPb8BlbeOeSCMdPbA/Otus3TNFbTrozC5EgKlSpjxx9c+1aZ60oSTbsOtTlGEXJeQlFFFanKFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcjr/wDyGJ/ov/oIrrqGs7WU75baF3IGWZASa3o0nUukJuxwFdT4SlU2c8ODuWTcT2wRj+hrV/s+y/587f8A79L/AIVLDbwQZ8mGOPd12KBn8q66OGlTnzXJbucLqX/ITuv+uz/+hGq6qzsFUFmY4AAySa9GoqXg7u/MHMcD/Z97/wA+dx/36b/Cuo8NidNPaG4jkRo3O0OhX5Tz6c85rWorWlh1TlzJg3ctJ9xfpTqan3F+lOrwp/Ez34fCjL1u/urWDy7G2mmnccMsZZUHr05Pt+fvxj6dqLuzvZ3TMxySYmJJ/KvR6KIysY1aHtHds82/sy//AOfG5/79N/hR/Zl//wA+Nz/36b/CvSaKr2jMvqce55t/Zl//AM+Nz/36b/Cj+zL/AP58bn/v03+Fek0Ue0YfU49zzb+zL/8A58bn/v03+FH9mX//AD43P/fpv8K9Joo9ow+px7nm39mX/wDz43P/AH6b/Cj+zL//AJ8bn/v03+Fek0Ue0YfU49zzb+zL/wD58bn/AL9N/hR/Zl//AM+Nz/36b/CvSaKPaMPqce55t/Zl/wD8+Nz/AN+m/wAK2/CdndW+pyPPbTRKYSAXQqM7l9a66ik53VioYVQkpXCsPxZBNcaZGkETysJgSEUscbW9K3KKhOzudM488XE80lsbyGMyS2s8aDqzRkAfjVevU6K19p5HG8EukjyyivU6KPaeQvqX978DyyivU6KPaeQfUv734HllFep0Ue08g+pf3vwPLKK9Too9p5B9S/vfgcp4X1pt62F1INuMQsx5z/d/w/L0rq6KKzbu7nXTg4R5W7le8/1Q/wB6qdXLz/VD/eqnW1PY87F/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDVt5PNhDdxw31rn7/xRPp901vcabtdeQRNww9R8vStO0kKuY95TzBt3DGQex5BqpKlvr8EtjeKIb+2JB2j7p/vrnqp44+nsa6VNyjo9RJ9DP/4TX/qH/wDkb/7Gj/hNf+of/wCRv/sa5u/sp9Pumt7hdrryCOjD1HtVes3UmupVztU8Y2JRS8FyGxyAFIB+uad/wmOn/wDPG6/75X/4quIoo9tILnb/APCY6f8A88br/vlf/iqu6VrtpqszxQLKjou7EigZHTsT7fnXndb3g2VI9ZZWODJEyrx1OQf5A1UKsnJJhc7q4nW3tZbhwSsSF2C9cAZ4rB/4TTTv+eN1/wB8L/8AFV0S/dFeR1i1ZtHTUqOKTR3X/Caad/zxuv8Avhf/AIqj/hNNO/543X/fC/8AxVcLRSMvbSO6/wCE007/AJ43X/fC/wDxVH/Caad/zxuv++F/+KrhaKA9tI7r/hNNO/543X/fC/8AxVH/AAmmnf8APG6/74X/AOKrhaKA9tI7r/hNNO/543X/AHwv/wAVR/wmmnf88br/AL4X/wCKrha0dI0W61aT9yu2ENh5W6L/AIn2HqOlA1Vm3ZHYWfie2v5xBa2l5JJgnAVBgepJbArdAyapafptnpNs4gURJjdJI55OB1JP/wCrrVez1yPUNcaxsyjQQxs8kuM7zkDC89OevOf1qHLsb8zXxbmlcyJbwPJI21EUuxxnAArJ/wCEn0f/AJ/P/IT/AOFL4suvs2iT4fa8uIl4znPUf987q85rljRVZuUiKlRxdkegT+LNJiQMkskxzjakZBHv82BUH/CZ6d/zxuv++V/+KrhqKtYWmZe2kdz/AMJnp3/PG6/75X/4qj/hM9O/543X/fK//FVw1dL4a0KOeIalflfsy5KIx4bHUt7DHTv9OszoUoK7KjUnJ2R2UExmgSUxSRFxnZIAGH1APFZUr75Wbnk55p1nqP8AaEV7cxvutlcRRLtweAMt+O78gPeoqrDU+W7HWaskgooorqOcKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKGvLWI7JbmFHAGVZwCKK5HX/APkMT/Rf/QRW9Gq6d2hNXOt/tCy/5/Lf/v6v+NSw3EE+fJmjk29djA4/KvPK6nwlEos55snc0m0jtgDP9TXXRxMqk+WxLVjeorm/Ftv/AMe9wF9Y2bP4gY/76rnVZkYMpKspyCDgg06mJ9nLlaBK56NRXA/2he/8/lx/39b/ABq/oV5dS6vAktzM6HdlWckH5TRHFxlJKwcp3KfcX6U6mp9xfpXFeIr68h1u4jiup40G3CrIQB8o7V40o802e1KqqdNNnb0V5t/ad/8A8/1z/wB/W/xo/tO//wCf65/7+t/jR7NmP1yPY9Jorzb+07//AJ/rn/v63+NH9p3/APz/AFz/AN/W/wAaPZsPrkex6TRXm39p3/8Az/XP/f1v8aP7Tv8A/n+uf+/rf40ezYfXI9j0mivNv7Tv/wDn+uf+/rf40f2nf/8AP9c/9/W/xo9mw+uR7HpNFebf2nf/APP9c/8Af1v8aP7Tv/8An+uf+/rf40ezYfXI9j0mivNv7Tv/APn+uf8Av63+NH9p3/8Az/XP/f1v8aPZsPrkex6TRWXolhdWsHmX1zNNO45VpCyoPTryff8AL31KzZ1xbau1YKKKw/Fk81vpkbwSvExmAJRipxtb0oSu7BOXJFyNyivNJb68mjMct1PIh6q0hIP4VXrX2fmcbxq6RPU6K8soo9n5i+u/3fxPU6K8soo9n5h9d/u/iep0V5ZRR7PzD67/AHfxPU6K8soo9n5h9d/u/iep0VynhfRW3rf3UY24zCrDnP8Ae/w/P0rq6zas7HXTm5x5mrFe8/1Q/wB6qdXLz/VD/eqnW1PY87F/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArK8TCSCW01a1JjmB8uR1wPmA4+uRn2wAK1aV4Eu7eazlOEnXbn+63VT+BqovoJlWGaz8V6cYZgIryIZ46qf7y+qnuP/rGuRv7KfT7pre4Xa68gjow9R7Uivcade5RjFcQORkHoRwR7118M1n4r04wzARXkQzx1U/3l9VPcf/WNX8e+4HE0VYv7KfT7pre4Xa68gjow9R7VXrJqwwrT8NypFr1o0hwCxXp3KkD9SKzKsadKkOo2ssh2okqMxxnABBNOLs0wPU0+7XmGr/8AIYvv+viT/wBCNenR96888V/8jFdf8A/9AWqqK02bz1ppmRRRRUGAUUUUAFFKiNI6oilmY4CgZJPpXZaB4UWMefqkYeTPyQ5yFwepxwfp0x+gVGDk9DN8P+GZb547i9Qx2hAZRnDS/wBQPf8ALrkdm72Oi2CGVkt7aPCqME/p1J7/AJmodX1q00eL982+cruSFerf4D3PocZrz3U9Uu9VmEl3Ju252KBhUBPQD+vXgVGstjZyjTVluaGveJLjVt0EY8m0DZCj7z+m7+eP54zW34Bg22V3cbs+ZIE246bRnP8A49+lcRXpfhq2+yeHrZSE3SL5hK993Iz74IH4VNRqMSad5SuzC8d3WTa2qv6yumPwU5/76rka2vFtz9o12VQUKwqIwV/M598kj8KxaKKtTRFR3kwoorR0PSn1W+WL51hXmWRR90f4np+vatJSUVdkpNuyLXhrRBqk7Sz5FtERuAyN5/ug/wA+/I9c1Y8Ta3FcoNPscC2jI3MnAbHQAD+Ef0GOnNrxBrEFlanSNMVQoUxyEchB3Uep9T/XpzmmWhvtRgtgCRI4DYIBC9SefbNYRTk/aS+Rq/dXJHc7W0h+yaNZW+GB2b2V/vAnkj8yaKnu333Dc5A4FQVrTVok1HeWgUUUVZmFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcjr/APyGJ/ov/oIrrq5HX/8AkMT/AEX/ANBFV9lgZ1dhp+La00m3Eh3SlnwOMgqzEfgWFclBE088cKkBpGCgnpknFdRNMp8UWdvGQEgjI2AYCkqf6ba6MPp73ovxJZHqCrdaJdhQ5a2unOAOp3kn8MN+lcxXUaUVmvtXs5HYCV2wo9MkEjtnkVy9TX1tL+tBoK0vD3/Iat/+Bf8AoJrNrS8Pf8hq3/4F/wCgms6Xxx9UD2O/T7i/SuD8Tf8AIeuf+A/+giu8T7i/SuD8Tf8AIeuf+A/+giudfxGelif4Mfl+RlUUUVoecFFFFABRRRQAUUUUAFFFFABXXeHdA8jbeXqfvescZ/g9z7+3b69Kvh3QPP23l6n7rrHGf4/c+3t3+nXr6ynPojvw1D7cvkFZNpq63uuSW1u4a3ihJLAfefcOh9Mf168Vl+KdZ62FpL6icr/6Dn+f5eoqr4N/5C0v/XA/+hLUqOl2ayr3qKETtKwPGX/IJi/67j/0Fq36wPGX/IJi/wCu4/8AQWpR3NK/8NnF0UUV0HjhRRRQAUUUUAFFFFABWx4d0YanO0k+RbxEbgMjefTP8/w9c1V0jTZdTvFjVT5SkGV+m1f8fSvQYIIraBIYECRoMKo7VnOVtEdeGoc75pbElc7Hrb3viSC1gO22RnBIP+sIU8/T0/P6Q+KNaXY1hayHdnEzKeMf3f8AH8vWsnwz/wAh62/4F/6CamMdLs3qV71FCPc7a8/1Q/3qp1cvP9UP96qdXT2ObF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAw/FlnlotRQcS/u5f8AfA4P4gdh296wLeeW1nSeBzHIhyrDtXePAl3bzWcpwk67c/3W6qfwNcFNE8EzxSDa8bFWGc4I4NU+4l2Ozhms/FmnGGYCK8iGeOqn+8vqp7j/AOsa5fVtLn0q68qb5kbmOQDhx/j6iqtvPLazpPA5jkQ5Vh2ruLG8s/E+nPb3KBZ1GXQdQf76/wCfY9edFapo9w2ODoq9q2lz6VdeVN8yNzHIBw4/x9RVGsmraMZ6tZzLcW8c6AhJUDgHrgjNcZ45/wCQxD/17r/6E1dP4fmWfRrN0BAEQTn1X5T+orD8e/8ALh/20/8AZaur8VzfekcjRRRWZgFWbCxn1G6W3tk3O3JJ6KPU+1WtG0O61d2MWI4UIDyt0+g9Tjn/AAzXoFhp9npVrthRIo1XLyNgFgO7H8/pSbsawp82r2Keg+H4NLhVnVJbo8tKR93jovoOfx/QVvEHieGwjktrFxJeZKs2MiL+hPt+fTBytf8AFjXK/Z9LaSKMH5pvus2DxjuB39fp35aps3uVKokuWJLc3E13cPPcSGSVzlmPeoqKKswHwxPPNHDEu6SRgqjOMknAr1mTyreAD5Ioo19gqqB+grzvwna/atft8pvSHMrc4xjof++ttdn4nnaDQ7t0AJKbOfRiFP6GubEapR7nRS0TZ5xczNc3Ms7gBpXLkDpknNR0VJb28t1OkECGSRzhVHeujRI59yWwsZ9Rult7ZNztySeij1PtXWatqEHhuxTT9PTE7Lu3EZx23H1PH6egAK/u/CWi4+Sa8nb6AnH5lR/M9s8cbcTy3U7zTuXkc5Zj3rBL2srv4V+Jt/DXmMd2kdndizMclickn1roPBtsHvprtwCtvHxychjnn8g351z1dp4cgFv4e80YL3MhJIGCADjGe/Q/nWlTa3cmn8V+xcJJOSck0lFFaGYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcjr/wDyGJ/ov/oIrrq5HX/+QxP9F/8AQRVfZYC+H7fz9Whyu5Y8yNzjGOh/PFW7Of7T4t83KkF3AK9CApAP5Ck8NbYVvrzBZoYuFzgEcn/2UVV8Pf8AIat/+Bf+gmuiGigu7uSW9On8nxTOCVCyySIS31JGPfIFZ+tReTq1yu7dl92cY+9z/Wi5l8jXJZtu7y7ktjOM4bNaHiuDZexTgKBImDjqSO5/Aj8qUvepy8mPqYVaXh7/AJDVv/wL/wBBNZtaXh7/AJDVv/wL/wBBNZUvjj6oHsd+n3F+lcH4m/5D1z/wH/0EV3ifcX6Vwfib/kPXP/Af/QRXOv4jPSxP8GPy/IyqKKK0POCiiigAooooAKKKKACtvw/oTag4uLgFbVT9DIfQe3qfw+kOhaRJqdyGZcW0bDzGP8X+yPf+X5V3iKqIqIoVVGAAMACs5ztojsw9Dn96Ww6ue8Ta01mgtLWQCdx87A8xj/E/p+INWfEOr/2bbBIWX7TJ90HnaP72P8/jg1wrszuzuxZmOSSckmphG+rNsTX5fcjuJW/4N/5C0v8A1wP/AKEtYFb/AIN/5C0v/XA/+hLWktjjofxEdpWB4y/5BMX/AF3H/oLVv1geMv8AkExf9dx/6C1Yx3PSr/w2cXRRRXQeOFFFFABRRRQAVNZ2st7dR28IG+Q4GTgDuT+VRIrO6oilmY4AAySa73QtIj0y2DMubmRR5jH+H/ZHt/P8qmUuVG1Gk6kvItabYx6dZJbRndt5ZsYLE9T/AJ7Yqj4i1k6ZAscGDcSg7ScHYPXH8vx9MVc1TU4NLtvNl+ZzwkYPLn/D3rz2eeW5neady8jnLMe9Zwjd3Z216qpx5I7/AJDHZndndizMckk5JNanhn/kPW3/AAL/ANBNZVavhn/kPW3/AAL/ANBNay2ZwUv4kfU7a8/1Q/3qp1cvP9UP96qdTT2NcX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArD8WWeWi1FBxL+7l/3wOD+IHYdvetyleBLu3ms5ThJ125/ut1U/gaqPYTPP6kt55bWdJ4HMciHKsO1JNE8EzxSDa8bFWGc4I4NMqRneWN5Z+J9Oe3uUCzqMug6g/31/wA+x688jq2lz6VdeVN8yNzHIBw4/wAfUVVt55bWdJ4HMciHKsO1dxY3ln4n057e5QLOoy6DqD/fX/PsevOyaqKz3FsO8ITLJokSKCDE7I2e5zu4/BhUXjlFOlQOVG4TgBscgFWyP0H5VP4dsZdMjubOUE7ZfMSUD5XUgAY9/l5H0qbxVF52gzqI98m5NgC5O4sBx784/GlUWiudENYNHnNdHoHhiS98q6vRstTyE5DSDt9AfXr+ea09A8KLbt5+pJHLIR8sX3lXjnPYnt6fXtq63rlvosS7l864flYg2Dj1J7D+f54wbsEaaS5plm5ns9GsDLKEhhThY0UDJPOAPU1weveILjVpmVGeK0HCxA/e56t6nj8P1NDUL+41K7a5uX3O3AA6KOwA7Cq1CXVkzqOWi2CiiiqMgooooA67wDa5mu7shxtURqf4Tk5P4jC/nU3jufFpbQbc+ZIX3Z6bRjH/AI9+laHg6FYfDscik5md3bPY528fgormPGM/m66ybceTGqZz1/iz/wCPfpXM/eqpdjofu0zDRGkdURSzMcBQMkn0rtdKsIPDVi9/qD4uHXaVU5x32j1PH6emSa3h/R4LG1XV9SZAAokjU8hB2Y+p9B/Xph63qj6rfNLlxCvESMfuj/E9f/1U5P2r5Vt1JivZrme/QrX97PqF01xcvuduAB0Ueg9qr0UV0JW0Rk3fViojSOqIpZmOAoGST6V6HJH9ngt7XcH8mJU3YxnAx/SuQ8NWhu9bgGDtiPmsQQMben64H4110z75nbOQTx9Kzes/QtaQfmR0UUVoZhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVyOv/APIYn+i/+giuurkdf/5DE/0X/wBBFV9lgWxtt/CLZJJuZeMDoQf/ALD9aq+Hv+Q1b/8AAv8A0E1a8QAW1rYWQYBo48uq/dJ4Gfz3f5NVfD3/ACGrf/gX/oJroelWMe1iehW1L/kJ3X/XZ/8A0I1r6ki3XhqyuEQ5hAUknGB90/qBWRqX/ITuv+uz/wDoRrX0oC78O3trudnQllUckcAgD6kHilT1lKPe42c/Wl4e/wCQ1b/8C/8AQTWbWl4e/wCQ1b/8C/8AQTWVL44+qB7Hfp9xfpXB+Jv+Q9c/8B/9BFd4n3F+lcH4m/5D1z/wH/0EVzr+Iz0sT/Bj8vyMqiiitDzgooooAKKKKACr2kabLqd4saqfKUgyv02r/j6VFp9lLqF5HbxA/MfmYDO1e5NehWNlBYWywW67UHUnqx9T71E5WOnD0PaO72JIIIraBIYECRoMKo7VS1vVF0uz8wKHlc7Y1J7+p9h/h61NqV9Hp1k9zIN23hVzgsT0H+e2a8/vr2e/uWnuG3OegHRR6D2rOEb6s669ZU1yx3I555bmd5p3LyOcsx71HRRW55e4Vv8Ag3/kLS/9cD/6EtYFb/g3/kLS/wDXA/8AoS1Mtjah/ER2lYHjL/kExf8AXcf+gtW/WB4y/wCQTF/13H/oLVjHc9Kv/DZxdFFFdB44UUUUAFFFdF4Z0RLv/TLoZhVsJGRw5Hc+o/mfpym7K5dODnLlRf8ADOiPaf6ZdDEzLhIyOUB7n0P8h9eNy6uI7S2kuJThI1LH39h71I7KiM7sFVRkknAArhfEOr/2lchIWb7NH90Hjcf72P8AP4ZNYpObPSnKOHhZFXVNTn1S582X5UHCRg8IP8feqVFFbpWPLbcndhWr4Z/5D1t/wL/0E1lVq+Gf+Q9bf8C/9BNKWzLpfHH1R215/qh/vVTq5ef6of71U6mnsa4v+IFFFFWcwUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBh+LLPLRaig4l/dy/wC+BwfxA7Dt71zleghLeaKSC8ANvIBvBYgcHIORTkm0GwdPKFsjovyvHHuIHT7wB5/HNaqPPrcWuyRwtrYXd5j7NbSygtt3Kp2g+56DrWxp/hrWo5xPGY7WSMgqzyA5/wC+c/r61uzeKLdUzFBIx77yFAH15qhP4vcMPKjhVcdGJc5/DFVyQW7K5J9rHURiTyUM2zzdo37M7c98Z7VOoLAV59P4kvJF2m5kIHIKAJn8Rg0Wmt3xYOl3MHX+FnLD8jwaVR8+iNqXuaXO31ZtQSyf+y4o3mIwC74K9OQCMHv1I/HpXn93oWsRPvns55HkJJZf3hJ7k7c+vetRfFt/bMVlKS7sYLxjA/LFXYfGoKASWyM/chyo/Ig/zrD2c4uw5csnqzjZoZYJTHNG8ci9VdSCPwNMr0aPxNpd0Hjk3rGykHzEDK3txmmtD4ZvocFLNVDdv3LZ/Q45+lL3luifZdmed0V6DL4P0i4KyQmaJCowIpMqffJBrMm8CyiImG/R5OyvEVB/EE/ypc6JdORyNFb9x4P1aHb5aRT5zny5MY+u7FM0fRdRTXLUS2ksSxTBmd0O0bTk/NjHbj8KrmRPK7nfW0H2Swgtt2/yo1j3YxnAxnH4VyOk6bFql7c6zfE/ZfNZo0l43Ad2J42gcY6ceg57GcB1KEkAjBwSD+Y6VhaxZXuoRiwtUitrNdod2x8w9FUdAMDrjP0rg5rzavbzOtwvrY5rxLrY1WdY4Mi2iJ2k5G8+uP5d+T64rHiiknkEcMbSOeioMk/hXUjRdF05xFeTvd3JBHkpnJPUfKvI49TitmC5SGMrbWcdspbO0ADt3A4z+J6V1Rdo2gtDGUNbzZzVn4Rv5iDctHbLkg5O5unUAcfrWxbeHdJssNOWuZBg/OeMjrwPX0OatvNJJ95yR6dqjp8k5fE/uFzwj8K+8si5SGMRWsKRRjoAoAH0A4qtRRVxgo7GcpyluFFFFUSFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXNX1v8AavFHkldysybhnHy7QT+ma6WsiGJW8U3M7kqkEYYt0UHYByfoT+Va0o8zS80JmV4imMuryjeGWMBFx245H5k0nh7/AJDVv/wL/wBBNUJ5WnnkmYANIxYgdMk5q/4e/wCQ1b/8C/8AQTTjLmrJ+YdCtqX/ACE7r/rs/wD6Ea0/CkxS/liLgLJHnB7kHj9CazNS/wCQndf9dn/9CNSaLL5OrWzbd2X24zj73H9aIS5at/MOhWuYvIuZYd27y3K5xjODir3h7/kNW/8AwL/0E1J4mi8vVmbdnzUVsY6dv6VH4e/5DVv/AMC/9BNNR5ayXmHQ79PuL9K4PxN/yHrn/gP/AKCK7xPuL9K4PxN/yHrn/gP/AKCK5F/EZ6WJ/gx+X5GVRRRWh5wUUUUAFTWdrLe3UdvCBvkOBk4A7k/lTYIJbmdIYELyOcKo713eiaNFpcGTh7hx88n9B7fz/lMpWN6NF1H5E+l6ZBpdt5UXzOeXkI5c/wCHtU15dRWVrJcTE7Ixk4GSewH50+eeK2geadwkaDLMe1cHresy6pPgZS3Q/JH/AFPv/L+eMYuTO+rUjRjZEOqanPqlz5svyoOEjB4Qf4+9UqKK6ErHlNuTuwooooEFb/g3/kLS/wDXA/8AoS1gVv8Ag3/kLS/9cD/6EtTLY2ofxEdpWB4y/wCQTF/13H/oLVv1geMv+QTF/wBdx/6C1Yx3PSr/AMNnF0UUV0HjhRRVrTbGTUb1LaM7d3LNjIUDqf8APfFA0m3ZFvQtIk1O5DMuLaNh5jH+L/ZHv/L8q7xFVEVEUKqjAAGABUVnaxWVrHbwg7IxgZOSe5P51keJNaWzga0t5D9qcclT/qx/iR/j6Vg25s9SEY4eF2UfE+tuZJNPtjtQcSuD97/ZHt6/l9eYoorZKysedUqOpK7CiiimZhWr4Z/5D1t/wL/0E1lVq+Gf+Q9bf8C/9BNKWzNKXxx9Udtef6of71U6uXn+qH+9VOpp7GuL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFV7mygugfMUhj/EpwasUUDTa2OZvtCuIyXhYzD9ayJI3icpIpVh1BFd7UNzaQXS4mjVvQ45FMLp7nDUqsVYMpwRW5eeHnU7rVgw/uscYrFmhkgfZKjI3oRQFrFtWW6iKnhu/wDjVN0aNirDmkVirBlOCKuqVu4jkYYfpV/Hp1L+P1KNPWWRcYc8e9I6NGxVhzTajVEaosR3s8bhlb5gcg9CD7YrQt/E2pQA7biRieu9t35bs4rHoo5m9xqcl1Ooh8Z3ioEdYnI/jdOT+R/pWrB4vjkZd9m6xnur5P5ECuMht1VfMm4A5wf608LNfzeRaoWHc9PxPoKv2cbXkjXnaWp02oeM4gxFnbs5/vSHAH4Dr+dZ8cusa3kz3DQWrZyEG0EHsB1I+tTadocNttkuMSyjt/CPw71rVkoQjsiJVZPS5WsrC3sU2wpyerHlj+NWaKKZmFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABWXef6PBrFx97zAkW3pj5AM5/4H+lalY/il0SyhiC4eSTeSB1wuOffkflW9HRSfb/hhM5itLw9/wAhq3/4F/6Caza0vD3/ACGrf/gX/oJqKXxx9UD2K2pf8hO6/wCuz/8AoRqtVnUv+Qndf9dn/wDQjVapl8TGdF4mVbizs71AArDHI+bDDI/kfzrP8Pf8hq3/AOBf+gmtBVF74RwMySW5J5P3cH/4k1n+Hv8AkNW//Av/AEE10z1qxl3sT0O/T7i/SuD8Tf8AIeuf+A/+giu8T7i/SuD8Tf8AIeuf+A/+giuBfxGenif4Mfl+RlUUUVoecFKis7qiKWZjgADJJpK7Dw3oTWpW9uwVmx+7j6bAR1Pvjt2+vSZSsjSlTdSVkT+H9CXT0FxcANdMPqIx6D39T+H12nZURndgqqMkk4AFOrkPEWv+fus7J/3XSSQfx+w9vfv9OuKTkz05ShQgVvEGutqDm3tyVtVP0Mh9T7eg/H6YlFFbpW0R5U5ubuwooopkhRRRQAVv+Df+QtL/ANcD/wChLWBW/wCDf+QtL/1wP/oS1Mtjah/ER2lYHjL/AJBMX/Xcf+gtW/WB4y/5BMX/AF3H/oLVjHc9Kv8Aw2cXRRRXQeOSQQS3M6QwIXkc4VR3r0DSNNi0yzWNVHmsAZX67m/w9Kq+HdGOmQNJPg3EoG4DB2D0z/P8PTNaN9ewWFs09w21B0A6sfQe9YzlfRHp4eiqa55blbW9UXS7PzAoeVztjUnv6n2H+HrXASyPNK8sh3O7FmOOpPWptQvZdQvJLiUn5j8qk52r2AqtWkY2Rx16zqS8goooqjAKKKKACtXwz/yHrb/gX/oJrKrV8M/8h62/4F/6CaUtmaUvjj6o7a8/1Q/3qp1cvP8AVD/eqnU09jXF/wAQKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACo5oIrhNsyBx71JRQBg3nh3JLWrgd9rVjSQXNjN+8jZCPbgiu3pskSSptkUMvoadyrnIMFu4crww7elUmUqxVhgiunuNCj3eZaOYn9Dyp9qy72ykXAlTY/Y9vz71fx+pbXOrrcywMnA5NXIoFiUPJy2eB7+g96uafpskn3B9XPT6VuWmnQ2xD43yj+Nu30HaqSUNZbk6R9TKtdHnuir3n7qLqIx94/X0/z0rdhhjt4hHCgRB0Ap9FZuTerJbuFFFFSIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArP1vSZNQRJYZTvjTAjP3W+nof/rdK0KcrlfpW1GUFdT2YmcBJG8TlJUZHHVWGCK0PD3/Iat/+Bf8AoJrptS0u31NAXJSRRhZF6/Q+orC0uwuLDX7ZLhMZ37WByG+U9K09i4Ti1qroV7ozdS/5Cd1/12f/ANCNVqs6l/yE7r/rs/8A6EarVzy+JlHQ+GCJ7a9s5HwjjhRjPIIJH6VR0BWTXYFYFWUsCCMEHaad4alaPV0UAYkVlOfTGf6Vat4vJ8Yld27Ls2cY+8pP9a6Yaxg+zsT3OyT7i/SuD8Tf8h65/wCA/wDoIrvE+4v0rg/E3/Ieuf8AgP8A6CK4F/EZ6eJ/gx+X5GVRRW/4Z0b7ZL9quos2yfcDdHb6dwP5/jVt2VzhhBzlyoseGNEcyR6hcjag5iQj73+0fb0/P69ZRWH4g11dPQ29uQ10w+ojHqff0H4/XB3kz1YqFCBV8S66saSWFqQzsCsr9Qo7qPf19Pr05Kiit4qyPLqVHUldhRRRTMwooooAKKKKACt/wb/yFpf+uB/9CWsCt/wb/wAhaX/rgf8A0JamWxtQ/iI7SsDxl/yCYv8AruP/AEFq36wPGX/IJi/67j/0FqxjuelX/hs4uur8L6Kuxb+6jO7OYVYcY/vf4fn6VQ8O6I97Kt1ONtsjZAI/1hHb6ev5fTt6ucuiOXDUL+/Ia7KiM7sFVRkknAArgNb1Z9VuQ23ZDHkRqevPUn3OBV7xNrS3ji0tZCYEPzsDxIf8B+v4A1z9OEbasnE1+Z8kdgooorQ4wooooAKKKKACtXwz/wAh62/4F/6Cayq1fDP/ACHrb/gX/oJpS2ZpS+OPqjtrz/VD/eqnVy8/1Q/3qp1NPY1xf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKRlV1KuoZT1BGRS0UAAAUAAAAcADtRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFADlYqeKkG19pIBKnIz2PT+tQ0oODkV0Ua7p6dBNXOW1zSp7aeW74eGSQtkdVyc8/nisivRVfdx3rn9Y8Prte4sVO7OWhHTH+z/AIfl6VpUoKS56eqEn0ZgWkqwXkEzAlY5FYgdcA5rqruJh4msJsja0bqB3yAx/wDZhXIMrIxVgVZTggjBBrtbIC8tNOuQwdoxlnb7x+Uqefr/ACow2t4+j/EGbafcX6Vwfib/AJD1z/wH/wBBFd4n3F+lcneaW2q+KrqMsUiQI0jAdtq8D3P+PpXn3tNnqV4uVOKXl+RR8PaR/aVyXmVvs0f3iONx/u5/z+GRXdIqoioihVUYAAwAKbBBFbQJDAgSNBhVHaq2qanBpdt5svzOeEjB5c/4e9ZybkzWnTjRhqQa3rMWlwYGHuHHyR/1Pt/P+XAuzO7O7FmY5JJySakuriS7uZLiU5eRix9vYe1RVtGPKjzq1Z1H5BRRRVGIUUUUAFFFFABRRRQAVv8Ag3/kLS/9cD/6EtYFb/g3/kLS/wDXA/8AoS1Mtjah/ER2lZ+sab/akEMBfYiyh3I64APA9+a0KK507HryipKzI4IIraBIYECRoMKo7VgeKNZNujWEGC8ifvG4O1T2+pH6H342dQe5Szk+xxGSdhhMFRtPqc+lccvhvVp58yxBS5JaSSQHn3wSauCW7OavKSXJBGPRW/8A8Ijf/wDPa2/76b/4mrKeDmKKXvgGxyBFkA/XNa88ThWHqvocvRXXQeD7dd32i6lf02KEx+eanTwlp6urGS4YA5Klhg+3Ape0RawtQ4qiu+/4RzSf+fT/AMiP/jViLSNOijCLZQED+8gY/meaXtEWsHPq0ec0V6ZDZ2tu5eC2hiYjBKIFOPwqel7TyKWCfWR5t/Zl/wD8+Nz/AN+m/wAK1vDml30WqQ3Mts8cSFgxf5T909jz3rsPMj/vr+dIZ41OC4/Dmk5t6WKjh6cGpORHef6of71U6s3MqPGArZOfSq1XBWRz4mSlUumFFFFWc4UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVIj9m/Oo6K0p1JU3dCauVNV0aG/VpFAjuccP2OOx/x6/yo0KKa2tZLW4I3wyHaB/dPII9ic/r6VeR8cHpUoORkV6NJwqS546Ml3RaT7i/SgKqliqgFjliB1OMc/gBQn3F+lOrwp/Ez34fCivfXsFhbNPcNtQdAOrH0HvXnuoXsuoXklxKT8x+VSc7V7AV317pdnfurXURkKDC/OwA/AGhNK09EVRZW+FGBmME/metOMlEwrUp1Xa9kecUqKzuqIpZmOAAMkmvTILW3tt32eCKLd12IFz+VTVXtPIxWC7yPNv7Mv/8Anxuf+/Tf4VYi0DVJYw62jAH+8wU/kTmvQaaXVThmAPuaXtGV9Ugt2cND4Y1OVyrxpCMZ3O4I+nGan/4RG/8A+e1t/wB9N/8AE12BmjUZLj8OaT7RF/e/Q0c0g9hQWjf4nNf8Ib/0/wD/AJB/+yqeHwhaqhE9zM7Z4KAKMfQ5rb+1x+jflSG7GeEJHuaPfC2GWv8AmZcXhTTkkDM08gH8LOMH8gDVj/hHNJ/59P8AyI/+NWmu2/hUD68003UmOij8KOWYe1w62X4BFpGnRRhFsoCB/eQMfzPNTQ2drbuXgtoYmIwSiBTj8Kr/AGiX+9+gpplkJzvb86OR9xfWqa2iaNISAMkgD3rNLFjliSfekp+z8xPG9omj5kf99fzpv2iL+9+hqhRT9miHjJ9EXTdRg8bj7gU03a4+VST78VUop+zRDxVRlo3fHCc/Wm/a5PRfyqvRT5IkPEVX1JjcS5+9j8Ka00jdXP4cVHRT5UQ6k3u2OLuRgsxHuabRRTJbb3CiiigQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU5WK02iqjJxd0BbF0gQDDZApPtf+x+tVaKzcU3dnR9ZqWsmWDdvnhVA96a1zIehA+gqGijlRDr1H1JTPKRgufwpvmSf32/OmUU7Ilzk92KTk5PWkoopkBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_55164477924b4245b737ef500a432be0" + } + }, + "a288de127d224e0e82c1712ebbf8deaf": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "a38751ef0642440ea032d88fa3c51b40": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_ccaf6040fd3442239aaf30c2b783a12c" + } + }, + "a487eb84e8204ecb917d2b7cd9b32355": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "a6e325eb84a34d7c886cc7e601eeb456": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_3e67b0173c7d4d0aa14f17cfe314c0ee" + } + }, + "a78bea59d3e24b07ba3db0ed935ee363": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "a7bd29798fd8472c9efb68a3dd2987cc": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "a9e96fb372744b529fdf439566b62018": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UF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iigAooooAKKKKACiiigAooooAKj1O1e902S3iKh3C4LdOCD/AEqSp1+6PpXZhEpOSfYmRU0uxbT7UwGYyjcWBIxgenU/5NXKKK9GMVFWRAUUUUwCiiigC0n3F+lOpqfcX6U6vmZ/Ez6GHwoKKKKkoKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAK95/qh/vVTq5ef6of71U63p7HlYv8AiBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAAaSg0V61CnyQt1O6nHliFFFFbGgUUUUAFOSm0o4NMUldFqPhBTHfPA6UO2AFB+tMrzLXk5M7oq0UgoooqigooooAKKKKACiiigAooooAjbrTkHGaGGSKdXl4j3ZNFX0CiiiucQUUUUAIelMqSmHrXRQe6PNx0dVISiiiug88KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP8AVD/eqnVy8/1Q/wB6qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANW3k82EN3HDfWpKz7GXy5tp6Px+PatEjuK7KcuZCUrOzEooorQsKKKKACiiigCUcgUUi/dFLXnyVm0dyd1cKKKKQwooooAKKKKACiiigApQMmhVz9Kk6VEpW2E2RuMACm0rnLUleXVlzTbAKKKKyAKKKQnFMAJxWNK++Vm55Oea0rlttu568Y/OsqvQwsLJsxxGlohRRRXYcoUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiii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RRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKcrFabRVRk4u6Ati6QIBhsgUn2v/AGP1qrRWbim7s6PrNS1kywbt88KoHvTWuZD0IH0FQ0UcqIdeo+pKZ5SMFz+FN8yT++350yinZEucnuxScnJ60lFFMgKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_25be8dd0b3c94728b96f4776197809fa" + } + }, + "b2604a3c2c8f4e269fd0c322dffc8e0b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b29d1852b22d4b8085ba983605d04c94": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b652f41ea28c4516a4d7a09fea6eecc9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b6b39687a287427883c31131a9b9f769": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "FloatLogSliderModel", + "state": { + "behavior": "drag-tap", + "description": "wireframe_thickness", + "layout": "IPY_MODEL_f432aafe4c29403f84c45513e18304ee", + "max": -0.4, + "min": -3, + "readout_format": ".3f", + "style": "IPY_MODEL_f0a1bf2ea9ee4df4985dee3252e798de", + "value": 0.0501187233627272 + } + }, + "b8a5514c3ef6441eabe6b134805c6bdd": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b97476a5b26741d69b598983a9f60d48": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_a78bea59d3e24b07ba3db0ed935ee363" + } + }, + "c152c49ec58846bd9ebe71b9fa88e1b6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "c29eb1dd56b94eac8a8d79fd36b76504": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "c69eefd6e3ba4c309cbe92b7ad430353": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFQ3V1DaQ+bcSBEzjJ7msS01qbUNagiQeXb5Yhe7fK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AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_883050fc8e244613b62e9aee196b7ae4" + } + }, + "c74d79409bc0415c85ff0e0ab84b90cc": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_5e1d0da65fef47868fe59005668870da" + } + }, + "c814137f17234c62af85b056cd34e3e3": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_c152c49ec58846bd9ebe71b9fa88e1b6" + } + }, + "c83af41cbb3542708293e7f95bfed76d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "cad2738b444c452ebf92880dbd7c86f1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "ccaf6040fd3442239aaf30c2b783a12c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "ccdb7dd7ad424cc295bd078a8bfe6fcb": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_b652f41ea28c4516a4d7a09fea6eecc9" + } + }, + "cf3fd1be75ab4524bfa268481d0adbe5": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "cfed2b9aa96e4204aa505002deb6e0fe": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "d19ff89eddb544b9a3265ad5d782bd1b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "d39adcded3294f6397e9601ed6533fff": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_a288de127d224e0e82c1712ebbf8deaf" + } + }, + "d659201e93404677ab5964b8d47f3efc": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UF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PQcdK2KKE2tiZQjJWkZX/COaT/z6f+RH/wAakh0LTIHLJZoSRj5yXH5HNaNFPmYvZwXRFT+zLD/nxtv+/S/4VYiijhjEcSLGg6KowB+FPopXKUUtkFFFFAwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKZ5kf8AfX86QzxqcFx+HNFmS5xW7I7z/VD/AHqp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/e/QU0yyE53t+dP2bIeMh0TNGkJAGSQB71mlixyxJPvSU/Z+ZDxvaJo+ZH/fX86b9oi/vfoaoUU/Zoh4yfRF03UYPG4+4FNN2uPlUk+/FVKKfs0Q8VUZaN3xwnP1pv2uT0X8qr0U+SJDxFV9SY3EufvY/CmtNI3Vz+HFR0U+VEOpN7tji7kYLMR7mm0UUyW29wooooEFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFOVitNoqoycXdAWxdIEAw2QKT7X/sfrVWis3FN3Z0fWalrJlg3b54VQPemtcyHoQPoKhoo5UQ69R9SUzykYLn8Kb5kn99vzplFOyJc5Pdik5OT1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_9548190091d34d27a44714164b565f8b" + } + }, + "d6f9d7e00b1e4d1b822d63b5dabee6c4": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_10785ebff0264da2a584b1cbdc280d7c" + } + }, + "d724b65f47394132bca6fee2f40b6372": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_45a32f90ecdc4264ba917e6a77b5be84" + } + }, + "d7790747ebbf424ca165460ce9d6033e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "d7995ce46a94421881e055f652521fac": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "d849a014eb9d4450b4390cc10fc7c2d2": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VISq7VJA3HABPU9f6Gs3VdZhsFaNSJLnHCdhnuf8Ov86w9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RRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU5WK02iqjJxd0BbF0gQDDZApPtf+x+tVaKzcU3dnR9ZqWsmWDdvnhVA96a1zIehA+gqGijlRDr1H1JTPKRgufwpvmSf32/OmUU7Ilzk92KTk5PWkoopkBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_687d435e027b48e984eb2789ad6f2d03" + } + }, + "db7c6da2896d474caab9f3273acd25e9": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_8f03211affc24281a3c755e1a413b5b7" + } + }, + "dbd2f3c8304f4641804ec118025a984d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "dc65a72c8e16444f9527a674358775f8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "de140a46f9804963aa30dd4770d5ea85": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoqRU7tV0xRkYKL+Ap1Iumk5Lc2o0XVvZ7GdRV/7PF/d/U0z7JH6t+dZe0Ro8JURToq2bQZ4cge4pptDj5XBPuMU+eJDw1VdCtRU5tZMdVP4037PL/d/UU+ZdyXRqL7LIqKeYpAcbG/KkZWX7ykfUU7kOLW6G0UUUyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiilAJOBTSbdkAdacxjhQyTOqKOpY4AqG7vLbTot9w+C2doAyW+grkNS1S41F/3jbYgcrGOg/xP/166lGNFXlrLsTub1vrjXmsxW1uALck5Yj5nwp/IdPfj8K3dV/5BN5/1wf/ANBNcT4e/wCQ1b/8C/8AQTXbar/yCbz/AK4P/wCgmubETlOMXLu/0O7CaKf9dzgf7Tv/APn+uf8Av63+NTw67qcCFUvHIJz84Dn8zms6iosjlU5LZmvF4m1RJAzTrIB/C0Ywfywasf8ACXX/APzxtv8Avlv/AIqsCilyrsWq1RdTqE8YsEUPYgtjkiXAJ+mKmg8YW7bvtFrKnpsYPn88VyNFLkiWsTVXU7VPFuns6qY7hQTgsVGB78GrP/CR6T/z9/8AkN/8K4Gil7NFLF1F2PRY9W02eIMLyDaezuFP5HmpYbiyuHKQS28rAZIRlY4/CvNaKPZ+ZX1tveKPTvs8X939TTTaxk8ZH0NeaIzI6ujFWU5BBwQatpqOou6ol5dMzHAAlYkn86OWXcPb0nvA742i4+ViD780htOOH5+lQ6NbXltZKL64aWU87WIOz2z1J/yPfQqOdrqdSoU5K7jYp/ZJPVfzpptpQeFB9wavVnazqUumQJMtoZ4ycOwfbs9M8Hr/AJ601OTM54alFXdxWhkXqh/DmmlHAyVYD3FZ0Pi+1ZCZ7aZGzwEIYY+pxU0XivTnkCss8YP8TIMD8iTVc0uxh7Ki9plmik/4SPSf+fv/AMhv/hU66jpkihxd2vzDPzOoP4g0c77B9Wi9pohoq1E9ndFjBJFLt6+W4OPripDbRkcAj6Gj2iD6pPdNFGirn2SP1b86b9k/2/0p88SHhaq6FWirBtHzwyke9Na2kHQA/Q0+ZEOh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91LtKqeq4zkfTmtyssYnGME99f0O7BK/OvT9TnvDOitZobu6jAncfIpHMY/xP6fiRWlq+pRaZZtIzDzWBESddzf4etWbqY29tJKsbSsikhFBJY9hwDXFT6drWrTvdS2z7icYfCbR6AE9K4l7zuzom/Yw5KauzLnnluZ3mncvI5yzHvUda8XhnVHkCtAsYP8AE0gwPyyasf8ACI3/APz2tv8Avpv/AImteZHB7Go9bMwKK6hPBzFFL3wDY5AiyAfrmpoPB9uu77RdSv6bFCY/PNLniWsNVfQ5Giu1Twlp6urGS4YA5Klhg+3Aqz/wjmk/8+n/AJEf/Gl7RFLCVH2OBor0WPSdNgiCizg2ju6Bj+Z5qWG3srdy8EVvExGCUVVOPwo9p5FfVGt5I82RWd1RFLMxwABkk1Z/sy//AOfG5/79N/hXon2iL+9+hppuoweMn6Cjml2D2FJbzOFi0DVJYw62jAH+8wU/kTmup8M2VxYafJFdR+W5lLAbgeMD0+lXzdrj5VJPvxSG744Tn60nzSWxcPYUpXUtS1WdrOmy6nAkK3ZgjBy6hN2/0zyOn+elS/a5PRfyppuZSeGA9gKShJFzxNKSs7mVD4QtVQie5mds8FAFGPoc1NF4U05JAzNPIB/CzjB/IA1daaRurn8OKaXcjBZiPc1XLLuYe1oraAz/AIRzSf8An0/8iP8A41OunaZGoQWlr8ox8yKT+JNQ0Ucj7h9ZitoItRJZ2pYQRxRbuvloBn64qQ3MYHBJ+gqjRR7NB9bnski59rj9G/Km/a/9j9aq0U+SJDxVV9Swbt88KoHvTWuZD0IH0FQ0U+VEOvUfUe8ruMM2R9KZRRVWsZuTk7thRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAkV+zVdMsYGS6/gazqKdSTqJKT2NqNZ0r2W5f+0Rf3v0NM+1x+jflVOisvZo0eLqMtm7GeEJHuaabs4+VAD7nNVqKfJEh4mq+pObqTHRR+FN+0S/3v0FRUU+VdiXWqP7THmWQnO9vzpGZm+8xP1NNop2Icm92FFFFMkKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_dbd2f3c8304f4641804ec118025a984d" + } + }, + "dfefc663d1aa478eb813d24a111499bf": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "e046c6442bc34b1eb9dfa1629f4552c3": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "edd25b2880624ccfa8df8c65afe0b939": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopyqWqybRcfKxB9+aJe6k31NKdKVS/L0KlFWjaccPz9Kb9kk9V/Op54lPD1V0K9FTG3lz93P401oZF6ofw5p8yIdOa3TI6KcUcDJVgPcU2mS01uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopaAEp6Jnk9KVE7t+VZGsa8lr5lva/PcDgt1VPX6n/PtXXToqC56v3Et9jVa5gjuI7ZnAlkBKp3IH8q0q4DQpHl16B5XZ3O7LMck/Ka7+sMXU9pGLt3/AEPQwKtzfL9TmYfGELORPZui44KOGOfocVP/AMJdYf8APG5/75X/AOKri6Kw5ImSxVTud9/wkek/8/f/AJDf/CpodZ02dCyXsIAOPnbYfyOK87opezRaxk+qR6ZDeWtw5SC5hlYDJCOGOPwqevLKKXs/MpY19YnqHlx/3F/KkMEbHJQfhxXnX9p3/wDz/XP/AH9b/Gp4dd1OBCqXjkE5+cBz+ZzRyS7j+s0nvE7w20ZHAI+hpptExwzZri4vE2qJIGadZAP4WjGD+WDVj/hLr/8A5423/fLf/FUcs+4e1w73idV9k/2/0pptHzwyke9YCeMWCKHsQWxyRLgE/TFTQeMLdt32i1lT02MHz+eKPfC2Gf8ATNdraQdAD9DSGCUDJQ/hVBPFuns6qY7hQTgsVGB78GrP/CR6T/z9/wDkN/8ACjml2F7Gg9pEnlyf3G/KmkYOD1qaLV9OljDrewAH+84U/keangure53fZ54pdvXY4bH5Ue0fVB9Vg9pFGitIorHLKCfcU0wxsMFB+HFHtEJ4OXRmfRV/7PF/d/U0z7JH6t+dP2iIeEqIp0VbNoM8OQPcU1rRv4WB+vFPniQ8NVXQrUVObWTHVT+NN+zy/wB39RT5l3JdGovssiop5ikBxsb8qaVKnDAg+9VczcWt0JRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiinKpY8U0nJ2QCAZOBT2McCGSV1RR1ZjgCiV1treSVgSsaljjqcDNcVqeqz6kwEmEiU5WNen1Pqa7FGOHXNLWRO5e1jXmule3tQUhJwz93H9B/n2rDoorlnOU3eRSVjS8Pf8hq3/wCBf+gmvQa8+8Pf8hq3/wCBf+gmvQazq/BH1f6Hdgt5fL9TyyiiimcIUUUUAFFFFABRRRQAUUUUAFFFFABRRUkEEtzOkMCF5HOFUd6A3JLGynv7lYLddznqT0Uep9q77S9Mg0u28qL5nPLyEcuf8Pao9E0tdLs/LLB5XO6RgO/oPYf4+tS6pqEWmWZuJQW52oo/ib09ulYSlzOyPUo0VSjzy3LlFc74WvZ7+5v57htzny8AdFHzcD2roqlqzsb05qceZBXL6rqOraLeDdMlxBID5fmIB6dduOR+XP5WtL1pf7TurC6kO77Q4hZjxjd93/D8vSta+soL+2aC4Xch6EdVPqPemvdepnL97G8HZnJ/8Jdf/wDPG2/75b/4qrX/AAmX/Th/5G/+xrn9QspdPvJLeUH5T8rEY3L2IqtWvLFnn+3qxdrnYQ+L7VkJntpkbPAQ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Xf8AmR/31/OkM8anBcfhzRzy7D+rUlvI4eLwzqjyBWgWMH+JpBgflk1Y/wCERv8A/ntbf99N/wDE11xuYwOCT9BTTdpjhWzRzT7B7LDreRzieDmKKXvgGxyBFkA/XNTQeD7dd32i6lf02KEx+ea2/tf+x+tNN2+eFUD3o98L4Zf0zNTwlp6urGS4YA5Klhg+3Aqz/wAI5pP/AD6f+RH/AMana5kPQgfQUhnlIwXP4Ucsu4vbUFtEdFpGnRRhFsoCB/eQMfzPNTwWtvbbvs8EUW7rsQLn8qqeZJ/fb86aTk5PWj2b6sPrUFtE0S6qcMwB9zTTNGoyXH4c1n0UezQnjJdEX/tEX979DTPtcfo35VTop+zRDxdRls3YzwhI9zTWu2/hUD681Wop8kSHiar6k5upMdFH4U37RL/e/QVFRT5V2Jdao/tMeZZCc72/OmlixyxJPvSUVVjNyb3YUUUUCCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBysVqybtcfKpJ9+KqUUS95JPoaU6sqd+XqWjd8cJz9ab9rk9F/Kq9FTyRKeIqvqTG4lz97H4U1ppG6ufw4qOinyoh1JvdscXcjBZiPc02iimS23uFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_cf3fd1be75ab4524bfa268481d0adbe5" + } + }, + "eddd2bdec793468ba5645a5eeb859468": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "ee7eb3a7bd584def8d242b9d7b76d100": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_d7790747ebbf424ca165460ce9d6033e" + } + }, + "f05d0264cb5b449b9543509c2bedc711": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_572f59892959494ca9ebeefdfd5c80af" + } + }, + "f0a1bf2ea9ee4df4985dee3252e798de": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "SliderStyleModel", + "state": { + "description_width": "" + } + }, + "f0f302daf7614dff902bc48644733b95": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_f27ccad7a18f4136b1ad6cde41a06b5a" + } + }, + "f27ccad7a18f4136b1ad6cde41a06b5a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "f432aafe4c29403f84c45513e18304ee": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "fd74b845a9f242c5969dee72199a79bc": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VWudTt7a5itQd87uq7B/CCepP9PpWZq3iIJmGwOXBwZcAj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1pKKKZAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q==", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_076373e179904a4ea7bb68807ef129a9" + } + }, + "fd76f2be3af54b05977e47137750f95f": { + "buffers": [ + { + "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAIABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKcqlqqMXJ2QDaKti1QoDlskUn2T/b/Ss3JJ2Z0fVqlrpFWirBtHzwyke9Na2kHQA/Q0cyIdCouhDRUpglAyUP4U3y5P7jflTuiXCS3QyilIwcHrSUyAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkRO7flWlOnKo7ITdhETPJ6VKBgYFFFerSoxprQhu5aT7i/SnU1PuL9KdXz0/iZ9BD4UFFFFSUFFFFABTSiscsoJ9xTqKAaT3IzDGwwUH4cUn2eL+7+pqWindkOnB7pFf7JH6t+dIbQZ4cge4qzRT55EPD030KjWjfwsD9eKabWTHVT+NXaKftGQ8LTKH2eX+7+oppikBxsb8q0aKftGQ8HDo2ZhUqcMCD70lalIQCMEAj3p+08iHgu0jMorR8uP+4v5U37PF/d/U0/aIh4OfRlCirptYyeNw9gaabRcfKxB9+aftEQ8LURUoq0bTjh+fpTfsknqv50+eJDw9VdCvRUxt5c/dz+NNaGReqH8OafMiHTmt0yOinFHAyVYD3FNpktNbhRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKCQoySAPU0AFFAIIyORRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgZOBSqpY8VKqhRXRRoSqa9BN2EVNvPenUUV6kIKCtEgKKKKoRaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAM8uP+4v5UhgjY5KD8OKkoouyXCL3RUuYkSMFVwc+tVquXn+qH+9VOt4O6PLxMVGpZIKKKKs5wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiimvIkYy7AU0m9ENJvRDqR3VFyxAHvVOS9J4jXA9T1qs7s7ZYkn3rqhhZP4tDqhhZP4tC5JegcRrk+p6VVd3kOXYk00CiuhU4Q+FHfSoRp6pD45XiOVP4HpV6G5SU4+63oazqCM1lVoqWq3Crh4VNdma1FUIbx0OJfmX171eR1ddyEEe1cTTWjPLq0Z0nqLRRRSMQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnKhb6U2p1+6PpXThqSqS16CbsAAAwKWiivVSS0RmFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/3qp1cvP9UP96qdb09jysX/ABAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio5Z44vvHJ9B1pqLk7Iai5OyJKZJMkQ+dufTvVKW7kfhfkHt1/OoCSTknJNdcMK3rI64YVvWRZkvHY/uxtH5mqxJY5Ykn1NJRXZCnGHwo7IU4w+FBTgKQClolLojaK6hRRRUFhRSgEkADJPQCpktJ3ziJuPXj+dJtLcCAjNCs8TbkODVxdOnK5JRT6E1L/Ziry8pK+gXFc9T2c+uoOzVmRwXiv8smFb17VZqnLYgE+W/4NTUM9twVLIM8D/PFcV1exw1sFf3qf3F6imRTJMMqefQ9afTPNlFxdmFFFFAgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/wBUP96qdXLz/VD/AHqp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAPIwec0xraFjkxj8OKcaep4r18PT5IWe51qLhHQqtYIR8rsD781G1g4PyupHvxV+it7FKtNdTKa2mUZMZ/DmhLWdyAIn59RitWrC8KB7VzV6jppWOqhNzbuZKafO2chV+p6/lUq6W235pQD6Bc1pUVxOtNnUVE06BTk7m9if8KlS1gQYES/iM/zqaioc5PdgIAAAAMAdAKWikJwMmpACQBk1CzFjzQzFjzSVtGNgGP1ptPfpTK46ytM0jsMeJHbdjDf3gcGnrkDBO73oorNSaM6lGFRe8haKSirU+5wzwH8j+8Wigc0VaaexwVKU6btJBRRRTMwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP96qdXLz/AFQ/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACg0Uhrow9Pnnd7I1pR5pBSr1pKB1r1DsaurElFFFWc4Dk4qzVdOWH1qxXn4x6pHbhVo2FFFFcR1hRRSE4GTQAE4GTULtuPtQ7bj7UlbwhbVgFFFFWAh5FR1LUR61y4hbMuIUUUVylBRRQBk4oAeg70h608cCmt1pUpe8efjY80ObsNooorpPJCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqdfuj6VBU6/dH0rtwfxMmQtFFFeiQFFFFABRRRQBaT7i/SnU1PuL9KdXzM/iZ9DD4UFFFFSUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAFe8/1Q/wB6qdXLz/VD/eqnW9PY8rF/xAoooqzmCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooADSUGivWoU+SFup3U48sQooorY0Hr0paavWnVSMJqzHR/fFT1DF94n2qavNxTvUO7DK0AoopK5ToConbceOlDvu4HSm1tCNtWAUUUVoAUUUUAFMfrT6a/SsqyvAcdxlFFFcBoFPQd6YBk4qWom+gmwpG6UtFZxdncxqR54uJHRS0ld54AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUGikNdGHp887vZGtKPNIKKKK9Q7QooooABwakqOnryKaM6i6k0XQmpKZF938afXlV3eozuoq1NCVE77uB0pXfPA6UyiEerNQooorQAooooAKKKKACkboaWik1dWAiooPWgDJxXmPQ1HoO9OoorBu7uQwooopCGN1pKc1Nrtpu8UeJiIclRoKKKKswCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAA0lBor1qFPkhbqd1OPLEKKKK2NAooooAKclNpRwaYpK6LUfCCmO+eB0odsAKD9aZXmWvJyZ3RVopBRRRVFBRRRQAUUUUAFFFFABRRRQBG3WnIOM0MMkU6vLxHuyaKvoFFFFc4gooooAQ9KZUlMPWuig90ebjo6qQlFFFdB54UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/AIgUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBq28nmwhu44b61JWfYy+XNtPR+Px7VokdxXZTlzISlZ2YlFFFaFhRRRQAUUUUASjkCikX7opa8+Ss2juTurhRRRSGFFFFABRRRQAUUUUAFKBk0KufpUnSolK2wmyNxgAU2lc5akry6suabYBRRRWQBRRSE4pgBOKxpX3ys3PJzzWlcttt3PXjH51lV6GFhZNmOI0tEKKKK7DlCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/AHqp1cvP9UP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0aJHcUlPppHpXZcIz6MSiiig0CiiigB6fdp1Mj70+uKorTZ2U3eKCiiisywooooAKKKAM0AFPVe5pVXH1paylPsS2FFFI3Cms27K4iI8nNFFFeaUFFFJSAKaTmgnNFaxjY1jGxT1BvlROOTk1Rqe7ffcNzkDgVBXqUo8sEefWlzTbCiiitDIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANe2l86EMeo4P1qWsyxl8ubaej8fj2rTrrpy5kYyVmNI7ikp9NI7itEy4T6MSiiimajk60+o0+9UlclZe8dVJ+6FFFFYmoUUU5Vz16Um7AIATTwAOlL0orKUrkt3CiiipEFMk6AU+o5D81Y1naAIbRRRXCUFNJoJ7UlaRj1NIx6hTWYKpY9AM06q965W3IH8RxW0VzSSKnLli2ZxJJyTkmkoor0zyQooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKnX7o+lQVOv3R9K7cH8TJkLRRRXokBRRRQAUUUUAWk+4v0p1NT7i/SnV8zP4mfQw+FBRRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBXvP9UP8AeqnVy8/1Q/3qp1vT2PKxf8QKKKKs5gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACte2l86EMeo4P1rIqzYy+XNtPR+Px7VpTlZkyV0adFFFdZkNI7ikp9NI7ihM0hPoxF+8KlqKpa5661TO6i9GFFAGTUirj61yykkbN2EVfWnUUVk22QFFFFIAooooAKhJyTUrHAJqKuXEPZDQUhOKCcU2sIxvqaRjfUKKKK1NQqhftmRV44FX6yZn3zO2cgnj6V0YeN5XObEytG3cjooortOAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFTr90fSu3B/EyZC0UUV6JAUUUUAFFFFAFpPuL9KdTU+4v0p1fMz+Jn0MPhQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV7z/VD/eqnVy8/wBUP96qdb09jysX/ECiiirOYKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA17aXzoQx6jg/Wpay7OdYZDvYKhHJPQe9TS6xp8LBWukJIz8mWH5iuuErrUzcHfRF6isKXxPbhR5NvK7Z6OQox+tVZfE9wWHk28SLjo5LHP6VXMi1Qm+h0pHcVKoLAVw0usahMoVrpwAc/JhT+YpkeqahE4dLybI7M5YfkeKxqe+rI6qUJQWp34AHSlriofE2oxbt7RzZ6b0xj8sVcj8XSCMCWzVn7lZNo/LB/nXM8PM0udTRWND4n06RyH82IYzudMj6cZq5Dq+nTIWS8iABx87bD+RxWTpyW6C5dopFZXQMjBlYZBByCKWpGFFFFADZD8tRE4p8h5qInNcVT3plxjcDzRVW4v7a2bY75kwcRoNzdM9B0/GojqDMPli288bjk/p/jW0aE2r20LlUhDdl+opLiKPq4z6Dms55pJPvOSPTtUdbRw38zOaWK/lRckvieI1wPU9ap0UV0RhGOxzznKe4UUUVRAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFTr90fSoKnX7o+lduD+JkyFooor0SAooooAKKKKALSfcX6U6mp9xfpTq+Zn8TPoYfCgoooqSgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr3n+qH+9VOrl5/qh/vVTrenseVi/4gUUUVZzBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUFxZw3HLrhv7y8Gp6KBptbGJcabNDyn71f9kc/lVMgqSCCCOCDXT1FPbQ3AxIgJ7MOoq1PubRrPqc5RWhPpUqHMJEi+h4IqgysjFXUqw7EYNWmmbqSlsNIpKdSEVpGXQUl1EooorQgVWZHDIxVlOQQcEGrsOs6jBu2Xch3dd53/zziqNFS4p7gbUfijUEjCssMhH8TIcn8iBV+LxajSAS2bKncq+4/lgfzrlwCTgVPBA8jbY13NRHDQnq1ZA5WOgu/EoYn7NAeR1kPQ/Qf41SE+oajkyTNHCc/d4H0wOv406105I/mmw7en8NXazfsKWlKOvdmcqsnoRQW0duuEHPdj1NS0UVhKTk7sxCiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVOv3R9Kgqdfuj6V24P4mTIWiiivRICiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUyaCKddsqBh+op9FAbGTPpLAkwOGH91utUJInifbIpVvQ10tNkiSVNsihl9DVqb6m0azW5zBFJWxPpKkEwOVP91ulZk8EsDYlQr/I1vCaehpeMtiKlVSxqe1tJblvkGF7selbVtZRW2Co3OP4jVucY/ERKaRRtdMZsGX5F9P4jWpHGkS7Y1Cj2p1Fc9SrKpvsYtthRRRWQgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACp1+6PpUFOVyv0rpw1VU5a9RNXJqKQEEZFLXqpp6ozCiiigAooooAtJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCvef6of71U6uXn+qH+9VOt6ex5WL/iBRRRVnMFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMqupV1DKeoIyKWigAACgAAADgAdqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAcrFTxUqsGFQUoODkV0Ua8qenQTVyeimq+7jvTq9SE1NXiQFFFFUItJ9xfpTqan3F+lOr5mfxM+hh8KCiiipKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimeZH/fX86QzxqcFx+HNFmS5xW7I7z/AFQ/3qp1ZuZUeMBWyc+lVq3grI8vEyUql0woooqznCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpEfs351HRWlOpKm7oTVyxRUSPjg9KlByMivVpVo1FoQ1YtJ9xfpTqan3F+lOr56fxM+gh8KCiiipKCiiigAooppdVOGYA+5oBtLcdRUZmjUZLj8OaT7RF/e/Q07Mh1ILdoloqv9rj9G/KkN2M8ISPc0+SRDxFNdSzRVRrtv4VA+vNNN1Jjoo/Cn7NkPFUy7RVD7RL/AHv0FNMshOd7fnT9myHjIdEzRpCQBkkAe9ZpYscsST70lP2fmQ8b2iaPmR/31/Om/aIv736GqFFP2aIeMn0RdN1GDxuPuBTTdrj5VJPvxVSin7NEPFVGWjd8cJz9ab9rk9F/Kq9FPkiQ8RVfUmNxLn72PwprTSN1c/hxUdFPlRDqTe7Y4u5GCzEe5ptFFMltvcKKKKBBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTlYrTaKqMnF3QFsXSBAMNkCk+1/7H61VorNxTd2dH1mpayZYN2+eFUD3prXMh6ED6CoaKOVEOvUfUlM8pGC5/Cm+ZJ/fb86ZRTsiXOT3YpOTk9aSiimQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9k=", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_570818bdbfe7490abbd09a27602e7dde" + } + } + }, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/anigen/representations/mesh/flexicubes/examples/loss.py b/anigen/representations/mesh/flexicubes/examples/loss.py new file mode 100644 index 0000000000000000000000000000000000000000..ba507f081d5a00229abb9f683f82ede735e153c4 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/loss.py @@ -0,0 +1,95 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +import torch +import torch_scatter + +############################################################################### +# Pytorch implementation of the developability regularizer introduced in paper +# "Developability of Triangle Meshes" by Stein et al. +############################################################################### +def mesh_developable_reg(mesh): + + verts = mesh.vertices + tris = mesh.faces + + device = verts.device + V = verts.shape[0] + F = tris.shape[0] + + POS_EPS = 1e-6 + REL_EPS = 1e-6 + + def normalize(vecs): + return vecs / (torch.linalg.norm(vecs, dim=-1, keepdim=True) + POS_EPS) + + tri_pos = verts[tris] + + vert_normal_covariance_sum = torch.zeros((V, 9), device=device) + vert_area = torch.zeros(V, device=device) + vert_degree = torch.zeros(V, dtype=torch.int32, device=device) + + for iC in range(3): # loop over three corners of each triangle + + # gather tri verts + pRoot = tri_pos[:, iC, :] + pA = tri_pos[:, (iC + 1) % 3, :] + pB = tri_pos[:, (iC + 2) % 3, :] + + # compute the corner angle & normal + vA = pA - pRoot + vAn = normalize(vA) + vB = pB - pRoot + vBn = normalize(vB) + area_normal = torch.linalg.cross(vA, vB, dim=-1) + face_area = 0.5 * torch.linalg.norm(area_normal, dim=-1) + normal = normalize(area_normal) + corner_angle = torch.acos(torch.clamp(torch.sum(vAn * vBn, dim=-1), min=-1., max=1.)) + + # add up the contribution to the covariance matrix + outer = normal[:, :, None] @ normal[:, None, :] + contrib = corner_angle[:, None] * outer.reshape(-1, 9) + + # scatter the result to the appropriate matrices + vert_normal_covariance_sum = torch_scatter.scatter_add(src=contrib, + index=tris[:, iC], + dim=-2, + out=vert_normal_covariance_sum) + + vert_area = torch_scatter.scatter_add(src=face_area / 3., + index=tris[:, iC], + dim=-1, + out=vert_area) + + vert_degree = torch_scatter.scatter_add(src=torch.ones(F, dtype=torch.int32, device=device), + index=tris[:, iC], + dim=-1, + out=vert_degree) + + # The energy is the smallest eigenvalue of the outer-product matrix + vert_normal_covariance_sum = vert_normal_covariance_sum.reshape( + -1, 3, 3) # reshape to a batch of matrices + vert_normal_covariance_sum = vert_normal_covariance_sum + torch.eye( + 3, device=device)[None, :, :] * REL_EPS + + min_eigvals = torch.min(torch.linalg.eigvals(vert_normal_covariance_sum).abs(), dim=-1).values + + # Mask out degree-3 vertices + vert_area = torch.where(vert_degree == 3, torch.tensor(0, dtype=vert_area.dtype,device=vert_area.device), vert_area) + + # Adjust the vertex area weighting so it is unit-less, and 1 on average + vert_area = vert_area * (V / torch.sum(vert_area, dim=-1, keepdim=True)) + + return vert_area * min_eigvals + +def sdf_reg_loss(sdf, all_edges): + sdf_f1x6x2 = sdf[all_edges.reshape(-1)].reshape(-1,2) + mask = torch.sign(sdf_f1x6x2[...,0]) != torch.sign(sdf_f1x6x2[...,1]) + sdf_f1x6x2 = sdf_f1x6x2[mask] + sdf_diff = torch.nn.functional.binary_cross_entropy_with_logits(sdf_f1x6x2[...,0], (sdf_f1x6x2[...,1] > 0).float()) + \ + torch.nn.functional.binary_cross_entropy_with_logits(sdf_f1x6x2[...,1], (sdf_f1x6x2[...,0] > 0).float()) + return sdf_diff \ No newline at end of file diff --git a/anigen/representations/mesh/flexicubes/examples/optimization.ipynb b/anigen/representations/mesh/flexicubes/examples/optimization.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..21f153b3ad77829b19ec5884716206216734c34d --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/optimization.ipynb @@ -0,0 +1,801 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Gradient-Based Mesh Optimization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "FlexiCubes is an isosurface representation designed for gradient-based mesh optimization, where we iteratively\n", + "optimize for a 3D surface mesh by representing it as the isosurface of a scalar field. Essentially, this paradigm allows objectives to be directly evaluated on the extracted surface, while offering the flexibility to optimize over meshes with different topologies.\n", + "\n", + "In this tutorial, we demonstrate how to reconstruct an unknown mesh using multiview masks and depth supervision with FlexiCubes. Note that in our paper, we demonstrate more objectives that FlexiCubes can optimize for a variety of applications." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We begin by importing the necessary packages and defining the hyperparameters for optimization." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import tqdm\n", + "import numpy as np\n", + "import kaolin as kal\n", + "from matplotlib import pyplot as plt\n", + "\n", + "import render\n", + "import loss\n", + "\n", + "iter = 1000\n", + "batch = 8\n", + "train_res = [2048, 2048]\n", + "learning_rate = 0.01\n", + "voxel_grid_res = 64\n", + "device = 'cuda'\n", + "sdf_regularizer = 0.2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we load the reference mesh and initialize a FlexiCubes object. We will be optimizing its SDF, weights, and deformations to fit the reference mesh. In this example, we are directly applying gradient descents on these parameters. Alternatively, you can parameterize them using a network of your choice and optimize the network weights instead (Please refer to the GET3D GitHub page for more details)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "gt_mesh = kal.io.obj.import_mesh('data/inputmodels/block.obj').cuda()\n", + "vertices = gt_mesh.vertices\n", + "vmin, vmax = vertices.min(dim=0)[0], vertices.max(dim=0)[0]\n", + "scale = 1.8 / torch.max(vmax - vmin).item()\n", + "vertices = vertices - (vmax + vmin) / 2 # Center mesh on origin\n", + "gt_mesh.vertices = vertices * scale # Rescale to [-0.9, 0.9]\n", + "\n", + "fc = kal.non_commercial.FlexiCubes(device)\n", + "x_nx3, cube_fx8 = fc.construct_voxel_grid(voxel_grid_res)\n", + "x_nx3 *= 2 # scale up the grid so that it's larger than the target object\n", + "sdf = torch.rand_like(x_nx3[:,0]) - 0.1 # randomly initialize SDF\n", + "sdf = torch.nn.Parameter(sdf.clone().detach(), requires_grad=True)\n", + "# set per-cube learnable weights to zeros\n", + "weight = torch.zeros((cube_fx8.shape[0], 21), dtype=torch.float, device='cuda') \n", + "weight = torch.nn.Parameter(weight.clone().detach(), requires_grad=True)\n", + "\n", + "# Retrieve all the edges of the voxel grid; these edges will be utilized to \n", + "# compute the regularization loss in subsequent steps of the process.\n", + "all_edges = cube_fx8[:, fc.cube_edges].reshape(-1, 2) \n", + "grid_edges = torch.unique(all_edges, dim=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now do random initiation for the optimization" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "deform = torch.nn.Parameter(torch.zeros_like(x_nx3), requires_grad=True)\n", + "grid_verts = x_nx3 + (2-1e-8) / (voxel_grid_res * 2) * torch.tanh(deform) # apply deformation to the grid vertices\n", + "vertices, faces, L_dev = fc(\n", + " grid_verts, sdf, cube_fx8, voxel_grid_res, beta=weight[:,:12], alpha=weight[:,12:20],\n", + " gamma_f=weight[:,20], training=False) # run isosurfacing to extract the mesh\n", + "init_mesh = kal.rep.SurfaceMesh(vertices=vertices, faces=faces)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's extract the meshes from the initial FlexiCubes grid to see what it looks like. The initial mesh topology (on the left) is very different from our reference (on the right). Don't worry, it will converge to the reference in the end! " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "camera = render.get_rotate_camera(0)\n", + "f, ax = plt.subplots(1, 2)\n", + "output = render.render_mesh(init_mesh, camera, [512, 512], return_types=['normals'])\n", + "ax[0].imshow(((output['normals'][0] + 1) / 2.).cpu().detach())\n", + "output = render.render_mesh(gt_mesh, camera, [512, 512], return_types=['normals'])\n", + "ax[1].imshow(((output['normals'][0] + 1) / 2.).cpu().detach())\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also visualize interactively with [kaolin's interactive visualizer](https://kaolin.readthedocs.io/en/latest/modules/kaolin.visualize.html), by moving around the camera and adjusting a wireframe to see the topology of the meshes." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d8848758a62646579a83b9512be4164f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Canvas(height=512, width=1024), interactive(children=(FloatLogSlider(value=0.3981071705534972, โ€ฆ" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8045d576349a4b9485522790f58ad90d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render.SplitVisualizer(init_mesh, gt_mesh, 512, 512).show(camera)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The last thing before we start the optimization is to set up the optimizers and a differentiable renderer." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def lr_schedule(iter):\n", + " return max(0.0, 10 ** (-(iter) * 0.0002)) # Exponential falloff from [1.0, 0.1] over 5k epochs. \n", + "optimizer = torch.optim.Adam([sdf, weight, deform], lr=learning_rate)\n", + "scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda x: lr_schedule(x)) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's execute the actual optimization loop. At every iteration, we perform the following steps:\n", + "\n", + "* Sample random camera poses to render both the reference and ground truth images.\n", + "* Extract the mesh with FlexiCubes, as we did above.\n", + "* Render the meshes and evaluate the reconstruction and regularization losses (please see inline comments for more details)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 1000/1000 [01:21<00:00, 12.34it/s]\n" + ] + } + ], + "source": [ + "intermediate_results = [init_mesh]\n", + "for it in tqdm.tqdm(range(iter)): \n", + " optimizer.zero_grad()\n", + " # sample random camera poses\n", + " cameras = render.get_random_camera_batch(batch, iter_res=train_res, device=device)\n", + " \n", + " # render gt mesh at sampled views\n", + " target = render.render_mesh(gt_mesh, cameras, train_res)\n", + "\n", + " # extract and render FlexiCubes mesh\n", + " grid_verts = x_nx3 + (2-1e-8) / (voxel_grid_res * 2) * torch.tanh(deform)\n", + " vertices, faces, L_dev = fc(\n", + " grid_verts, sdf, cube_fx8, voxel_grid_res, beta=weight[:,:12], alpha=weight[:,12:20],\n", + " gamma_f=weight[:,20], training=True)\n", + " flexicubes_mesh = kal.rep.SurfaceMesh(vertices=vertices, faces=faces)\n", + " buffers = render.render_mesh(flexicubes_mesh, cameras, train_res)\n", + "\n", + " # evaluate reconstruction loss\n", + " mask_loss = (buffers['mask'] - target['mask']).abs().mean() # mask loss\n", + " depth_loss = (((((buffers['depth'] - (target['depth']))* target['mask'])**2).sum(-1)+1e-8)).sqrt().mean() * 10 # depth loss\n", + " # evaluate regularization losses\n", + " t_iter = it / iter\n", + " # this is the regularization loss described in Equation 2 of the nvdiffrec paper by Munkberg et al., which serves to remove internal floating elements that are not visible to the user.\n", + " sdf_weight = sdf_regularizer - (sdf_regularizer - sdf_regularizer/20)*min(1.0, 4.0 * t_iter)\n", + " reg_loss = loss.sdf_reg_loss(sdf, grid_edges).mean() * sdf_weight \n", + "\n", + " reg_loss += L_dev.mean() * 0.5 # L_dev as in Equation 8 of our paper\n", + " reg_loss += (weight[:,:20]).abs().mean() * 0.1 # regularize weights to be zeros to improve the stability of the optimization process\n", + " total_loss = mask_loss + depth_loss + reg_loss\n", + " total_loss.backward()\n", + " optimizer.step()\n", + " scheduler.step()\n", + " if (it + 1) % 20 == 0: # save intermediate results every 100 iters\n", + " with torch.no_grad():\n", + " # run the mesh extraction again with the parameter 'training=False' so that each quadrilateral face is divided into two triangles, as opposed to the four triangles during the training phase.\n", + " vertices, faces, L_dev = fc(\n", + " grid_verts, sdf, cube_fx8, voxel_grid_res, beta=weight[:,:12], alpha=weight[:,12:20], gamma_f=weight[:,20], training=False)\n", + " intermediate_results.append(kal.rep.SurfaceMesh(vertices, faces))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's now visualize how the isosurface of FlexiCubes evolves during optimization. As you can see, it converges smoothly to the reference mesh, successfully recovering all sharp features." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAa4AAAGiCAYAAAC/NyLhAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8WgzjOAAAACXBIWXMAAA9hAAAPYQGoP6dpAACL1UlEQVR4nO39eZhcV33nj7/OuVXVm9Qta7dsywtehTewwW62JFixYxwCwfP9Er4e8GR4kl8YmSfgDBOcIayTmIeZJyRkDJlnhoHMTBgHZ1gyBowXwCyWF2QbvGDhDUteJNmSpZZa3dVV935+f5y7162tu3op6fPyU1b1veeee+6pe8/7fD7nc841IiIoiqIoSp9gF7sAiqIoitINKlyKoihKX6HCpSiKovQVKlyKoihKX6HCpSiKovQVKlyKoihKX6HCpSiKovQVKlyKoihKX6HCpSiKovQVKlyKoihKX7FownXDDTdw0kknMTg4yEUXXcS99967WEVRFEVR+ohFEa5//Md/5Nprr+VjH/sY999/P+eddx6XXXYZe/bsWYziKIqiKH2EWYxFdi+66CJe85rX8J//838GIAgCTjjhBN7//vfz4Q9/eKGLoyiKovQRpYU+4czMDNu2beO6666Lt1lr2bx5M1u3bi08plqtUq1W47+DIGDfvn2sWrUKY8y8l1lRFEXpLSLCwYMH2bBhA9Z25/xbcOF66aWX8H2fdevWZbavW7eOxx57rPCY66+/nk984hMLUTxFURRlAdm5cyfHH398V8csuHDNhuuuu45rr702/vvAgQNs3LiRD37wgwwMDCxiyRRFUZTZUK1W+exnP8vy5cu7PnbBhWv16tV4nsfu3bsz23fv3s369esLjxkYGCgUqGbbFUVRlP5gNsM9Cx5VWKlUuOCCC7jjjjvibUEQcMcddzA+Pr7QxVEURVH6jEVxFV577bVcffXVXHjhhbz2ta/lr//6r5mcnOT3f//3F6M4iqIoSh+xKML1zne+kxdffJGPfvSj7Nq1i/PPP59bbrmlIWBDURRFUfIsWnDGNddcwzXXXLNYp1cURVH6FF2rUFEURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekrVLgURVGUvkKFS1EURekruhauH/7wh7z1rW9lw4YNGGP4xje+kdkvInz0ox/l2GOPZWhoiM2bN/P4449n0uzbt4+rrrqK0dFRVqxYwXvf+14OHTo0pwtRFEVRjg66Fq7JyUnOO+88brjhhsL9n/nMZ/jc5z7H3/3d33HPPfcwMjLCZZddxvT0dJzmqquu4pFHHuG2227j5ptv5oc//CF/+Id/OPurUBRFUY4aSt0ecPnll3P55ZcX7hMR/vqv/5qPfOQjvO1tbwPgf/yP/8G6dev4xje+we/93u/xi1/8gltuuYX77ruPCy+8EIC//du/5S1veQv/6T/9JzZs2DCHy1EURVGOdHo6xvX000+za9cuNm/eHG8bGxvjoosuYuvWrQBs3bqVFStWxKIFsHnzZqy13HPPPYX5VqtVJiYmMh9FURTl6KSnwrVr1y4A1q1bl9m+bt26eN+uXbtYu3ZtZn+pVGLlypVxmjzXX389Y2Nj8eeEE07oZbEVRVGUPqIvogqvu+46Dhw4EH927ty52EVSFEVRFomeCtf69esB2L17d2b77t27433r169nz549mf31ep19+/bFafIMDAwwOjqa+SiKoihHJz0VrpNPPpn169dzxx13xNsmJia45557GB8fB2B8fJz9+/ezbdu2OM33vvc9giDgoosu6mVxFEVRlCOQrqMKDx06xBNPPBH//fTTT/Pggw+ycuVKNm7cyAc+8AH+w3/4D5x2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PPzww/Lggw/KW97yFtm4caMcOnQoTvNHf/RHcsIJJ8gdd9whP/3pT+Xiiy+W173udfH+er0uZ599tmzevFkeeOAB+fa3vy2rV6+W6667bjEuqaf88z//s3zrW9+SX/7yl7J9+3b5sz/7MymXy/Lwww+LyNFdN3nuvfdeOemkk+Tcc8+VP/7jP463H8119LGPfUxe+cpXygsvvBB/XnzxxXj/QtZN3wnXa1/7WtmyZUv8t+/7smHDBrn++usXsVQLT164giCQ9evXy3/8j/8x3rZ//34ZGBiQ//2//7eIiDz66KMCyH333Ren+c53viPGGHnuuecWrOwLxZ49ewSQO++8U0RcfZTLZbnpppviNL/4xS8EkK1bt4qI6xxYa2XXrl1xmi984QsyOjoq1Wp1YS9gATjmmGPkv/23/6Z1k+LgwYNy2mmnyW233Sa/9mu/FgvX0V5HH/vYx+S8884r3LfQddNXrsKZmRm2bdvG5s2b423WWjZv3szWrVsXsWSLz9NPP82uXbsydTM2NsZFF10U183WrVtZsWIFF154YZxm8+bNWGu55557FrzM882BAweAZFHmbdu2UavVMnV05plnsnHjxkwdnXPOOaxbty5Oc9lllzExMcEjjzyygKWfX3zf58Ybb2RycpLx8XGtmxRbtmzhiiuuyNQF6P0D8Pjjj7NhwwZOOeUUrrrqKnbs2AEsfN301SK7L730Er7vZy4cYN26dTz22GOLVKqlwa5duwAK6ybat2vXLtauXZvZXyqVWLlyZZzmSCEIAj7wgQ/w+te/nrPPPhtw11+pVFixYkUmbb6Oiuow2tfvPPTQQ4yPjzM9Pc2yZcv4+te/zqZNm3jwwQeP+roBuPHGG7n//vu57777GvYd7ffPRRddxJe//GXOOOMMXnjhBT7xiU/wxje+kYcffnjB66avhEtROmXLli08/PDD/PjHP17soiwpzjjjDB588EEOHDjAP/3TP3H11Vdz5513LnaxlgQ7d+7kj//4j7ntttsYHBxc7OIsOS6//PL4+7nnnstFF13EiSeeyFe/+lWGhoYWtCx95SpcvXo1nuc1RKrs3r2b9evXL1KplgbR9beqm/Xr17Nnz57M/nq9zr59+46o+rvmmmu4+eab+f73v595Qd369euZmZlh//79mfT5Oiqqw2hfv1OpVDj11FO54IILuP766znvvPP4m7/5G60bnLtrz549vPrVr6ZUKlEqlbjzzjv53Oc+R6lUYt26dUd9HaVZsWIFp59+Ok888cSC3z99JVyVSoULLriAO+64I94WBAF33HEH4+Pji1iyxefkk09m/fr1mbqZmJjgnnvuietmfHyc/fv3s23btjjN9773PYIg4KKLLlrwMvcaEeGaa67h61//Ot/73vc4+eSTM/svuOACyuVypo62b9/Ojh07MnX00EMPZQT+tttuY3R0lE2bNi3MhSwgQRBQrVa1boBLLrmEhx56iAcffDD+XHjhhVx11VXx96O9jtIcOnSIJ598kmOPPXbh75+uQ0sWmRtvvFEGBgbky1/+sjz66KPyh3/4h7JixYpMpMqRysGDB+WBBx6QBx54QAD5q7/6K3nggQfkmWeeEREXDr9ixQr55je/KT//+c/lbW97W2E4/Kte9Sq555575Mc//rGcdtppR0w4/Pve9z4ZGxuTH/zgB5mQ3cOHD8dp/uiP/kg2btwo3/ve9+SnP/2pjI+Py/j4eLw/Ctm99NJL5cEHH5RbbrlF1qxZc0SEM3/4wx+WO++8U55++mn5+c9/Lh/+8IfFGCO33nqriBzdddOMdFShyNFdR3/yJ38iP/jBD+Tpp5+Wn/zkJ7J582ZZvXq17NmzR0QWtm76TrhERP72b/9WNm7cKJVKRV772tfK3XffvdhFWhC+//3vC9Dwufrqq0XEhcT/+Z//uaxbt04GBgbkkksuke3bt2fy2Lt3r7zrXe+SZcuWyejoqPz+7/++HDx4cBGupvcU1Q0gX/rSl+I0U1NT8m/+zb+RY445RoaHh+V3f/d35YUXXsjk86tf/Uouv/xyGRoaktWrV8uf/MmfSK1WW+Cr6T3/+l//aznxxBOlUqnImjVr5JJLLolFS+Torptm5IXraK6jd77znXLsscdKpVKR4447Tt75znfKE088Ee9fyLrR15ooiqIofUVfjXEpiqIoigqXoiiK0leocCmKoih9hQqXoiiK0leocCmKoih9hQqXoiiK0leocCmKoih9hQqXoiiK0leocCmKoih9hQqXoiiK0leocCmKoih9hQqXoiiK0lf8/wHLUQ8mh4w7dQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "camera = render.get_rotate_camera(0)\n", + "output = render.render_mesh(intermediate_results[-1], camera, [512, 512], return_types=['normals'])\n", + "plt.imshow(((output['normals'][0] + 1) / 2.).cpu().detach())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the interactive visualizer we can observe the progress over the training" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c8a0ec569bd94bc1a1d03d28c11966ea", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Canvas(height=512, width=512), interactive(children=(FloatLogSlider(value=0.3981071705534972, dโ€ฆ" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "25bfe4b620af4b639c6fa224959aa387", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render.TimelineVisualizer(intermediate_results, 512, 512).show(camera)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "01464b2da2504749adbd6b7274ca75bb": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "085feef5177e4177bad0226481487082": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "08dc165a05b44abea377150ca236aaee": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "0c9a335ed82a4ac69b95375ac2072493": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "1406a0b086c44fba885def3f125720b8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "IntSliderModel", + "state": { + "behavior": "drag-tap", + "description": "idx", + "layout": "IPY_MODEL_fb7e2caa208e4d23b3b7d213a846ffa6", + "max": 50, + "style": "IPY_MODEL_9f80c79a1b74412ebecafe3fec0ba1fd", + "value": 50 + } + }, + "146c8be3e4684709bd7a0cc4c9c26d8d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "FloatLogSliderModel", + "state": { + "behavior": "drag-tap", + "description": "wireframe_thickness", + "layout": "IPY_MODEL_87b796e68c60495bb44ff34e732eb7b7", + "max": -0.4, + "min": -3, + "readout_format": ".3f", + "style": "IPY_MODEL_d01e0946a1e6414c8392a524428fd2c7", + "value": 0.3981071705534972 + } + }, + "1674125334404fbd990fcf02c764cf17": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "175e276283194ef3ad6cbff39faddcc5": { + "model_module": "ipycanvas", + "model_module_version": "^0.13", + "model_name": "CanvasModel", + "state": { + "_canvas_manager": "IPY_MODEL_e7677c2fde314a1eaa968047de653735", + "_model_module_version": "^0.13", + "_view_count": 1, + "_view_module_version": "^0.13", + "height": 512, + "layout": "IPY_MODEL_01464b2da2504749adbd6b7274ca75bb", + "width": 512 + } + }, + "1efa833afd634966815b8cc068895996": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "25bfe4b620af4b639c6fa224959aa387": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_085feef5177e4177bad0226481487082" + } + }, + "2664be4ab5fa40488c971516942f36bf": { + "buffers": [ + { + "data": "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", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_9e32b3d443874996b6e59c76b1a91d85" + } + }, + "39e313aa8d364b41ac45d082fca25d28": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_fc524bdc0f9b4b94ae6f1999e3f95554" + } + }, + "408895046d204616a9ebab6116a5e615": { + "model_module": "ipyevents", + "model_module_version": "2.0.2", + "model_name": "EventModel", + "state": { + "_supported_key_events": [ + "keydown", + "keyup" + ], + "_supported_mouse_events": [ + "click", + "auxclick", + "dblclick", + "mouseenter", + "mouseleave", + "mousedown", + "mouseup", + "mousemove", + "wheel", + "contextmenu", + "dragstart", + "drag", + "dragend", + "dragenter", + "dragover", + "dragleave", + "drop" + ], + "_supported_touch_events": [ + "touchstart", + "touchend", + "touchmove", + "touchcancel" + ], + "_view_module": "@jupyter-widgets/controls", + "prevent_default_action": true, + "source": "IPY_MODEL_175e276283194ef3ad6cbff39faddcc5", + "throttle_or_debounce": "throttle", + "wait": 41, + "watched_events": [ + "wheel", + "mousedown", + "mouseup", + "mousemove", + "mouseleave", + "mouseenter", + "contextmenu" + ], + "xy_coordinate_system": "" + } + }, + "46056691cdb14083bbbd2524092c8538": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "_dom_classes": [ + "widget-interact" + ], + "children": [ + "IPY_MODEL_146c8be3e4684709bd7a0cc4c9c26d8d", + "IPY_MODEL_39e313aa8d364b41ac45d082fca25d28" + ], + "layout": "IPY_MODEL_1674125334404fbd990fcf02c764cf17" + } + }, + "652fdbe26efa422490669fffad179fac": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "692844d2e14f4206aac1e7dc1b48cb75": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "FloatLogSliderModel", + "state": { + "behavior": "drag-tap", + "description": "wireframe_thickness", + "layout": "IPY_MODEL_08dc165a05b44abea377150ca236aaee", + "max": -0.4, + "min": -3, + "readout_format": ".3f", + "style": "IPY_MODEL_be225802930544059b5aa511a33856be", + "value": 0.3981071705534972 + } + }, + "8045d576349a4b9485522790f58ad90d": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_0c9a335ed82a4ac69b95375ac2072493" + } + }, + "87b796e68c60495bb44ff34e732eb7b7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "8c4eaa0629234d68b57a3385c47d803f": { + "model_module": "ipycanvas", + "model_module_version": "^0.13", + "model_name": "CanvasModel", + "state": { + "_canvas_manager": "IPY_MODEL_e7677c2fde314a1eaa968047de653735", + "_model_module_version": "^0.13", + "_view_count": 1, + "_view_module_version": "^0.13", + "height": 512, + "layout": "IPY_MODEL_ade19f04d8b54ac4b076762f0ed8312b", + "width": 1024 + } + }, + "9e32b3d443874996b6e59c76b1a91d85": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "9f80c79a1b74412ebecafe3fec0ba1fd": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "SliderStyleModel", + "state": { + "description_width": "" + } + }, + "a5ecfee9168f4742ae520973c29793b8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "ade19f04d8b54ac4b076762f0ed8312b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b50e4f7ce4b3423d9a087161008a50a3": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "b874d18332f847bf9297a360fc401ef3": { + "model_module": "ipyevents", + "model_module_version": "2.0.2", + "model_name": "EventModel", + "state": { + "_supported_key_events": [ + "keydown", + "keyup" + ], + "_supported_mouse_events": [ + "click", + "auxclick", + "dblclick", + "mouseenter", + "mouseleave", + "mousedown", + "mouseup", + "mousemove", + "wheel", + "contextmenu", + "dragstart", + "drag", + "dragend", + "dragenter", + "dragover", + "dragleave", + "drop" + ], + "_supported_touch_events": [ + "touchstart", + "touchend", + "touchmove", + "touchcancel" + ], + "_view_module": "@jupyter-widgets/controls", + "prevent_default_action": true, + "source": "IPY_MODEL_8c4eaa0629234d68b57a3385c47d803f", + "throttle_or_debounce": "throttle", + "wait": 41, + "watched_events": [ + "wheel", + "mousedown", + "mouseup", + "mousemove", + "mouseleave", + "mouseenter", + "contextmenu" + ], + "xy_coordinate_system": "" + } + }, + "be225802930544059b5aa511a33856be": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "SliderStyleModel", + "state": { + "description_width": "" + } + }, + "c8a0ec569bd94bc1a1d03d28c11966ea": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "HBoxModel", + "state": { + "children": [ + "IPY_MODEL_175e276283194ef3ad6cbff39faddcc5", + "IPY_MODEL_e72fa88747c64c5c8b96a4335bcf2ce4" + ], + "layout": "IPY_MODEL_1efa833afd634966815b8cc068895996" + } + }, + "c8e3c3d3f224452f806184dd700058ad": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "d01e0946a1e6414c8392a524428fd2c7": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "SliderStyleModel", + "state": { + "description_width": "" + } + }, + "d4d90b2d46b94685a64c5d3a6fa98b2e": { + "buffers": [ + { + "data": "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", + "encoding": "base64", + "path": [ + "value" + ] + } + ], + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "ImageModel", + "state": { + "layout": "IPY_MODEL_c8e3c3d3f224452f806184dd700058ad" + } + }, + "d8848758a62646579a83b9512be4164f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "children": [ + "IPY_MODEL_8c4eaa0629234d68b57a3385c47d803f", + "IPY_MODEL_46056691cdb14083bbbd2524092c8538" + ], + "layout": "IPY_MODEL_b50e4f7ce4b3423d9a087161008a50a3" + } + }, + "e72fa88747c64c5c8b96a4335bcf2ce4": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "_dom_classes": [ + "widget-interact" + ], + "children": [ + "IPY_MODEL_692844d2e14f4206aac1e7dc1b48cb75", + "IPY_MODEL_1406a0b086c44fba885def3f125720b8", + "IPY_MODEL_f95ef5123fce4aaf8063256ec35a2316" + ], + "layout": "IPY_MODEL_a5ecfee9168f4742ae520973c29793b8" + } + }, + "e7677c2fde314a1eaa968047de653735": { + "model_module": "ipycanvas", + "model_module_version": "^0.13", + "model_name": "CanvasManagerModel", + "state": { + "_model_module_version": "^0.13", + "_view_module": null, + "_view_module_version": "" + } + }, + "f95ef5123fce4aaf8063256ec35a2316": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_652fdbe26efa422490669fffad179fac" + } + }, + "fb7e2caa208e4d23b3b7d213a846ffa6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "fc524bdc0f9b4b94ae6f1999e3f95554": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + } + }, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/anigen/representations/mesh/flexicubes/examples/optimize.py b/anigen/representations/mesh/flexicubes/examples/optimize.py new file mode 100644 index 0000000000000000000000000000000000000000..332fa2cd2de6866ab2751c6609ae7d82cb2a22b3 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/optimize.py @@ -0,0 +1,150 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +import argparse +import numpy as np +import torch +import nvdiffrast.torch as dr +import trimesh +import os +from util import * +import render +import loss +import imageio + +import sys +sys.path.append('..') +from flexicubes import FlexiCubes + +############################################################################### +# Functions adapted from https://github.com/NVlabs/nvdiffrec +############################################################################### + +def lr_schedule(iter): + return max(0.0, 10**(-(iter)*0.0002)) # Exponential falloff from [1.0, 0.1] over 5k epochs. + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='flexicubes optimization') + parser.add_argument('-o', '--out_dir', type=str, default=None) + parser.add_argument('-rm', '--ref_mesh', type=str) + + parser.add_argument('-i', '--iter', type=int, default=1000) + parser.add_argument('-b', '--batch', type=int, default=8) + parser.add_argument('-r', '--train_res', nargs=2, type=int, default=[2048, 2048]) + parser.add_argument('-lr', '--learning_rate', type=float, default=0.01) + parser.add_argument('--voxel_grid_res', type=int, default=64) + + parser.add_argument('--sdf_loss', type=bool, default=True) + parser.add_argument('--develop_reg', type=bool, default=False) + parser.add_argument('--sdf_regularizer', type=float, default=0.2) + + parser.add_argument('-dr', '--display_res', nargs=2, type=int, default=[512, 512]) + parser.add_argument('-si', '--save_interval', type=int, default=20) + FLAGS = parser.parse_args() + device = 'cuda' + + os.makedirs(FLAGS.out_dir, exist_ok=True) + glctx = dr.RasterizeGLContext() + + # Load GT mesh + gt_mesh = load_mesh(FLAGS.ref_mesh, device) + gt_mesh.auto_normals() # compute face normals for visualization + + # ============================================================================================== + # Create and initialize FlexiCubes + # ============================================================================================== + fc = FlexiCubes(device) + x_nx3, cube_fx8 = fc.construct_voxel_grid(FLAGS.voxel_grid_res) + x_nx3 *= 2 # scale up the grid so that it's larger than the target object + + sdf = torch.rand_like(x_nx3[:,0]) - 0.1 # randomly init SDF + sdf = torch.nn.Parameter(sdf.clone().detach(), requires_grad=True) + # set per-cube learnable weights to zeros + weight = torch.zeros((cube_fx8.shape[0], 21), dtype=torch.float, device='cuda') + weight = torch.nn.Parameter(weight.clone().detach(), requires_grad=True) + deform = torch.nn.Parameter(torch.zeros_like(x_nx3), requires_grad=True) + + # Retrieve all the edges of the voxel grid; these edges will be utilized to + # compute the regularization loss in subsequent steps of the process. + all_edges = cube_fx8[:, fc.cube_edges].reshape(-1, 2) + grid_edges = torch.unique(all_edges, dim=0) + + # ============================================================================================== + # Setup optimizer + # ============================================================================================== + optimizer = torch.optim.Adam([sdf, weight,deform], lr=FLAGS.learning_rate) + scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda x: lr_schedule(x)) + + # ============================================================================================== + # Train loop + # ============================================================================================== + for it in range(FLAGS.iter): + optimizer.zero_grad() + # sample random camera poses + mv, mvp = render.get_random_camera_batch(FLAGS.batch, iter_res=FLAGS.train_res, device=device, use_kaolin=False) + # render gt mesh + target = render.render_mesh_paper(gt_mesh, mv, mvp, FLAGS.train_res) + # extract and render FlexiCubes mesh + grid_verts = x_nx3 + (2-1e-8) / (FLAGS.voxel_grid_res * 2) * torch.tanh(deform) + vertices, faces, L_dev = fc(grid_verts, sdf, cube_fx8, FLAGS.voxel_grid_res, beta_fx12=weight[:,:12], alpha_fx8=weight[:,12:20], + gamma_f=weight[:,20], training=True) + flexicubes_mesh = Mesh(vertices, faces) + buffers = render.render_mesh_paper(flexicubes_mesh, mv, mvp, FLAGS.train_res) + + # evaluate reconstruction loss + mask_loss = (buffers['mask'] - target['mask']).abs().mean() + depth_loss = (((((buffers['depth'] - (target['depth']))* target['mask'])**2).sum(-1)+1e-8)).sqrt().mean() * 10 + + t_iter = it / FLAGS.iter + sdf_weight = FLAGS.sdf_regularizer - (FLAGS.sdf_regularizer - FLAGS.sdf_regularizer/20)*min(1.0, 4.0 * t_iter) + reg_loss = loss.sdf_reg_loss(sdf, grid_edges).mean() * sdf_weight # Loss to eliminate internal floaters that are not visible + reg_loss += L_dev.mean() * 0.5 + reg_loss += (weight[:,:20]).abs().mean() * 0.1 + total_loss = mask_loss + depth_loss + reg_loss + + if FLAGS.sdf_loss: # optionally add SDF loss to eliminate internal structures + with torch.no_grad(): + pts = sample_random_points(1000, gt_mesh) + gt_sdf = compute_sdf(pts, gt_mesh.vertices, gt_mesh.faces) + pred_sdf = compute_sdf(pts, flexicubes_mesh.vertices, flexicubes_mesh.faces) + total_loss += torch.nn.functional.mse_loss(pred_sdf, gt_sdf) * 2e3 + + # optionally add developability regularizer, as described in paper section 5.2 + if FLAGS.develop_reg: + reg_weight = max(0, t_iter - 0.8) * 5 + if reg_weight > 0: # only applied after shape converges + reg_loss = loss.mesh_developable_reg(flexicubes_mesh).mean() * 10 + reg_loss += (deform).abs().mean() + reg_loss += (weight[:,:20]).abs().mean() + total_loss = mask_loss + depth_loss + reg_loss + + total_loss.backward() + optimizer.step() + scheduler.step() + + if (it % FLAGS.save_interval == 0 or it == (FLAGS.iter-1)): # save normal image for visualization + with torch.no_grad(): + # extract mesh with training=False + vertices, faces, L_dev = fc(grid_verts, sdf, cube_fx8, FLAGS.voxel_grid_res, beta_fx12=weight[:,:12], alpha_fx8=weight[:,12:20], + gamma_f=weight[:,20], training=False) + flexicubes_mesh = Mesh(vertices, faces) + + flexicubes_mesh.auto_normals() # compute face normals for visualization + mv, mvp = render.get_rotate_camera(it//FLAGS.save_interval, iter_res=FLAGS.display_res, device=device,use_kaolin=False) + val_buffers = render.render_mesh_paper(flexicubes_mesh, mv.unsqueeze(0), mvp.unsqueeze(0), FLAGS.display_res, return_types=["normal"], white_bg=True) + val_image = ((val_buffers["normal"][0].detach().cpu().numpy()+1)/2*255).astype(np.uint8) + + gt_buffers = render.render_mesh_paper(gt_mesh, mv.unsqueeze(0), mvp.unsqueeze(0), FLAGS.display_res, return_types=["normal"], white_bg=True) + gt_image = ((gt_buffers["normal"][0].detach().cpu().numpy()+1)/2*255).astype(np.uint8) + imageio.imwrite(os.path.join(FLAGS.out_dir, '{:04d}.png'.format(it)), np.concatenate([val_image, gt_image], 1)) + print(f"Optimization Step [{it}/{FLAGS.iter}], Loss: {total_loss.item():.4f}") + + # ============================================================================================== + # Save ouput + # ============================================================================================== + mesh_np = trimesh.Trimesh(vertices = vertices.detach().cpu().numpy(), faces=faces.detach().cpu().numpy(), process=False) + mesh_np.export(os.path.join(FLAGS.out_dir, 'output_mesh.obj')) \ No newline at end of file diff --git a/anigen/representations/mesh/flexicubes/examples/render.py b/anigen/representations/mesh/flexicubes/examples/render.py new file mode 100644 index 0000000000000000000000000000000000000000..034f9613f012dbfebaa4de1672497c4df37483f2 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/render.py @@ -0,0 +1,267 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +import numpy as np +import copy +import math +from ipywidgets import interactive, HBox, VBox, FloatLogSlider, IntSlider + +import torch +import nvdiffrast.torch as dr +import kaolin as kal +import util + +############################################################################### +# Functions adapted from https://github.com/NVlabs/nvdiffrec +############################################################################### + +def get_random_camera_batch(batch_size, fovy = np.deg2rad(45), iter_res=[512,512], cam_near_far=[0.1, 1000.0], cam_radius=3.0, device="cuda", use_kaolin=True): + if use_kaolin: + camera_pos = torch.stack(kal.ops.coords.spherical2cartesian( + *kal.ops.random.sample_spherical_coords((batch_size,), azimuth_low=0., azimuth_high=math.pi * 2, + elevation_low=-math.pi / 2., elevation_high=math.pi / 2., device='cuda'), + cam_radius + ), dim=-1) + return kal.render.camera.Camera.from_args( + eye=camera_pos + torch.rand((batch_size, 1), device='cuda') * 0.5 - 0.25, + at=torch.zeros(batch_size, 3), + up=torch.tensor([[0., 1., 0.]]), + fov=fovy, + near=cam_near_far[0], far=cam_near_far[1], + height=iter_res[0], width=iter_res[1], + device='cuda' + ) + else: + def get_random_camera(): + proj_mtx = util.perspective(fovy, iter_res[1] / iter_res[0], cam_near_far[0], cam_near_far[1]) + mv = util.translate(0, 0, -cam_radius) @ util.random_rotation_translation(0.25) + mvp = proj_mtx @ mv + return mv, mvp + mv_batch = [] + mvp_batch = [] + for i in range(batch_size): + mv, mvp = get_random_camera() + mv_batch.append(mv) + mvp_batch.append(mvp) + return torch.stack(mv_batch).to(device), torch.stack(mvp_batch).to(device) + +def get_rotate_camera(itr, fovy = np.deg2rad(45), iter_res=[512,512], cam_near_far=[0.1, 1000.0], cam_radius=3.0, device="cuda", use_kaolin=True): + if use_kaolin: + ang = (itr / 10) * np.pi * 2 + camera_pos = torch.stack(kal.ops.coords.spherical2cartesian(torch.tensor(ang), torch.tensor(0.4), -torch.tensor(cam_radius))) + return kal.render.camera.Camera.from_args( + eye=camera_pos, + at=torch.zeros(3), + up=torch.tensor([0., 1., 0.]), + fov=fovy, + near=cam_near_far[0], far=cam_near_far[1], + height=iter_res[0], width=iter_res[1], + device='cuda' + ) + else: + proj_mtx = util.perspective(fovy, iter_res[1] / iter_res[0], cam_near_far[0], cam_near_far[1]) + + # Smooth rotation for display. + ang = (itr / 10) * np.pi * 2 + mv = util.translate(0, 0, -cam_radius) @ (util.rotate_x(-0.4) @ util.rotate_y(ang)) + mvp = proj_mtx @ mv + return mv.to(device), mvp.to(device) + +glctx = dr.RasterizeGLContext() +def render_mesh(mesh, camera, iter_res, return_types = ["mask", "depth"], white_bg=False, wireframe_thickness=0.4): + vertices_camera = camera.extrinsics.transform(mesh.vertices) + face_vertices_camera = kal.ops.mesh.index_vertices_by_faces( + vertices_camera, mesh.faces + ) + + # Projection: nvdiffrast take clip coordinates as input to apply barycentric perspective correction. + # Using `camera.intrinsics.transform(vertices_camera) would return the normalized device coordinates. + proj = camera.projection_matrix().unsqueeze(1) + proj[:, :, 1, 1] = -proj[:, :, 1, 1] + homogeneous_vecs = kal.render.camera.up_to_homogeneous( + vertices_camera + ) + vertices_clip = (proj @ homogeneous_vecs.unsqueeze(-1)).squeeze(-1) + faces_int = mesh.faces.int() + + rast, _ = dr.rasterize( + glctx, vertices_clip, faces_int, iter_res) + + out_dict = {} + for type in return_types: + if type == "mask" : + img = dr.antialias((rast[..., -1:] > 0).float(), rast, vertices_clip, faces_int) + elif type == "depth": + img = dr.interpolate(homogeneous_vecs, rast, faces_int)[0] + elif type == "wireframe": + img = torch.logical_or( + torch.logical_or(rast[..., 0] < wireframe_thickness, rast[..., 1] < wireframe_thickness), + (rast[..., 0] + rast[..., 1]) > (1. - wireframe_thickness) + ).unsqueeze(-1) + elif type == "normals" : + img = dr.interpolate( + mesh.face_normals.reshape(len(mesh), -1, 3), rast, + torch.arange(mesh.faces.shape[0] * 3, device='cuda', dtype=torch.int).reshape(-1, 3) + )[0] + if white_bg: + bg = torch.ones_like(img) + alpha = (rast[..., -1:] > 0).float() + img = torch.lerp(bg, img, alpha) + out_dict[type] = img + + + return out_dict + +def render_mesh_paper(mesh, mv, mvp, iter_res, return_types = ["mask", "depth"], white_bg=False): + ''' + The rendering function used to produce the results in the paper. + ''' + v_pos_clip = util.xfm_points(mesh.vertices.unsqueeze(0), mvp) # Rotate it to camera coordinates + rast, db = dr.rasterize( + dr.RasterizeGLContext(), v_pos_clip, mesh.faces.int(), iter_res) + + out_dict = {} + for type in return_types: + if type == "mask" : + img = dr.antialias((rast[..., -1:] > 0).float(), rast, v_pos_clip, mesh.faces.int()) + elif type == "depth": + v_pos_cam = util.xfm_points(mesh.vertices.unsqueeze(0), mv) + img, _ = util.interpolate(v_pos_cam, rast, mesh.faces.int()) + elif type == "normal" : + normal_indices = (torch.arange(0, mesh.nrm.shape[0], dtype=torch.int64, device='cuda')[:, None]).repeat(1, 3) + img, _ = util.interpolate(mesh.nrm.unsqueeze(0).contiguous(), rast, normal_indices.int()) + elif type == "vertex_normal": + img, _ = util.interpolate(mesh.v_nrm.unsqueeze(0).contiguous(), rast, mesh.faces.int()) + img = dr.antialias((img + 1) * 0.5, rast, v_pos_clip, mesh.faces.int()) + if white_bg: + bg = torch.ones_like(img) + alpha = (rast[..., -1:] > 0).float() + img = torch.lerp(bg, img, alpha) + out_dict[type] = img + return out_dict + +class SplitVisualizer(): + def __init__(self, lh_mesh, rh_mesh, height, width): + self.lh_mesh = lh_mesh + self.rh_mesh = rh_mesh + self.height = height + self.width = width + self.wireframe_thickness = 0.4 + + + def render(self, camera): + lh_outputs = render_mesh( + self.lh_mesh, camera, (self.height, self.width), + return_types=["normals", "wireframe"], wireframe_thickness=self.wireframe_thickness + ) + rh_outputs = render_mesh( + self.rh_mesh, camera, (self.height, self.width), + return_types=["normals", "wireframe"], wireframe_thickness=self.wireframe_thickness + ) + outputs = { + k: torch.cat( + [lh_outputs[k][0].permute(1, 0, 2), rh_outputs[k][0].permute(1, 0, 2)], + dim=0 + ).permute(1, 0, 2) for k in ["normals", "wireframe"] + } + return { + 'img': (outputs['wireframe'] * ((outputs['normals'] + 1.) / 2.) * 255).to(torch.uint8), + 'normals': outputs['normals'] + } + + def show(self, init_camera): + visualizer = kal.visualize.IpyTurntableVisualizer( + self.height, self.width * 2, copy.deepcopy(init_camera), self.render, + max_fps=24, world_up_axis=1) + + def slider_callback(new_wireframe_thickness): + """ipywidgets sliders callback""" + with visualizer.out: # This is in case of bug + self.wireframe_thickness = new_wireframe_thickness + # this is how we request a new update + visualizer.render_update() + + wireframe_thickness_slider = FloatLogSlider( + value=self.wireframe_thickness, + base=10, + min=-3, + max=-0.4, + step=0.1, + description='wireframe_thickness', + continuous_update=True, + readout=True, + readout_format='.3f', + ) + + interactive_slider = interactive( + slider_callback, + new_wireframe_thickness=wireframe_thickness_slider, + ) + + full_output = VBox([visualizer.canvas, interactive_slider]) + display(full_output, visualizer.out) + +class TimelineVisualizer(): + def __init__(self, meshes, height, width): + self.meshes = meshes + self.height = height + self.width = width + self.wireframe_thickness = 0.4 + self.idx = len(meshes) - 1 + + def render(self, camera): + outputs = render_mesh( + self.meshes[self.idx], camera, (self.height, self.width), + return_types=["normals", "wireframe"], wireframe_thickness=self.wireframe_thickness + ) + + return { + 'img': (outputs['wireframe'] * ((outputs['normals'] + 1.) / 2.) * 255).to(torch.uint8)[0], + 'normals': outputs['normals'][0] + } + + def show(self, init_camera): + visualizer = kal.visualize.IpyTurntableVisualizer( + self.height, self.width, copy.deepcopy(init_camera), self.render, + max_fps=24, world_up_axis=1) + + def slider_callback(new_wireframe_thickness, new_idx): + """ipywidgets sliders callback""" + with visualizer.out: # This is in case of bug + self.wireframe_thickness = new_wireframe_thickness + self.idx = new_idx + # this is how we request a new update + visualizer.render_update() + + wireframe_thickness_slider = FloatLogSlider( + value=self.wireframe_thickness, + base=10, + min=-3, + max=-0.4, + step=0.1, + description='wireframe_thickness', + continuous_update=True, + readout=True, + readout_format='.3f', + ) + + idx_slider = IntSlider( + value=self.idx, + min=0, + max=len(self.meshes) - 1, + description='idx', + continuous_update=True, + readout=True + ) + + interactive_slider = interactive( + slider_callback, + new_wireframe_thickness=wireframe_thickness_slider, + new_idx=idx_slider + ) + full_output = HBox([visualizer.canvas, interactive_slider]) + display(full_output, visualizer.out) diff --git a/anigen/representations/mesh/flexicubes/examples/util.py b/anigen/representations/mesh/flexicubes/examples/util.py new file mode 100644 index 0000000000000000000000000000000000000000..f39ea1c7570ba74e9f5315209e57a8dcc1839af0 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/examples/util.py @@ -0,0 +1,122 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +import numpy as np +import torch +import trimesh +import kaolin +import nvdiffrast.torch as dr + +############################################################################### +# Functions adapted from https://github.com/NVlabs/nvdiffrec +############################################################################### + +def dot(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return torch.sum(x*y, -1, keepdim=True) + +def length(x: torch.Tensor, eps: float =1e-8) -> torch.Tensor: + return torch.sqrt(torch.clamp(dot(x,x), min=eps)) # Clamp to avoid nan gradients because grad(sqrt(0)) = NaN + +def safe_normalize(x: torch.Tensor, eps: float =1e-8) -> torch.Tensor: + return x / length(x, eps) + +def perspective(fovy=0.7854, aspect=1.0, n=0.1, f=1000.0, device=None): + y = np.tan(fovy / 2) + return torch.tensor([[1/(y*aspect), 0, 0, 0], + [ 0, 1/-y, 0, 0], + [ 0, 0, -(f+n)/(f-n), -(2*f*n)/(f-n)], + [ 0, 0, -1, 0]], dtype=torch.float32, device=device) + +def translate(x, y, z, device=None): + return torch.tensor([[1, 0, 0, x], + [0, 1, 0, y], + [0, 0, 1, z], + [0, 0, 0, 1]], dtype=torch.float32, device=device) + +@torch.no_grad() +def random_rotation_translation(t, device=None): + m = np.random.normal(size=[3, 3]) + m[1] = np.cross(m[0], m[2]) + m[2] = np.cross(m[0], m[1]) + m = m / np.linalg.norm(m, axis=1, keepdims=True) + m = np.pad(m, [[0, 1], [0, 1]], mode='constant') + m[3, 3] = 1.0 + m[:3, 3] = np.random.uniform(-t, t, size=[3]) + return torch.tensor(m, dtype=torch.float32, device=device) + +def rotate_x(a, device=None): + s, c = np.sin(a), np.cos(a) + return torch.tensor([[1, 0, 0, 0], + [0, c, s, 0], + [0, -s, c, 0], + [0, 0, 0, 1]], dtype=torch.float32, device=device) + +def rotate_y(a, device=None): + s, c = np.sin(a), np.cos(a) + return torch.tensor([[ c, 0, s, 0], + [ 0, 1, 0, 0], + [-s, 0, c, 0], + [ 0, 0, 0, 1]], dtype=torch.float32, device=device) + +class Mesh: + def __init__(self, vertices, faces): + self.vertices = vertices + self.faces = faces + + def auto_normals(self): + v0 = self.vertices[self.faces[:, 0], :] + v1 = self.vertices[self.faces[:, 1], :] + v2 = self.vertices[self.faces[:, 2], :] + nrm = safe_normalize(torch.cross(v1 - v0, v2 - v0)) + self.nrm = nrm + +def load_mesh(path, device): + mesh_np = trimesh.load(path) + vertices = torch.tensor(mesh_np.vertices, device=device, dtype=torch.float) + faces = torch.tensor(mesh_np.faces, device=device, dtype=torch.long) + + # Normalize + vmin, vmax = vertices.min(dim=0)[0], vertices.max(dim=0)[0] + scale = 1.8 / torch.max(vmax - vmin).item() + vertices = vertices - (vmax + vmin) / 2 # Center mesh on origin + vertices = vertices * scale # Rescale to [-0.9, 0.9] + return Mesh(vertices, faces) + +def compute_sdf(points, vertices, faces): + face_vertices = kaolin.ops.mesh.index_vertices_by_faces(vertices.clone().unsqueeze(0), faces) + distance = kaolin.metrics.trianglemesh.point_to_mesh_distance(points.unsqueeze(0), face_vertices)[0] + with torch.no_grad(): + sign = (kaolin.ops.mesh.check_sign(vertices.unsqueeze(0), faces, points.unsqueeze(0))<1).float() * 2 - 1 + sdf = (sign*distance).squeeze(0) + return sdf + +def sample_random_points(n, mesh): + pts_random = (torch.rand((n//2,3),device='cuda') - 0.5) * 2 + pts_surface = kaolin.ops.mesh.sample_points(mesh.vertices.unsqueeze(0), mesh.faces, 500)[0].squeeze(0) + pts_surface += torch.randn_like(pts_surface) * 0.05 + pts = torch.cat([pts_random, pts_surface]) + return pts + +def xfm_points(points, matrix): + '''Transform points. + Args: + points: Tensor containing 3D points with shape [minibatch_size, num_vertices, 3] or [1, num_vertices, 3] + matrix: A 4x4 transform matrix with shape [minibatch_size, 4, 4] + use_python: Use PyTorch's torch.matmul (for validation) + Returns: + Transformed points in homogeneous 4D with shape [minibatch_size, num_vertices, 4]. + ''' + out = torch.matmul( + torch.nn.functional.pad(points, pad=(0, 1), mode='constant', value=1.0), torch.transpose(matrix, 1, 2)) + if torch.is_anomaly_enabled(): + assert torch.all(torch.isfinite(out)), "Output of xfm_points contains inf or NaN" + return out + +def interpolate(attr, rast, attr_idx, rast_db=None): + return dr.interpolate( + attr, rast, attr_idx, rast_db=rast_db, + diff_attrs=None if rast_db is None else 'all') \ No newline at end of file diff --git a/anigen/representations/mesh/flexicubes/flexicubes.py b/anigen/representations/mesh/flexicubes/flexicubes.py new file mode 100644 index 0000000000000000000000000000000000000000..c7174ff33f5ee57c24012084d58d76c218e40595 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/flexicubes.py @@ -0,0 +1,387 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. + +import torch +from .tables import * +from kaolin.utils.testing import check_tensor + +__all__ = [ + 'FlexiCubes' +] + + +class FlexiCubes: + def __init__(self, device="cuda", use_color=True): + + self.device = device + self.use_color = use_color + self.dmc_table = torch.tensor(dmc_table, dtype=torch.long, device=device, requires_grad=False) + self.num_vd_table = torch.tensor(num_vd_table, + dtype=torch.long, device=device, requires_grad=False) + self.check_table = torch.tensor( + check_table, + dtype=torch.long, device=device, requires_grad=False) + + self.tet_table = torch.tensor(tet_table, dtype=torch.long, device=device, requires_grad=False) + self.quad_split_1 = torch.tensor([0, 1, 2, 0, 2, 3], dtype=torch.long, device=device, requires_grad=False) + self.quad_split_2 = torch.tensor([0, 1, 3, 3, 1, 2], dtype=torch.long, device=device, requires_grad=False) + self.quad_split_train = torch.tensor( + [0, 1, 1, 2, 2, 3, 3, 0], dtype=torch.long, device=device, requires_grad=False) + + self.cube_corners = torch.tensor([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [ + 1, 0, 1], [0, 1, 1], [1, 1, 1]], dtype=torch.float, device=device) + self.cube_corners_idx = torch.pow(2, torch.arange(8, requires_grad=False)) + self.cube_edges = torch.tensor([0, 1, 1, 5, 4, 5, 0, 4, 2, 3, 3, 7, 6, 7, 2, 6, + 2, 0, 3, 1, 7, 5, 6, 4], dtype=torch.long, device=device, requires_grad=False) + + self.edge_dir_table = torch.tensor([0, 2, 0, 2, 0, 2, 0, 2, 1, 1, 1, 1], + dtype=torch.long, device=device) + self.dir_faces_table = torch.tensor([ + [[5, 4], [3, 2], [4, 5], [2, 3]], + [[5, 4], [1, 0], [4, 5], [0, 1]], + [[3, 2], [1, 0], [2, 3], [0, 1]] + ], dtype=torch.long, device=device) + self.adj_pairs = torch.tensor([0, 1, 1, 3, 3, 2, 2, 0], dtype=torch.long, device=device) + + def __call__(self, voxelgrid_vertices, scalar_field, cube_idx, resolution, qef_reg_scale=1e-3, + weight_scale=0.99, beta=None, alpha=None, gamma_f=None, voxelgrid_colors=None, training=False, no_sigmoid=False): + assert torch.is_tensor(voxelgrid_vertices) and \ + check_tensor(voxelgrid_vertices, (None, 3), throw=False), \ + "'voxelgrid_vertices' should be a tensor of shape (num_vertices, 3)" + num_vertices = voxelgrid_vertices.shape[0] + assert torch.is_tensor(scalar_field) and \ + check_tensor(scalar_field, (num_vertices,), throw=False), \ + "'scalar_field' should be a tensor of shape (num_vertices,)" + assert torch.is_tensor(cube_idx) and \ + check_tensor(cube_idx, (None, 8), throw=False), \ + "'cube_idx' should be a tensor of shape (num_cubes, 8)" + num_cubes = cube_idx.shape[0] + assert beta is None or ( + torch.is_tensor(beta) and + check_tensor(beta, (num_cubes, 12), throw=False) + ), "'beta' should be a tensor of shape (num_cubes, 12)" + assert alpha is None or ( + torch.is_tensor(alpha) and + check_tensor(alpha, (num_cubes, 8), throw=False) + ), "'alpha' should be a tensor of shape (num_cubes, 8)" + assert gamma_f is None or ( + torch.is_tensor(gamma_f) and + check_tensor(gamma_f, (num_cubes,), throw=False) + ), "'gamma_f' should be a tensor of shape (num_cubes,)" + + surf_cubes, occ_fx8 = self._identify_surf_cubes(scalar_field, cube_idx) + if surf_cubes.sum() == 0: + return ( + torch.zeros((0, 3), device=self.device), + torch.zeros((0, 3), dtype=torch.long, device=self.device), + torch.zeros((0), device=self.device), + torch.zeros((0, voxelgrid_colors.shape[-1]), device=self.device) if voxelgrid_colors is not None else None + ) + beta, alpha, gamma_f = self._normalize_weights( + beta, alpha, gamma_f, surf_cubes, weight_scale) + + if voxelgrid_colors is not None: + if not no_sigmoid: + voxelgrid_colors = torch.sigmoid(voxelgrid_colors) + + case_ids = self._get_case_id(occ_fx8, surf_cubes, resolution) + + surf_edges, idx_map, edge_counts, surf_edges_mask = self._identify_surf_edges( + scalar_field, cube_idx, surf_cubes + ) + + vd, L_dev, vd_gamma, vd_idx_map, vd_color = self._compute_vd( + voxelgrid_vertices, cube_idx[surf_cubes], surf_edges, scalar_field, + case_ids, beta, alpha, gamma_f, idx_map, qef_reg_scale, voxelgrid_colors) + vertices, faces, s_edges, edge_indices, vertices_color = self._triangulate( + scalar_field, surf_edges, vd, vd_gamma, edge_counts, idx_map, + vd_idx_map, surf_edges_mask, training, vd_color) + + return vertices, faces, L_dev, vertices_color + + def _compute_reg_loss(self, vd, ue, edge_group_to_vd, vd_num_edges): + """ + Regularizer L_dev as in Equation 8 + """ + dist = torch.norm(ue - torch.index_select(input=vd, index=edge_group_to_vd, dim=0), dim=-1) + mean_l2 = torch.zeros_like(vd[:, 0]) + mean_l2 = (mean_l2).index_add_(0, edge_group_to_vd, dist.type(vd.dtype)) / vd_num_edges.squeeze(1).type(vd.dtype) + mad = (dist - torch.index_select(input=mean_l2, index=edge_group_to_vd, dim=0)).abs() + return mad.type(vd.dtype) + + def _normalize_weights(self, beta, alpha, gamma_f, surf_cubes, weight_scale): + """ + Normalizes the given weights to be non-negative. If input weights are None, it creates and returns a set of weights of ones. + """ + n_cubes = surf_cubes.shape[0] + + if beta is not None: + beta = (torch.tanh(beta) * weight_scale + 1) + else: + beta = torch.ones((n_cubes, 12), dtype=torch.float, device=self.device) + + if alpha is not None: + alpha = (torch.tanh(alpha) * weight_scale + 1) + else: + alpha = torch.ones((n_cubes, 8), dtype=torch.float, device=self.device) + + if gamma_f is not None: + gamma_f = torch.sigmoid(gamma_f) * weight_scale + (1 - weight_scale) / 2 + else: + gamma_f = torch.ones((n_cubes), dtype=torch.float, device=self.device) + + return beta[surf_cubes], alpha[surf_cubes], gamma_f[surf_cubes] + + @torch.no_grad() + def _get_case_id(self, occ_fx8, surf_cubes, res): + """ + Obtains the ID of topology cases based on cell corner occupancy. This function resolves the + ambiguity in the Dual Marching Cubes (DMC) configurations as described in Section 1.3 of the + supplementary material. It should be noted that this function assumes a regular grid. + """ + case_ids = (occ_fx8[surf_cubes] * self.cube_corners_idx.to(self.device).unsqueeze(0)).sum(-1) + + problem_config = self.check_table.to(self.device)[case_ids] + to_check = problem_config[..., 0] == 1 + problem_config = problem_config[to_check] + if not isinstance(res, (list, tuple)): + res = [res, res, res] + + # The 'problematic_configs' only contain configurations for surface cubes. Next, we construct a 3D array, + # 'problem_config_full', to store configurations for all cubes (with default config for non-surface cubes). + # This allows efficient checking on adjacent cubes. + problem_config_full = torch.zeros(list(res) + [5], device=self.device, dtype=torch.long) + vol_idx = torch.nonzero(problem_config_full[..., 0] == 0) # N, 3 + vol_idx_problem = vol_idx[surf_cubes][to_check] + problem_config_full[vol_idx_problem[..., 0], vol_idx_problem[..., 1], vol_idx_problem[..., 2]] = problem_config + vol_idx_problem_adj = vol_idx_problem + problem_config[..., 1:4] + + within_range = ( + vol_idx_problem_adj[..., 0] >= 0) & ( + vol_idx_problem_adj[..., 0] < res[0]) & ( + vol_idx_problem_adj[..., 1] >= 0) & ( + vol_idx_problem_adj[..., 1] < res[1]) & ( + vol_idx_problem_adj[..., 2] >= 0) & ( + vol_idx_problem_adj[..., 2] < res[2]) + + vol_idx_problem = vol_idx_problem[within_range] + vol_idx_problem_adj = vol_idx_problem_adj[within_range] + problem_config = problem_config[within_range] + problem_config_adj = problem_config_full[vol_idx_problem_adj[..., 0], + vol_idx_problem_adj[..., 1], vol_idx_problem_adj[..., 2]] + # If two cubes with cases C16 and C19 share an ambiguous face, both cases are inverted. + to_invert = (problem_config_adj[..., 0] == 1) + idx = torch.arange(case_ids.shape[0], device=self.device)[to_check][within_range][to_invert] + case_ids.index_put_((idx,), problem_config[to_invert][..., -1]) + return case_ids + + @torch.no_grad() + def _identify_surf_edges(self, scalar_field, cube_idx, surf_cubes): + """ + Identifies grid edges that intersect with the underlying surface by checking for opposite signs. As each edge + can be shared by multiple cubes, this function also assigns a unique index to each surface-intersecting edge + and marks the cube edges with this index. + """ + occ_n = scalar_field < 0 + all_edges = cube_idx[surf_cubes][:, self.cube_edges].reshape(-1, 2) + unique_edges, _idx_map, counts = torch.unique(all_edges, dim=0, return_inverse=True, return_counts=True) + + unique_edges = unique_edges.long() + mask_edges = occ_n[unique_edges.reshape(-1)].reshape(-1, 2).sum(-1) == 1 + + surf_edges_mask = mask_edges[_idx_map] + counts = counts[_idx_map] + + mapping = torch.ones((unique_edges.shape[0]), dtype=torch.long, device=cube_idx.device) * -1 + mapping[mask_edges] = torch.arange(mask_edges.sum(), device=cube_idx.device) + # Shaped as [number of cubes x 12 edges per cube]. This is later used to map a cube edge to the unique index + # for a surface-intersecting edge. Non-surface-intersecting edges are marked with -1. + idx_map = mapping[_idx_map] + surf_edges = unique_edges[mask_edges] + return surf_edges, idx_map, counts, surf_edges_mask + + @torch.no_grad() + def _identify_surf_cubes(self, scalar_field, cube_idx): + """ + Identifies grid cubes that intersect with the underlying surface by checking if the signs at + all corners are not identical. + """ + occ_n = scalar_field < 0 + occ_fx8 = occ_n[cube_idx.reshape(-1)].reshape(-1, 8) + _occ_sum = torch.sum(occ_fx8, -1) + surf_cubes = (_occ_sum > 0) & (_occ_sum < 8) + return surf_cubes, occ_fx8 + + def _linear_interp(self, edges_weight, edges_x): + """ + Computes the location of zero-crossings on 'edges_x' using linear interpolation with 'edges_weight'. + """ + edge_dim = edges_weight.dim() - 2 + assert edges_weight.shape[edge_dim] == 2 + edges_weight = torch.cat([torch.index_select(input=edges_weight, index=torch.tensor(1, device=self.device), dim=edge_dim), - + torch.index_select(input=edges_weight, index=torch.tensor(0, device=self.device), dim=edge_dim)] + , edge_dim) + denominator = edges_weight.sum(edge_dim) + ue = (edges_x * edges_weight).sum(edge_dim) / denominator + return ue + + def _solve_vd_QEF(self, p_bxnx3, norm_bxnx3, c_bx3, qef_reg_scale): + p_bxnx3 = p_bxnx3.reshape(-1, 7, 3) + norm_bxnx3 = norm_bxnx3.reshape(-1, 7, 3) + c_bx3 = c_bx3.reshape(-1, 3) + A = norm_bxnx3 + B = ((p_bxnx3) * norm_bxnx3).sum(-1, keepdims=True) + + A_reg = (torch.eye(3, device=p_bxnx3.device) * qef_reg_scale).unsqueeze(0).repeat(p_bxnx3.shape[0], 1, 1) + B_reg = (qef_reg_scale * c_bx3).unsqueeze(-1) + A = torch.cat([A, A_reg], 1) + B = torch.cat([B, B_reg], 1) + dual_verts = torch.linalg.lstsq(A, B).solution.squeeze(-1) + return dual_verts + + def _compute_vd(self, voxelgrid_vertices, surf_cubes_fx8, surf_edges, scalar_field, + case_ids, beta, alpha, gamma_f, idx_map, qef_reg_scale, voxelgrid_colors): + """ + Computes the location of dual vertices as described in Section 4.2 + """ + alpha_nx12x2 = torch.index_select(input=alpha, index=self.cube_edges, dim=1).reshape(-1, 12, 2) + surf_edges_x = torch.index_select(input=voxelgrid_vertices, index=surf_edges.reshape(-1), dim=0).reshape(-1, 2, 3) + surf_edges_s = torch.index_select(input=scalar_field, index=surf_edges.reshape(-1), dim=0).reshape(-1, 2, 1) + zero_crossing = self._linear_interp(surf_edges_s, surf_edges_x) + + if voxelgrid_colors is not None: + C = voxelgrid_colors.shape[-1] + surf_edges_c = torch.index_select(input=voxelgrid_colors, index=surf_edges.reshape(-1), dim=0).reshape(-1, 2, C) + + idx_map = idx_map.reshape(-1, 12) + num_vd = torch.index_select(input=self.num_vd_table, index=case_ids, dim=0) + edge_group, edge_group_to_vd, edge_group_to_cube, vd_num_edges, vd_gamma = [], [], [], [], [] + + # if color is not None: + # vd_color = [] + + total_num_vd = 0 + vd_idx_map = torch.zeros((case_ids.shape[0], 12), dtype=torch.long, device=self.device, requires_grad=False) + + for num in torch.unique(num_vd): + cur_cubes = (num_vd == num) # consider cubes with the same numbers of vd emitted (for batching) + curr_num_vd = cur_cubes.sum() * num + curr_edge_group = self.dmc_table[case_ids[cur_cubes], :num].reshape(-1, num * 7) + curr_edge_group_to_vd = torch.arange( + curr_num_vd, device=self.device).unsqueeze(-1).repeat(1, 7) + total_num_vd + total_num_vd += curr_num_vd + curr_edge_group_to_cube = torch.arange(idx_map.shape[0], device=self.device)[ + cur_cubes].unsqueeze(-1).repeat(1, num * 7).reshape_as(curr_edge_group) + + curr_mask = (curr_edge_group != -1) + edge_group.append(torch.masked_select(curr_edge_group, curr_mask)) + edge_group_to_vd.append(torch.masked_select(curr_edge_group_to_vd.reshape_as(curr_edge_group), curr_mask)) + edge_group_to_cube.append(torch.masked_select(curr_edge_group_to_cube, curr_mask)) + vd_num_edges.append(curr_mask.reshape(-1, 7).sum(-1, keepdims=True)) + vd_gamma.append(torch.masked_select(gamma_f, cur_cubes).unsqueeze(-1).repeat(1, num).reshape(-1)) + # if color is not None: + # vd_color.append(color[cur_cubes].unsqueeze(1).repeat(1, num, 1).reshape(-1, 3)) + + edge_group = torch.cat(edge_group) + edge_group_to_vd = torch.cat(edge_group_to_vd) + edge_group_to_cube = torch.cat(edge_group_to_cube) + vd_num_edges = torch.cat(vd_num_edges) + vd_gamma = torch.cat(vd_gamma) + # if color is not None: + # vd_color = torch.cat(vd_color) + # else: + # vd_color = None + + vd = torch.zeros((total_num_vd, 3), device=self.device, dtype=beta.dtype) + beta_sum = torch.zeros((total_num_vd, 1), device=self.device, dtype=beta.dtype) + + idx_group = torch.gather(input=idx_map.reshape(-1), dim=0, index=edge_group_to_cube * 12 + edge_group) + + x_group = torch.index_select(input=surf_edges_x, index=idx_group.reshape(-1), dim=0).reshape(-1, 2, 3) + s_group = torch.index_select(input=surf_edges_s, index=idx_group.reshape(-1), dim=0).reshape(-1, 2, 1) + + + zero_crossing_group = torch.index_select( + input=zero_crossing, index=idx_group.reshape(-1), dim=0).reshape(-1, 3) + + alpha_group = torch.index_select(input=alpha_nx12x2.reshape(-1, 2), dim=0, + index=edge_group_to_cube * 12 + edge_group).reshape(-1, 2, 1) + ue_group = self._linear_interp(s_group * alpha_group, x_group).type(beta.dtype) + + beta_group = torch.gather(input=beta.reshape(-1), dim=0, + index=edge_group_to_cube * 12 + edge_group).reshape(-1, 1) + beta_sum = beta_sum.index_add_(0, index=edge_group_to_vd, source=beta_group) + vd = vd.index_add_(0, index=edge_group_to_vd, source=ue_group * beta_group) / beta_sum + + ''' + interpolate colors use the same method as dual vertices + ''' + if voxelgrid_colors is not None: + vd_color = torch.zeros((total_num_vd, C), device=self.device, dtype=voxelgrid_colors.dtype) + c_group = torch.index_select(input=surf_edges_c, index=idx_group.reshape(-1), dim=0).reshape(-1, 2, C) + uc_group = self._linear_interp(s_group * alpha_group, c_group).type(voxelgrid_colors.dtype) + vd_color = vd_color.index_add_(0, index=edge_group_to_vd, source=uc_group * beta_group) / beta_sum + else: + vd_color = None + + L_dev = self._compute_reg_loss(vd, zero_crossing_group, edge_group_to_vd, vd_num_edges) + + v_idx = torch.arange(vd.shape[0], device=self.device) # + total_num_vd + + vd_idx_map = (vd_idx_map.reshape(-1)).scatter(dim=0, index=edge_group_to_cube * + 12 + edge_group, src=v_idx[edge_group_to_vd]) + + return vd, L_dev, vd_gamma, vd_idx_map, vd_color + + def _triangulate(self, scalar_field, surf_edges, vd, vd_gamma, edge_counts, idx_map, vd_idx_map, surf_edges_mask, training, vd_color): + """ + Connects four neighboring dual vertices to form a quadrilateral. The quadrilaterals are then split into + triangles based on the gamma parameter, as described in Section 4.3. + """ + with torch.no_grad(): + group_mask = (edge_counts == 4) & surf_edges_mask # surface edges shared by 4 cubes. + group = idx_map.reshape(-1)[group_mask] + vd_idx = vd_idx_map[group_mask] + edge_indices, indices = torch.sort(group, stable=True) + quad_vd_idx = vd_idx[indices].reshape(-1, 4) + + # Ensure all face directions point towards the positive SDF to maintain consistent winding. + s_edges = scalar_field[surf_edges[edge_indices.reshape(-1, 4)[:, 0]].reshape(-1)].reshape(-1, 2) + flip_mask = s_edges[:, 0] > 0 + quad_vd_idx = torch.cat((quad_vd_idx[flip_mask][:, [0, 1, 3, 2]], + quad_vd_idx[~flip_mask][:, [2, 3, 1, 0]])) + + quad_gamma = torch.index_select(input=vd_gamma, index=quad_vd_idx.reshape(-1), dim=0).reshape(-1, 4) + gamma_02 = quad_gamma[:, 0] * quad_gamma[:, 2] + gamma_13 = quad_gamma[:, 1] * quad_gamma[:, 3] + if not training: + mask = (gamma_02 > gamma_13) + faces = torch.zeros((quad_gamma.shape[0], 6), dtype=torch.long, device=quad_vd_idx.device) + faces[mask] = quad_vd_idx[mask][:, self.quad_split_1] + faces[~mask] = quad_vd_idx[~mask][:, self.quad_split_2] + faces = faces.reshape(-1, 3) + else: + vd_quad = torch.index_select(input=vd, index=quad_vd_idx.reshape(-1), dim=0).reshape(-1, 4, 3) + vd_02 = (vd_quad[:, 0] + vd_quad[:, 2]) / 2 + vd_13 = (vd_quad[:, 1] + vd_quad[:, 3]) / 2 + weight_sum = (gamma_02 + gamma_13) + 1e-8 + vd_center = (vd_02 * gamma_02.unsqueeze(-1) + vd_13 * gamma_13.unsqueeze(-1)) / weight_sum.unsqueeze(-1) + + if vd_color is not None: + color_quad = torch.index_select(input=vd_color, index=quad_vd_idx.reshape(-1), dim=0).reshape(-1, 4, vd_color.shape[-1]) + color_02 = (color_quad[:, 0] + color_quad[:, 2]) / 2 + color_13 = (color_quad[:, 1] + color_quad[:, 3]) / 2 + color_center = (color_02 * gamma_02.unsqueeze(-1) + color_13 * gamma_13.unsqueeze(-1)) / weight_sum.unsqueeze(-1) + vd_color = torch.cat([vd_color, color_center]) + + + vd_center_idx = torch.arange(vd_center.shape[0], device=self.device) + vd.shape[0] + vd = torch.cat([vd, vd_center]) + faces = quad_vd_idx[:, self.quad_split_train].reshape(-1, 4, 2) + faces = torch.cat([faces, vd_center_idx.reshape(-1, 1, 1).repeat(1, 4, 1)], -1).reshape(-1, 3) + return vd, faces, s_edges, edge_indices, vd_color \ No newline at end of file diff --git a/anigen/representations/mesh/flexicubes/images/ablate_L_dev.jpg b/anigen/representations/mesh/flexicubes/images/ablate_L_dev.jpg new file mode 100644 index 0000000000000000000000000000000000000000..461bd1ce2a73d6b6e0ee61648af7746c2254bc53 Binary files /dev/null and b/anigen/representations/mesh/flexicubes/images/ablate_L_dev.jpg differ diff --git a/anigen/representations/mesh/flexicubes/images/block_final.png b/anigen/representations/mesh/flexicubes/images/block_final.png new file mode 100644 index 0000000000000000000000000000000000000000..8b197719e1a3b09bce4a99077e4e0752aa21fe9b Binary files /dev/null and b/anigen/representations/mesh/flexicubes/images/block_final.png differ diff --git a/anigen/representations/mesh/flexicubes/images/block_init.png b/anigen/representations/mesh/flexicubes/images/block_init.png new file mode 100644 index 0000000000000000000000000000000000000000..aadc74a6da402df263d4b35396d033284e22a630 --- /dev/null +++ b/anigen/representations/mesh/flexicubes/images/block_init.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:699ba21d95cce9d1504d31fca3694ba339f21703ac0bc3240c87df6ac2d2db3e +size 198533 diff --git a/anigen/representations/mesh/flexicubes/images/teaser_top.png b/anigen/representations/mesh/flexicubes/images/teaser_top.png new file mode 100644 index 0000000000000000000000000000000000000000..5ae12891d528010988e427e935e7a0620cd1b66a --- /dev/null +++ b/anigen/representations/mesh/flexicubes/images/teaser_top.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71c27efaeeb7fc3357440607b34805495fc34acf39be00bb70dd315b5b25a71d +size 3562986 diff --git a/anigen/representations/mesh/flexicubes/tables.py b/anigen/representations/mesh/flexicubes/tables.py new file mode 100644 index 0000000000000000000000000000000000000000..5873e7727b5595a1e4fbc3bd10ae5be8f3d06cca --- /dev/null +++ b/anigen/representations/mesh/flexicubes/tables.py @@ -0,0 +1,791 @@ +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# NVIDIA CORPORATION & AFFILIATES and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION & AFFILIATES is strictly prohibited. +dmc_table = [ +[[-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 8, 9, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 7, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 5, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 8, 9, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 7, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 7, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 5, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 8, 9, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 7, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 7, 8, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 8, 11, -1, -1, -1], [4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 5, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 8, 9, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 7, 8, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 5, 7, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 8, 9, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 7, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 9, 10, -1, -1, -1], [4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 7, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 5, 9, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 5, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 5, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 8, 9, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 7, 9, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 7, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 8, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 9, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[8, 9, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [1, 3, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 7, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 9, 10, 11, -1, -1], [4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 9, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [1, 3, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 8, 10, 11, -1, -1], [4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 5, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 8, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 8, 9, -1, -1, -1], [1, 3, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 7, 9, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 7, 8, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 8, 9, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 6, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 6, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 6, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 5, 9, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 5, 8, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 6, 8, 9, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 6, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 6, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 5, 6, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 6, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 6, 7, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 6, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 6, 7, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 6, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 4, 6, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 6, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [2, 3, 6, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 6, 7, 8, -1, -1], [4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, -1, -1, -1], [2, 3, 6, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 5, 6, 7, 8], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 6, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 6, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 5, 6, 8], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 5, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 10, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 9, 10, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 8, 9, 10, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 8, 11, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 6, 11, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 9, 10, -1, -1, -1], [4, 6, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 6, 9, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 5, 9, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1]], +[[0, 2, 4, 5, 10, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 5, 8, 10, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 6, 8, 9, 11, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 6, 9, 11, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 6, 8, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 6, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 6, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 6, 7, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 6, 7, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[6, 7, 8, 9, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 6, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 6, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 6, 8, 9, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [1, 3, 6, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 6, 7, 8, 10, -1], [4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 5, 6, 7, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 6, 7, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 5, 6, 8, 9, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 6, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 8, 9, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 7, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 7, 8, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 7, 9, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 6, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 6, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 6, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[6, 7, 8, 9, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 6, 7, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 6, 7, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 6, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 11, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 8, 11, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 8, 9, 11, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 7, 11, -1, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 7, 8, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [5, 6, 10, -1, -1, -1, -1]], +[[1, 2, 4, 7, 9, 11, -1], [5, 6, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 9, 10, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 8, 11, -1, -1, -1], [4, 6, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 6, 10, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 6, 8, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[6, 7, 8, 9, 10, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 6, 7, 9, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 6, 7, 8, 10, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 6, 7, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 5, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 5, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 6, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 6, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [1, 2, 5, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 7, -1, -1, -1], [1, 2, 5, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 6, 9, -1, -1], [4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 5, 6, 7, 9], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 6, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 4, 6, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 6, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 6, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 6, 7, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 6, 7, 9], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 6, 7, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 6, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 5, 6, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 6, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 6, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 6, 8, 9, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [1, 3, 5, 6, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, 6, 7, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 6, 9, 11, -1], [4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 6, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 6, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 6, 8, 9, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 6, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 6, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 6, 7, 8, 9, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 6, 7, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[6, 7, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [5, 7, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [5, 7, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 8, 9, -1, -1, -1], [5, 7, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 8, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 5, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [4, 5, 8, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 5, 9, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 9, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [4, 7, 9, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 7, 10, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 7, 8, 10, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[8, 9, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 9, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 8, 10, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 10, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 7, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 5, 7, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 5, 7, 8, 9, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 5, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 5, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [2, 3, 4, 5, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 5, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 7, 9, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 7, 8, 9, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 4, 7, 10], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 8, 9, 10, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 9, 10, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 8, 10, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 10, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 5, 7, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 5, 7, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 5, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 5, 7, 8, 9, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 5, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 4, 5, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 5, 8, 9, 11], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 4, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [1, 2, 4, 7, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 4, 7, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 4, 7, 8, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 2, 8, 9, 11, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 2, 3, 9, 11, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 2, 8, 11, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[2, 3, 11, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 5, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 5, 7, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 5, 7, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[5, 7, 8, 9, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 5, 8, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 5, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 5, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 5, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 4, 7, 9, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 4, 7, 8, 9, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 4, 7, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[4, 7, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[1, 3, 8, 9, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 1, 9, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[0, 3, 8, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], +[[-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]] +] +num_vd_table = [0, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 2, 2, +2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1, 2, 3, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, +1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 2, 3, 2, 2, 1, 1, 1, 1, +1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 4, 2, +2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, +3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 3, 2, 3, 2, 4, 2, 2, 2, 2, 1, 2, 1, 2, 1, 1, +2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, +1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, +1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0] +check_table = [ +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 1, 0, 0, 194], +[1, -1, 0, 0, 193], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 1, 0, 164], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, -1, 0, 161], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, 1, 152], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, 1, 145], +[1, 0, 0, 1, 144], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, -1, 137], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 1, 0, 133], +[1, 0, 1, 0, 132], +[1, 1, 0, 0, 131], +[1, 1, 0, 0, 130], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, 1, 100], +[0, 0, 0, 0, 0], +[1, 0, 0, 1, 98], +[0, 0, 0, 0, 0], +[1, 0, 0, 1, 96], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 1, 0, 88], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, -1, 0, 82], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 1, 0, 74], +[0, 0, 0, 0, 0], +[1, 0, 1, 0, 72], +[0, 0, 0, 0, 0], +[1, 0, 0, -1, 70], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, -1, 0, 0, 67], +[0, 0, 0, 0, 0], +[1, -1, 0, 0, 65], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 1, 0, 0, 56], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, -1, 0, 0, 52], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 1, 0, 0, 44], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 1, 0, 0, 40], +[0, 0, 0, 0, 0], +[1, 0, 0, -1, 38], +[1, 0, -1, 0, 37], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, -1, 0, 33], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, -1, 0, 0, 28], +[0, 0, 0, 0, 0], +[1, 0, -1, 0, 26], +[1, 0, 0, -1, 25], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, -1, 0, 0, 20], +[0, 0, 0, 0, 0], +[1, 0, -1, 0, 18], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, -1, 9], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[1, 0, 0, -1, 6], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0], +[0, 0, 0, 0, 0] +] +tet_table = [ +[-1, -1, -1, -1, -1, -1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[4, 4, 4, 4, 4, 4], +[0, 0, 0, 0, 0, 0], +[4, 0, 0, 4, 4, -1], +[1, 1, 1, 1, 1, 1], +[4, 4, 4, 4, 4, 4], +[0, 4, 0, 4, 4, -1], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[5, 5, 5, 5, 5, 5], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, -1, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, -1, 2, 4, 4, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, 4, 4, 2], +[1, 1, 1, 1, 1, 1], +[2, 4, 2, 4, 4, 2], +[0, 4, 0, 4, 4, 0], +[2, 0, 2, 0, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, 5, 2, 5, 5, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, 0, 0, 2], +[1, 1, 1, 1, 1, 1], +[1, 1, 1, 1, 1, 1], +[0, 1, 1, -1, 0, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[4, 1, 1, 4, 4, 1], +[0, 1, 1, 0, 0, 1], +[4, 0, 0, 4, 4, 0], +[2, 2, 2, 2, 2, 2], +[-1, 1, 1, 4, 4, 1], +[0, 1, 1, 4, 4, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[5, 1, 1, 5, 5, 1], +[0, 1, 1, 0, 0, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[8, 8, 8, 8, 8, 8], +[1, 1, 1, 4, 4, 1], +[0, 0, 0, 0, 0, 0], +[4, 0, 0, 4, 4, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 4, 4, 1], +[0, 4, 0, 4, 4, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 5, 5, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[5, 5, 5, 5, 5, 5], +[6, 6, 6, 6, 6, 6], +[6, -1, 0, 6, 0, 6], +[6, 0, 0, 6, 0, 6], +[6, 1, 1, 6, 1, 6], +[4, 4, 4, 4, 4, 4], +[0, 0, 0, 0, 0, 0], +[4, 0, 0, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[6, 4, -1, 6, 4, 6], +[6, 4, 0, 6, 4, 6], +[6, 0, 0, 6, 0, 6], +[6, 1, 1, 6, 1, 6], +[5, 5, 5, 5, 5, 5], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, 2, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[2, 4, 2, 2, 4, 2], +[0, 4, 0, 4, 4, 0], +[2, 0, 2, 2, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[6, 1, 1, 6, -1, 6], +[6, 1, 1, 6, 0, 6], +[6, 0, 0, 6, 0, 6], +[6, 2, 2, 6, 2, 6], +[4, 1, 1, 4, 4, 1], +[0, 1, 1, 0, 0, 1], +[4, 0, 0, 4, 4, 4], +[2, 2, 2, 2, 2, 2], +[6, 1, 1, 6, 4, 6], +[6, 1, 1, 6, 4, 6], +[6, 0, 0, 6, 0, 6], +[6, 2, 2, 6, 2, 6], +[5, 1, 1, 5, 5, 1], +[0, 1, 1, 0, 0, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[6, 6, 6, 6, 6, 6], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 4, 1], +[0, 4, 0, 4, 4, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 5, 0, 5, 0, 5], +[5, 5, 5, 5, 5, 5], +[5, 5, 5, 5, 5, 5], +[0, 5, 0, 5, 0, 5], +[-1, 5, 0, 5, 0, 5], +[1, 5, 1, 5, 1, 5], +[4, 5, -1, 5, 4, 5], +[0, 5, 0, 5, 0, 5], +[4, 5, 0, 5, 4, 5], +[1, 5, 1, 5, 1, 5], +[4, 4, 4, 4, 4, 4], +[0, 4, 0, 4, 4, 4], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[6, 6, 6, 6, 6, 6], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[2, 5, 2, 5, -1, 5], +[0, 5, 0, 5, 0, 5], +[2, 5, 2, 5, 0, 5], +[1, 5, 1, 5, 1, 5], +[2, 5, 2, 5, 4, 5], +[0, 5, 0, 5, 0, 5], +[2, 5, 2, 5, 4, 5], +[1, 5, 1, 5, 1, 5], +[2, 4, 2, 4, 4, 2], +[0, 4, 0, 4, 4, 4], +[2, 0, 2, 0, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, 6, 2, 6, 6, 2], +[0, 0, 0, 0, 0, 0], +[2, 0, 2, 0, 0, 2], +[1, 1, 1, 1, 1, 1], +[1, 1, 1, 1, 1, 1], +[0, 1, 1, 1, 0, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[4, 1, 1, 1, 4, 1], +[0, 1, 1, 1, 0, 1], +[4, 0, 0, 4, 4, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[5, 5, 5, 5, 5, 5], +[1, 1, 1, 1, 4, 1], +[0, 0, 0, 0, 0, 0], +[4, 0, 0, 4, 4, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[6, 0, 0, 6, 0, 6], +[0, 0, 0, 0, 0, 0], +[6, 6, 6, 6, 6, 6], +[5, 5, 5, 5, 5, 5], +[5, 5, 0, 5, 0, 5], +[5, 5, 0, 5, 0, 5], +[5, 5, 1, 5, 1, 5], +[4, 4, 4, 4, 4, 4], +[0, 0, 0, 0, 0, 0], +[4, 4, 0, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[4, 4, 4, 4, 4, 4], +[4, 4, 0, 4, 4, 4], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[8, 8, 8, 8, 8, 8], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 0, 2], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[4, 1, 1, 4, 4, 1], +[2, 2, 2, 2, 2, 2], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[1, 1, 1, 1, 1, 1], +[1, 1, 1, 1, 1, 1], +[1, 1, 1, 1, 0, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[2, 4, 2, 4, 4, 2], +[1, 1, 1, 1, 1, 1], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[2, 2, 2, 2, 2, 2], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[5, 5, 5, 5, 5, 5], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[4, 4, 4, 4, 4, 4], +[1, 1, 1, 1, 1, 1], +[0, 0, 0, 0, 0, 0], +[0, 0, 0, 0, 0, 0], +[12, 12, 12, 12, 12, 12] +] diff --git a/anigen/representations/mesh/utils_cube.py b/anigen/representations/mesh/utils_cube.py new file mode 100644 index 0000000000000000000000000000000000000000..81a04c6ef89cf9fb8e6b98bcdaaecf0e59e1c9ce --- /dev/null +++ b/anigen/representations/mesh/utils_cube.py @@ -0,0 +1,70 @@ +import torch +cube_corners = torch.tensor([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [ + 1, 0, 1], [0, 1, 1], [1, 1, 1]], dtype=torch.int) +cube_neighbor = torch.tensor([[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]]) +cube_edges = torch.tensor([0, 1, 1, 5, 4, 5, 0, 4, 2, 3, 3, 7, 6, 7, 2, 6, + 2, 0, 3, 1, 7, 5, 6, 4], dtype=torch.long, requires_grad=False) + +def construct_dense_grid(res, device='cuda'): + '''construct a dense grid based on resolution''' + res_v = res + 1 + vertsid = torch.arange(res_v ** 3, device=device) + coordsid = vertsid.reshape(res_v, res_v, res_v)[:res, :res, :res].flatten() + cube_corners_bias = (cube_corners[:, 0] * res_v + cube_corners[:, 1]) * res_v + cube_corners[:, 2] + cube_fx8 = (coordsid.unsqueeze(1) + cube_corners_bias.unsqueeze(0).to(device)) + verts = torch.stack([vertsid // (res_v ** 2), (vertsid // res_v) % res_v, vertsid % res_v], dim=1) + return verts, cube_fx8 + + +def construct_voxel_grid(coords): + verts = (cube_corners.unsqueeze(0).to(coords) + coords.unsqueeze(1)).reshape(-1, 3) + verts_unique, inverse_indices = torch.unique(verts, dim=0, return_inverse=True) + cubes = inverse_indices.reshape(-1, 8) + return verts_unique, cubes + + +def cubes_to_verts(num_verts, cubes, value, reduce='mean'): + """ + Args: + cubes [Vx8] verts index for each cube + value [Vx8xM] value to be scattered + Operation: + reduced[cubes[i][j]][k] += value[i][k] + """ + M = value.shape[2] # number of channels + reduced = torch.zeros(num_verts, M, device=cubes.device, dtype=value.dtype) + flat_idx = cubes.reshape(-1) + flat_value = value.reshape(-1, M) + reduced.index_add_(0, flat_idx, flat_value) + if reduce == 'mean': + counts = torch.zeros(num_verts, 1, device=cubes.device, dtype=value.dtype) + counts.index_add_(0, flat_idx, torch.ones_like(flat_idx, dtype=value.dtype).unsqueeze(-1)) + reduced = reduced / counts.clamp_min(1) + elif reduce == 'sum': + pass + else: + raise ValueError(f"Unsupported reduce mode: {reduce}") + return reduced + +def sparse_cube2verts(coords, feats, training=True): + new_coords, cubes = construct_voxel_grid(coords) + new_feats = cubes_to_verts(new_coords.shape[0], cubes, feats) + if training: + con_loss = torch.mean((feats - new_feats[cubes]) ** 2) + else: + con_loss = 0.0 + return new_coords, new_feats, con_loss + + +def get_dense_attrs(coords : torch.Tensor, feats : torch.Tensor, res : int, sdf_init=True): + F = feats.shape[-1] + dense_attrs = torch.zeros([res] * 3 + [F], device=feats.device, dtype=feats.dtype) + if sdf_init: + dense_attrs[..., 0] = 1 # initial outside sdf value + dense_attrs[coords[:, 0], coords[:, 1], coords[:, 2], :] = feats + return dense_attrs.reshape(-1, F) + + +def get_defomed_verts(v_pos : torch.Tensor, deform : torch.Tensor, res): + return v_pos / res - 0.5 + (1 - 1e-8) / (res * 2) * torch.tanh(deform) + \ No newline at end of file diff --git a/anigen/representations/octree/__init__.py b/anigen/representations/octree/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f66a39a5a7498e2e99fe9d94d663796b3bc157b5 --- /dev/null +++ b/anigen/representations/octree/__init__.py @@ -0,0 +1 @@ +from .octree_dfs import DfsOctree \ No newline at end of file diff --git a/anigen/representations/octree/octree_dfs.py b/anigen/representations/octree/octree_dfs.py new file mode 100644 index 0000000000000000000000000000000000000000..c2bd4dc41b0d471227df0248f8c122be9bf9f453 --- /dev/null +++ b/anigen/representations/octree/octree_dfs.py @@ -0,0 +1,347 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class DfsOctree: + """ + Sparse Voxel Octree (SVO) implementation for PyTorch. + Using Depth-First Search (DFS) order to store the octree. + DFS order suits rendering and ray tracing. + + The structure and data are separatedly stored. + Structure is stored as a continuous array, each element is a 3*32 bits descriptor. + |-----------------------------------------| + | 0:3 bits | 4:31 bits | + | leaf num | unused | + |-----------------------------------------| + | 0:31 bits | + | child ptr | + |-----------------------------------------| + | 0:31 bits | + | data ptr | + |-----------------------------------------| + Each element represents a non-leaf node in the octree. + The valid mask is used to indicate whether the children are valid. + The leaf mask is used to indicate whether the children are leaf nodes. + The child ptr is used to point to the first non-leaf child. Non-leaf children descriptors are stored continuously from the child ptr. + The data ptr is used to point to the data of leaf children. Leaf children data are stored continuously from the data ptr. + + There are also auxiliary arrays to store the additional structural information to facilitate parallel processing. + - Position: the position of the octree nodes. + - Depth: the depth of the octree nodes. + + Args: + depth (int): the depth of the octree. + """ + + def __init__( + self, + depth, + aabb=[0,0,0,1,1,1], + sh_degree=2, + primitive='voxel', + primitive_config={}, + device='cuda', + ): + self.max_depth = depth + self.aabb = torch.tensor(aabb, dtype=torch.float32, device=device) + self.device = device + self.sh_degree = sh_degree + self.active_sh_degree = sh_degree + self.primitive = primitive + self.primitive_config = primitive_config + + self.structure = torch.tensor([[8, 1, 0]], dtype=torch.int32, device=self.device) + self.position = torch.zeros((8, 3), dtype=torch.float32, device=self.device) + self.depth = torch.zeros((8, 1), dtype=torch.uint8, device=self.device) + self.position[:, 0] = torch.tensor([0.25, 0.75, 0.25, 0.75, 0.25, 0.75, 0.25, 0.75], device=self.device) + self.position[:, 1] = torch.tensor([0.25, 0.25, 0.75, 0.75, 0.25, 0.25, 0.75, 0.75], device=self.device) + self.position[:, 2] = torch.tensor([0.25, 0.25, 0.25, 0.25, 0.75, 0.75, 0.75, 0.75], device=self.device) + self.depth[:, 0] = 1 + + self.data = ['position', 'depth'] + self.param_names = [] + + if primitive == 'voxel': + self.features_dc = torch.zeros((8, 1, 3), dtype=torch.float32, device=self.device) + self.features_ac = torch.zeros((8, (sh_degree+1)**2-1, 3), dtype=torch.float32, device=self.device) + self.data += ['features_dc', 'features_ac'] + self.param_names += ['features_dc', 'features_ac'] + if not primitive_config.get('solid', False): + self.density = torch.zeros((8, 1), dtype=torch.float32, device=self.device) + self.data.append('density') + self.param_names.append('density') + elif primitive == 'gaussian': + self.features_dc = torch.zeros((8, 1, 3), dtype=torch.float32, device=self.device) + self.features_ac = torch.zeros((8, (sh_degree+1)**2-1, 3), dtype=torch.float32, device=self.device) + self.opacity = torch.zeros((8, 1), dtype=torch.float32, device=self.device) + self.data += ['features_dc', 'features_ac', 'opacity'] + self.param_names += ['features_dc', 'features_ac', 'opacity'] + elif primitive == 'trivec': + self.trivec = torch.zeros((8, primitive_config['rank'], 3, primitive_config['dim']), dtype=torch.float32, device=self.device) + self.density = torch.zeros((8, primitive_config['rank']), dtype=torch.float32, device=self.device) + self.features_dc = torch.zeros((8, primitive_config['rank'], 1, 3), dtype=torch.float32, device=self.device) + self.features_ac = torch.zeros((8, primitive_config['rank'], (sh_degree+1)**2-1, 3), dtype=torch.float32, device=self.device) + self.density_shift = 0 + self.data += ['trivec', 'density', 'features_dc', 'features_ac'] + self.param_names += ['trivec', 'density', 'features_dc', 'features_ac'] + elif primitive == 'decoupoly': + self.decoupoly_V = torch.zeros((8, primitive_config['rank'], 3), dtype=torch.float32, device=self.device) + self.decoupoly_g = torch.zeros((8, primitive_config['rank'], primitive_config['degree']), dtype=torch.float32, device=self.device) + self.density = torch.zeros((8, primitive_config['rank']), dtype=torch.float32, device=self.device) + self.features_dc = torch.zeros((8, primitive_config['rank'], 1, 3), dtype=torch.float32, device=self.device) + self.features_ac = torch.zeros((8, primitive_config['rank'], (sh_degree+1)**2-1, 3), dtype=torch.float32, device=self.device) + self.density_shift = 0 + self.data += ['decoupoly_V', 'decoupoly_g', 'density', 'features_dc', 'features_ac'] + self.param_names += ['decoupoly_V', 'decoupoly_g', 'density', 'features_dc', 'features_ac'] + + self.setup_functions() + + def setup_functions(self): + self.density_activation = (lambda x: torch.exp(x - 2)) if self.primitive != 'trivec' else (lambda x: x) + self.opacity_activation = lambda x: torch.sigmoid(x - 6) + self.inverse_opacity_activation = lambda x: torch.log(x / (1 - x)) + 6 + self.color_activation = lambda x: torch.sigmoid(x) + + @property + def num_non_leaf_nodes(self): + return self.structure.shape[0] + + @property + def num_leaf_nodes(self): + return self.depth.shape[0] + + @property + def cur_depth(self): + return self.depth.max().item() + + @property + def occupancy(self): + return self.num_leaf_nodes / 8 ** self.cur_depth + + @property + def get_xyz(self): + return self.position + + @property + def get_depth(self): + return self.depth + + @property + def get_density(self): + if self.primitive == 'voxel' and self.primitive_config.get('solid', False): + return torch.full((self.position.shape[0], 1), torch.finfo(torch.float32).max, dtype=torch.float32, device=self.device) + return self.density_activation(self.density) + + @property + def get_opacity(self): + return self.opacity_activation(self.density) + + @property + def get_trivec(self): + return self.trivec + + @property + def get_decoupoly(self): + return F.normalize(self.decoupoly_V, dim=-1), self.decoupoly_g + + @property + def get_color(self): + return self.color_activation(self.colors) + + @property + def get_features(self): + if self.sh_degree == 0: + return self.features_dc + return torch.cat([self.features_dc, self.features_ac], dim=-2) + + def state_dict(self): + ret = {'structure': self.structure, 'position': self.position, 'depth': self.depth, 'sh_degree': self.sh_degree, 'active_sh_degree': self.active_sh_degree, 'primitive_config': self.primitive_config, 'primitive': self.primitive} + if hasattr(self, 'density_shift'): + ret['density_shift'] = self.density_shift + for data in set(self.data + self.param_names): + if not isinstance(getattr(self, data), nn.Module): + ret[data] = getattr(self, data) + else: + ret[data] = getattr(self, data).state_dict() + return ret + + def load_state_dict(self, state_dict): + keys = list(set(self.data + self.param_names + list(state_dict.keys()) + ['structure', 'position', 'depth'])) + for key in keys: + if key not in state_dict: + print(f"Warning: key {key} not found in the state_dict.") + continue + try: + if not isinstance(getattr(self, key), nn.Module): + setattr(self, key, state_dict[key]) + else: + getattr(self, key).load_state_dict(state_dict[key]) + except Exception as e: + print(e) + raise ValueError(f"Error loading key {key}.") + + def gather_from_leaf_children(self, data): + """ + Gather the data from the leaf children. + + Args: + data (torch.Tensor): the data to gather. The first dimension should be the number of leaf nodes. + """ + leaf_cnt = self.structure[:, 0] + leaf_cnt_masks = [leaf_cnt == i for i in range(1, 9)] + ret = torch.zeros((self.num_non_leaf_nodes,), dtype=data.dtype, device=self.device) + for i in range(8): + if leaf_cnt_masks[i].sum() == 0: + continue + start = self.structure[leaf_cnt_masks[i], 2] + for j in range(i+1): + ret[leaf_cnt_masks[i]] += data[start + j] + return ret + + def gather_from_non_leaf_children(self, data): + """ + Gather the data from the non-leaf children. + + Args: + data (torch.Tensor): the data to gather. The first dimension should be the number of leaf nodes. + """ + non_leaf_cnt = 8 - self.structure[:, 0] + non_leaf_cnt_masks = [non_leaf_cnt == i for i in range(1, 9)] + ret = torch.zeros_like(data, device=self.device) + for i in range(8): + if non_leaf_cnt_masks[i].sum() == 0: + continue + start = self.structure[non_leaf_cnt_masks[i], 1] + for j in range(i+1): + ret[non_leaf_cnt_masks[i]] += data[start + j] + return ret + + def structure_control(self, mask): + """ + Control the structure of the octree. + + Args: + mask (torch.Tensor): the mask to control the structure. 1 for subdivide, -1 for merge, 0 for keep. + """ + # Dont subdivide when the depth is the maximum. + mask[self.depth.squeeze() == self.max_depth] = torch.clamp_max(mask[self.depth.squeeze() == self.max_depth], 0) + # Dont merge when the depth is the minimum. + mask[self.depth.squeeze() == 1] = torch.clamp_min(mask[self.depth.squeeze() == 1], 0) + + # Gather control mask + structre_ctrl = self.gather_from_leaf_children(mask) + structre_ctrl[structre_ctrl==-8] = -1 + + new_leaf_num = self.structure[:, 0].clone() + # Modify the leaf num. + structre_valid = structre_ctrl >= 0 + new_leaf_num[structre_valid] -= structre_ctrl[structre_valid] # Add the new nodes. + structre_delete = structre_ctrl < 0 + merged_nodes = self.gather_from_non_leaf_children(structre_delete.int()) + new_leaf_num += merged_nodes # Delete the merged nodes. + + # Update the structure array to allocate new nodes. + mem_offset = torch.zeros((self.num_non_leaf_nodes + 1,), dtype=torch.int32, device=self.device) + mem_offset.index_add_(0, self.structure[structre_valid, 1], structre_ctrl[structre_valid]) # Add the new nodes. + mem_offset[:-1] -= structre_delete.int() # Delete the merged nodes. + new_structre_idx = torch.arange(0, self.num_non_leaf_nodes + 1, dtype=torch.int32, device=self.device) + mem_offset.cumsum(0) + new_structure_length = new_structre_idx[-1].item() + new_structre_idx = new_structre_idx[:-1] + new_structure = torch.empty((new_structure_length, 3), dtype=torch.int32, device=self.device) + new_structure[new_structre_idx[structre_valid], 0] = new_leaf_num[structre_valid] + + # Initialize the new nodes. + new_node_mask = torch.ones((new_structure_length,), dtype=torch.bool, device=self.device) + new_node_mask[new_structre_idx[structre_valid]] = False + new_structure[new_node_mask, 0] = 8 # Initialize to all leaf nodes. + new_node_num = new_node_mask.sum().item() + + # Rebuild child ptr. + non_leaf_cnt = 8 - new_structure[:, 0] + new_child_ptr = torch.cat([torch.zeros((1,), dtype=torch.int32, device=self.device), non_leaf_cnt.cumsum(0)[:-1]]) + new_structure[:, 1] = new_child_ptr + 1 + + # Rebuild data ptr with old data. + leaf_cnt = torch.zeros((new_structure_length,), dtype=torch.int32, device=self.device) + leaf_cnt.index_add_(0, new_structre_idx, self.structure[:, 0]) + old_data_ptr = torch.cat([torch.zeros((1,), dtype=torch.int32, device=self.device), leaf_cnt.cumsum(0)[:-1]]) + + # Update the data array + subdivide_mask = mask == 1 + merge_mask = mask == -1 + data_valid = ~(subdivide_mask | merge_mask) + mem_offset = torch.zeros((self.num_leaf_nodes + 1,), dtype=torch.int32, device=self.device) + mem_offset.index_add_(0, old_data_ptr[new_node_mask], torch.full((new_node_num,), 8, dtype=torch.int32, device=self.device)) # Add data array for new nodes + mem_offset[:-1] -= subdivide_mask.int() # Delete data elements for subdivide nodes + mem_offset[:-1] -= merge_mask.int() # Delete data elements for merge nodes + mem_offset.index_add_(0, self.structure[structre_valid, 2], merged_nodes[structre_valid]) # Add data elements for merge nodes + new_data_idx = torch.arange(0, self.num_leaf_nodes + 1, dtype=torch.int32, device=self.device) + mem_offset.cumsum(0) + new_data_length = new_data_idx[-1].item() + new_data_idx = new_data_idx[:-1] + new_data = {data: torch.empty((new_data_length,) + getattr(self, data).shape[1:], dtype=getattr(self, data).dtype, device=self.device) for data in self.data} + for data in self.data: + new_data[data][new_data_idx[data_valid]] = getattr(self, data)[data_valid] + + # Rebuild data ptr + leaf_cnt = new_structure[:, 0] + new_data_ptr = torch.cat([torch.zeros((1,), dtype=torch.int32, device=self.device), leaf_cnt.cumsum(0)[:-1]]) + new_structure[:, 2] = new_data_ptr + + # Initialize the new data array + ## For subdivide nodes + if subdivide_mask.sum() > 0: + subdivide_data_ptr = new_structure[new_node_mask, 2] + for data in self.data: + for i in range(8): + if data == 'position': + offset = torch.tensor([i // 4, (i // 2) % 2, i % 2], dtype=torch.float32, device=self.device) - 0.5 + scale = 2 ** (-1.0 - self.depth[subdivide_mask]) + new_data['position'][subdivide_data_ptr + i] = self.position[subdivide_mask] + offset * scale + elif data == 'depth': + new_data['depth'][subdivide_data_ptr + i] = self.depth[subdivide_mask] + 1 + elif data == 'opacity': + new_data['opacity'][subdivide_data_ptr + i] = self.inverse_opacity_activation(torch.sqrt(self.opacity_activation(self.opacity[subdivide_mask]))) + elif data == 'trivec': + offset = torch.tensor([i // 4, (i // 2) % 2, i % 2], dtype=torch.float32, device=self.device) * 0.5 + coord = (torch.linspace(0, 0.5, self.trivec.shape[-1], dtype=torch.float32, device=self.device)[None] + offset[:, None]).reshape(1, 3, self.trivec.shape[-1], 1) + axis = torch.linspace(0, 1, 3, dtype=torch.float32, device=self.device).reshape(1, 3, 1, 1).repeat(1, 1, self.trivec.shape[-1], 1) + coord = torch.stack([coord, axis], dim=3).reshape(1, 3, self.trivec.shape[-1], 2).expand(self.trivec[subdivide_mask].shape[0], -1, -1, -1) * 2 - 1 + new_data['trivec'][subdivide_data_ptr + i] = F.grid_sample(self.trivec[subdivide_mask], coord, align_corners=True) + else: + new_data[data][subdivide_data_ptr + i] = getattr(self, data)[subdivide_mask] + ## For merge nodes + if merge_mask.sum() > 0: + merge_data_ptr = torch.empty((merged_nodes.sum().item(),), dtype=torch.int32, device=self.device) + merge_nodes_cumsum = torch.cat([torch.zeros((1,), dtype=torch.int32, device=self.device), merged_nodes.cumsum(0)[:-1]]) + for i in range(8): + merge_data_ptr[merge_nodes_cumsum[merged_nodes > i] + i] = new_structure[new_structre_idx[merged_nodes > i], 2] + i + old_merge_data_ptr = self.structure[structre_delete, 2] + for data in self.data: + if data == 'position': + scale = 2 ** (1.0 - self.depth[old_merge_data_ptr]) + new_data['position'][merge_data_ptr] = ((self.position[old_merge_data_ptr] + 0.5) / scale).floor() * scale + 0.5 * scale - 0.5 + elif data == 'depth': + new_data['depth'][merge_data_ptr] = self.depth[old_merge_data_ptr] - 1 + elif data == 'opacity': + new_data['opacity'][subdivide_data_ptr + i] = self.inverse_opacity_activation(self.opacity_activation(self.opacity[subdivide_mask])**2) + elif data == 'trivec': + new_data['trivec'][merge_data_ptr] = self.trivec[old_merge_data_ptr] + else: + new_data[data][merge_data_ptr] = getattr(self, data)[old_merge_data_ptr] + + # Update the structure and data array + self.structure = new_structure + for data in self.data: + setattr(self, data, new_data[data]) + + # Save data array control temp variables + self.data_rearrange_buffer = { + 'subdivide_mask': subdivide_mask, + 'merge_mask': merge_mask, + 'data_valid': data_valid, + 'new_data_idx': new_data_idx, + 'new_data_length': new_data_length, + 'new_data': new_data + } diff --git a/anigen/representations/radiance_field/__init__.py b/anigen/representations/radiance_field/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b72a1b7e76b509ee5a5e6979858eb17b4158a151 --- /dev/null +++ b/anigen/representations/radiance_field/__init__.py @@ -0,0 +1 @@ +from .strivec import Strivec \ No newline at end of file diff --git a/anigen/representations/radiance_field/strivec.py b/anigen/representations/radiance_field/strivec.py new file mode 100644 index 0000000000000000000000000000000000000000..8fc4b749786d934dae82864b560baccd91fcabbc --- /dev/null +++ b/anigen/representations/radiance_field/strivec.py @@ -0,0 +1,28 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from ..octree import DfsOctree as Octree + + +class Strivec(Octree): + def __init__( + self, + resolution: int, + aabb: list, + sh_degree: int = 0, + rank: int = 8, + dim: int = 8, + device: str = "cuda", + ): + assert np.log2(resolution) % 1 == 0, "Resolution must be a power of 2" + self.resolution = resolution + depth = int(np.round(np.log2(resolution))) + super().__init__( + depth=depth, + aabb=aabb, + sh_degree=sh_degree, + primitive="trivec", + primitive_config={"rank": rank, "dim": dim}, + device=device, + ) diff --git a/anigen/representations/skeleton/grouping.py b/anigen/representations/skeleton/grouping.py new file mode 100644 index 0000000000000000000000000000000000000000..0c227b2afdb87fc4c8d5a59094e9650efe274f43 --- /dev/null +++ b/anigen/representations/skeleton/grouping.py @@ -0,0 +1,181 @@ +import torch +import numpy as np +from pytorch3d.ops import ball_query, knn_points + + +def disjoint_set_unioin_find(N, pairs): + def find(x, parent): + if parent[x] != x: + parent[x] = find(parent[x], parent) + return parent[x] + def union(a, b, parent, rank): + rootA = find(a, parent) + rootB = find(b, parent) + if rootA != rootB: + if rank[rootA] > rank[rootB]: + parent[rootB] = rootA + elif rank[rootA] < rank[rootB]: + parent[rootA] = rootB + else: + parent[rootB] = rootA + rank[rootA] += 1 + parent = list(range(N)) + rank = [0] * N + for a, b in pairs: + if a >= 0 and b >= 0: + union(a, b, parent, rank) + for i in range(N): + find(i, parent) + root_ids = np.unique(parent) + num_joints = len(root_ids) + joints_index_map = {root_id: idx for idx, root_id in enumerate(root_ids)} + joints_idx = [joints_index_map[parent[i]] for i in range(N)] + return num_joints, joints_idx + + +def threshold_grouping(joints, parents, joints_conf=None, parents_conf=None, conf_threshold=0.1, threshold=1/32): + ''' + Cluster joints and parents with confidence based on the threshold + Input: + joints: torch.Tensor [N, 3] coordinates of predicted joints + parents: torch.Tensor [N, 3] coordinates of predicted parents + joints_conf: torch.Tensor [N, 1] confidence of predicted joints + parents_conf: torch.Tensor [N, 1] confidence of predicted parents + conf_threshold: confidence threshold to filter joints and parents + threshold: distance threshold to group joints and parents + Output: + grouped_joints: [M, 3] coordinates of grouped joints + grouped_parents: [M] indexes of grouped parents + ''' + assert joints.shape == parents.shape, "joints and parents must have the same shape" + # Confidence filtering + joints_conf = torch.ones_like(joints[:, 0:1]) if joints_conf is None else joints_conf + parents_conf = torch.ones_like(parents[:, 0:1]) if parents_conf is None else parents_conf + conf_mask = ((joints_conf >= conf_threshold) & (parents_conf >= conf_threshold)).squeeze() + if not torch.any(conf_mask): + return joints.new_empty((0, 3)), joints.new_empty((0, 1), dtype=torch.long) + joints, parents, joints_conf, parents_conf = joints[conf_mask], parents[conf_mask], joints_conf[conf_mask], parents_conf[conf_mask] + # Threshold grouping + _, ball_query_idx, _ = ball_query(joints.unsqueeze(0), joints.unsqueeze(0), K=9, radius=threshold) + ball_query_idx = ball_query_idx[0, :, 1:] + pairs = [[idx, neighbor.item()] for idx, neighbors in enumerate(ball_query_idx) for neighbor in neighbors] + Nj, joints_idx = disjoint_set_unioin_find(joints.shape[0], pairs) + joints_idx = torch.tensor(joints_idx, device=joints.device).long() + # Compute grouped joints and parents + grouped_joints_weighted = torch.scatter_add(torch.zeros((Nj, 3), device=joints.device), 0, joints_idx.unsqueeze(1).expand(-1, 3), joints * joints_conf) + grouped_joints_conf_sum = torch.scatter_add(torch.zeros((Nj, 1), device=joints.device), 0, joints_idx.unsqueeze(1), joints_conf) + grouped_joints = grouped_joints_weighted / (grouped_joints_conf_sum + 1e-8) + grouped_parents_weighted = torch.scatter_add(torch.zeros((Nj, 3), device=joints.device), 0, joints_idx.unsqueeze(1).expand(-1, 3), parents * parents_conf) + grouped_parents_conf_sum = torch.scatter_add(torch.zeros((Nj, 1), device=joints.device), 0, joints_idx.unsqueeze(1), parents_conf) + grouped_parents = grouped_parents_weighted / (grouped_parents_conf_sum + 1e-8) + # Determine the parents index + parents_idx = knn_points(grouped_parents.unsqueeze(0), grouped_joints.unsqueeze(0), K=1).idx[0, :, 0] + parents_idx[parents_idx == torch.arange(parents_idx.shape[0], device=parents_idx.device)] = -1 + return grouped_joints, parents_idx + + +def mean_shift_grouping(joints, parents, joints_conf=None, parents_conf=None, conf_threshold=0.5, threshold=1/100, cluster_size_threshold=5): + ''' + Cluster joints and parents with confidence based on a mean shift procedure + Input: + joints: torch.Tensor [N, 3] coordinates of predicted joints + parents: torch.Tensor [N, 3] coordinates of predicted parents + joints_conf: torch.Tensor [N, 1] confidence of predicted joints + parents_conf: torch.Tensor [N, 1] confidence of predicted parents + conf_threshold: confidence threshold to filter joints and parents + threshold: bandwidth parameter for mean shift (radius of local window) + Output: + grouped_joints: [M, 3] coordinates of grouped joints + grouped_parents: [M] indexes of grouped parents + ''' + assert joints.shape == parents.shape, "joints and parents must have the same shape" + joints_conf = torch.ones_like(joints[:, 0:1]) if joints_conf is None else joints_conf + parents_conf = torch.ones_like(parents[:, 0:1]) if parents_conf is None else parents_conf + + conf_mask = ((joints_conf >= conf_threshold) & (parents_conf >= conf_threshold)).squeeze() + if not torch.any(conf_mask): + return torch.zeros_like(joints[:1]), torch.zeros([1], device=joints.device, dtype=torch.long) + + joints = joints[conf_mask] + parents = parents[conf_mask] + joints_conf = joints_conf[conf_mask] + parents_conf = parents_conf[conf_mask] + + bandwidth = max(float(threshold), 1e-4) + tol = bandwidth * 0.1 + max_iters = 30 + max_neighbors = 32 + inv_two_sigma_sq = 0.5 / (bandwidth * bandwidth) + + # Mean shift iterations (vectorized over all points) + shifted = joints.clone() + weights = joints_conf + for _ in range(max_iters): + neighbor_dist, neighbor_idx, _ = ball_query(shifted.unsqueeze(0), shifted.unsqueeze(0), K=max_neighbors+1, radius=bandwidth) + neighbor_dist, neighbor_idx = neighbor_dist[0, :, 1:], neighbor_idx[0, :, 1:] + valid_mask = (neighbor_idx >= 0) + safe_idx = neighbor_idx.clamp(min=0) + neighbor_points = shifted[safe_idx] + neighbor_weights = weights[safe_idx] + neighbor_weights = neighbor_weights * valid_mask[..., None].float() + + kernel = torch.exp(-neighbor_dist.unsqueeze(-1) * inv_two_sigma_sq) * valid_mask[..., None].float() + neighbor_weights = neighbor_weights * kernel + + weight_sum = neighbor_weights.sum(dim=1) + weighted_sum = (neighbor_points * neighbor_weights).sum(dim=1) + updated = torch.where(weight_sum > 0, weighted_sum / (weight_sum + 1e-8), shifted) + max_shift = (updated - shifted).norm(dim=1).max() + shifted = updated + if max_shift <= tol: + break + + # Merge converged points into discrete clusters + Nc = shifted.shape[0] + cluster_indices = torch.full((Nc,), -1, dtype=torch.long, device=joints.device) + merge_radius = bandwidth * 0.5 + cluster_count = 0 + for i in range(Nc): + if cluster_indices[i] >= 0: + continue + center = shifted[i] + distances = torch.norm(shifted - center, dim=1) + same_cluster = distances <= merge_radius + cluster_indices[same_cluster] = cluster_count + cluster_count += 1 + + Nj = cluster_count + joints_idx = cluster_indices + + cluster_sizes = torch.bincount(joints_idx, minlength=Nj).float() + if cluster_size_threshold > 0: + keep_mask = cluster_sizes >= cluster_size_threshold + else: + keep_mask = torch.ones((Nj,), dtype=torch.bool, device=joints.device) + if not torch.any(keep_mask): + keep_mask = torch.ones((Nj,), dtype=torch.bool, device=joints.device) + + grouped_joints_weighted = torch.scatter_add(torch.zeros((Nj, 3), device=joints.device), 0, joints_idx.unsqueeze(1).expand(-1, 3), joints * joints_conf) + grouped_joints_conf_sum = torch.scatter_add(torch.zeros((Nj, 1), device=joints.device), 0, joints_idx.unsqueeze(1), joints_conf) + grouped_joints = grouped_joints_weighted / (grouped_joints_conf_sum + 1e-8) + + grouped_parents_weighted = torch.scatter_add( torch.zeros((Nj, 3), device=joints.device), 0, joints_idx.unsqueeze(1).expand(-1, 3), parents * parents_conf) + grouped_parents_conf_sum = torch.scatter_add( torch.zeros((Nj, 1), device=joints.device), 0, joints_idx.unsqueeze(1), parents_conf) + grouped_parents = grouped_parents_weighted / (grouped_parents_conf_sum + 1e-8) + + grouped_joints = grouped_joints[keep_mask] + grouped_parents = grouped_parents[keep_mask] + + if grouped_joints.numel() == 0: + return torch.zeros_like(joints[:1]), torch.zeros([1], device=joints.device, dtype=torch.long) + + parents_idx = knn_points(grouped_parents.unsqueeze(0), grouped_joints.unsqueeze(0), K=1).idx[0, :, 0] + parents_idx[parents_idx == torch.arange(parents_idx.shape[0], device=parents_idx.device)] = -1 + return grouped_joints, parents_idx + + +GROUPING_STRATEGIES = { + "threshold": threshold_grouping, + "mean_shift": mean_shift_grouping, +} + diff --git a/anigen/trainers/__init__.py b/anigen/trainers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..690fe484de378ff992f036ddfa9ac3252e4f471f --- /dev/null +++ b/anigen/trainers/__init__.py @@ -0,0 +1,35 @@ +import importlib + +__attributes = { + 'BasicTrainer': 'basic', + + 'AniGenSparseStructureVaeTrainer': 'vae.anigen_sparse_structure_vae', + 'AniGenSLatVaeSkeletonTrainer': 'vae.anigen_slat_mesh_vae', + 'AniGenSLatGaussianVAETrainer': 'vae.anigen_slat_gs_vae', + 'AniGenSkinAETrainer': 'vae.anigen_skin_ae', + 'AniGenFlowMatchingTrainer': 'flow_matching.anigen_flow_matching', + 'AniGenFlowMatchingCFGTrainer': 'flow_matching.anigen_flow_matching', + 'AniGenTextConditionedFlowMatchingCFGTrainer': 'flow_matching.anigen_flow_matching', + 'AniGenImageConditionedFlowMatchingCFGTrainer': 'flow_matching.anigen_flow_matching', + 'AniGenSparseFlowMatchingTrainer': 'flow_matching.anigen_sparse_flow_matching', + 'AniGenSparseFlowMatchingCFGTrainer': 'flow_matching.anigen_sparse_flow_matching', + 'AniGenTextConditionedSparseFlowMatchingCFGTrainer': 'flow_matching.anigen_sparse_flow_matching', + 'AniGenImageConditionedSparseFlowMatchingCFGTrainer': 'flow_matching.anigen_sparse_flow_matching', +} + +__submodules = [] + +__all__ = list(__attributes.keys()) + __submodules + +def __getattr__(name): + if name not in globals(): + if name in __attributes: + module_name = __attributes[name] + module = importlib.import_module(f".{module_name}", __name__) + globals()[name] = getattr(module, name) + elif name in __submodules: + module = importlib.import_module(f".{name}", __name__) + globals()[name] = module + else: + raise AttributeError(f"module {__name__} has no attribute {name}") + return globals()[name] diff --git a/anigen/trainers/base.py b/anigen/trainers/base.py new file mode 100644 index 0000000000000000000000000000000000000000..552d46a5e86d99d4af9826040226dbd07075da39 --- /dev/null +++ b/anigen/trainers/base.py @@ -0,0 +1,556 @@ +from abc import abstractmethod +import os +import time +import json + +import torch +import torch.distributed as dist +from torch.utils.data import DataLoader +import numpy as np + +from torchvision import utils +from torch.utils.tensorboard import SummaryWriter + +from .utils import * +from ..utils.general_utils import * +from ..utils.data_utils import recursive_to_device, cycle, ResumableSampler + + +class Trainer: + """ + Base class for training. + """ + def __init__(self, + models, + dataset, + *, + output_dir, + load_dir, + step, + max_steps, + batch_size=None, + batch_size_per_gpu=None, + batch_split=None, + optimizer={}, + lr_scheduler=None, + elastic=None, + grad_clip=None, + ema_rate=0.9999, + fp16_mode='inflat_all', + fp16_scale_growth=1e-3, + finetune_ckpt=None, + log_param_stats=False, + prefetch_data=True, + i_print=500, + i_log=500, + i_sample=10000, + i_save=10000, + i_ddpcheck=10000, + skip_init_snapshot=False, + loss_scaling=True, + muon_param_dtype=None, + num_workers_dl=None, + **kwargs + ): + assert batch_size is not None or batch_size_per_gpu is not None, 'Either batch_size or batch_size_per_gpu must be specified.' + + self.models = models + self.dataset = dataset + self.num_workers_dl = num_workers_dl if num_workers_dl is not None else int(np.ceil(os.cpu_count() / torch.cuda.device_count())) + self.batch_split = batch_split if batch_split is not None else 1 + self.max_steps = max_steps + self.optimizer_config = optimizer + self.lr_scheduler_config = lr_scheduler + self.elastic_controller_config = elastic + self.grad_clip = grad_clip + self.ema_rate = [ema_rate] if isinstance(ema_rate, float) else ema_rate + self.fp16_mode = fp16_mode + self.fp16_scale_growth = fp16_scale_growth + self.log_param_stats = log_param_stats + self.prefetch_data = prefetch_data + if self.prefetch_data: + self._data_prefetched = None + + self.output_dir = output_dir + self.i_print = i_print + self.i_log = i_log + self.i_sample = i_sample + self.i_save = i_save + self.i_ddpcheck = i_ddpcheck + self.skip_init_snapshot = skip_init_snapshot + self.loss_scaling = loss_scaling + self.muon_param_dtype = muon_param_dtype + + if dist.is_initialized(): + # Multi-GPU params + self.world_size = dist.get_world_size() + self.rank = dist.get_rank() + self.local_rank = dist.get_rank() % torch.cuda.device_count() + self.is_master = self.rank == 0 + else: + # Single-GPU params + self.world_size = 1 + self.rank = 0 + self.local_rank = 0 + self.is_master = True + + self.batch_size = batch_size if batch_size_per_gpu is None else batch_size_per_gpu * self.world_size + self.batch_size_per_gpu = batch_size_per_gpu if batch_size_per_gpu is not None else batch_size // self.world_size + assert self.batch_size % self.world_size == 0, 'Batch size must be divisible by the number of GPUs.' + assert self.batch_size_per_gpu % self.batch_split == 0, 'Batch size per GPU must be divisible by batch split.' + + self.init_models_and_more(**kwargs) + self.prepare_dataloader(**kwargs) + + # Load checkpoint + self.step = 0 + if load_dir is not None and step is not None: + self.load(load_dir, step) + elif finetune_ckpt is not None: + self.finetune_from(finetune_ckpt) + if step is None or step == 0: + self.load_pretrain(load_dir) + + if self.is_master: + os.makedirs(os.path.join(self.output_dir, 'ckpts'), exist_ok=True) + os.makedirs(os.path.join(self.output_dir, 'samples'), exist_ok=True) + self.writer = SummaryWriter(os.path.join(self.output_dir, 'tb_logs')) + + if self.world_size > 1: + self.check_ddp() + + if self.is_master: + print('\n\nTrainer initialized.') + print(self) + + @property + def device(self): + for _, model in self.models.items(): + if hasattr(model, 'device'): + return model.device + return next(list(self.models.values())[0].parameters()).device + + @abstractmethod + def init_models_and_more(self, **kwargs): + """ + Initialize models and more. + """ + pass + + def prepare_dataloader(self, **kwargs): + """ + Prepare dataloader. + """ + self.data_sampler = ResumableSampler( + self.dataset, + shuffle=True, + ) + self.dataloader = DataLoader( + self.dataset, + batch_size=self.batch_size_per_gpu, + num_workers=self.num_workers_dl, + pin_memory=True, + drop_last=True, + persistent_workers=True if self.num_workers_dl > 0 else False, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + sampler=self.data_sampler, + ) + self.data_iterator = cycle(self.dataloader) + + def load_pretrain(self, load_dir): + """ + Load pretrained checkpoints. + Should be called by all processes. + """ + pass + + @abstractmethod + def load(self, load_dir, step=0): + """ + Load a checkpoint. + Should be called by all processes. + """ + pass + + @abstractmethod + def save(self): + """ + Save a checkpoint. + Should be called only by the rank 0 process. + """ + pass + + @abstractmethod + def finetune_from(self, finetune_ckpt): + """ + Finetune from a checkpoint. + Should be called by all processes. + """ + pass + + @abstractmethod + def run_snapshot(self, num_samples, batch_size=4, verbose=False, **kwargs): + """ + Run a snapshot of the model. + """ + pass + + @torch.no_grad() + def visualize_sample(self, sample): + """ + Convert a sample to an image. + """ + if hasattr(self.dataset, 'visualize_sample'): + return self.dataset.visualize_sample(sample) + else: + return sample + + @torch.no_grad() + def snapshot_dataset(self, num_samples=100): + """ + Sample images from the dataset. + """ + dataloader = torch.utils.data.DataLoader( + self.dataset, + batch_size=num_samples, + num_workers=0, + shuffle=True, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + data = next(iter(dataloader)) + data = recursive_to_device(data, self.device) + vis = self.visualize_sample(data) + if isinstance(vis, dict): + save_cfg = [(f'dataset_{k}', v) for k, v in vis.items()] + elif vis is None: + save_cfg = [] + else: + save_cfg = [('dataset', vis)] + for name, image in save_cfg: + utils.save_image( + image, + os.path.join(self.output_dir, 'samples', f'{name}.jpg'), + nrow=int(np.sqrt(num_samples)), + normalize=True, + value_range=self.dataset.value_range, + ) + + @torch.no_grad() + def snapshot(self, suffix=None, num_samples=64, batch_size=4, verbose=False, force_no_split=False, **kwargs): + """ + Sample images from the model. + NOTE: This function should be called by all processes. + """ + if self.is_master: + print(f'\nSampling {num_samples} images...', end='') + + if suffix is None: + suffix = f'step{self.step:07d}' + + # Assign tasks + num_samples_per_process = int(np.ceil(num_samples / self.world_size)) if not force_no_split else num_samples + samples = self.run_snapshot(num_samples_per_process, batch_size=batch_size, verbose=verbose, **kwargs) + + # Preprocess images + for key in list(samples.keys()): + if samples[key]['type'] == 'sample': + vis = self.visualize_sample(samples[key]['value']) + if isinstance(vis, dict): + for k, v in vis.items(): + samples[f'{key}_{k}'] = {'value': v, 'type': 'image'} + del samples[key] + else: + samples[key] = {'value': vis, 'type': 'image'} + + # Gather results + if self.world_size > 1: + for key in sorted(samples.keys()): + samples[key]['value'] = samples[key]['value'].contiguous() if type(samples[key]['value']) is torch.Tensor else samples[key]['value'] + if self.is_master: + all_images = [torch.empty_like(samples[key]['value']) for _ in range(self.world_size)] if type(samples[key]['value']) is torch.Tensor else [None for _ in range(self.world_size)] + else: + all_images = [] + if type(samples[key]['value']) is torch.Tensor: + dist.gather(samples[key]['value'], all_images, dst=0) + else: + dist.gather_object(samples[key]['value'], all_images, dst=0) + if self.is_master: + if type(samples[key]['value']) is torch.Tensor: + samples[key]['value'] = torch.cat(all_images, dim=0)[:num_samples].cpu() + else: + del samples[key] # Free memory on non-master processes + torch.cuda.empty_cache() + + # Save images + if self.is_master: + os.makedirs(os.path.join(self.output_dir, 'samples', suffix), exist_ok=True) + scalars = {} + for key in samples.keys(): + if samples[key]['type'] == 'image': + utils.save_image( + samples[key]['value'], + os.path.join(self.output_dir, 'samples', suffix, f'{key}_{suffix}.jpg'), + nrow=int(np.sqrt(num_samples)), + normalize=True, + value_range=self.dataset.value_range, + ) + elif samples[key]['type'] == 'number': + min = samples[key]['value'].min() + max = samples[key]['value'].max() + images = (samples[key]['value'] - min) / (max - min) + images = utils.make_grid( + images, + nrow=int(np.sqrt(num_samples)), + normalize=False, + ) + save_image_with_notes( + images, + os.path.join(self.output_dir, 'samples', suffix, f'{key}_{suffix}.jpg'), + notes=f'{key} min: {min}, max: {max}', + ) + elif samples[key]['type'] == 'skeletoned_mesh_list': + if samples[key]['value'] is not None: + mesh_list = samples[key]['value'] + import trimesh + for mesh in mesh_list: + save_dir = os.path.join(self.output_dir, 'samples', suffix, key, mesh['instance']) + os.makedirs(save_dir, exist_ok=True) + trimesh.Trimesh(vertices=mesh['vertices'].cpu().numpy(), faces=mesh['faces'].cpu().numpy(), process=False).export(save_dir + '/mesh_skl.obj') + np.savez(os.path.join(save_dir, 'skeleton.npz'), + joints=mesh['joints'].cpu().numpy(), + parents=mesh['parents'].cpu().numpy(), + skin=mesh['skin'].cpu().numpy()) + elif samples[key]['type'] == 'joints_parents': + if samples[key]['value'] is not None: + jp_list = samples[key]['value'] + for jp in jp_list: + # Save N*6 arrays as colored point clouds + def save_colored_pcl(array, filename): + array = array.detach().cpu().numpy() + points = array[:, :3] + colors = (array[:, 3:6] * 255).astype(np.uint8) + # Combine points and colors into a single array + data = np.hstack((points, colors)) + # Define the .ply header + header = f"""ply\nformat ascii 1.0\nelement vertex {points.shape[0]}\nproperty float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header\n""" + # Write to the .ply file + with open(filename, 'w') as file: + file.write(header) + np.savetxt(file, data, fmt='%f %f %f %d %d %d') + save_dir = os.path.join(self.output_dir, 'samples', suffix, key, jp['instance']) + os.makedirs(save_dir, exist_ok=True) + for jp_key in jp.keys(): + if jp_key != 'instance': + save_colored_pcl(jp[jp_key], os.path.join(save_dir, f'{jp_key}.ply')) + elif samples[key]['type'] == 'point_cloud': + if samples[key]['value'] is not None: + pcl_list = samples[key]['value'] + save_dir = os.path.join(self.output_dir, 'samples', suffix, key) + os.makedirs(save_dir, exist_ok=True) + for i, item in enumerate(pcl_list): + pcl = item['pcl'] + name = item['instance'] # item.get('instance', f'{i}') + filename = os.path.join(save_dir, f'{name}.ply') + array = pcl.detach().cpu().numpy() + points = array[:, :3] + colors = (array[:, 3:6] * 255).astype(np.uint8) + data = np.hstack((points, colors)) + header = f"""ply\nformat ascii 1.0\nelement vertex {points.shape[0]}\nproperty float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header\n""" + with open(filename, 'w') as file: + file.write(header) + np.savetxt(file, data, fmt='%f %f %f %d %d %d') + elif samples[key]['type'] == 'scalar': + scalars[key] = samples[key]['value'].mean().item() + elif samples[key]['type'] == 'text': + with open(f'{self.output_dir}/samples/{suffix}/{key}.txt', 'w') as file: + for line in samples[key]['value']: + file.writelines(line + '\n') + # If scalars is not empty, save them to a JSON file + if scalars: + with open(os.path.join(self.output_dir, 'samples', suffix, 'scalars.json'), 'w') as f: + json.dump(scalars, f, indent=4) + + # Delete previous saved samples to save disk space. Keep only the first and the last twos + samples_dir = os.path.join(self.output_dir, 'samples') + all_saved = sorted([d for d in os.listdir(samples_dir) if d.startswith('step')]) + if self.is_master and len(all_saved) > 3: + for saved in all_saved[1:-2]: + saved_path = os.path.join(samples_dir, saved) + print(f'Removing previous sample at {saved_path} to save disk space.') + if os.path.isdir(saved_path): + import shutil + shutil.rmtree(saved_path) + else: + os.remove(saved_path) + + if self.is_master: + print(' Done.') + + @abstractmethod + def update_ema(self): + """ + Update exponential moving average. + Should only be called by the rank 0 process. + """ + pass + + @abstractmethod + def check_ddp(self): + """ + Check if DDP is working properly. + Should be called by all process. + """ + pass + + @abstractmethod + def training_losses(**mb_data): + """ + Compute training losses. + """ + pass + + def load_data(self): + """ + Load data. + """ + if self.prefetch_data: + if self._data_prefetched is None: + self._data_prefetched = recursive_to_device(next(self.data_iterator), self.device, non_blocking=True) + data = self._data_prefetched + self._data_prefetched = recursive_to_device(next(self.data_iterator), self.device, non_blocking=True) + else: + data = recursive_to_device(next(self.data_iterator), self.device, non_blocking=True) + + # if the data is a dict, we need to split it into multiple dicts with batch_size_per_gpu + if isinstance(data, dict): + if self.batch_split == 1: + data_list = [data] + else: + batch_size = list(data.values())[0].shape[0] if hasattr(list(data.values())[0], 'shape') else len(list(data.values())[0]) + data_list = [ + {k: v[i * batch_size // self.batch_split:(i + 1) * batch_size // self.batch_split] for k, v in data.items()} + for i in range(self.batch_split) + ] + elif isinstance(data, list): + data_list = data + else: + raise ValueError('Data must be a dict or a list of dicts.') + + return data_list + + @abstractmethod + def run_step(self, data_list): + """ + Run a training step. + """ + pass + + def run(self): + """ + Run training. + """ + if not self.skip_init_snapshot: + if self.is_master: + print('\nStarting training...') + self.snapshot_dataset() + if self.step == 0: + self.snapshot(suffix='init') + else: # resume + self.snapshot(suffix=f'resume_step{self.step:07d}') + + log = [] + time_last_print = 0.0 + time_elapsed = 0.0 + while self.step < self.max_steps: + time_start = time.time() + + data_list = self.load_data() + step_log = self.run_step(data_list) + + time_end = time.time() + time_elapsed += time_end - time_start + + self.step += 1 + + # Print progress + if self.is_master and self.step % self.i_print == 0: + speed = self.i_print / (time_elapsed - time_last_print) * 3600 + columns = [ + f'Step: {self.step}/{self.max_steps} ({self.step / self.max_steps * 100:.2f}%)', + f'Elapsed: {time_elapsed / 3600:.2f} h', + f'Speed: {speed:.2f} steps/h', + f'ETA: {(self.max_steps - self.step) / speed:.2f} h', + ] + print(' | '.join([c.ljust(25) for c in columns]), flush=True) + time_last_print = time_elapsed + + # Check ddp + if self.world_size > 1 and self.i_ddpcheck is not None and self.step % self.i_ddpcheck == 0: + self.check_ddp() + + # Sample images + if self.i_sample > 0 and self.step % self.i_sample == 0: + self.snapshot() + + if self.is_master: + log.append((self.step, {})) + + # Log time + log[-1][1]['time'] = { + 'step': time_end - time_start, + 'elapsed': time_elapsed, + } + + # Log losses + if step_log is not None: + log[-1][1].update(step_log) + + # Log scale + if 'amp' in self.fp16_mode: + log[-1][1]['scale'] = self.scaler.get_scale() + elif self.fp16_mode == 'inflat_all' or self.loss_scaling: + log[-1][1]['log_scale'] = self.log_scale + + # Save log + if self.step % self.i_log == 0: + ## save to log file + log_str = '\n'.join([ + f'{step}: {json.dumps(log)}' for step, log in log + ]) + with open(os.path.join(self.output_dir, 'log.txt'), 'a') as log_file: + log_file.write(log_str + '\n') + + # show with mlflow + log_show = [l for _, l in log if not dict_any(l, lambda x: np.isnan(x))] + if len(log_show) > 0: + log_show = dict_reduce(log_show, lambda x: np.mean(x)) + log_show = dict_flatten(log_show, sep='/') + for key, value in log_show.items(): + self.writer.add_scalar(key, value, self.step) + else: + print(f'No valid logs to show. Skipping logging at step {self.step}.') + log = [] + + # Save checkpoint + if self.step % self.i_save == 0: + self.save() + + if self.is_master: + self.snapshot(suffix='final') + self.writer.close() + print('Training finished.') + + def profile(self, wait=2, warmup=3, active=5): + """ + Profile the training loop. + """ + with torch.profiler.profile( + schedule=torch.profiler.schedule(wait=wait, warmup=warmup, active=active, repeat=1), + on_trace_ready=torch.profiler.tensorboard_trace_handler(os.path.join(self.output_dir, 'profile')), + profile_memory=True, + with_stack=True, + ) as prof: + for _ in range(wait + warmup + active): + self.run_step() + prof.step() + \ No newline at end of file diff --git a/anigen/trainers/basic.py b/anigen/trainers/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..f38bb7503bb22a2974bf09747f045f118dd901b4 --- /dev/null +++ b/anigen/trainers/basic.py @@ -0,0 +1,684 @@ +from email.policy import strict +import os +import copy +from functools import partial +from contextlib import nullcontext + +import torch +import torch.distributed as dist +from torch.nn.parallel import DistributedDataParallel as DDP +import numpy as np + +from .utils import * +from .base import Trainer +from ..utils.general_utils import * +from ..utils.dist_utils import * +from ..utils import grad_clip_utils, elastic_utils + + +class BasicTrainer(Trainer): + """ + Trainer for basic training loop. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + """ + + def __str__(self): + lines = [] + lines.append(self.__class__.__name__) + lines.append(f' - Models:') + for name, model in self.models.items(): + lines.append(f' - {name}: {model.__class__.__name__}') + lines.append(f' - Dataset: {indent(str(self.dataset), 2)}') + lines.append(f' - Dataloader:') + lines.append(f' - Sampler: {self.dataloader.sampler.__class__.__name__}') + lines.append(f' - Num workers: {self.dataloader.num_workers}') + lines.append(f' - Number of steps: {self.max_steps}') + lines.append(f' - Number of GPUs: {self.world_size}') + lines.append(f' - Batch size: {self.batch_size}') + lines.append(f' - Batch size per GPU: {self.batch_size_per_gpu}') + lines.append(f' - Batch split: {self.batch_split}') + lines.append(f' - Optimizer: {self.optimizer.__class__.__name__}') + lines.append(f' - Learning rate: {self.optimizer.param_groups[0]["lr"]}') + if self.lr_scheduler_config is not None: + lines.append(f' - LR scheduler: {self.lr_scheduler.__class__.__name__}') + if self.elastic_controller_config is not None: + lines.append(f' - Elastic memory: {indent(str(self.elastic_controller), 2)}') + if self.grad_clip is not None: + lines.append(f' - Gradient clip: {indent(str(self.grad_clip), 2)}') + lines.append(f' - EMA rate: {self.ema_rate}') + lines.append(f' - FP16 mode: {self.fp16_mode}') + return '\n'.join(lines) + + def init_models_and_more(self, **kwargs): + """ + Initialize models and more. + """ + if self.optimizer_config['name'].lower() == 'muon': + self._ensure_uniform_param_dtype_for_muon() + + if self.world_size > 1: + # Prepare distributed data parallel. + # NOTE: PyTorch will raise if a module has no trainable parameters. + self.training_models = {} + for name, model in self.models.items(): + has_trainable_params = any(p.requires_grad for p in model.parameters()) + if has_trainable_params: + self.training_models[name] = DDP( + model, + device_ids=[self.local_rank], + output_device=self.local_rank, + bucket_cap_mb=128, + find_unused_parameters=False + ) + else: + self.training_models[name] = model + if self.is_master: + print(f"\n\033[93mWarning: Model '{name}' has no trainable parameters; skipping DDP wrapping.\033[0m") + else: + self.training_models = self.models + + if self.optimizer_config['name'].lower() == 'muon' and self.fp16_mode == 'inflat_all': + self.fp16_mode = 'amp_manual' + print(f'\n\033[93mWarning: Muon optimizer does not support inflat_all mode, switching to amp mode.\033[0m') + + # Build master params + # self.model_params = sum([[p for p in model.parameters() if p.requires_grad] for model in self.models.values()], []) + self.model_params_names, self.model_params = [], [] + for key in self.models: + model = self.models[key] + for name, param in model.named_parameters(): + if param.requires_grad: + self.model_params_names.append(key + '.' + name) + self.model_params.append(param) + + if 'amp' in self.fp16_mode: + self.master_params = self.model_params + self.scaler = torch.GradScaler() + elif self.fp16_mode == 'inflat_all': + self.master_params = make_master_params(self.model_params) + self.fp16_scale_growth = self.fp16_scale_growth + self.log_scale = 15.0 + elif self.loss_scaling: + self.master_params = make_master_params_regular(self.model_params) + self.log_scale = 15.0 + else: + self.master_params = self.model_params + + # Build EMA params + if self.is_master: + self.ema_params = [copy.deepcopy(self.master_params) for _ in self.ema_rate] + + # Initialize optimizer + if self.optimizer_config['name'].lower() == 'muon': + from muon import MuonWithAuxAdam + hidden_attn_params, other_params = [], [] + for n, p in zip(self.model_params_names, self.master_params): + attn_only = self.optimizer_config['args'].get('attn_only', False) + if ((attn_only and 'attn' in n) or not attn_only) and p.ndim >= 2: + hidden_attn_params.append(p) + else: + other_params.append(p) + param_groups = [ + dict(use_muon=True, params=hidden_attn_params, lr=self.optimizer_config['args']['muon_lr'], weight_decay=self.optimizer_config['args'].get('muon_weight_decay', 0.01)), + dict(use_muon=False, params=other_params, lr=self.optimizer_config['args']['other_lr'], weight_decay=self.optimizer_config['args'].get('other_weight_decay', 0.01)) + ] + self.optimizer = MuonWithAuxAdam(param_groups) + elif hasattr(torch.optim, self.optimizer_config['name']): + self.optimizer = getattr(torch.optim, self.optimizer_config['name'])(self.master_params, **self.optimizer_config['args']) + else: + self.optimizer = globals()[self.optimizer_config['name']](self.master_params, **self.optimizer_config['args']) + + # Initalize learning rate scheduler + if self.lr_scheduler_config is not None: + if hasattr(torch.optim.lr_scheduler, self.lr_scheduler_config['name']): + if self.lr_scheduler_config['name'] == 'SequentialLR': + scheduler_list = [] + for scheduler_config in self.lr_scheduler_config['schedulers']: + scheduler_list.append(getattr(torch.optim.lr_scheduler, scheduler_config['name'])(self.optimizer, **scheduler_config['args'])) + self.lr_scheduler = getattr(torch.optim.lr_scheduler, self.lr_scheduler_config['name'])(self.optimizer, scheduler_list, **self.lr_scheduler_config['args']) + else: + self.lr_scheduler = getattr(torch.optim.lr_scheduler, self.lr_scheduler_config['name'])(self.optimizer, **self.lr_scheduler_config['args']) + else: + self.lr_scheduler = globals()[self.lr_scheduler_config['name']](self.optimizer, **self.lr_scheduler_config['args']) + + # Initialize elastic memory controller + if self.elastic_controller_config is not None: + assert any([isinstance(model, (elastic_utils.ElasticModule, elastic_utils.ElasticModuleMixin)) for model in self.models.values()]), \ + 'No elastic module found in models, please inherit from ElasticModule or ElasticModuleMixin' + self.elastic_controller = getattr(elastic_utils, self.elastic_controller_config['name'])(**self.elastic_controller_config['args']) + for model in self.models.values(): + if isinstance(model, (elastic_utils.ElasticModule, elastic_utils.ElasticModuleMixin)): + model.register_memory_controller(self.elastic_controller) + + # Initialize gradient clipper + if self.grad_clip is not None: + if isinstance(self.grad_clip, (float, int)): + self.grad_clip = float(self.grad_clip) + else: + self.grad_clip = getattr(grad_clip_utils, self.grad_clip['name'])(**self.grad_clip['args']) + + def _ensure_uniform_param_dtype_for_muon(self): + """Muon optimizer gathers parameters across ranks and requires uniform dtypes.""" + target_dtype = self._determine_muon_param_dtype() + casted_any = False + for model in self.models.values(): + if any(param.dtype != target_dtype for param in model.parameters() if param.requires_grad): + casted_any = True + if not self._cast_model_to_dtype(model, target_dtype): + for param in model.parameters(): + if param.requires_grad and param.dtype != target_dtype: + param.data = param.data.to(dtype=target_dtype) + for buffer in model.buffers(): + if buffer.is_floating_point() and buffer.dtype != target_dtype: + buffer.data = buffer.data.to(dtype=target_dtype) + if casted_any and self.is_master: + print(f"\nMuon optimizer converted trainable parameters to {target_dtype} to keep dtype consistent across ranks.") + + def _determine_muon_param_dtype(self): + if isinstance(self.muon_param_dtype, torch.dtype): + return self.muon_param_dtype + if self.muon_param_dtype is None: + return torch.float32 + key = str(self.muon_param_dtype).lower() + if key in ('fp16', 'float16', 'half'): + return torch.float16 + if key in ('bf16', 'bfloat16'): + return torch.bfloat16 + if key in ('fp32', 'float32'): + return torch.float32 + raise ValueError(f'Unsupported muon_param_dtype: {self.muon_param_dtype}') + + def _cast_model_to_dtype(self, model, target_dtype): + if target_dtype == torch.float16 and hasattr(model, 'convert_to_fp16'): + model.convert_to_fp16() + return True + if target_dtype == torch.float32 and hasattr(model, 'convert_to_fp32'): + model.convert_to_fp32() + return True + if target_dtype == torch.bfloat16 and hasattr(model, 'convert_to_bf16'): + model.convert_to_bf16() + return True + return False + + def _master_params_to_state_dicts(self, master_params): + """ + Convert master params to dict of state_dicts. + """ + if self.fp16_mode == 'inflat_all': + master_params = unflatten_master_params(self.model_params, master_params) + state_dicts = {name: model.state_dict() for name, model in self.models.items()} + master_params_names = sum( + [[(name, n) for n, p in model.named_parameters() if p.requires_grad] for name, model in self.models.items()] + , []) + for i, (model_name, param_name) in enumerate(master_params_names): + state_dicts[model_name][param_name] = master_params[i] + return state_dicts + + def _state_dicts_to_master_params(self, master_params, state_dicts, strict=True): + """ + Convert a state_dict to master params. + """ + master_params_names = sum( + [[(name, n) for n, p in model.named_parameters() if p.requires_grad] for name, model in self.models.items()], []) + if strict: + params = [state_dicts[name][param_name] for name, param_name in master_params_names] + else: + param_dict = {key: dict(value.named_parameters()) for key, value in self.models.items()} + params = [] + for i, (name, param_name) in enumerate(master_params_names): + if name in state_dicts and param_name in state_dicts[name]: + params.append(state_dicts[name][param_name].to(master_params[0].device)) + else: + params.append(param_dict[name][param_name].data.clone().to(master_params[0].device)) + if self.fp16_mode == 'inflat_all': + model_params_to_master_params(params, master_params) + else: + for i, param in enumerate(params): + master_params[i].data.copy_(param.data) + + def load_pretrain(self, load_dir): + """ + Load pretrained checkpoints. + Should be called by all processes. + """ + if self.is_master: + print(f'\nLoading pretrained checkpoint from step {load_dir}...', end='') + + need_load = False + model_ckpts = {} + for name, model in self.models.items(): + if hasattr(model, 'use_pretrain_branch') and model.use_pretrain_branch: + class_names = model.__class__.__name__ if not hasattr(model, 'pretrain_class_name') else model.pretrain_class_name + need_load = True + from safetensors.torch import load_file + if type(class_names) is not list: + class_names = [class_names] + for class_name in class_names: + if os.path.exists(os.path.join('ckpts/pretrained_ckpts', f'{class_name}.safetensors')): + pretrain_ckpt = load_file(os.path.join('ckpts/pretrained_ckpts', f'{class_name}.safetensors')) + elif os.path.exists(os.path.join('ckpts/pretrained_ckpts', f'{class_name}.pt')): + pretrain_ckpt = torch.load(os.path.join('ckpts/pretrained_ckpts', f'{class_name}.pt'), weights_only=True) + else: + continue + if hasattr(model, 'pretrain_ckpt_filter_prefix') and class_name in model.pretrain_ckpt_filter_prefix: + prefix = model.pretrain_ckpt_filter_prefix[class_name] + pretrain_ckpt = {key: value for key, value in pretrain_ckpt.items() if key.startswith(prefix)} + model_ckpts[name] = pretrain_ckpt + model.load_state_dict(pretrain_ckpt, strict=False) + if need_load: + self._state_dicts_to_master_params(self.master_params, model_ckpts, strict=False) + del model_ckpts + if self.world_size > 1: + dist.barrier() + if self.is_master: + print('Load Pretrained Checkpoints Done.') + if self.world_size > 1: + self.check_ddp() + + def load(self, load_dir, step=0): + """ + Load a checkpoint. + Should be called by all processes. + """ + if self.is_master: + print(f'\nLoading checkpoint from step {step}...', end='') + + model_ckpts = {} + for name, model in self.models.items(): + if os.path.exists(os.path.join(load_dir, 'ckpts', f'{name}_step{step:07d}.pt')): + model_ckpt = torch.load(read_file_dist(os.path.join(load_dir, 'ckpts', f'{name}_step{step:07d}.pt')), map_location=self.device, weights_only=True) + model_ckpts[name] = model_ckpt + model.load_state_dict(model_ckpt, strict=True) + else: + model_ckpts[name] = model.state_dict() + if self.fp16_mode == 'inflat_all' or self.loss_scaling: + model.convert_to_fp16() + self._state_dicts_to_master_params(self.master_params, model_ckpts, strict=True) + del model_ckpts + + if self.is_master: + for i, ema_rate in enumerate(self.ema_rate): + ema_ckpts = {} + for name, model in self.models.items(): + ckpt_path = os.path.join(load_dir, 'ckpts', f'{name}_ema{ema_rate}_step{step:07d}.pt') + ckpt_path = ckpt_path if os.path.exists(ckpt_path) else os.path.join(load_dir, 'ckpts', f'{name}_step{step:07d}.pt') # If EMA ckpt not found, load normal ckpt instead + if os.path.exists(ckpt_path): + ema_ckpt = torch.load(ckpt_path, map_location=self.device, weights_only=True) + ema_ckpts[name] = ema_ckpt + self._state_dicts_to_master_params(self.ema_params[i], ema_ckpts, strict=False) + del ema_ckpts + misc_ckpt_path = os.path.join(load_dir, 'ckpts', f'misc_step{step:07d}.pt') + if os.path.exists(misc_ckpt_path): + misc_ckpt = torch.load(read_file_dist(misc_ckpt_path), map_location=torch.device('cpu'), weights_only=False) + self.optimizer.load_state_dict(misc_ckpt['optimizer']) + self.step = misc_ckpt['step'] + self.data_sampler.load_state_dict(misc_ckpt['data_sampler']) + if 'amp' in self.fp16_mode: + self.scaler.load_state_dict(misc_ckpt['scaler']) + elif self.fp16_mode == 'inflat_all' or self.loss_scaling: + self.log_scale = misc_ckpt['log_scale'] + if self.lr_scheduler_config is not None: + self.lr_scheduler.load_state_dict(misc_ckpt['lr_scheduler']) + if self.elastic_controller_config is not None: + self.elastic_controller.load_state_dict(misc_ckpt['elastic_controller']) + if self.grad_clip is not None and not isinstance(self.grad_clip, float): + self.grad_clip.load_state_dict(misc_ckpt['grad_clip']) + del misc_ckpt + else: + self.step = step + + if self.world_size > 1: + dist.barrier() + if self.is_master: + print(' Done.') + + if self.world_size > 1: + self.check_ddp() + + def save(self): + """ + Save a checkpoint. + Should be called only by the rank 0 process. + """ + assert self.is_master, 'save() should be called only by the rank 0 process.' + print(f'\nSaving checkpoint at step {self.step}...', end='') + + model_ckpts = self._master_params_to_state_dicts(self.master_params) + for name, model_ckpt in model_ckpts.items(): + torch.save(model_ckpt, os.path.join(self.output_dir, 'ckpts', f'{name}_step{self.step:07d}.pt')) + + for i, ema_rate in enumerate(self.ema_rate): + ema_ckpts = self._master_params_to_state_dicts(self.ema_params[i]) + for name, ema_ckpt in ema_ckpts.items(): + torch.save(ema_ckpt, os.path.join(self.output_dir, 'ckpts', f'{name}_ema{ema_rate}_step{self.step:07d}.pt')) + + misc_ckpt = { + 'optimizer': self.optimizer.state_dict(), + 'step': self.step, + 'data_sampler': self.data_sampler.state_dict(), + } + if 'amp' in self.fp16_mode: + misc_ckpt['scaler'] = self.scaler.state_dict() + elif self.fp16_mode == 'inflat_all' or self.loss_scaling: + misc_ckpt['log_scale'] = self.log_scale + if self.lr_scheduler_config is not None: + misc_ckpt['lr_scheduler'] = self.lr_scheduler.state_dict() + if self.elastic_controller_config is not None: + misc_ckpt['elastic_controller'] = self.elastic_controller.state_dict() + if self.grad_clip is not None and not isinstance(self.grad_clip, float): + misc_ckpt['grad_clip'] = self.grad_clip.state_dict() + torch.save(misc_ckpt, os.path.join(self.output_dir, 'ckpts', f'misc_step{self.step:07d}.pt')) + print(' Done.') + + if not hasattr(self, 'model_saved_steps'): + self.model_saved_steps = [self.step] + else: + self.model_saved_steps.append(self.step) + + # Deleting old checkpoints and keep the last 5 checkpoints + self.manage_checkpoints() + + def manage_checkpoints(self): + def get_step_from_filename(filename, prefix, suffix): + match = re.search(rf'{prefix}(\d+){suffix}', filename) + return int(match.group(1)) if match else None + ckpt_dir = os.path.join(self.output_dir, 'ckpts') + if not os.path.exists(ckpt_dir): + print("Checkpoint directory does not exist, skipping cleanup.") + return + checkpoints = [] + total_steps = [] + for filename in os.listdir(ckpt_dir): + if filename.endswith('.pt'): + step = get_step_from_filename(filename, 'step', '.pt') + if step is not None: + checkpoints.append((step, filename)) + total_steps.append(step) + checkpoints.sort(key=lambda x: x[0]) + total_steps = sorted(np.unique(total_steps).tolist()) + # Avoid deleting steps mod 100000 to 0 + total_steps = [step for step in total_steps if step % 100000 != 0] + + # Keep only the latest 2 checkpoints + if len(total_steps) > 2: + old_steps = total_steps[:-2] + old_checkpoints = [(step, filename) for step, filename in checkpoints if step in old_steps] + for step, filename in old_checkpoints: + os.remove(os.path.join(ckpt_dir, filename)) + print(f'\nDeleted old checkpoint file: {filename}') + for old_step, _ in old_checkpoints: + for name in self.models: + model_ckpt = os.path.join(ckpt_dir, f'{name}_step{old_step:07d}.pt') + if os.path.exists(model_ckpt): + os.remove(model_ckpt) + print(f'Deleted model checkpoint: {model_ckpt}') + for ema_rate in self.ema_rate: + ema_ckpt = os.path.join(ckpt_dir, f'{name}_ema{ema_rate}_step{old_step:07d}.pt') + if os.path.exists(ema_ckpt): + os.remove(ema_ckpt) + print(f'Deleted EMA checkpoint: {ema_ckpt}') + misc_ckpt = os.path.join(ckpt_dir, f'misc_step{old_step:07d}.pt') + if os.path.exists(misc_ckpt): + os.remove(misc_ckpt) + print(f'Deleted misc checkpoint: {misc_ckpt}') + + def finetune_from(self, finetune_ckpt): + """ + Finetune from a checkpoint. + Should be called by all processes. + """ + if self.is_master: + print('\nFinetuning from:') + for name, path in finetune_ckpt.items(): + print(f' - {name}: {path}') + + model_ckpts = {} + for name, model in self.models.items(): + model_state_dict = model.state_dict() + if name in finetune_ckpt: + model_ckpt = torch.load(read_file_dist(finetune_ckpt[name]), map_location=self.device, weights_only=True) + for k, v in model_ckpt.items(): + if model_ckpt[k].shape != model_state_dict[k].shape: + if self.is_master: + print(f'Warning: {k} shape mismatch, {model_ckpt[k].shape} vs {model_state_dict[k].shape}, skipped.') + model_ckpt[k] = model_state_dict[k] + model_ckpts[name] = model_ckpt + model.load_state_dict(model_ckpt) + if self.fp16_mode == 'inflat_all' or self.loss_scaling: + model.convert_to_fp16() + else: + if self.is_master: + print(f'Warning: {name} not found in finetune_ckpt, skipped.') + model_ckpts[name] = model_state_dict + self._state_dicts_to_master_params(self.master_params, model_ckpts) + del model_ckpts + + if self.world_size > 1: + dist.barrier() + if self.is_master: + print('Done.') + + if self.world_size > 1: + self.check_ddp() + + def update_ema(self): + """ + Update exponential moving average. + Should only be called by the rank 0 process. + """ + assert self.is_master, 'update_ema() should be called only by the rank 0 process.' + for i, ema_rate in enumerate(self.ema_rate): + for master_param, ema_param in zip(self.master_params, self.ema_params[i]): + ema_param.detach().mul_(ema_rate).add_(master_param, alpha=1.0 - ema_rate) + + def check_ddp(self): + """ + Check if DDP is working properly. + Should be called by all process. + """ + if self.is_master: + print('\nPerforming DDP check...') + + if self.is_master: + print('Checking if parameters are consistent across processes...') + dist.barrier() + try: + for n, p in zip(self.model_params_names, self.master_params): + # split to avoid OOM + for i in range(0, p.numel(), 10000000): + sub_size = min(10000000, p.numel() - i) + sub_p = p.detach().reshape(-1)[i:i+sub_size] + # gather from all processes + sub_p_gather = [torch.empty_like(sub_p) for _ in range(self.world_size)] + dist.all_gather(sub_p_gather, sub_p) + # check if equal + assert all([torch.equal(sub_p, sub_p_gather[i]) for i in range(self.world_size)]), 'parameters are not consistent across processes' + except AssertionError as e: + if self.is_master: + print(f'\n\033[91mError: {e}\033[0m') + print('DDP check failed.') + raise e + + dist.barrier() + if self.is_master: + print('Done.') + + def run_step(self, data_list): + """ + Run a training step. + """ + step_log = {'loss': {}, 'status': {}} + amp_context = partial(torch.autocast, device_type='cuda') if self.fp16_mode == 'amp' else nullcontext + elastic_controller_context = self.elastic_controller.record if self.elastic_controller_config is not None else nullcontext + + # Train + losses = [] + statuses = [] + elastic_controller_logs = [] + zero_grad(self.model_params) + for i, mb_data in enumerate(data_list): + ## sync at the end of each batch split + sync_contexts = [getattr(self.training_models[name], 'no_sync', nullcontext) for name in self.training_models] if i != len(data_list) - 1 and self.world_size > 1 else [nullcontext] + with nested_contexts(*sync_contexts), elastic_controller_context(): + with amp_context(): + loss, status = self.training_losses(**mb_data) + l = loss['loss'] / len(data_list) + ## backward + if 'amp' in self.fp16_mode: + self.scaler.scale(l).backward() + elif self.fp16_mode == 'inflat_all': + scaled_l = l * (2 ** self.log_scale) + scaled_l.backward() + elif self.loss_scaling: + # Mirror manual loss scaling path to keep updates unbiased. + scaled_l = l * (2 ** self.log_scale) + scaled_l.backward() + else: + l.backward() + ## log + losses.append(dict_foreach(loss, lambda x: x.item() if isinstance(x, torch.Tensor) else x)) + statuses.append(dict_foreach(status, lambda x: x.item() if isinstance(x, torch.Tensor) else x)) + if self.elastic_controller_config is not None: + elastic_controller_logs.append(self.elastic_controller.log()) + + ## gradient clip + if self.grad_clip is not None: + if 'amp' in self.fp16_mode: + self.scaler.unscale_(self.optimizer) + elif self.fp16_mode == 'inflat_all': + model_grads_to_master_grads(self.model_params, self.master_params) + scale = 2 ** self.log_scale + self.master_params[0].grad.mul_(1.0 / scale if scale > 1e-30 else 1.0) + elif self.loss_scaling: + model_grads_to_master_grads_regular(self.model_params, self.master_params) + scale = 2 ** self.log_scale + inv_scale = 1.0 / scale if scale > 1e-30 else 1.0 + for p in self.master_params: + if p.grad is not None: + p.grad.mul_(inv_scale) + if isinstance(self.grad_clip, float): + grad_norm = torch.nn.utils.clip_grad_norm_(self.master_params, self.grad_clip) + else: + grad_norm = self.grad_clip(self.master_params) + if torch.isfinite(grad_norm): + statuses[-1]['grad_norm'] = grad_norm.item() + + # Cache params for NaN recovery + if self.step % 10 == 0 and not any(not p.isfinite().all() for p in self.master_params): + self.previous_step = self.step + self.previous_params = [p.clone().detach() for p in self.master_params] + self.previous_params_model = [p.clone().detach() for p in self.model_params] + + # # Check which parameter does not have gradients and print its name + # for name, param in self.training_models.items(): + # for p_name, p in param.named_parameters(): + # if p.requires_grad and p.grad is None: + # print(f'\n\033[93mWarning: {name}.{p_name} does not have gradients at step {self.step}.\033[0m') + # exit(0) + + ## step + if 'amp' in self.fp16_mode: + prev_scale = self.scaler.get_scale() + self.scaler.step(self.optimizer) + self.scaler.update() + elif self.fp16_mode == 'inflat_all' or self.loss_scaling: + prev_scale = 2 ** self.log_scale + if not any(not p.grad.isfinite().all() for p in self.master_params if p.grad is not None): + if self.grad_clip is None: + if self.fp16_mode == 'inflat_all': + model_grads_to_master_grads(self.model_params, self.master_params) + scale = 2 ** self.log_scale + self.master_params[0].grad.mul_(1.0 / scale if scale > 1e-30 else 1.0) + else: + model_grads_to_master_grads_regular(self.model_params, self.master_params) + scale = 2 ** self.log_scale + inv_scale = 1.0 / scale if scale > 1e-30 else 1.0 + for p in self.master_params: + if p.grad is not None: + p.grad.mul_(inv_scale) + self.optimizer.step() + if self.fp16_mode == 'inflat_all': + master_params_to_model_params(self.model_params, self.master_params) + else: + master_params_to_model_params_regular(self.model_params, self.master_params) + self.log_scale += self.fp16_scale_growth + else: + self.log_scale -= 1 + if self.log_scale < -100: + self.log_scale = -100 + else: + prev_scale = 1.0 + if not any(not p.grad.isfinite().all() for p in self.model_params): + self.optimizer.step() + else: + print('\n\033[93mWarning: NaN detected in gradients. Skipping update.\033[0m') + ## adjust learning rate + if self.lr_scheduler_config is not None: + statuses[-1]['lr'] = self.lr_scheduler.get_last_lr()[0] + self.lr_scheduler.step() + + # If parameters are not finite, revert to previous parameters + if any(not p.isfinite().all() for p in self.master_params): + if hasattr(self, 'previous_params'): + print(f'\n\033[91mError: NaN loss detected in parameters at step {self.step}. Reverting to previous parameters at step {self.previous_step}.\033[0m') + for i, p in enumerate(self.master_params): + p.data.copy_(self.previous_params[i].data) + for i, p in enumerate(self.model_params): + p.data.copy_(self.previous_params_model[i].data) + else: + print(f'\n\033[91mError: NaN loss detected in parameters at step {self.step}. No previous parameters to revert to.\033[0m') + raise RuntimeError('NaN loss detected in parameters and no previous parameters to revert to.') + + # Logs + step_log['loss'] = dict_reduce(losses, lambda x: np.mean(x)) + step_log['status'] = dict_reduce(statuses, lambda x: np.mean(x), special_func={'min': lambda x: np.min(x), 'max': lambda x: np.max(x)}) + if self.elastic_controller_config is not None: + step_log['elastic'] = dict_reduce(elastic_controller_logs, lambda x: np.mean(x)) + if self.grad_clip is not None: + step_log['grad_clip'] = self.grad_clip if isinstance(self.grad_clip, float) else self.grad_clip.log() + + # Check grad and norm of each param + if self.log_param_stats: + for key in self.models: + param_norms = {} + param_grads = {} + for name, param in self.models[key].named_parameters(): + if param.requires_grad: + param_norms[name] = param.norm().item() + if param.grad is not None and torch.isfinite(param.grad).all(): + param_grads[name] = param.grad.norm().item() / prev_scale + step_log[key+'-param_norms'] = param_norms + step_log[key+'-param_grads'] = param_grads + + # Update exponential moving average + if self.is_master: + self.update_ema() + + return step_log diff --git a/anigen/trainers/flow_matching/anigen_flow_matching.py b/anigen/trainers/flow_matching/anigen_flow_matching.py new file mode 100644 index 0000000000000000000000000000000000000000..bcf1476b99195a8bc060fff4d21aa461f8073b95 --- /dev/null +++ b/anigen/trainers/flow_matching/anigen_flow_matching.py @@ -0,0 +1,455 @@ +from typing import * +import copy +import torch +import torch.nn.functional as F +from torch.utils.data import DataLoader +import numpy as np +from easydict import EasyDict as edict + +from ..basic import BasicTrainer +from ...pipelines import samplers +from ...utils.general_utils import dict_reduce +from .mixins.classifier_free_guidance import ClassifierFreeGuidanceMixin +from .mixins.text_conditioned import TextConditionedMixin +from .mixins.image_conditioned import ImageConditionedMixin + + +class AniGenFlowMatchingTrainer(BasicTrainer): + """ + Trainer for diffusion model with flow matching objective. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + """ + def __init__( + self, + *args, + t_schedule: dict = { + 'name': 'logitNormal', + 'args': { + 'mean': 0.0, + 'std': 1.0, + } + }, + sigma_min: float = 1e-5, + + # inpaint training (x0 known) controls + train_inpaint: bool = False, + p_x0_inject: float = 0.0, + **kwargs + ): + super().__init__(*args, **kwargs) + self.t_schedule = t_schedule + self.sigma_min = sigma_min + + self.train_inpaint = bool(train_inpaint) + self.p_x0_inject = float(p_x0_inject) + + def diffuse(self, x_0: torch.Tensor, x_0_skl: torch.Tensor, t: torch.Tensor, noise: Optional[torch.Tensor] = None, noise_skl: Optional[torch.Tensor] = None) -> torch.Tensor: + """ + Diffuse the data for a given number of diffusion steps. + In other words, sample from q(x_t | x_0). + + Args: + x_0: The [N x C x ...] tensor of noiseless inputs. + t: The [N] tensor of diffusion steps [0-1]. + noise: If specified, use this noise instead of generating new noise. + + Returns: + x_t, the noisy version of x_0 under timestep t. + """ + if noise is None: + noise = torch.randn_like(x_0) + if noise_skl is None: + noise_skl = torch.randn_like(x_0_skl) + + assert noise.shape == x_0.shape, "noise must have same shape as x_0" + assert noise_skl.shape == x_0_skl.shape, "noise_skl must have same shape as x_0_skl" + + t = t.view(-1, *[1 for _ in range(len(x_0.shape) - 1)]) + x_t = (1 - t) * x_0 + (self.sigma_min + (1 - self.sigma_min) * t) * noise + x_t_skl = (1 - t) * x_0_skl + (self.sigma_min + (1 - self.sigma_min) * t) * noise_skl + + return x_t, x_t_skl + + def reverse_diffuse(self, x_t: torch.Tensor, x_t_skl: torch.Tensor, t: torch.Tensor, noise: torch.Tensor, noise_skl: torch.Tensor) -> torch.Tensor: + """ + Get original image from noisy version under timestep t. + """ + assert noise.shape == x_t.shape, "noise must have same shape as x_t" + assert noise_skl.shape == x_t_skl.shape, "noise_skl must have same shape as x_t_skl" + t = t.view(-1, *[1 for _ in range(len(x_t.shape) - 1)]) + x_0 = (x_t - (self.sigma_min + (1 - self.sigma_min) * t) * noise) / (1 - t) + x_0_skl = (x_t_skl - (self.sigma_min + (1 - self.sigma_min) * t) * noise_skl) / (1 - t) + return x_0, x_0_skl + + def get_v(self, x_0: torch.Tensor, noise: torch.Tensor, t: torch.Tensor) -> torch.Tensor: + """ + Compute the velocity of the diffusion process at time t. + """ + return (1 - self.sigma_min) * noise - x_0 + + def get_cond(self, cond, **kwargs): + """ + Get the conditioning data. + """ + return cond + + def get_inference_cond(self, cond, **kwargs): + """ + Get the conditioning data for inference. + """ + return {'cond': cond, **kwargs} + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.AniGenFlowEulerSampler(self.sigma_min) + + def vis_cond(self, **kwargs): + """ + Visualize the conditioning data. + """ + return {} + + def sample_t(self, batch_size: int) -> torch.Tensor: + """ + Sample timesteps. + """ + if self.t_schedule['name'] == 'uniform': + t = torch.rand(batch_size) + elif self.t_schedule['name'] == 'logitNormal': + mean = self.t_schedule['args']['mean'] + std = self.t_schedule['args']['std'] + t = torch.sigmoid(torch.randn(batch_size) * std + mean) + else: + raise ValueError(f"Unknown t_schedule: {self.t_schedule['name']}") + return t + + def training_losses( + self, + x_0: torch.Tensor, + x_0_skl: torch.Tensor, + cond=None, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses for a single timestep. + + Args: + x_0: The [N x C x ...] tensor of noiseless inputs. + cond: The [N x ...] tensor of additional conditions. + kwargs: Additional arguments to pass to the backbone. + + Returns: + a dict with the key "loss" containing a tensor of shape [N]. + may also contain other keys for different terms. + """ + noise = torch.randn_like(x_0) + noise_skl = torch.randn_like(x_0_skl) + t = self.sample_t(x_0.shape[0]).to(x_0.device).float() + x_t, x_t_skl = self.diffuse(x_0=x_0, x_0_skl=x_0_skl, t=t, noise=noise, noise_skl=noise_skl) + cond = self.get_cond(cond, **kwargs) + + if self.train_inpaint: + kwargs = dict(kwargs) + kwargs.update({ + 'x0': x_0, + }) + + pred, pred_skl = self.training_models['denoiser'](x_t, x_t_skl, t * 1000, cond, **kwargs) + assert pred.shape == noise.shape == x_0.shape + assert pred_skl.shape == noise_skl.shape == x_0_skl.shape + + target = self.get_v(x_0, noise, t) + target_skl = self.get_v(x_0_skl, noise_skl, t) + + terms = edict() + terms["mse"] = F.mse_loss(pred, target) + terms["loss"] = terms["mse"] + terms["mse_skl"] = F.mse_loss(pred_skl, target_skl) + terms["loss"] = terms["loss"] + terms["mse_skl"] + + # log loss with time bins + mse_per_instance = np.array([ + F.mse_loss(pred[i], target[i]).item() + for i in range(x_0.shape[0]) + ]) + mse_skl_per_instance = np.array([ + F.mse_loss(pred_skl[i], target_skl[i]).item() + for i in range(x_0_skl.shape[0]) + ]) + time_bin = np.digitize(t.cpu().numpy(), np.linspace(0, 1, 11)) - 1 + for i in range(10): + if (time_bin == i).sum() != 0: + terms[f"bin_{i}"] = {"mse": mse_per_instance[time_bin == i].mean()} + terms[f"bin_{i}"]["mse_skl"] = mse_skl_per_instance[time_bin == i].mean() + + return terms, {} + + def voxel2pcl(self, voxels, voxels_skl=None, names=None, density=3, threshold=0.5): + if hasattr(self.dataset, 'decode_latent') and voxels_skl is not None: + voxels, voxels_skl = self.dataset.decode_latent(voxels, voxels_skl) + def _convert(v): + if v.dim() == 5: + v = v[:, 0] + N, D, H, W = v.shape + device = v.device + offset = (torch.arange(density, device=device) + 0.5) / density + oz, oy, ox = torch.meshgrid(offset, offset, offset, indexing='ij') + offsets = torch.stack([ox, oy, oz], dim=-1).reshape(-1, 3) # (density^3, 3) + pcls = [] + for i in range(N): + occupied = (v[i] > threshold).nonzero() # (M, 3) -> (z, y, x) + if occupied.shape[0] == 0: + pcl = torch.zeros((0, 6), device=device) + else: + z_idx, y_idx, x_idx = occupied[:, 0], occupied[:, 1], occupied[:, 2] + base_coords = torch.stack([x_idx, y_idx, z_idx], dim=-1).float() + points = base_coords.unsqueeze(1) + offsets.unsqueeze(0) + points = points.reshape(-1, 3) + scale = torch.tensor([W, H, D], device=device).float() + points = points / scale - 0.5 + colors = points + 0.5 + pcl = torch.cat([points, colors], dim=-1) + if names is not None: + pcls.append({'instance': names[i], 'pcl': pcl}) + else: + pcls.append(pcl) + return pcls + pcls = _convert(voxels) + if voxels_skl is not None: + pcls_skl = _convert(voxels_skl) + return pcls, pcls_skl + return pcls + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + verbose: bool = False, + **kwargs, + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + sampler = self.get_sampler() + sample_gt = [] + sample_gt_skl = [] + sample = [] + sample_skl = [] + cond_vis = [] + instances = [] + for i in range(0, num_samples, batch_size): + batch = min(batch_size, num_samples - i) + data = next(iter(dataloader)) + instances.extend(data['instance'][:batch]) + + data = {k: v[:batch].cuda() if isinstance(v, torch.Tensor) else v[:batch] for k, v in data.items()} + noise = torch.randn_like(data['x_0']) + noise_skl = torch.randn_like(data['x_0_skl']) + sample_gt.append(data['x_0']) + sample_gt_skl.append(data['x_0_skl']) + cond_vis.append(self.vis_cond(**data)) + data['x0'] = data['x_0'] + del data['x_0'] + args = self.get_inference_cond(**data) + res = sampler.sample( + self.models['denoiser'], + noise=noise, + noise_skl=noise_skl, + **args, + steps=50, cfg_strength=0 if self.train_inpaint else 3.0, verbose=verbose, + ) + sample.append(res.samples) + sample_skl.append(res.samples_skl) + + sample_gt = torch.cat(sample_gt, dim=0) + sample = torch.cat(sample, dim=0) + sample_gt_skl = torch.cat(sample_gt_skl, dim=0) + sample_skl = torch.cat(sample_skl, dim=0) + + sample_pcl, sample_skl_pcl = self.voxel2pcl(sample, sample_skl, names=instances) + + sample_dict = { + 'sample_gt': {'value': {'x_0': sample_gt, 'x_0_skl': sample_gt_skl}, 'type': 'sample'}, + 'sample': {'value': {'x_0': sample, 'x_0_skl': sample_skl}, 'type': 'sample'}, + 'sample_pcl': {'value': sample_pcl, 'type': 'point_cloud'}, + 'sample_skl_pcl': {'value': sample_skl_pcl, 'type': 'point_cloud'}, + } + sample_dict.update(dict_reduce(cond_vis, None, { + 'value': lambda x: torch.cat(x, dim=0), + 'type': lambda x: x[0], + })) + + return sample_dict + + +class AniGenFlowMatchingCFGTrainer(ClassifierFreeGuidanceMixin, AniGenFlowMatchingTrainer): + """ + Trainer for diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + """ + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.AniGenFlowEulerSampler(self.sigma_min) + + +class AniGenTextConditionedFlowMatchingCFGTrainer(TextConditionedMixin, AniGenFlowMatchingCFGTrainer): + """ + Trainer for text-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + text_cond_model(str): Text conditioning model. + """ + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.AniGenFlowEulerSampler(self.sigma_min) + + +class AniGenImageConditionedFlowMatchingCFGTrainer(ImageConditionedMixin, AniGenFlowMatchingCFGTrainer): + """ + Trainer for image-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + image_cond_model (str): Image conditioning model. + """ + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.AniGenFlowEulerSampler(self.sigma_min) diff --git a/anigen/trainers/flow_matching/anigen_sparse_flow_matching.py b/anigen/trainers/flow_matching/anigen_sparse_flow_matching.py new file mode 100644 index 0000000000000000000000000000000000000000..e2e46bfc5d2a050661b0289d28973f18a82a1070 --- /dev/null +++ b/anigen/trainers/flow_matching/anigen_sparse_flow_matching.py @@ -0,0 +1,562 @@ +from typing import * +import os +import copy +import functools +import torch +import torch.nn.functional as F +from torch.utils.data import DataLoader +import numpy as np +from easydict import EasyDict as edict + +import utils3d.torch +from ...pipelines import samplers +from ...modules import sparse as sp +from ...utils.general_utils import dict_reduce +from ...utils.data_utils import cycle, BalancedResumableSampler +from .flow_matching import FlowMatchingTrainer +from .mixins.classifier_free_guidance import ClassifierFreeGuidanceMixin +from .mixins.text_conditioned import TextConditionedMixin +from .mixins.image_conditioned import ImageConditionedMixin +from ...representations import MeshExtractResult +from ...utils.skin_utils import get_transform +from pytorch3d.ops import knn_points +from ...renderers import MeshRenderer +from ...utils.data_utils import recursive_to_device +import copy + + +class AniGenSparseFlowMatchingTrainer(FlowMatchingTrainer): + """ + Trainer for sparse diffusion model with flow matching objective. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + """ + def __init__( + self, + *args, + use_joint_num_cond: bool = False, + p_uncond_joint_num: float = 0.1, + **kwargs, + ): + super().__init__(*args, **kwargs) + self.use_joint_num_cond = use_joint_num_cond + self.p_uncond_joint_num = p_uncond_joint_num + self._init_renderer() + + def _init_renderer(self): + rendering_options = {"near" : 1, + "far" : 3} + self.renderer = MeshRenderer(rendering_options, device=self.device) + + def prepare_dataloader(self, **kwargs): + """ + Prepare dataloader. + """ + self.data_sampler = BalancedResumableSampler( + self.dataset, + shuffle=True, + batch_size=self.batch_size_per_gpu, + ) + self.dataloader = DataLoader( + self.dataset, + batch_size=self.batch_size_per_gpu, + num_workers=int(np.ceil(os.cpu_count() / torch.cuda.device_count())), + pin_memory=True, + drop_last=True, + persistent_workers=True, + collate_fn=functools.partial(self.dataset.collate_fn, split_size=self.batch_split), + sampler=self.data_sampler, + ) + self.data_iterator = cycle(self.dataloader) + + def training_losses( + self, + x_0: sp.SparseTensor, + x_0_skl: sp.SparseTensor, + cond=None, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses for a single timestep. + + Args: + x_0: The [N x ... x C] sparse tensor of the inputs. + cond: The [N x ...] tensor of additional conditions. + kwargs: Additional arguments to pass to the backbone. + + Returns: + a dict with the key "loss" containing a tensor of shape [N]. + may also contain other keys for different terms. + """ + noise = x_0.replace(torch.randn_like(x_0.feats)) + t = self.sample_t(x_0.shape[0]).to(x_0.device).float() + x_t = self.diffuse(x_0, t, noise=noise) + noise_skl = x_0_skl.replace(torch.randn_like(x_0_skl.feats)) + x_t_skl = self.diffuse(x_0_skl, t, noise=noise_skl) + cond = self.get_cond(cond, **kwargs) + + local_kwargs = dict(kwargs) + joints_num = None + if self.use_joint_num_cond and ('joints_num' in local_kwargs) and (local_kwargs['joints_num'] is not None): + joints_num = local_kwargs.pop('joints_num') + if not torch.is_tensor(joints_num): + joints_num = torch.tensor(joints_num, device=x_0.device) + joints_num = joints_num.to(device=x_0.device) + if joints_num.dim() == 0: + joints_num = joints_num[None].expand(x_0.shape[0]) + joints_num = joints_num.reshape(x_0.shape[0]).clone() + + # IMPORTANT: independent dropout from image/text CFG dropout. + if self.p_uncond_joint_num and self.p_uncond_joint_num > 0: + mask_joint = torch.rand(x_0.shape[0], device=x_0.device) < float(self.p_uncond_joint_num) + joints_num[mask_joint] = 0 + + if self.use_joint_num_cond: + pred, pred_skl = self.training_models['denoiser'](x_t, x_t_skl, t * 1000, cond, joints_num=joints_num, **local_kwargs) + else: + pred, pred_skl = self.training_models['denoiser'](x_t, x_t_skl, t * 1000, cond, **kwargs) + assert pred.shape == noise.shape == x_0.shape + assert pred_skl.shape == noise_skl.shape == x_0_skl.shape + target = self.get_v(x_0, noise, t) + target_skl = self.get_v(x_0_skl, noise_skl, t) + + terms = edict() + terms["mse"] = F.mse_loss(pred.feats, target.feats) + terms["mse_skl"] = F.mse_loss(pred_skl.feats, target_skl.feats) + terms["loss"] = terms["mse"] + terms["mse_skl"] + + # log loss with time bins + mse_per_instance = np.array([ + F.mse_loss(pred.feats[x_0.layout[i]], target.feats[x_0.layout[i]]).item() + for i in range(x_0.shape[0]) + ]) + mse_skl_per_instance = np.array([ + F.mse_loss(pred_skl.feats[x_0_skl.layout[i]], target_skl.feats[x_0_skl.layout[i]]).item() + for i in range(x_0_skl.shape[0]) + ]) + time_bin = np.digitize(t.cpu().numpy(), np.linspace(0, 1, 11)) - 1 + for i in range(10): + if (time_bin == i).sum() != 0: + terms[f"bin_{i}"] = {"mse": mse_per_instance[time_bin == i].mean()} + terms[f"bin_{i}_skl"] = {"mse": mse_skl_per_instance[time_bin == i].mean()} + + return terms, {} + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.AniGenFlowEulerSampler(self.sigma_min) + + @torch.no_grad() + def _flip_normal(self, normal: torch.Tensor, extrinsics: torch.Tensor, intrinsics: torch.Tensor) -> torch.Tensor: + """ + Flip normal to align with camera. + """ + normal = normal * 2.0 - 1.0 + R = torch.zeros_like(extrinsics) + R[:, :3, :3] = extrinsics[:, :3, :3] + R[:, 3, 3] = 1.0 + view_dir = utils3d.torch.unproject_cv( + utils3d.torch.image_uv(*normal.shape[-2:], device=self.device).reshape(1, -1, 2), + torch.ones(*normal.shape[-2:], device=self.device).reshape(1, -1), + R, intrinsics + ).reshape(-1, *normal.shape[-2:], 3).permute(0, 3, 1, 2) + unflip = (normal * view_dir).sum(1, keepdim=True) < 0 + normal *= unflip * 2.0 - 1.0 + return (normal + 1.0) / 2.0 + + def _render_batch(self, reps: List[MeshExtractResult], extrinsics: torch.Tensor, intrinsics: torch.Tensor, return_types=['mask', 'normal', 'depth'], specified_colors=None) -> Dict[str, torch.Tensor]: + """ + Render a batch of representations. + + Args: + reps: The dictionary of lists of representations. + extrinsics: The [N x 4 x 4] tensor of extrinsics. + intrinsics: The [N x 3 x 3] tensor of intrinsics. + return_types: vary in ['mask', 'normal', 'depth', 'normal_map', 'color'] + + Returns: + a dict with + reg_loss : [N] tensor of regularization losses + mask : [N x 1 x H x W] tensor of rendered masks + normal : [N x 3 x H x W] tensor of rendered normals + depth : [N x 1 x H x W] tensor of rendered depths + """ + if extrinsics.shape[0] == 1: + extrinsics = extrinsics.expand(len(reps), -1, -1) + if intrinsics.shape[0] == 1: + intrinsics = intrinsics.expand(len(reps), -1, -1) + ret = {k : [] for k in return_types} + for i, rep in enumerate(reps): + specified_color = None if specified_colors is None else specified_colors[i] + out_dict = self.renderer.render(rep, extrinsics[i], intrinsics[i], return_types=return_types, specified_color=specified_color) + for k in out_dict: + ret[k].append(out_dict[k][None] if k in ['mask', 'depth'] else out_dict[k]) + for k in ret: + ret[k] = torch.stack(ret[k]) + return ret + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + verbose: bool = False, + **kwargs, + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + sampler = self.get_sampler() + ret_dict = {} + cond_vis = [] + gt_meshes, gt_reps, gt_reps_skl, reps, reps_skl, instances = [], [], [], [], [], [] + joints_gt, parents_gt, skins_gt = [], [], [] + gt_skin_colors, pred_skin_colors, gt_recon_skin_colors, pred_skin_colors_with_gt_skl, pred_skin_colors_with_gt_ss = [], [], [], [], [] + incorrect_grouping_instances = [] + for i in range(0, num_samples, batch_size): + data = next(iter(dataloader)) + for key in data: + if type(data[key]) is list and hasattr(data[key][0], 'device'): + for j in range(len(data[key])): + data[key][j] = data[key][j].to(self.device) + data = recursive_to_device(data, self.device) + noise = data['x_0'].replace(torch.randn_like(data['x_0'].feats)) + noise_skl = data['x_0_skl'].replace(torch.randn_like(data['x_0_skl'].feats)) + gt_rep, gt_rep_skl = self.dataset.decode_latent(data['x_0'], data['x_0_skl']) + gt_reps.extend(gt_rep) + gt_reps_skl.extend(gt_rep_skl) + gt_meshes.extend(data['mesh']) + cond_vis.append(self.vis_cond(**data)) + del data['x_0'] + del data['x_0_skl'] + args = self.get_inference_cond(**data) + + # `get_inference_cond(**data)` already forwards extra kwargs, including `joints_num`. + if self.use_joint_num_cond and ('joints_num' in args) and (args['joints_num'] is not None): + # If CFG is active (neg_cond provided), make unconditional joints_num explicit. + if 'neg_cond' in args and 'neg_joints_num' not in args: + jn = args['joints_num'] + args['neg_joints_num'] = torch.zeros_like(jn) if torch.is_tensor(jn) else 0 + + res = sampler.sample( + self.models['denoiser'], + noise=noise, + noise_skl=noise_skl, + **args, + steps=50, cfg_strength=3.0, verbose=verbose, + ) + rep, rep_skl, skins_gt_sskin, skins_gt_sklskin = self.dataset.decode_latent(res.samples.cuda(), res.samples_skl.cuda(), gt_reps=gt_rep, gt_reps_skl=gt_rep_skl) + reps.extend(rep) + reps_skl.extend(rep_skl) + instances.extend(data['instance']) + joints_gt.extend(data['joints']) + parents_gt.extend(data['parents']) + skins_gt.extend(data['skin']) + + jmapping_gtrec2gt = [knn_points(gt_j[None], gt_rep_skl_.joints_grouped[None], K=1)[1][0, :, 0] for gt_rep_skl_, gt_j in zip(gt_rep_skl, data['joints'])] + jmapping_gen2gt = [knn_points(gt_j[None], rep_skl_.joints_grouped[None], K=1)[1][0, :, 0] for rep_skl_, gt_j in zip(rep_skl, data['joints'])] + + # Skin color for GT mesh and pred mesh + skin_color_trans_funcs = [get_transform(skin) for skin in data['skin']] + gt_skin_colors.extend( [func(skin) for func, skin in zip(skin_color_trans_funcs, data['skin'])]) + pred_skin_colors_with_gt_ss.extend( [func(skin[:, jmap]) for func, skin, jmap in zip(skin_color_trans_funcs, skins_gt_sskin, jmapping_gen2gt)]) + pred_skin_colors_with_gt_skl.extend([func(skin[:, jmap]) for func, skin, jmap in zip(skin_color_trans_funcs, skins_gt_sklskin, jmapping_gtrec2gt)]) + gt_recon_skin_colors.extend( [func(skin[:, jmap]) for func, skin, jmap in zip(skin_color_trans_funcs, [rs['skin_pred'] for rs in gt_rep_skl], jmapping_gtrec2gt)]) + pred_skin_colors.extend( [func(skin[:, jmap]) for func, skin, jmap in zip(skin_color_trans_funcs, [rs['skin_pred'] for rs in rep_skl], jmapping_gen2gt)]) + + jmapping_gen2gtrec = [knn_points(gt_rep_skl_.joints_grouped[None], rep_skl_.joints_grouped[None], K=1)[1][0, :, 0] for rep_skl_, gt_rep_skl_ in zip(rep_skl, gt_rep_skl)] + incorrect_grouping_instances.extend([ins for ins, jmap, rep_skl_ in zip(args['instance'], jmapping_gen2gtrec, rep_skl) if not (torch.bincount(jmap, minlength=rep_skl_.joints_grouped.shape[0]) == 1).all()]) + + ret_dict.update({f'incorrect_grouping_instances': {'value': incorrect_grouping_instances, 'type': 'text'}}) + + # Build camera + self.renderer.rendering_options.bg_color = (0, 0, 0) + self.renderer.rendering_options.resolution = 512 + yaws = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + yaws_offset = np.random.uniform(-np.pi / 4, np.pi / 4) + yaws = [y + yaws_offset for y in yaws] + pitch = [np.random.uniform(-np.pi / 4, np.pi / 4) for _ in range(4)] + exts = [] + ints = [] + for yaw, pitch in zip(yaws, pitch): + orig = torch.tensor([ + np.sin(yaw) * np.cos(pitch), + np.cos(yaw) * np.cos(pitch), + np.sin(pitch), + ]).float().cuda() * 2 + fov = torch.deg2rad(torch.tensor(40)).cuda() + extrinsics = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intrinsics = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + exts.append(extrinsics) + ints.append(intrinsics) + exts = torch.stack(exts, dim=0)[0] + ints = torch.stack(ints, dim=0)[0] + + # GT + return_types = ['normal', 'specified'] + gt_render_results = self._render_batch([ + MeshExtractResult(vertices=mesh['vertices'].to(self.device), faces=mesh['faces'].to(self.device)) + for mesh in gt_meshes + ], exts[None], ints[None], return_types=return_types, specified_colors=gt_skin_colors) + ret_dict.update({f'gt_normal': {'value': self._flip_normal(gt_render_results['normal'], exts[None], ints[None]), 'type': 'image'}}) + ret_dict.update({f'gt_skin_map': {'value': gt_render_results['specified'], 'type': 'image'}}) + # GT Recon + return_types = ['normal', 'color', 'normal_map', 'specified'] + render_results = self._render_batch(gt_reps, exts[None], ints[None], return_types=return_types, specified_colors=gt_recon_skin_colors) + ret_dict.update({f'gt_rec_normal': {'value': render_results['normal'], 'type': 'image'}}) + ret_dict.update({f'gt_rec_image': {'value': render_results['color'], 'type': 'image'}}) + ret_dict.update({f'gt_rec_normal_map': {'value': render_results['normal_map'], 'type': 'image'}}) + ret_dict.update({f'gt_rec_skin_map': {'value': render_results['specified'], 'type': 'image'}}) + # Pred + return_types = ['normal', 'color', 'normal_map', 'specified'] + render_results = self._render_batch(reps, exts[None], ints[None], return_types=return_types, specified_colors=pred_skin_colors) + ret_dict.update({f'gen_normal': {'value': render_results['normal'], 'type': 'image'}}) + ret_dict.update({f'gen_image': {'value': render_results['color'], 'type': 'image'}}) + ret_dict.update({f'gen_normal_map': {'value': render_results['normal_map'], 'type': 'image'}}) + ret_dict.update({f'gen_skin_map': {'value': render_results['specified'], 'type': 'image'}}) + # Pred with GT skl skin + render_results = self._render_batch(reps, exts[None], ints[None], return_types=['specified'], specified_colors=pred_skin_colors_with_gt_skl) + ret_dict.update({f'gen_skin_map_with_gt_skl': {'value': render_results['specified'], 'type': 'image'}}) + # Pred with GT ss skin + render_results = self._render_batch(gt_reps, exts[None], ints[None], return_types=['specified'], specified_colors=pred_skin_colors_with_gt_ss) + ret_dict.update({f'gen_skin_map_with_gt_ss': {'value': render_results['specified'], 'type': 'image'}}) + + ret_dict.update(dict_reduce(cond_vis, None, { + 'value': lambda x: torch.cat(x, dim=0), + 'type': lambda x: x[0], + })) + + ## Skeletoned Meshes + skeletoned_meshes = [] + joints_parents = [] + for i, rep_skl in enumerate(reps_skl): + ################################## + # Predicted mesh with GT skeleton + ################################## + skeletoned_mesh = dict() + skeletoned_mesh['instance'] = instances[i] + vertices_pred, faces_pred = reps[i].vertices, reps[i].faces + skeletoned_mesh['vertices'] = vertices_pred + skeletoned_mesh['faces'] = faces_pred + skeletoned_mesh['joints'] = rep_skl.joints_grouped + skeletoned_mesh['parents'] = rep_skl.parents_grouped + skeletoned_mesh['skin'] = rep_skl.skin_pred + skeletoned_meshes.append(skeletoned_mesh) + + ################################## + # Predicted mesh with GT skeleton + ################################## + joint_parent = dict() + joint_parent['instance'] = instances[i] + # GT joints + joint_gt, parent_idx_gt = joints_gt[i], parents_gt[i] + import matplotlib.pyplot as plt + joint_colors_gt = torch.tensor(plt.cm.get_cmap('tab20')(np.arange(len(joint_gt)))[:, :3], dtype=joint_gt.dtype, device=joint_gt.device) + joint_gt_with_color = torch.cat([joint_gt, joint_colors_gt], dim=-1) + # GT parents + parent_gt = joint_gt[parent_idx_gt[1:]] + parent_colors_gt = joint_colors_gt[parent_idx_gt[1:]] + parent_gt_with_color = torch.cat([parent_gt, parent_colors_gt], dim=-1) + # Predicted joints + position_skl = rep_skl.positions + _, joint_nn_idx, _ = knn_points(position_skl[None], joint_gt[None], K=1, norm=2, return_nn=False) + joint_nn_idx = joint_nn_idx[0, :, 0] + joint_pred = rep_skl.joints + joint_colors_pred = joint_colors_gt[joint_nn_idx] + joint_pred_with_color = torch.cat([joint_pred, joint_colors_pred], dim=-1) + # Predicted parents + parent_pred = rep_skl.parents + parents_nn_idx = parent_idx_gt[joint_nn_idx] + parents_nn_idx[parents_nn_idx == -1] = 0 + parent_colors_pred = joint_colors_gt[parents_nn_idx] + parent_pred_with_color = torch.cat([parent_pred, parent_colors_pred], dim=-1) + # Combine + joint_parent['joints_gt'] = joint_gt_with_color + joint_parent['parents_gt'] = parent_gt_with_color + joint_parent['joints_pred'] = joint_pred_with_color + joint_parent['parents_pred'] = parent_pred_with_color + # Confidence + if rep_skl.conf_j is not None: + color_conf_j = rep_skl.conf_j.expand(-1, 1) + color_conf_j = (color_conf_j - color_conf_j.min()) / (color_conf_j.max() - color_conf_j.min() + 1e-8) + color_conf_j = torch.cat([color_conf_j, torch.zeros_like(color_conf_j), 1-color_conf_j], dim=-1) + joint_parent['joints_conf'] = torch.cat([joint_pred, color_conf_j], dim=-1) + if rep_skl.conf_p is not None: + color_conf_p = rep_skl.conf_p.expand(-1, 1) + color_conf_p = (color_conf_p - color_conf_p.min()) / (color_conf_p.max() - color_conf_p.min() + 1e-8) + color_conf_p = torch.cat([color_conf_p, torch.zeros_like(color_conf_p), 1-color_conf_p], dim=-1) + joint_parent['parents_conf'] = torch.cat([parent_pred, color_conf_p], dim=-1) + if rep_skl.joints_grouped is not None: + joint_parent['joints_grouped'] = torch.cat([rep_skl.joints_grouped, torch.ones_like(rep_skl.joints_grouped)], dim=-1) + if rep_skl.parents_grouped is not None: + parents_grouped = rep_skl.joints_grouped[rep_skl.parents_grouped] + joint_parent['parents_grouped'] = torch.cat([parents_grouped, torch.ones_like(parents_grouped)], dim=-1) + joints_parents.append(joint_parent) + + ret_dict.update({ + 'skeletoned_meshes': {'value': skeletoned_meshes, 'type': 'skeletoned_mesh_list'}, + 'joints_parents': {'value': joints_parents, 'type': 'joints_parents'}, + }) + + return ret_dict + + +class AniGenSparseFlowMatchingCFGTrainer(ClassifierFreeGuidanceMixin, AniGenSparseFlowMatchingTrainer): + """ + Trainer for sparse diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + """ + + def get_sampler(self, **kwargs) -> samplers.AniGenFlowEulerCfgSampler: + """ + Get the sampler for the diffusion process with classifier-free guidance. + """ + return samplers.AniGenFlowEulerCfgSampler(self.sigma_min) + + +class AniGenTextConditionedSparseFlowMatchingCFGTrainer(TextConditionedMixin, AniGenSparseFlowMatchingCFGTrainer): + """ + Trainer for sparse text-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + text_cond_model(str): Text conditioning model. + """ + pass + + +class AniGenImageConditionedSparseFlowMatchingCFGTrainer(ImageConditionedMixin, AniGenSparseFlowMatchingCFGTrainer): + """ + Trainer for sparse image-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + image_cond_model (str): Image conditioning model. + """ + pass diff --git a/anigen/trainers/flow_matching/flow_matching.py b/anigen/trainers/flow_matching/flow_matching.py new file mode 100644 index 0000000000000000000000000000000000000000..1df8efa29e4e0dcf027f38e28a81a0130beb26bf --- /dev/null +++ b/anigen/trainers/flow_matching/flow_matching.py @@ -0,0 +1,353 @@ +from typing import * +import copy +import torch +import torch.nn.functional as F +from torch.utils.data import DataLoader +import numpy as np +from easydict import EasyDict as edict + +from ..basic import BasicTrainer +from ...pipelines import samplers +from ...utils.general_utils import dict_reduce +from .mixins.classifier_free_guidance import ClassifierFreeGuidanceMixin +from .mixins.text_conditioned import TextConditionedMixin +from .mixins.image_conditioned import ImageConditionedMixin + + +class FlowMatchingTrainer(BasicTrainer): + """ + Trainer for diffusion model with flow matching objective. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + """ + def __init__( + self, + *args, + t_schedule: dict = { + 'name': 'logitNormal', + 'args': { + 'mean': 0.0, + 'std': 1.0, + } + }, + sigma_min: float = 1e-5, + **kwargs + ): + super().__init__(*args, **kwargs) + self.t_schedule = t_schedule + self.sigma_min = sigma_min + + def diffuse(self, x_0: torch.Tensor, t: torch.Tensor, noise: Optional[torch.Tensor] = None) -> torch.Tensor: + """ + Diffuse the data for a given number of diffusion steps. + In other words, sample from q(x_t | x_0). + + Args: + x_0: The [N x C x ...] tensor of noiseless inputs. + t: The [N] tensor of diffusion steps [0-1]. + noise: If specified, use this noise instead of generating new noise. + + Returns: + x_t, the noisy version of x_0 under timestep t. + """ + if noise is None: + noise = torch.randn_like(x_0) + assert noise.shape == x_0.shape, "noise must have same shape as x_0" + + t = t.view(-1, *[1 for _ in range(len(x_0.shape) - 1)]) + x_t = (1 - t) * x_0 + (self.sigma_min + (1 - self.sigma_min) * t) * noise + + return x_t + + def reverse_diffuse(self, x_t: torch.Tensor, t: torch.Tensor, noise: torch.Tensor) -> torch.Tensor: + """ + Get original image from noisy version under timestep t. + """ + assert noise.shape == x_t.shape, "noise must have same shape as x_t" + t = t.view(-1, *[1 for _ in range(len(x_t.shape) - 1)]) + x_0 = (x_t - (self.sigma_min + (1 - self.sigma_min) * t) * noise) / (1 - t) + return x_0 + + def get_v(self, x_0: torch.Tensor, noise: torch.Tensor, t: torch.Tensor) -> torch.Tensor: + """ + Compute the velocity of the diffusion process at time t. + """ + return (1 - self.sigma_min) * noise - x_0 + + def get_cond(self, cond, **kwargs): + """ + Get the conditioning data. + """ + return cond + + def get_inference_cond(self, cond, **kwargs): + """ + Get the conditioning data for inference. + """ + return {'cond': cond, **kwargs} + + def get_sampler(self, **kwargs) -> samplers.FlowEulerSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.FlowEulerSampler(self.sigma_min) + + def vis_cond(self, **kwargs): + """ + Visualize the conditioning data. + """ + return {} + + def sample_t(self, batch_size: int) -> torch.Tensor: + """ + Sample timesteps. + """ + if self.t_schedule['name'] == 'uniform': + t = torch.rand(batch_size) + elif self.t_schedule['name'] == 'logitNormal': + mean = self.t_schedule['args']['mean'] + std = self.t_schedule['args']['std'] + t = torch.sigmoid(torch.randn(batch_size) * std + mean) + else: + raise ValueError(f"Unknown t_schedule: {self.t_schedule['name']}") + return t + + def training_losses( + self, + x_0: torch.Tensor, + cond=None, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses for a single timestep. + + Args: + x_0: The [N x C x ...] tensor of noiseless inputs. + cond: The [N x ...] tensor of additional conditions. + kwargs: Additional arguments to pass to the backbone. + + Returns: + a dict with the key "loss" containing a tensor of shape [N]. + may also contain other keys for different terms. + """ + noise = torch.randn_like(x_0) + t = self.sample_t(x_0.shape[0]).to(x_0.device).float() + x_t = self.diffuse(x_0, t, noise=noise) + cond = self.get_cond(cond, **kwargs) + + pred = self.training_models['denoiser'](x_t, t * 1000, cond, **kwargs) + assert pred.shape == noise.shape == x_0.shape + target = self.get_v(x_0, noise, t) + terms = edict() + terms["mse"] = F.mse_loss(pred, target) + terms["loss"] = terms["mse"] + + # log loss with time bins + mse_per_instance = np.array([ + F.mse_loss(pred[i], target[i]).item() + for i in range(x_0.shape[0]) + ]) + time_bin = np.digitize(t.cpu().numpy(), np.linspace(0, 1, 11)) - 1 + for i in range(10): + if (time_bin == i).sum() != 0: + terms[f"bin_{i}"] = {"mse": mse_per_instance[time_bin == i].mean()} + + return terms, {} + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + verbose: bool = False, + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + sampler = self.get_sampler() + sample_gt = [] + sample = [] + cond_vis = [] + for i in range(0, num_samples, batch_size): + batch = min(batch_size, num_samples - i) + data = next(iter(dataloader)) + data = {k: v[:batch].cuda() if isinstance(v, torch.Tensor) else v[:batch] for k, v in data.items()} + noise = torch.randn_like(data['x_0']) + sample_gt.append(data['x_0']) + cond_vis.append(self.vis_cond(**data)) + del data['x_0'] + args = self.get_inference_cond(**data) + res = sampler.sample( + self.models['denoiser'], + noise=noise, + **args, + steps=50, cfg_strength=3.0, verbose=verbose, + ) + sample.append(res.samples) + + sample_gt = torch.cat(sample_gt, dim=0) + sample = torch.cat(sample, dim=0) + sample_dict = { + 'sample_gt': {'value': sample_gt, 'type': 'sample'}, + 'sample': {'value': sample, 'type': 'sample'}, + } + sample_dict.update(dict_reduce(cond_vis, None, { + 'value': lambda x: torch.cat(x, dim=0), + 'type': lambda x: x[0], + })) + + return sample_dict + + +class FlowMatchingCFGTrainer(ClassifierFreeGuidanceMixin, FlowMatchingTrainer): + """ + Trainer for diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + """ + pass + + +class TextConditionedFlowMatchingCFGTrainer(TextConditionedMixin, FlowMatchingCFGTrainer): + """ + Trainer for text-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + text_cond_model(str): Text conditioning model. + """ + pass + + +class ImageConditionedFlowMatchingCFGTrainer(ImageConditionedMixin, FlowMatchingCFGTrainer): + """ + Trainer for image-conditioned diffusion model with flow matching objective and classifier-free guidance. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + t_schedule (dict): Time schedule for flow matching. + sigma_min (float): Minimum noise level. + p_uncond (float): Probability of dropping conditions. + image_cond_model (str): Image conditioning model. + """ + pass diff --git a/anigen/trainers/flow_matching/mixins/classifier_free_guidance.py b/anigen/trainers/flow_matching/mixins/classifier_free_guidance.py new file mode 100644 index 0000000000000000000000000000000000000000..666ddb8e41dbd6a101bedddc6d67c89e88fa28a6 --- /dev/null +++ b/anigen/trainers/flow_matching/mixins/classifier_free_guidance.py @@ -0,0 +1,64 @@ +import torch +import numpy as np +from ....utils.general_utils import dict_foreach +from ....pipelines import samplers + + +class ClassifierFreeGuidanceMixin: + def __init__(self, *args, p_uncond: float = 0.1, **kwargs): + super().__init__(*args, **kwargs) + self.p_uncond = p_uncond + + def get_cond(self, cond, neg_cond=None, **kwargs): + """ + Get the conditioning data. + """ + assert neg_cond is not None, "neg_cond must be provided for classifier-free guidance" + + # Default: no unconditional mask applied. + self._last_uncond_mask = None + + if self.p_uncond > 0: + # randomly drop the class label + def get_batch_size(cond): + if isinstance(cond, torch.Tensor): + return cond.shape[0] + elif isinstance(cond, list): + return len(cond) + else: + raise ValueError(f"Unsupported type of cond: {type(cond)}") + + ref_cond = cond if not isinstance(cond, dict) else cond[list(cond.keys())[0]] + B = get_batch_size(ref_cond) + + def select(cond, neg_cond, mask): + if isinstance(cond, torch.Tensor): + mask = torch.tensor(mask, device=cond.device).reshape(-1, *[1] * (cond.ndim - 1)) + return torch.where(mask, neg_cond, cond) + elif isinstance(cond, list): + return [nc if m else c for c, nc, m in zip(cond, neg_cond, mask)] + else: + raise ValueError(f"Unsupported type of cond: {type(cond)}") + + mask = list(np.random.rand(B) < self.p_uncond) + # Cache for downstream (e.g., to drop auxiliary conditions like joints_num). + self._last_uncond_mask = mask + if not isinstance(cond, dict): + cond = select(cond, neg_cond, mask) + else: + cond = dict_foreach([cond, neg_cond], lambda x: select(x[0], x[1], mask)) + + return cond + + def get_inference_cond(self, cond, neg_cond=None, **kwargs): + """ + Get the conditioning data for inference. + """ + assert neg_cond is not None, "neg_cond must be provided for classifier-free guidance" + return {'cond': cond, 'neg_cond': neg_cond, **kwargs} + + def get_sampler(self, **kwargs) -> samplers.FlowEulerCfgSampler: + """ + Get the sampler for the diffusion process. + """ + return samplers.FlowEulerCfgSampler(self.sigma_min) diff --git a/anigen/trainers/flow_matching/mixins/image_conditioned.py b/anigen/trainers/flow_matching/mixins/image_conditioned.py new file mode 100644 index 0000000000000000000000000000000000000000..d47dab990e84e9f7ca4070258b1f5d048e0bd1fb --- /dev/null +++ b/anigen/trainers/flow_matching/mixins/image_conditioned.py @@ -0,0 +1,97 @@ +from typing import * +import torch +import torch.nn.functional as F +from torchvision import transforms +import numpy as np +from PIL import Image + +from ....utils import dist_utils + + +class ImageConditionedMixin: + """ + Mixin for image-conditioned models. + + Args: + image_cond_model: The image conditioning model. + """ + def __init__(self, *args, image_cond_model: str = 'dinov2_vitl14_reg', **kwargs): + super().__init__(*args, **kwargs) + self.image_cond_model_name = image_cond_model + self.image_cond_model = None # the model is init lazily + + @staticmethod + def prepare_for_training(image_cond_model: str, **kwargs): + """ + Prepare for training. + """ + if hasattr(super(ImageConditionedMixin, ImageConditionedMixin), 'prepare_for_training'): + super(ImageConditionedMixin, ImageConditionedMixin).prepare_for_training(**kwargs) + # download the model + # torch.hub.load('facebookresearch/dinov2', image_cond_model, pretrained=True) + torch.hub.load('./ckpts/dinov2', image_cond_model, pretrained=True, source='local') + + def _init_image_cond_model(self): + """ + Initialize the image conditioning model. + """ + with dist_utils.local_master_first(): + if self.image_cond_model is None: + # dinov2_model = torch.hub.load('facebookresearch/dinov2', self.image_cond_model_name, pretrained=True) + dinov2_model = torch.hub.load('./ckpts/dinov2', self.image_cond_model_name, pretrained=True, source='local') + + if self.image_cond_model is None: + dinov2_model.eval().cuda() + transform = transforms.Compose([ + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + self.image_cond_model = { + 'model': dinov2_model, + 'transform': transform, + } + + @torch.no_grad() + def encode_image(self, image: Union[torch.Tensor, List[Image.Image]]) -> torch.Tensor: + """ + Encode the image. + """ + if isinstance(image, torch.Tensor): + assert image.ndim == 4, "Image tensor should be batched (B, C, H, W)" + elif isinstance(image, list): + assert all(isinstance(i, Image.Image) for i in image), "Image list should be list of PIL images" + image = [i.resize((518, 518), Image.LANCZOS) for i in image] + image = [np.array(i.convert('RGB')).astype(np.float32) / 255 for i in image] + image = [torch.from_numpy(i).permute(2, 0, 1).float() for i in image] + image = torch.stack(image).cuda() + else: + raise ValueError(f"Unsupported type of image: {type(image)}") + + self._init_image_cond_model() + image = self.image_cond_model['transform'](image).cuda() + features = self.image_cond_model['model'](image, is_training=True)['x_prenorm'] + patchtokens = F.layer_norm(features, features.shape[-1:]) + return patchtokens + + def get_cond(self, cond, **kwargs): + """ + Get the conditioning data. + """ + cond = self.encode_image(cond) + kwargs['neg_cond'] = torch.zeros_like(cond) + cond = super().get_cond(cond, **kwargs) + return cond + + def get_inference_cond(self, cond, **kwargs): + """ + Get the conditioning data for inference. + """ + cond = self.encode_image(cond) + kwargs['neg_cond'] = torch.zeros_like(cond) + cond = super().get_inference_cond(cond, **kwargs) + return cond + + def vis_cond(self, cond, **kwargs): + """ + Visualize the conditioning data. + """ + return {'image': {'value': cond, 'type': 'image'}} diff --git a/anigen/trainers/flow_matching/mixins/text_conditioned.py b/anigen/trainers/flow_matching/mixins/text_conditioned.py new file mode 100644 index 0000000000000000000000000000000000000000..85f1dcf2582c07edd9b629c07181265f24a90134 --- /dev/null +++ b/anigen/trainers/flow_matching/mixins/text_conditioned.py @@ -0,0 +1,68 @@ +from typing import * +import os +os.environ['TOKENIZERS_PARALLELISM'] = 'true' +import torch +from transformers import AutoTokenizer, CLIPTextModel + +from ....utils import dist_utils + + +class TextConditionedMixin: + """ + Mixin for text-conditioned models. + + Args: + text_cond_model: The text conditioning model. + """ + def __init__(self, *args, text_cond_model: str = 'openai/clip-vit-large-patch14', **kwargs): + super().__init__(*args, **kwargs) + self.text_cond_model_name = text_cond_model + self.text_cond_model = None # the model is init lazily + + def _init_text_cond_model(self): + """ + Initialize the text conditioning model. + """ + # load model + with dist_utils.local_master_first(): + model = CLIPTextModel.from_pretrained(self.text_cond_model_name) + tokenizer = AutoTokenizer.from_pretrained(self.text_cond_model_name) + model.eval() + model = model.cuda() + self.text_cond_model = { + 'model': model, + 'tokenizer': tokenizer, + } + self.text_cond_model['null_cond'] = self.encode_text(['']) + + @torch.no_grad() + def encode_text(self, text: List[str]) -> torch.Tensor: + """ + Encode the text. + """ + assert isinstance(text, list) and isinstance(text[0], str), "TextConditionedMixin only supports list of strings as cond" + if self.text_cond_model is None: + self._init_text_cond_model() + encoding = self.text_cond_model['tokenizer'](text, max_length=77, padding='max_length', truncation=True, return_tensors='pt') + tokens = encoding['input_ids'].cuda() + embeddings = self.text_cond_model['model'](input_ids=tokens).last_hidden_state + + return embeddings + + def get_cond(self, cond, **kwargs): + """ + Get the conditioning data. + """ + cond = self.encode_text(cond) + kwargs['neg_cond'] = self.text_cond_model['null_cond'].repeat(cond.shape[0], 1, 1) + cond = super().get_cond(cond, **kwargs) + return cond + + def get_inference_cond(self, cond, **kwargs): + """ + Get the conditioning data for inference. + """ + cond = self.encode_text(cond) + kwargs['neg_cond'] = self.text_cond_model['null_cond'].repeat(cond.shape[0], 1, 1) + cond = super().get_inference_cond(cond, **kwargs) + return cond diff --git a/anigen/trainers/utils.py b/anigen/trainers/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..91a7893397c572e7e9fdbfeae0ee0080cb9e8010 --- /dev/null +++ b/anigen/trainers/utils.py @@ -0,0 +1,123 @@ +import torch.nn as nn + + +def make_master_params_regular(model_params): + """ + Copy model parameters into a inflated tensor of full-precision parameters. + """ + master_params = [] + for param in model_params: + if param.requires_grad: + master_param = nn.Parameter(param.detach().float()) + master_param.requires_grad = True + master_params.append(master_param) + return master_params + + +def model_params_to_master_params_regular(model_params, master_params): + for param, master_param in zip(model_params, master_params): + master_param.detach().copy_(param.detach().float()) + + +def master_params_to_model_params_regular(model_params, master_params): + for param, master_param in zip(model_params, master_params): + param.detach().copy_(master_param.detach().float()) + + +def model_grads_to_master_grads_regular(model_params, master_params): + for param, master_param in zip(model_params, master_params): + if param.grad is not None: + master_param.grad = param.grad.data.detach().float() + else: + master_param.grad = param.data.new_zeros(param.data.shape, dtype=param.data.dtype).float() + + +# FP16 utils +from torch._utils import _flatten_dense_tensors, _unflatten_dense_tensors + +def make_master_params(model_params): + """ + Copy model parameters into a inflated tensor of full-precision parameters. + """ + master_params = _flatten_dense_tensors( + [param.detach().float() for param in model_params] + ) + master_params = nn.Parameter(master_params) + master_params.requires_grad = True + return [master_params] + + +def unflatten_master_params(model_params, master_params): + """ + Unflatten the master parameters to look like model_params. + """ + return _unflatten_dense_tensors(master_params[0].detach(), model_params) + + +def model_params_to_master_params(model_params, master_params): + """ + Copy the model parameter data into the master parameters. + """ + master_params[0].detach().copy_( + _flatten_dense_tensors([param.detach().float() for param in model_params]) + ) + + +def master_params_to_model_params(model_params, master_params): + """ + Copy the master parameter data back into the model parameters. + """ + for param, master_param in zip( + model_params, _unflatten_dense_tensors(master_params[0].detach(), model_params) + ): + param.detach().copy_(master_param) + + +def model_grads_to_master_grads_unsave(model_params, master_params): + """ + Copy the gradients from the model parameters into the master parameters + from make_master_params(). + """ + master_params[0].grad = _flatten_dense_tensors( + [param.grad.data.detach().float() for param in model_params] + ) + + +def model_grads_to_master_grads(model_params, master_params): + """ + Copy the gradients from the model parameters into the master parameters + from make_master_params(). + If a parameter has no gradient, use zeros of the same shape and dtype. + """ + grads = [] + for param in model_params: + if param.grad is not None: + grads.append(param.grad.data.detach().float()) + else: + grads.append(param.data.new_zeros(param.data.shape, dtype=param.data.dtype).float()) + master_params[0].grad = _flatten_dense_tensors(grads) + + +def zero_grad(model_params): + for param in model_params: + if param.grad is not None: + if param.grad.grad_fn is not None: + param.grad.detach_() + else: + param.grad.requires_grad_(False) + param.grad.zero_() + + +# LR Schedulers +from torch.optim.lr_scheduler import LambdaLR + +class LinearWarmupLRScheduler(LambdaLR): + def __init__(self, optimizer, warmup_steps, last_epoch=-1): + self.warmup_steps = warmup_steps + super(LinearWarmupLRScheduler, self).__init__(optimizer, self.lr_lambda, last_epoch=last_epoch) + + def lr_lambda(self, current_step): + if current_step < self.warmup_steps: + return float(current_step + 1) / self.warmup_steps + return 1.0 + \ No newline at end of file diff --git a/anigen/trainers/vae/anigen_skin_ae.py b/anigen/trainers/vae/anigen_skin_ae.py new file mode 100644 index 0000000000000000000000000000000000000000..ceb4ec4511f153319f473fce506a8e43aef93098 --- /dev/null +++ b/anigen/trainers/vae/anigen_skin_ae.py @@ -0,0 +1,320 @@ +from typing import * +import copy +import torch +from torch.utils.data import DataLoader +import numpy as np +from easydict import EasyDict as edict +import utils3d.torch +from ...renderers import MeshRenderer +from ...representations import MeshExtractResult +from ...utils.data_utils import recursive_to_device +from ...utils.skin_utils import get_transform + +from ..basic import BasicTrainer + +from ...representations import Gaussian +from ...renderers import GaussianRenderer +from ...representations.octree import DfsOctree as Octree +from ...renderers import OctreeRenderer + +from ...modules.sparse import SparseTensor +from ...utils.loss_utils import l1_loss, smooth_l1_loss, l2_loss, ssim, lpips +from pytorch3d.ops import knn_points +import torch.nn.functional as F + + +class AniGenSkinAETrainer(BasicTrainer): + """ + Trainer for structured latent VAE. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + loss_type (str): Loss type. Can be 'l1', 'l2' + lambda_ssim (float): SSIM loss weight. + lambda_lpips (float): LPIPS loss weight. + lambda_kl (float): KL loss weight. + regularizations (dict): Regularization config. + """ + + def __init__( + self, + *args, + lambda_kl_skin: float = 1.0, + lambda_l1_skin: float = 0., + lambda_l2_skin: float = 0., + num_skin_samples: Optional[int] = None, + + regularizations: Dict = {}, + **kwargs + ): + super().__init__(*args, **kwargs) + self.lambda_kl_skin = lambda_kl_skin + self.lambda_l1_skin = lambda_l1_skin + self.lambda_l2_skin = lambda_l2_skin + self.num_skin_samples = num_skin_samples + self._init_renderer() + + def _init_renderer(self): + rendering_options = {"near" : 1, + "far" : 3} + self.renderer = MeshRenderer(rendering_options, device=self.device) + + @torch.no_grad() + def render_coords(self, coords_list, extrinsics: torch.Tensor, intrinsics: torch.Tensor, colors_overwrite_list=None, ss_resolution=64): + renderer = OctreeRenderer() + renderer.rendering_options.resolution = 512 + renderer.rendering_options.near = 0.8 + renderer.rendering_options.far = 1.6 + renderer.rendering_options.bg_color = (0, 0, 0) + renderer.rendering_options.ssaa = 4 + renderer.pipe.primitive = 'voxel' + images = [] + for i in range(len(coords_list)): + representation = Octree( + depth=10, + aabb=[-0.5, -0.5, -0.5, 1, 1, 1], + device='cuda', + primitive='voxel', + sh_degree=0, + primitive_config={'solid': True}, + ) + coords = coords_list[i] + representation.position = coords.float() / ss_resolution + representation.depth = torch.full((representation.position.shape[0], 1), int(np.log2(ss_resolution)), dtype=torch.uint8, device='cuda') + + image = torch.zeros(3, 1024, 1024).cuda() + tile = [2, 2] + for j, (ext, intr) in enumerate(zip(extrinsics, intrinsics)): + res = renderer.render(representation, ext, intr, colors_overwrite=representation.position if colors_overwrite_list is None else colors_overwrite_list[i]) + image[:, 512 * (j // tile[1]):512 * (j // tile[1] + 1), 512 * (j % tile[1]):512 * (j % tile[1] + 1)] = res['color'] + images.append(image) + return torch.stack(images) + + def _render_batch(self, reps: List[MeshExtractResult], extrinsics: torch.Tensor, intrinsics: torch.Tensor, return_types=['mask', 'normal', 'depth'], specified_colors=None) -> Dict[str, torch.Tensor]: + """ + Render a batch of representations. + + Args: + reps: The dictionary of lists of representations. + extrinsics: The [N x 4 x 4] tensor of extrinsics. + intrinsics: The [N x 3 x 3] tensor of intrinsics. + return_types: vary in ['mask', 'normal', 'depth', 'normal_map', 'color'] + + Returns: + a dict with + reg_loss : [N] tensor of regularization losses + mask : [N x 1 x H x W] tensor of rendered masks + normal : [N x 3 x H x W] tensor of rendered normals + depth : [N x 1 x H x W] tensor of rendered depths + """ + ret = {k : [] for k in return_types} + for i, rep in enumerate(reps): + specified_color = None if specified_colors is None else specified_colors[i] + out_dict = self.renderer.render(rep, extrinsics[i], intrinsics[i], return_types=return_types, specified_color=specified_color) + for k in out_dict: + ret[k].append(out_dict[k][None] if k in ['mask', 'depth'] else out_dict[k]) + for k in ret: + ret[k] = torch.stack(ret[k]) + return ret + + def _sample_barycentric_coords(self, num_samples: int, device: torch.device) -> torch.Tensor: + u = torch.rand(num_samples, device=device) + v = torch.rand(num_samples, device=device) + sqrt_u = torch.sqrt(u) + bary_coords = torch.stack([1 - sqrt_u, sqrt_u * (1 - v), sqrt_u * v], dim=-1) + return bary_coords + + def _sample_skin_from_surface(self, mesh: Dict[str, torch.Tensor], skin: torch.Tensor, num_samples: int) -> torch.Tensor: + # Sample surface points proportional to triangle area and barycentrically interpolate skin weights. + device = skin.device + vertices = mesh['vertices'].to(device) + faces = mesh['faces'].to(device) + if faces.dtype != torch.long: + faces = faces.long() + face_vertices = vertices[faces] + vec0 = face_vertices[:, 1] - face_vertices[:, 0] + vec1 = face_vertices[:, 2] - face_vertices[:, 0] + cross_prod = torch.cross(vec0, vec1, dim=-1) + face_areas = torch.linalg.norm(cross_prod, dim=-1) * 0.5 + face_areas = torch.clamp(face_areas, min=1e-12) + if not torch.isfinite(face_areas).all() or face_areas.sum() <= 0: + face_areas = torch.ones_like(face_areas) + probs = face_areas / face_areas.sum() + face_indices = torch.multinomial(probs, num_samples, replacement=True) + sampled_faces = faces[face_indices] + bary_coords = self._sample_barycentric_coords(num_samples, device=device) + skin_vertices = skin[sampled_faces] + sampled_skin = torch.sum(bary_coords.unsqueeze(-1) * skin_vertices, dim=1) + return sampled_skin + + def _prepare_surface_skin_samples(self, mesh_list: List[Dict[str, torch.Tensor]], skin_list: List[torch.Tensor]) -> List[torch.Tensor]: + sampled_skins: List[torch.Tensor] = [] + for mesh, skin in zip(mesh_list, skin_list): + num_samples = skin.shape[0] if self.num_skin_samples is None else self.num_skin_samples + sampled_skins.append(self._sample_skin_from_surface(mesh, skin, num_samples)) + return sampled_skins + + def skeleton_losses( + self, + skin_pred_list, + skin_gt_list, + ): + skin_kl_loss = 0.0 + skin_l1_loss = 0.0 + skin_l2_loss = 0.0 + for i in range(len(skin_pred_list)): + skin_pred = skin_pred_list[i] + skin_gt = skin_gt_list[i] + skin_kl_loss = skin_kl_loss + F.kl_div(torch.log(skin_pred + 1e-10), skin_gt, reduce="batchmean") + if self.lambda_l1_skin > 0: + skin_l1_loss = skin_l1_loss + l1_loss(skin_pred, skin_gt) + if self.lambda_l2_skin > 0: + skin_l2_loss = skin_l2_loss + l2_loss(skin_pred, skin_gt) + skin_kl_loss = skin_kl_loss / len(skin_pred_list) + skin_l1_loss = skin_l1_loss / len(skin_pred_list) + skin_l2_loss = skin_l2_loss / len(skin_pred_list) + return {'skin_kl_loss': skin_kl_loss, 'skin_l1_loss': skin_l1_loss, 'skin_l2_loss': skin_l2_loss} + + def training_losses( + self, + feats: SparseTensor, + feats_skl: SparseTensor, + + joints, + parents, + skin, + mesh: List[Dict], + + image: torch.Tensor, + alpha: torch.Tensor, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + normal_map: torch.Tensor = None, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses. + + Args: + feats: The [N x * x C] sparse tensor of features. + image: The [N x 3 x H x W] tensor of images. + alpha: The [N x H x W] tensor of alpha channels. + extrinsics: The [N x 4 x 4] tensor of extrinsics. + intrinsics: The [N x 3 x 3] tensor of intrinsics. + mesh: The list of mesh dicts with 'vertices' and 'faces'. + skin: The list of skin tensors of shape [num_vertices x num_joints]. + + Returns: + a dict with the key "loss" containing a scalar tensor. + may also contain other keys for different terms. + """ + sampled_skin = self._prepare_surface_skin_samples(mesh, skin) + skin_pred_list, joint_skin_embeds, vert_skin_embeds = self.training_models['model'](joints_list=joints, parents_list=parents, skin_list=sampled_skin) + self.renderer.rendering_options.resolution = image.shape[-1] + terms = edict(loss = 0.0) + skin_loss = self.skeleton_losses(skin_pred_list, sampled_skin) + terms.loss = terms.loss + self.lambda_kl_skin * skin_loss['skin_kl_loss'] + self.lambda_l1_skin * skin_loss['skin_l1_loss'] + self.lambda_l2_skin * skin_loss['skin_l2_loss'] + terms.update(skin_loss) + return terms, {} + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + verbose: bool = False, + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + ret_dict = {} + gt_images = [] + gt_normal_maps = [] + gt_meshes = [] + exts = [] + ints = [] + instances = [] + gt_skin_colors, pred_skin_colors = [], [] + error = {} + for i in range(0, num_samples, batch_size): + data = next(iter(dataloader)) + for key in data: + if type(data[key]) is list and hasattr(data[key][0], 'device'): + for j in range(len(data[key])): + data[key][j] = data[key][j].to(self.device) + args = recursive_to_device(data, 'cuda') + gt_images.append(args['image'] * args['alpha'][:, None]) + gt_meshes.extend(args['mesh']) + exts.append(args['extrinsics']) + ints.append(args['intrinsics']) + + skin_pred_list, joint_skin_embeds, vert_skin_embeds = self.training_models['model'](joints_list=args['joints'], parents_list=args['parents'], skin_list=args['skin']) + + with torch.no_grad(): + skl_loss = self.skeleton_losses(skin_pred_list, args['skin']) + for k in skl_loss: + if k not in error: + error[k] = [] + error[k].append(skl_loss[k]) + + instances.extend(args['instance']) + + skin_color_trans_funcs = [get_transform(skin) for skin in data['skin']] + gt_skin_colors.extend([func(skin) for func, skin in zip(skin_color_trans_funcs, args['skin'])]) + pred_skin_colors.extend([func(skin) for func, skin in zip(skin_color_trans_funcs, skin_pred_list)]) + + gt_images = torch.cat(gt_images, dim=0) + ret_dict.update({f'gt_image': {'value': gt_images, 'type': 'image'}}) + ret_dict.update({'skin_error': {'value': torch.stack(error['skin_kl_loss']), 'type': 'scalar'}}) + + # render single view + # GT + exts = torch.cat(exts, dim=0) + ints = torch.cat(ints, dim=0) + self.renderer.rendering_options.bg_color = (0, 0, 0) + self.renderer.rendering_options.resolution = gt_images.shape[-1] + return_types = ['specified'] + gt_render_results = self._render_batch([ + MeshExtractResult(vertices=mesh['vertices'].to(self.device), faces=mesh['faces'].to(self.device)) + for mesh in gt_meshes + ], exts, ints, return_types=return_types, specified_colors=gt_skin_colors) + ret_dict.update({f'gt_skin_map': {'value': gt_render_results['specified'], 'type': 'image'}}) + # Pred + render_results = self._render_batch([ + MeshExtractResult(vertices=mesh['vertices'].to(self.device), faces=mesh['faces'].to(self.device)) + for mesh in gt_meshes + ], exts, ints, return_types=return_types, specified_colors=pred_skin_colors) + ret_dict.update({f'rec_skin_map': {'value': render_results['specified'], 'type': 'image'}}) + return ret_dict diff --git a/anigen/trainers/vae/anigen_slat_mesh_vae.py b/anigen/trainers/vae/anigen_slat_mesh_vae.py new file mode 100644 index 0000000000000000000000000000000000000000..c95529e01c0e897254112b102643d23768a86937 --- /dev/null +++ b/anigen/trainers/vae/anigen_slat_mesh_vae.py @@ -0,0 +1,918 @@ +from typing import * +import copy +import torch +from torch.utils.data import DataLoader +import numpy as np +from easydict import EasyDict as edict +import utils3d.torch +from ...renderers import MeshRenderer +from ...representations import MeshExtractResult +from ...utils.data_utils import recursive_to_device +from ...utils.skin_utils import get_transform + +from ..basic import BasicTrainer + +from ...representations import Gaussian +from ...renderers import GaussianRenderer +from ...representations.octree import DfsOctree as Octree +from ...renderers import OctreeRenderer + +from ...modules.sparse import SparseTensor +from ...utils.loss_utils import l1_loss, smooth_l1_loss, l2_loss, ssim, lpips +from pytorch3d.ops import knn_points +import torch.nn.functional as F + + +class AniGenSLatVaeSkeletonTrainer(BasicTrainer): + """ + Trainer for structured latent VAE. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + loss_type (str): Loss type. Can be 'l1', 'l2' + lambda_ssim (float): SSIM loss weight. + lambda_lpips (float): LPIPS loss weight. + lambda_kl (float): KL loss weight. + regularizations (dict): Regularization config. + """ + + def __init__( + self, + *args, + depth_loss_type: str = 'l1', + lambda_ssim: float = 0.2, + lambda_lpips: float = 0.2, + lambda_depth: int = 1, + lambda_tsdf: float = 0.01, + lambda_color: float = 0.0, + lambda_kl: float = 1e-3, + lambda_kl_skl: float = 1e-3, + + alpha_conf_j: float = 0.1, + alpha_conf_p: float = 0.1, + + lambda_joints: float = 1.0, + lambda_parents: float = 1.0, + lambda_skin_kl: float = 0.5, + lambda_skin_feats_l2: float = 1.0, + lambda_skin_feats_l2_skl: float = 1.0, + lambda_skin_var: float = 1.0, + + latent_denoising=False, + latent_denoising_gamma=1.0, + latent_denoising_skl=False, + latent_denoising_gamma_skl=1.0, + latent_time_max=0.5, + latent_time_max_skl=0.5, + latent_achive_max_step=0, + latent_achive_max_step_skl=0, + + regularizations: Dict = {}, + **kwargs + ): + super().__init__(*args, **kwargs) + self.depth_loss_type = depth_loss_type + self.lambda_ssim = lambda_ssim + self.lambda_lpips = lambda_lpips + self.lambda_depth = lambda_depth + self.lambda_tsdf = lambda_tsdf + self.lambda_color = lambda_color + self.lambda_kl = lambda_kl + self.lambda_kl_skl = lambda_kl_skl + self.alpha_conf_j = alpha_conf_j + self.alpha_conf_p = alpha_conf_p + self.lambda_joints = lambda_joints + self.lambda_parents = lambda_parents + self.lambda_skin_kl = lambda_skin_kl + self.lambda_skin_feats_l2 = lambda_skin_feats_l2 + self.lambda_skin_feats_l2_skl = lambda_skin_feats_l2_skl + self.lambda_skin_var = lambda_skin_var + + self.latent_denoising = latent_denoising + self.latent_denoising_gamma = latent_denoising_gamma + self.latent_denoising_skl = latent_denoising_skl + self.latent_denoising_gamma_skl = latent_denoising_gamma_skl + self.latent_time_max = latent_time_max + self.latent_time_max_skl = latent_time_max_skl + self.latent_achive_max_step = latent_achive_max_step + self.latent_achive_max_step_skl = latent_achive_max_step_skl + + self.regularizations = regularizations + self.use_color = self.lambda_color > 0 + self._init_renderer() + + def _init_renderer(self): + rendering_options = {"near" : 1, + "far" : 3} + self.renderer = MeshRenderer(rendering_options, device=self.device) + + @torch.no_grad() + def render_coords(self, coords_list, extrinsics: torch.Tensor, intrinsics: torch.Tensor, colors_overwrite_list=None, ss_resolution=64): + renderer = OctreeRenderer() + renderer.rendering_options.resolution = 512 + renderer.rendering_options.near = 0.8 + renderer.rendering_options.far = 1.6 + renderer.rendering_options.bg_color = (0, 0, 0) + renderer.rendering_options.ssaa = 4 + renderer.pipe.primitive = 'voxel' + images = [] + for i in range(len(coords_list)): + representation = Octree( + depth=10, + aabb=[-0.5, -0.5, -0.5, 1, 1, 1], + device='cuda', + primitive='voxel', + sh_degree=0, + primitive_config={'solid': True}, + ) + coords = coords_list[i][:, 1:] + representation.position = coords.float() / ss_resolution + representation.depth = torch.full((representation.position.shape[0], 1), int(np.log2(ss_resolution)), dtype=torch.uint8, device='cuda') + + image = renderer.render(representation, extrinsics[i], intrinsics[i], colors_overwrite=representation.position if colors_overwrite_list is None else colors_overwrite_list[i])['color'] + images.append(image) + return torch.stack(images, dim=0) + + def _render_batch(self, reps: List[MeshExtractResult], extrinsics: torch.Tensor, intrinsics: torch.Tensor, return_types=['mask', 'normal', 'depth'], specified_colors=None) -> Dict[str, torch.Tensor]: + """ + Render a batch of representations. + + Args: + reps: The dictionary of lists of representations. + extrinsics: The [N x 4 x 4] tensor of extrinsics. + intrinsics: The [N x 3 x 3] tensor of intrinsics. + return_types: vary in ['mask', 'normal', 'depth', 'normal_map', 'color'] + + Returns: + a dict with + reg_loss : [N] tensor of regularization losses + mask : [N x 1 x H x W] tensor of rendered masks + normal : [N x 3 x H x W] tensor of rendered normals + depth : [N x 1 x H x W] tensor of rendered depths + """ + ret = {k : [] for k in return_types} + for i, rep in enumerate(reps): + specified_color = None if specified_colors is None else specified_colors[i] + out_dict = self.renderer.render(rep, extrinsics[i], intrinsics[i], return_types=return_types, specified_color=specified_color) + for k in out_dict: + ret[k].append(out_dict[k][None] if k in ['mask', 'depth'] else out_dict[k]) + for k in ret: + ret[k] = torch.stack(ret[k]) + return ret + + @staticmethod + def _tsdf_reg_loss(rep: MeshExtractResult, depth_map: torch.Tensor, extrinsics: torch.Tensor, intrinsics: torch.Tensor) -> torch.Tensor: + # Calculate tsdf + with torch.no_grad(): + # Project points to camera and calculate pseudo-sdf as difference between gt depth and projected depth + projected_pts, pts_depth = utils3d.torch.project_cv(extrinsics=extrinsics, intrinsics=intrinsics, points=rep.tsdf_v) + projected_pts = (projected_pts - 0.5) * 2.0 + depth_map_res = depth_map.shape[1] + gt_depth = torch.nn.functional.grid_sample(depth_map.reshape(1, 1, depth_map_res, depth_map_res), projected_pts.reshape(1, 1, -1, 2), mode='bilinear', padding_mode='border', align_corners=True) + pseudo_sdf = gt_depth.flatten() - pts_depth.flatten() + # Truncate pseudo-sdf + delta = 1 / rep.res * 3.0 + trunc_mask = pseudo_sdf > -delta + + # Loss + gt_tsdf = pseudo_sdf[trunc_mask] + tsdf = rep.tsdf_s.flatten()[trunc_mask] + gt_tsdf = torch.clamp(gt_tsdf, -delta, delta) + return torch.mean((tsdf - gt_tsdf) ** 2) + + def _calc_tsdf_loss(self, reps : list[MeshExtractResult], depth_maps, extrinsics, intrinsics) -> torch.Tensor: + tsdf_loss = 0.0 + for i, rep in enumerate(reps): + tsdf_loss += self._tsdf_reg_loss(rep, depth_maps[i], extrinsics[i], intrinsics[i]) + return tsdf_loss / len(reps) + + @torch.no_grad() + def _flip_normal(self, normal: torch.Tensor, extrinsics: torch.Tensor, intrinsics: torch.Tensor) -> torch.Tensor: + """ + Flip normal to align with camera. + """ + normal = normal * 2.0 - 1.0 + R = torch.zeros_like(extrinsics) + R[:, :3, :3] = extrinsics[:, :3, :3] + R[:, 3, 3] = 1.0 + view_dir = utils3d.torch.unproject_cv( + utils3d.torch.image_uv(*normal.shape[-2:], device=self.device).reshape(1, -1, 2), + torch.ones(*normal.shape[-2:], device=self.device).reshape(1, -1), + R, intrinsics + ).reshape(-1, *normal.shape[-2:], 3).permute(0, 3, 1, 2) + unflip = (normal * view_dir).sum(1, keepdim=True) < 0 + normal *= unflip * 2.0 - 1.0 + return (normal + 1.0) / 2.0 + + def _perceptual_loss(self, gt: torch.Tensor, pred: torch.Tensor, name: str) -> Dict[str, torch.Tensor]: + """ + Combination of L1, SSIM, and LPIPS loss. + """ + if gt.shape[1] != 3: + assert gt.shape[-1] == 3 + gt = gt.permute(0, 3, 1, 2) + if pred.shape[1] != 3: + assert pred.shape[-1] == 3 + pred = pred.permute(0, 3, 1, 2) + terms = { + f"{name}_loss" : l1_loss(gt, pred), + f"{name}_loss_ssim" : 1 - ssim(gt, pred), + f"{name}_loss_lpips" : lpips(gt, pred) + } + terms[f"{name}_loss_perceptual"] = terms[f"{name}_loss"] + terms[f"{name}_loss_ssim"] * self.lambda_ssim + terms[f"{name}_loss_lpips"] * self.lambda_lpips + return terms + + def geometry_losses( + self, + reps: List[MeshExtractResult], + mesh: List[Dict], + normal_map: torch.Tensor, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + ): + with torch.no_grad(): + gt_meshes = [] + for i in range(len(reps)): + gt_mesh = MeshExtractResult(mesh[i]['vertices'].to(self.device), mesh[i]['faces'].to(self.device)) + gt_meshes.append(gt_mesh) + target = self._render_batch(gt_meshes, extrinsics, intrinsics, return_types=['mask', 'depth', 'normal']) + target['normal'] = self._flip_normal(target['normal'], extrinsics, intrinsics) + + terms = edict(geo_loss = 0.0) + if self.lambda_tsdf > 0: + tsdf_loss = self._calc_tsdf_loss(reps, target['depth'], extrinsics, intrinsics) + terms['tsdf_loss'] = tsdf_loss + terms['geo_loss'] += tsdf_loss * self.lambda_tsdf + + return_types = ['mask', 'depth', 'normal', 'normal_map'] if self.use_color else ['mask', 'depth', 'normal'] + buffer = self._render_batch(reps, extrinsics, intrinsics, return_types=return_types) + + success_mask = torch.tensor([rep.success for rep in reps], device=self.device) + if success_mask.sum() != 0: + for k, v in buffer.items(): + buffer[k] = v[success_mask] + for k, v in target.items(): + target[k] = v[success_mask] + + terms['mask_loss'] = l1_loss(buffer['mask'], target['mask']) + if self.depth_loss_type == 'l1': + terms['depth_loss'] = l1_loss(buffer['depth'] * target['mask'], target['depth'] * target['mask']) + elif self.depth_loss_type == 'smooth_l1': + terms['depth_loss'] = smooth_l1_loss(buffer['depth'] * target['mask'], target['depth'] * target['mask'], beta=1.0 / (2 * reps[0].res)) + else: + raise ValueError(f"Unsupported depth loss type: {self.depth_loss_type}") + terms.update(self._perceptual_loss(buffer['normal'] * target['mask'], target['normal'] * target['mask'], 'normal')) + terms['geo_loss'] = terms['geo_loss'] + terms['mask_loss'] + terms['depth_loss'] * self.lambda_depth + terms['normal_loss_perceptual'] + if self.use_color and normal_map is not None: + terms.update(self._perceptual_loss(normal_map[success_mask], buffer['normal_map'], 'normal_map')) + terms['geo_loss'] = terms['geo_loss'] + terms['normal_map_loss_perceptual'] * self.lambda_color + + return terms + + def color_losses(self, reps, image, alpha, extrinsics, intrinsics): + terms = edict(color_loss = torch.tensor(0.0, device=self.device)) + buffer = self._render_batch(reps, extrinsics, intrinsics, return_types=['color']) + success_mask = torch.tensor([rep.success for rep in reps], device=self.device) + if success_mask.sum() != 0: + terms.update(self._perceptual_loss(image * alpha[:, None][success_mask], buffer['color'][success_mask], 'color')) + terms['color_loss'] = terms['color_loss'] + terms['color_loss_perceptual'] * self.lambda_color + return terms + + def skeleton_losses(self, joints_list, parents_list, skin_list, is_bad_skin_list, reps, reps_skl, gt_meshes, joint_skin_embeds_gt_list, vert_skin_embeds_gt_list, cache_gt_skin_embeds=False, cache_gt_nn_skin=False, **kwargs): + terms = edict( + joints_loss = torch.tensor(0.0, device=self.device), + parents_loss = torch.tensor(0.0, device=self.device), + skin_feats_joints_var_loss =torch.tensor(0.0, device=self.device), + skin_kl_loss = torch.tensor(0.0, device=self.device), + skin_feats_l2_loss_vert = torch.tensor(0.0, device=self.device), + skin_feats_l2_loss_joints = torch.tensor(0.0, device=self.device), + ) + for i, rep, rep_skl in zip(range(len(reps)), reps, reps_skl): + joints_gt, parents_gt, skin_gt, is_bad_skin = joints_list[i], parents_list[i], skin_list[i], is_bad_skin_list[i] + gt_mesh = gt_meshes[i] + + # Read predicted skeleton data + joints_pred = rep_skl.joints + parents_pred = rep_skl.parents + positions_skl = rep_skl.positions + + ########################## + # Joint and Parent Loss + ########################## + # Calculate GT joints and parents + dist_nn_12, joints_nn_idx, _ = knn_points(positions_skl[None], joints_gt[None], K=2, norm=2, return_nn=False) + joints_nn_idx = joints_nn_idx[0, :, 0] + joints_nn_gt = joints_gt[joints_nn_idx] + parents_nn_idx = parents_gt[joints_nn_idx] + parents_nn_idx[parents_nn_idx == -1] = 0 + parents_nn_gt = joints_gt[parents_nn_idx] + + # Calculate NN dist between joints to weight the parents loss + nn_dist_joints, _, _ = knn_points(joints_gt[None], joints_gt[None], K=2, norm=2, return_nn=False) + nn_dist_joints = nn_dist_joints[0, :, 1] + dist_weights = (nn_dist_joints.max().clamp(min=1e-6) / nn_dist_joints.clamp(min=1e-6)).clamp(min=1.0, max=10.0) + joints_weights = dist_weights[joints_nn_idx] + parents_weights = dist_weights[parents_nn_idx] + + # Confidence loss of joint and parent predictions + if rep_skl.conf_j is None or rep_skl.conf_p is None: + joints_loss = (joints_pred - joints_nn_gt).abs() * joints_weights[:, None] + parents_loss = (parents_pred - parents_nn_gt).abs() * parents_weights[:, None] + else: + if rep_skl.jp_hyper_continuous: + factor = (1 - (dist_nn_12[0, :, 0:1] / (dist_nn_12[0, :, 1:2] + 1e-8)).clamp(max=1.0)).clamp(min=0.1) + conf_j = conf_p = factor + joint_conf_loss = (rep_skl.conf_j - factor).abs().mean() + parent_conf_loss = (rep_skl.conf_p - factor).abs().mean() + else: + conf_j = torch.exp(rep_skl.conf_j) + 1 + conf_p = torch.exp(rep_skl.conf_p) + 1 + joint_conf_loss = - torch.maximum((2**5) * torch.ones_like(conf_j), torch.log(conf_j)) * self.alpha_conf_j + parent_conf_loss = - torch.maximum((2**5) * torch.ones_like(conf_p), torch.log(conf_p)) * self.alpha_conf_p + joint_conf_loss = joint_conf_loss - joint_conf_loss.detach() + parent_conf_loss = parent_conf_loss - parent_conf_loss.detach() + joints_loss = conf_j * (joints_pred - joints_nn_gt).abs() * joints_weights[:, None] + joint_conf_loss + parents_loss = conf_p * (parents_pred - parents_nn_gt).abs() * parents_weights[:, None] + parent_conf_loss + + terms['joints_loss'] += joints_loss.mean() + terms['parents_loss'] += parents_loss.mean() + + ########################## + # Skin Loss + ########################## + if rep.success: + # Encode skin features + joint_skin_embeds_gt, vert_skin_embeds_gt = joint_skin_embeds_gt_list[i].detach(), vert_skin_embeds_gt_list[i].detach() + # Calculate nearest vertices on GT to predicted mesh vertices + mesh_verts = rep.vertices.detach() + mesh_verts_gt = gt_mesh['vertices'] + + # Joint mapping of: joints_gt, rep_skl.joints.detach() + jmap = knn_points(rep_skl.joints_grouped.detach()[None], joints_gt[None], K=1).idx[0, :, 0] + skin_gt = skin_gt[:, jmap] + + if 'cubvh' in kwargs: + bvh = kwargs['cubvh'][i].to(mesh_verts.device) + _, face_id, uvw = bvh.unsigned_distance(mesh_verts, return_uvw=True) + uvw = uvw.clamp(min=0.0) + uvw_sum = uvw.sum(dim=-1, keepdim=True).clamp_min(1e-3) + uvw = uvw / uvw_sum + face_id = gt_mesh['faces'][face_id] + skin_nn_gt = (skin_gt[face_id] * uvw[..., None]).sum(1) + vert_skin_embeds_gt_nn = (vert_skin_embeds_gt[face_id] * uvw[..., None]).sum(1) + else: + _, vertex_nn_idx, _ = knn_points(mesh_verts[None], mesh_verts_gt[None], K=1, norm=2, return_nn=False) + vertex_nn_idx = vertex_nn_idx[0, :, 0] + # Use NN's skin as GT skin + skin_nn_gt = skin_gt[vertex_nn_idx] + vert_skin_embeds_gt_nn = vert_skin_embeds_gt[vertex_nn_idx] + + joint_skin_embeds_gt_nn = joint_skin_embeds_gt[joints_nn_idx] + # Skin feature loss + vert_skin_embeds_pred = rep.vertex_skin_feats + joint_skin_embeds_pred = rep_skl.skin_feats + skin_pred = rep_skl.skin_pred + + # Cache GT Skin Embeds + if cache_gt_skin_embeds: + rep.vertex_skin_feats_gt = vert_skin_embeds_gt_nn + rep_skl.skin_feats_gt = joint_skin_embeds_gt_nn + if cache_gt_nn_skin: + rep_skl.skin_nn_gt = skin_nn_gt + + if is_bad_skin: + # Ensure the parameters have gradients + vert_skin_term = l2_loss(vert_skin_embeds_pred, vert_skin_embeds_pred.detach()) + joint_skin_term = l2_loss(joint_skin_embeds_pred, joint_skin_embeds_pred.detach()) + terms['skin_feats_l2_loss_vert'] += vert_skin_term + terms['skin_feats_l2_loss_joints'] += joint_skin_term + else: + vert_skin_term = l2_loss(vert_skin_embeds_pred, vert_skin_embeds_gt_nn) + joint_skin_diff = (joint_skin_embeds_pred - joint_skin_embeds_gt_nn) ** 2 + if rep_skl.conf_skin is not None: + joint_skin_term = (rep_skl.conf_skin * joint_skin_diff).mean() + else: + joint_skin_term = joint_skin_diff.mean() + terms['skin_feats_l2_loss_vert'] += vert_skin_term + terms['skin_feats_l2_loss_joints'] += joint_skin_term + # KL Divergence for skin loss + skin_pred_f = skin_pred.float().clamp_min(1e-8) + skin_nn_gt_f = skin_nn_gt.float() + skin_nn_gt_f = skin_nn_gt_f / skin_nn_gt_f.sum(dim=-1, keepdim=True).clamp_min(1e-8) + skin_kl_loss = F.kl_div(skin_pred_f.log(), skin_nn_gt_f, reduction='batchmean') + terms['skin_kl_loss'] += skin_kl_loss + # Variance of joint's skin features from different vertices + terms['skin_feats_joints_var_loss'] += rep_skl.skin_feats_joints_var_loss + + for k in terms: + terms[k] = (terms[k] / max(1, len([rep for rep in reps if rep.success]))) if 'skin' in k else (terms[k] / len(reps)) + + return terms + + def training_losses( + self, + feats: SparseTensor, + feats_skl: SparseTensor, + + joints, + parents, + skin, + mesh: List[Dict], + is_bad_skin, + + image: torch.Tensor, + alpha: torch.Tensor, + extrinsics: torch.Tensor, + intrinsics: torch.Tensor, + normal_map: torch.Tensor = None, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses. + + Args: + feats: The [N x * x C] sparse tensor of features. + image: The [N x 3 x H x W] tensor of images. + alpha: The [N x H x W] tensor of alpha channels. + extrinsics: The [N x 4 x 4] tensor of extrinsics. + intrinsics: The [N x 3 x 3] tensor of intrinsics. + + Returns: + a dict with the key "loss" containing a scalar tensor. + may also contain other keys for different terms. + """ + z, mean, logvar, z_skl, mean_skl, logvar_skl, joint_skin_embeds_gt, vert_skin_embeds_gt, joints_pos_gt = self.training_models['encoder'](feats, feats_skl, sample_posterior=True, return_raw=True, gt_joints=joints, gt_parents=parents, gt_skin=skin, gt_mesh=mesh, bvh_list=kwargs.get('cubvh', None)) + + terms = edict(loss = 0.0, rec = 0.0) + if self.latent_denoising: + # Progressively increase the maximum time + latent_time_max = min(1, (self.step / self.latent_achive_max_step)) * self.latent_time_max if self.latent_achive_max_step > 0 else self.latent_time_max + encoder = getattr(self.training_models['encoder'], 'module', self.training_models['encoder']) + latent_channels = encoder.latent_channels + z_geo_feats, z_skin_feats = z.feats[:, :latent_channels], z.feats[:, latent_channels:] + noise = torch.randn_like(z_skin_feats) * self.latent_denoising_gamma + time = torch.rand([z.coords[:, 0].max() + 1]).to(z_skin_feats)[:, None] + time = (1 - (1 - time).clip(min=1e-10).sqrt()) * latent_time_max + time = time[z.coords[:, 0]] + z_skin_feats = (1 - time) * z_skin_feats + time * noise + z = z.replace(torch.cat([z_geo_feats, z_skin_feats], dim=1)) + else: + terms["kl"] = 0.5 * torch.mean(mean.pow(2) + logvar.exp() - logvar - 1) + terms["loss"] = terms["loss"] + self.lambda_kl * terms["kl"] + if self.latent_denoising_skl: + # Progressively increase the maximum time + latent_time_max_skl = min(1, (self.step / self.latent_achive_max_step_skl)) * self.latent_time_max_skl if self.latent_achive_max_step_skl > 0 else self.latent_time_max_skl + noise_skl = torch.randn_like(z_skl.feats) * self.latent_denoising_gamma_skl + time_skl = torch.rand([z_skl.coords[:, 0].max() + 1]).to(z_skl.feats)[:, None] + time_skl = (1 - (1 - time_skl).clip(min=1e-10).sqrt()) * latent_time_max_skl + time_skl = time_skl[z_skl.coords[:, 0]] + z_skl = z_skl.replace((1 - time_skl) * z_skl.feats + time_skl * noise_skl) + else: + terms["kl_skl"] = 0.5 * torch.mean(mean_skl.pow(2) + logvar_skl.exp() - logvar_skl - 1) + terms["loss"] = terms["loss"] + self.lambda_kl_skl * terms["kl_skl"] + + reps, reps_skl = self.training_models['decoder'](z, z_skl, joints, parents) + self.renderer.rendering_options.resolution = image.shape[-1] + + terms['reg_loss'] = sum([rep.reg_loss for rep in reps]) / len(reps) + terms['loss'] = terms['loss'] + terms['reg_loss'] + + geo_terms = self.geometry_losses(reps, mesh, normal_map, extrinsics, intrinsics) if len(reps) > 0 else {'geo_loss': torch.tensor(0.0, device=self.device)} + terms.update(geo_terms) + terms['loss'] = terms['loss'] + terms['geo_loss'] + + if reps_skl is not None: + terms['reg_skl_loss'] = sum([rep_skl.reg_loss for rep_skl in reps_skl]) / len(reps_skl) + terms['loss'] = terms['loss'] + terms['reg_skl_loss'] + + skl_terms = self.skeleton_losses(joints, parents, skin, is_bad_skin, reps, reps_skl, mesh, joint_skin_embeds_gt, vert_skin_embeds_gt, **kwargs) if len(reps) > 0 else {'joints_loss': torch.tensor(0.0, device=self.device), + 'parents_loss': torch.tensor(0.0, device=self.device), + 'skin_feats_joints_var_loss': torch.tensor(0.0, device=self.device), + 'skin_kl_loss': torch.tensor(0.0, device=self.device), + 'skin_feats_l2_loss_vert': torch.tensor(0.0, device=self.device), + 'skin_feats_l2_loss_joints': torch.tensor(0.0, device=self.device), + } + terms.update(skl_terms) + + terms['loss'] = terms['loss'] + terms['joints_loss'] * self.lambda_joints + terms['loss'] = terms['loss'] + terms['parents_loss'] * self.lambda_parents + terms['loss'] = terms['loss'] + terms['skin_feats_joints_var_loss'] * self.lambda_skin_var + terms['loss'] = terms['loss'] + terms['skin_kl_loss'] * self.lambda_skin_kl + terms['loss'] = terms['loss'] + terms['skin_feats_l2_loss_vert'] * self.lambda_skin_feats_l2 + terms['loss'] = terms['loss'] + terms['skin_feats_l2_loss_joints'] * self.lambda_skin_feats_l2_skl + + if self.use_color: + color_terms = self.color_losses(reps, image, alpha, extrinsics, intrinsics) if len(reps) > 0 else {'color_loss': torch.tensor(0.0, device=self.device)} + terms.update(color_terms) + terms['loss'] = terms['loss'] + terms['color_loss'] + return terms, {} + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + visualize_feats: bool = False, + disturbance: float = 0.0, + **kwargs, + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + ret_dict = {} + gt_images = [] + gt_normal_maps = [] + gt_meshes = [] + exts = [] + ints = [] + reps, reps_skl, instances = [], [], [] + joints_gt, parents_gt, skins_gt = [], [], [] + gt_skin_colors, pred_skin_colors, gt_supervised_colors = [], [], [] + error = {} + incorrect_grouping_instances = [] + + # Feature visualization for checking + if visualize_feats: + input_skin_feats_ss_imgs, input_skin_feats_ssskl_imgs = [], [] # Visualize 1 + pred_skin_feats_verts_colors, gt_skin_feats_verts_colors = [], [] # Visualize 2 + pred_skin_feats_ssskl_imgs, gt_skin_feats_ssskl_imgs = [], [] # Visualize 3 + input_joint_pose_ssskl_imgs = [] # Visualize 4 + + for i in range(0, num_samples, batch_size): + data = next(iter(dataloader)) + for key in data: + if type(data[key]) is list and hasattr(data[key][0], 'device'): + for j in range(len(data[key])): + data[key][j] = data[key][j].to(self.device) + args = recursive_to_device(data, 'cuda') + gt_images.append(args['image'] * args['alpha'][:, None]) + if self.use_color and 'normal_map' in data: + gt_normal_maps.append(args['normal_map']) + gt_meshes.extend(args['mesh']) + exts.append(args['extrinsics']) + ints.append(args['intrinsics']) + + z, z_skl, joint_skin_embeds_gt, vert_skin_embeds_gt, joints_pos_gt, x_skin, x_skl = self.models['encoder'](args['feats'], args['feats_skl'], sample_posterior=True, return_raw=False, return_skin_encoded=True, gt_joints=args['joints'], gt_parents=args['parents'], gt_skin=args['skin'], gt_mesh=args['mesh'], bvh_list=args.get('cubvh', None)) + if disturbance > 0.0: + noise = torch.randn_like(z.feats) + t = torch.rand([z.coords[:, 0].max() + 1]).to(z.feats)[:, None] * disturbance + t = t[z.coords[:, 0]] + z = z.replace((1 - t) * z.feats + t * noise) + noise_skl = torch.randn_like(z_skl.feats) + t_skl = torch.rand([z_skl.coords[:, 0].max() + 1]).to(z_skl.feats)[:, None] * disturbance + t_skl = t_skl[z_skl.coords[:, 0]] + z_skl = z_skl.replace((1 - t_skl) * z_skl.feats + t_skl * noise_skl) + rep, rep_skl = self.models['decoder'](z, z_skl) if self.step >= 10000 else self.models['decoder'](z, z_skl, gt_joints=args['joints'], gt_parents=args['parents']) + + with torch.no_grad(): + skl_loss = self.skeleton_losses(args['joints'], args['parents'], args['skin'], args['is_bad_skin'], rep, rep_skl, args['mesh'], joint_skin_embeds_gt, vert_skin_embeds_gt, cache_gt_skin_embeds=True, cache_gt_nn_skin=True, **args) + for k in skl_loss: + if k not in error: + error[k] = [] + error[k].append(skl_loss[k]) + + if visualize_feats: + # Visualize 1 & 3 + coords_list, coords_skl_list, in_vert_skin_colors, in_skl_skin_colors, pred_skl_skin_colors, gt_skl_skin_colors, in_joint_pose_colors = [], [], [], [], [], [], [] + for j in range(x_skin.data.batch_size): + # Sparse Structure Coordinates + coords_list.append(x_skin[j].coords) + coords_skl_list.append(x_skl[j].coords) + # Input Skin Features + in_vert_skin_colors.append(get_transform(x_skin[j].feats)(x_skin[j].feats)) + in_skl_skin_colors.append(get_transform(x_skl[j].feats)(x_skl[j].feats)) + # Predicted Skeleton Skin Features + out_skl_skin_color_func = get_transform(rep_skl[j].skin_feats_gt) + pred_skl_skin_colors.append(out_skl_skin_color_func(rep_skl[j].skin_feats)) + gt_skl_skin_colors.append(out_skl_skin_color_func(rep_skl[j].skin_feats_gt)) + # Input JP Pose Features + in_joint_pose_colors.append(get_transform(joints_pos_gt[j])(joints_pos_gt[j])) + input_skin_feats_ss_imgs.append(self.render_coords(coords_list, args['extrinsics'], args['intrinsics'], in_vert_skin_colors, self.models['encoder'].resolution)) + input_skin_feats_ssskl_imgs.append(self.render_coords(coords_skl_list, args['extrinsics'], args['intrinsics'], in_skl_skin_colors, self.models['encoder'].resolution)) + pred_skin_feats_ssskl_imgs.append(self.render_coords(coords_skl_list, args['extrinsics'], args['intrinsics'], pred_skl_skin_colors, self.models['encoder'].resolution)) + gt_skin_feats_ssskl_imgs.append(self.render_coords(coords_skl_list, args['extrinsics'], args['intrinsics'], gt_skl_skin_colors, self.models['encoder'].resolution)) + input_joint_pose_ssskl_imgs.append(self.render_coords(coords_skl_list, args['extrinsics'], args['intrinsics'], in_joint_pose_colors, self.models['encoder'].resolution)) + del coords_list, coords_skl_list, in_vert_skin_colors, in_skl_skin_colors, pred_skl_skin_colors, gt_skl_skin_colors, in_joint_pose_colors + + reps.extend(rep) + reps_skl.extend(rep_skl) + instances.extend(args['instance']) + joints_gt.extend(args['joints']) + parents_gt.extend(args['parents']) + skins_gt.extend(args['skin']) + + skin_color_trans_funcs = [get_transform(skin) for skin in data['skin']] + gt_skin_colors.extend([func(skin) for func, skin in zip(skin_color_trans_funcs, args['skin'])]) + joints_mapping = [knn_points(args['joints'][idx][None], rep_skl_.joints_grouped[None], K=1, norm=2, return_nn=False)[1][0, :, 0] for idx, rep_skl_ in enumerate(rep_skl)] + pred_skin_mapped = [skin_pred_[:, jmap] for jmap, skin_pred_ in zip(joints_mapping, [rs['skin_pred'] for rs in rep_skl])] + pred_skin_colors.extend([func(skin) for func, skin in zip(skin_color_trans_funcs, pred_skin_mapped)]) + + incorrect_grouping_instances.extend([ins for ins, jmap, rep_skl_ in zip(args['instance'], joints_mapping, rep_skl) if not (torch.bincount(jmap, minlength=rep_skl_.joints_grouped.shape[0]) == 1).all()]) + + if visualize_feats: + # Visualize 3 + skin_embed_color_trans_func = [get_transform(rep_.vertex_skin_feats_gt) for rep_ in rep] + gt_skin_feats_verts_colors.extend([func(skin) for func, skin in zip(skin_embed_color_trans_func, [rep_.vertex_skin_feats_gt for rep_ in rep])]) + pred_skin_feats_verts_colors.extend([func(skin) for func, skin in zip(skin_embed_color_trans_func, [rep_.vertex_skin_feats for rep_ in rep])]) + + gt_supervised_colors_list = [] + for idx, (rep_, mesh, skin_gt, func) in enumerate(zip(rep, args['mesh'], args['skin'], skin_color_trans_funcs)): + # Calculate nearest vertices on GT to predicted mesh vertices + mesh_verts = rep_.vertices + mesh_verts_gt = mesh['vertices'] + + if 'cubvh' in args: + bvh = args['cubvh'][idx].to(mesh_verts.device) + _, face_id, uvw = bvh.unsigned_distance(mesh_verts, return_uvw=True) + uvw = uvw.clamp(min=0.0) + uvw_sum = uvw.sum(dim=-1, keepdim=True).clamp_min(1e-6) + uvw = uvw / uvw_sum + face_id = mesh['faces'][face_id] + skin_nn_gt = (skin_gt[face_id] * uvw[..., None]).sum(1) + else: + _, vertex_nn_idx, _ = knn_points(mesh_verts[None], mesh_verts_gt[None], K=1, norm=2, return_nn=False) + vertex_nn_idx = vertex_nn_idx[0, :, 0] + # Use NN's skin as GT skin + skin_nn_gt = skin_gt[vertex_nn_idx] + + gt_supervised_colors_list.append(func(skin_nn_gt)) + gt_supervised_colors.extend(gt_supervised_colors_list) + + ret_dict.update({f'incorrect_grouping_instances': {'value': incorrect_grouping_instances, 'type': 'text'}}) + + gt_images = torch.cat(gt_images, dim=0) + ret_dict.update({f'gt_image': {'value': gt_images, 'type': 'image'}}) + if self.use_color and gt_normal_maps: + gt_normal_maps = torch.cat(gt_normal_maps, dim=0) + ret_dict.update({f'gt_normal_map': {'value': gt_normal_maps, 'type': 'image'}}) + + if visualize_feats: + # Visualize 1 & 3 + input_skin_feats_ss_imgs = torch.cat(input_skin_feats_ss_imgs, dim=0) + input_skin_feats_ssskl_imgs = torch.cat(input_skin_feats_ssskl_imgs, dim=0) + pred_skin_feats_ssskl_imgs = torch.cat(pred_skin_feats_ssskl_imgs, dim=0) + gt_skin_feats_ssskl_imgs = torch.cat(gt_skin_feats_ssskl_imgs, dim=0) + input_joint_pose_ssskl_imgs = torch.cat(input_joint_pose_ssskl_imgs, dim=0) + ret_dict.update({f'input_ss_skin_embed': {'value': input_skin_feats_ss_imgs, 'type': 'image'}}) + ret_dict.update({f'input_skl_skin_embed': {'value': input_skin_feats_ssskl_imgs, 'type': 'image'}}) + ret_dict.update({f'output_pred_skin_embed_skl': {'value': pred_skin_feats_ssskl_imgs, 'type': 'image'}}) + ret_dict.update({f'output_gt_skin_embed_skl': {'value': gt_skin_feats_ssskl_imgs, 'type': 'image'}}) + ret_dict.update({f'input_joint_pose_ssskl': {'value': input_joint_pose_ssskl_imgs, 'type': 'image'}}) + + ret_dict.update({'skin_error': {'value': torch.stack(error['skin_kl_loss']), 'type': 'scalar'}}) + ret_dict.update({'skin_feats_l2_error_vert': {'value': torch.stack(error['skin_feats_l2_loss_vert']), 'type': 'scalar'}}) + ret_dict.update({'skin_feats_l2_error_joints': {'value': torch.stack(error['skin_feats_l2_loss_joints']), 'type': 'scalar'}}) + ret_dict.update({'joints_error': {'value': torch.stack(error['joints_loss']), 'type': 'scalar'}}) + ret_dict.update({'parents_error': {'value': torch.stack(error['parents_loss']), 'type': 'scalar'}}) + + # render single view + # GT + exts = torch.cat(exts, dim=0) + ints = torch.cat(ints, dim=0) + self.renderer.rendering_options.bg_color = (0, 0, 0) + self.renderer.rendering_options.resolution = gt_images.shape[-1] + return_types = ['normal'] + return_types.append('specified') + gt_render_results = self._render_batch([ + MeshExtractResult(vertices=mesh['vertices'].to(self.device), faces=mesh['faces'].to(self.device)) + for mesh in gt_meshes + ], exts, ints, return_types=return_types, specified_colors=gt_skin_colors) + ret_dict.update({f'gt_normal': {'value': self._flip_normal(gt_render_results['normal'], exts, ints), 'type': 'image'}}) + if 'specified' in return_types: + ret_dict.update({f'gt_skin_map': {'value': gt_render_results['specified'], 'type': 'image'}}) + # Pred + return_types = ['normal'] + if self.use_color: + return_types.append('color') + if 'normal_map' in data: + return_types.append('normal_map') + return_types.append('specified') + render_results = self._render_batch(reps, exts, ints, return_types=return_types, specified_colors=pred_skin_colors) + gtsup_render_results = self._render_batch(reps, exts, ints, return_types=['specified'], specified_colors=gt_supervised_colors) + ret_dict.update({f'rec_normal': {'value': render_results['normal'], 'type': 'image'}}) + if 'color' in return_types: + ret_dict.update({f'rec_image': {'value': render_results['color'], 'type': 'image'}}) + if 'normal_map' in return_types: + ret_dict.update({f'rec_normal_map': {'value': render_results['normal_map'], 'type': 'image'}}) + if 'specified' in return_types: + ret_dict.update({f'rec_skin_map': {'value': render_results['specified'], 'type': 'image'}}) + ret_dict.update({f'rec_skin_gtsup_map': {'value': gtsup_render_results['specified'], 'type': 'image'}}) + + if visualize_feats: + gt_skin_feats_verts_imgs = self._render_batch(reps, exts, ints, return_types=['specified'], specified_colors=gt_skin_feats_verts_colors)['specified'] + pred_skin_feats_verts_imgs = self._render_batch(reps, exts, ints, return_types=['specified'], specified_colors=pred_skin_feats_verts_colors)['specified'] + ret_dict.update({f'output_gt_skin_embed_verts': {'value': gt_skin_feats_verts_imgs, 'type': 'image'}}) + ret_dict.update({f'output_pred_skin_embed_verts': {'value': pred_skin_feats_verts_imgs, 'type': 'image'}}) + + ############################################ + # render multiview + self.renderer.rendering_options.resolution = 512 + ## Build camera + yaws = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + yaws_offset = np.random.uniform(-np.pi / 4, np.pi / 4) + yaws = [y + yaws_offset for y in yaws] + pitch = [np.random.uniform(-np.pi / 4, np.pi / 4) for _ in range(4)] + + ## render each view + multiview_normals = [] + multiview_normal_maps = [] + multiview_skin_maps = [] + multiview_skin_gtsup_maps = [] + miltiview_images = [] + for yaw, pitch in zip(yaws, pitch): + orig = torch.tensor([ + np.sin(yaw) * np.cos(pitch), + np.cos(yaw) * np.cos(pitch), + np.sin(pitch), + ]).float().cuda() * 2 + fov = torch.deg2rad(torch.tensor(30)).cuda() + extrinsics = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intrinsics = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + extrinsics = extrinsics.unsqueeze(0).expand(len(reps), -1, -1) + intrinsics = intrinsics.unsqueeze(0).expand(len(reps), -1, -1) + render_results = self._render_batch(reps, extrinsics, intrinsics, return_types=return_types, specified_colors=pred_skin_colors) + gtsup_render_results = self._render_batch(reps, extrinsics, intrinsics, return_types=['specified'], specified_colors=gt_supervised_colors) + multiview_normals.append(render_results['normal']) + if 'color' in return_types: + miltiview_images.append(render_results['color']) + if 'normal_map' in return_types: + multiview_normal_maps.append(render_results['normal_map']) + if 'specified' in return_types: + multiview_skin_maps.append(render_results['specified']) + multiview_skin_gtsup_maps.append(gtsup_render_results['specified']) + + ## Concatenate views + multiview_normals = torch.cat([ + torch.cat(multiview_normals[:2], dim=-2), + torch.cat(multiview_normals[2:], dim=-2), + ], dim=-1) + ret_dict.update({f'multiview_normal': {'value': multiview_normals, 'type': 'image'}}) + if 'color' in return_types: + miltiview_images = torch.cat([ + torch.cat(miltiview_images[:2], dim=-2), + torch.cat(miltiview_images[2:], dim=-2), + ], dim=-1) + ret_dict.update({f'multiview_image': {'value': miltiview_images, 'type': 'image'}}) + if 'normal_map' in return_types: + multiview_normal_maps = torch.cat([ + torch.cat(multiview_normal_maps[:2], dim=-2), + torch.cat(multiview_normal_maps[2:], dim=-2), + ], dim=-1) + ret_dict.update({f'multiview_normal_map': {'value': multiview_normal_maps, 'type': 'image'}}) + if 'specified' in return_types: + # Concatenate specified colors + multiview_specified_colors = torch.cat([ + torch.cat(multiview_skin_maps[:2], dim=-2), + torch.cat(multiview_skin_maps[2:], dim=-2), + ], dim=-1) + ret_dict.update({f'multiview_skin_map': {'value': multiview_specified_colors, 'type': 'image'}}) + multiview_skin_gtsup_maps = torch.cat([ + torch.cat(multiview_skin_gtsup_maps[:2], dim=-2), + torch.cat(multiview_skin_gtsup_maps[2:], dim=-2), + ], dim=-1) + ret_dict.update({f'multiview_skin_gtsup_map': {'value': multiview_skin_gtsup_maps, 'type': 'image'}}) + + ## Skeletoned Meshes + skeletoned_meshes = [] + skeletoned_meshes_gtskin = [] + + if visualize_feats: + gt_skin_feats_verts = [rep.vertex_skin_feats_gt for rep in reps] + gt_skin_feats_skl = [rep_skl.skin_feats_gt for rep_skl in reps_skl] + + skin_preds_gt_skinfeats = self.models['decoder'].skinweight_forward(reps, reps_skl, return_skin_pred_only=True, skin_feats_verts_list=gt_skin_feats_verts, skin_feats_skl_list=gt_skin_feats_skl) + skin_preds_gt_vert_skinfeats = self.models['decoder'].skinweight_forward(reps, reps_skl, return_skin_pred_only=True, skin_feats_verts_list=gt_skin_feats_verts) + skin_preds_gt_skl_skinfeats = self.models['decoder'].skinweight_forward(reps, reps_skl, return_skin_pred_only=True, skin_feats_skl_list=gt_skin_feats_skl) + + skeletoned_meshes_gt_skinfeats = [] + skeletoned_meshes_gt_vert_skinfeats = [] + skeletoned_meshes_gt_skl_skinfeats = [] + + joints_parents = [] + for i, rep_skl in enumerate(reps_skl): + ################################## + # Predicted mesh with Pred skeleton + ################################## + skeletoned_mesh = dict() + skeletoned_mesh['instance'] = instances[i] + vertices_pred, faces_pred = reps[i].vertices, reps[i].faces + skeletoned_mesh['vertices'] = vertices_pred + skeletoned_mesh['faces'] = faces_pred + skeletoned_mesh['joints'] = rep_skl.joints_grouped + skeletoned_mesh['parents'] = rep_skl.parents_grouped + skeletoned_mesh['skin'] = rep_skl.skin_pred + skeletoned_meshes.append(skeletoned_mesh) + skeletoned_mesh_gtskin = dict(**skeletoned_mesh) + skeletoned_mesh_gtskin['skin'] = rep_skl.skin_nn_gt + skeletoned_meshes_gtskin.append(skeletoned_mesh_gtskin) + + if visualize_feats: + # Check GT Skin Embeds + skeletoned_mesh_gt_skinfeats = dict(**skeletoned_mesh) + skeletoned_mesh_gt_skinfeats['skin'] = skin_preds_gt_skinfeats[i] + skeletoned_meshes_gt_skinfeats.append(skeletoned_mesh_gt_skinfeats) + skeletoned_mesh_gt_vert_skinfeats = dict(**skeletoned_mesh) + skeletoned_mesh_gt_vert_skinfeats['skin'] = skin_preds_gt_vert_skinfeats[i] + skeletoned_meshes_gt_vert_skinfeats.append(skeletoned_mesh_gt_vert_skinfeats) + skeletoned_mesh_gt_skl_skinfeats = dict(**skeletoned_mesh) + skeletoned_mesh_gt_skl_skinfeats['skin'] = skin_preds_gt_skl_skinfeats[i] + skeletoned_meshes_gt_skl_skinfeats.append(skeletoned_mesh_gt_skl_skinfeats) + + ################################## + # Joints and Parents Visualization + ################################## + joint_parent = dict() + joint_parent['instance'] = instances[i] + # GT joints + joint_gt, parent_idx_gt = joints_gt[i], parents_gt[i] + import matplotlib.pyplot as plt + joint_colors_gt = torch.tensor(plt.cm.get_cmap('tab20')(np.arange(len(joint_gt)))[:, :3], dtype=joint_gt.dtype, device=joint_gt.device) + joint_gt_with_color = torch.cat([joint_gt, joint_colors_gt], dim=-1) + # GT parents + parent_gt = joint_gt[parent_idx_gt[1:]] + parent_colors_gt = joint_colors_gt[parent_idx_gt[1:]] + parent_gt_with_color = torch.cat([parent_gt, parent_colors_gt], dim=-1) + # Predicted joints + position_skl = rep_skl.positions + _, joint_nn_idx, _ = knn_points(position_skl[None], joint_gt[None], K=1, norm=2, return_nn=False) + joint_nn_idx = joint_nn_idx[0, :, 0] + joint_pred = rep_skl.joints + joint_colors_pred = joint_colors_gt[joint_nn_idx] + joint_pred_with_color = torch.cat([joint_pred, joint_colors_pred], dim=-1) + # Predicted parents + parent_pred = rep_skl.parents + parents_nn_idx = parent_idx_gt[joint_nn_idx] + parents_nn_idx[parents_nn_idx == -1] = 0 + parent_colors_pred = joint_colors_gt[parents_nn_idx] + parent_pred_with_color = torch.cat([parent_pred, parent_colors_pred], dim=-1) + # Combine + joint_parent['joints_gt'] = joint_gt_with_color + joint_parent['parents_gt'] = parent_gt_with_color + joint_parent['joints_pred'] = joint_pred_with_color + joint_parent['parents_pred'] = parent_pred_with_color + # Confidence + if rep_skl.conf_j is not None: + color_conf_j = rep_skl.conf_j.expand(-1, 1) + if color_conf_j.max() > 1 + 1e-3 or color_conf_j.min() < 0 - 1e-3: + color_conf_j = (color_conf_j - color_conf_j.min()) / (color_conf_j.max() - color_conf_j.min() + 1e-8) + color_conf_j = torch.cat([color_conf_j, torch.zeros_like(color_conf_j), 1-color_conf_j], dim=-1) + joint_parent['joints_conf'] = torch.cat([joint_pred, color_conf_j], dim=-1) + if rep_skl.conf_p is not None: + color_conf_p = rep_skl.conf_p.expand(-1, 1) + if color_conf_p.max() > 1 + 1e-3 or color_conf_p.min() < 0 - 1e-3: + color_conf_p = (color_conf_p - color_conf_p.min()) / (color_conf_p.max() - color_conf_p.min() + 1e-8) + color_conf_p = torch.cat([color_conf_p, torch.zeros_like(color_conf_p), 1-color_conf_p], dim=-1) + joint_parent['parents_conf'] = torch.cat([parent_pred, color_conf_p], dim=-1) + if rep_skl.joints_grouped is not None: + joint_parent['joints_grouped'] = torch.cat([rep_skl.joints_grouped, torch.ones_like(rep_skl.joints_grouped)], dim=-1) + if rep_skl.parents_grouped is not None: + parents_grouped = rep_skl.joints_grouped[rep_skl.parents_grouped] + joint_parent['parents_grouped'] = torch.cat([parents_grouped, torch.ones_like(parents_grouped)], dim=-1) + joints_parents.append(joint_parent) + + ret_dict.update({ + 'skeletoned_meshes': {'value': skeletoned_meshes, 'type': 'skeletoned_mesh_list'}, + 'skeletoned_meshes_gtskin': {'value': skeletoned_meshes_gtskin, 'type': 'skeletoned_mesh_list'}, + 'joints_parents': {'value': joints_parents, 'type': 'joints_parents'}, + }) + + if visualize_feats: + ret_dict.update({ + 'skeletoned_meshes_gt_skinfeats': {'value': skeletoned_meshes_gt_skinfeats, 'type': 'skeletoned_mesh_list'}, + 'skeletoned_meshes_gt_vert_skinfeats': {'value': skeletoned_meshes_gt_vert_skinfeats, 'type': 'skeletoned_mesh_list'}, + 'skeletoned_meshes_gt_skl_skinfeats': {'value': skeletoned_meshes_gt_skl_skinfeats, 'type': 'skeletoned_mesh_list'}, + }) + + return ret_dict diff --git a/anigen/trainers/vae/anigen_sparse_structure_vae.py b/anigen/trainers/vae/anigen_sparse_structure_vae.py new file mode 100644 index 0000000000000000000000000000000000000000..e96f0a13457c0cec7250809b6651c69750d0848e --- /dev/null +++ b/anigen/trainers/vae/anigen_sparse_structure_vae.py @@ -0,0 +1,192 @@ +from typing import * +import copy +import torch +import torch.nn.functional as F +from torch.utils.data import DataLoader +from easydict import EasyDict as edict + +from ..basic import BasicTrainer + + +class AniGenSparseStructureVaeTrainer(BasicTrainer): + """ + Trainer for Sparse Structure VAE. + + Args: + models (dict[str, nn.Module]): Models to train. + dataset (torch.utils.data.Dataset): Dataset. + output_dir (str): Output directory. + load_dir (str): Load directory. + step (int): Step to load. + batch_size (int): Batch size. + batch_size_per_gpu (int): Batch size per GPU. If specified, batch_size will be ignored. + batch_split (int): Split batch with gradient accumulation. + max_steps (int): Max steps. + optimizer (dict): Optimizer config. + lr_scheduler (dict): Learning rate scheduler config. + elastic (dict): Elastic memory management config. + grad_clip (float or dict): Gradient clip config. + ema_rate (float or list): Exponential moving average rates. + fp16_mode (str): FP16 mode. + - None: No FP16. + - 'inflat_all': Hold a inflated fp32 master param for all params. + - 'amp': Automatic mixed precision. + fp16_scale_growth (float): Scale growth for FP16 gradient backpropagation. + finetune_ckpt (dict): Finetune checkpoint. + log_param_stats (bool): Log parameter stats. + i_print (int): Print interval. + i_log (int): Log interval. + i_sample (int): Sample interval. + i_save (int): Save interval. + i_ddpcheck (int): DDP check interval. + + loss_type (str): Loss type. 'bce' for binary cross entropy, 'l1' for L1 loss, 'dice' for Dice loss. + lambda_kl (float): KL divergence loss weight. + """ + + def __init__( + self, + *args, + loss_type='bce', + lambda_kl=1e-3, + lambda_kl_skl=1e-3, + latent_denoising=False, + latent_denoising_gamma=1.0, + latent_denoising_skl=False, + latent_denoising_gamma_skl=1.0, + latent_time_max=0.5, + latent_time_max_skl=0.5, + latent_achive_max_step=0, + latent_achive_max_step_skl=0, + **kwargs + ): + super().__init__(*args, **kwargs) + self.loss_type = loss_type + self.lambda_kl = lambda_kl + self.lambda_kl_skl = lambda_kl_skl + self.latent_denoising = latent_denoising + self.latent_denoising_gamma = latent_denoising_gamma + self.latent_denoising_skl = latent_denoising_skl + self.latent_denoising_gamma_skl = latent_denoising_gamma_skl + self.latent_time_max = latent_time_max + self.latent_time_max_skl = latent_time_max_skl + self.latent_achive_max_step = latent_achive_max_step + self.latent_achive_max_step_skl = latent_achive_max_step_skl + + def training_losses( + self, + ss: torch.Tensor, + ss_skl: torch.Tensor, + **kwargs + ) -> Tuple[Dict, Dict]: + """ + Compute training losses. + + Args: + ss: The [N x 1 x H x W x D] tensor of binary sparse structure. + + Returns: + a dict with the key "loss" containing a scalar tensor. + may also contain other keys for different terms. + """ + + z, mean, logvar, z_skl, mean_skl, logvar_skl = self.training_models['encoder'](ss.float(), ss_skl.float(), sample_posterior=True, return_raw=True) + + terms = edict(loss = 0.0) + if self.latent_denoising: + # Progressively increase the maximum time + latent_time_max = min(1, (self.step / self.latent_achive_max_step)) * self.latent_time_max if self.latent_achive_max_step > 0 else self.latent_time_max + noise = torch.randn_like(z) * self.latent_denoising_gamma + time = torch.rand(z.shape[0], *[1] * (len(z.shape) -1)).to(z) + time = (1 - (1 - time).clip(min=1e-8).sqrt()) * latent_time_max + z = (1 - time) * z + time * noise + else: + terms["kl"] = 0.5 * torch.mean(mean.pow(2) + logvar.exp() - logvar - 1) + terms["loss"] = terms["loss"] + self.lambda_kl * terms["kl"] + if self.latent_denoising_skl: + # Progressively increase the maximum time + latent_time_max_skl = min(1, (self.step / self.latent_achive_max_step_skl)) * self.latent_time_max_skl if self.latent_achive_max_step_skl > 0 else self.latent_time_max_skl + noise_skl = torch.randn_like(z_skl) * self.latent_denoising_gamma_skl + time_skl = torch.rand(z_skl.shape[0], *[1] * (len(z_skl.shape) -1)).to(z_skl) + time_skl = (1 - (1 - time_skl).clip(min=1e-8).sqrt()) * latent_time_max_skl + z_skl = (1 - time_skl) * z_skl + time_skl * noise_skl + else: + if mean_skl is not None and logvar_skl is not None: + terms["kl_skl"] = 0.5 * torch.mean(mean_skl.pow(2) + logvar_skl.exp() - logvar_skl - 1) + terms["loss"] = terms["loss"] + self.lambda_kl_skl * terms["kl_skl"] + + logits, logits_skl = self.training_models['decoder'](z, z_skl) + + if self.loss_type == 'bce': + terms["bce"] = F.binary_cross_entropy_with_logits(logits, ss.float(), reduction='mean') + terms["bce_skl"] = F.binary_cross_entropy_with_logits(logits_skl, ss_skl.float(), reduction='mean') + terms["loss"] = terms["loss"] + terms["bce"] + terms["bce_skl"] + elif self.loss_type == 'l1': + terms["l1"] = F.l1_loss(F.sigmoid(logits), ss.float(), reduction='mean') + terms["l1_skl"] = F.l1_loss(F.sigmoid(logits_skl), ss_skl.float(), reduction='mean') + terms["loss"] = terms["loss"] + terms["l1"] + terms["l1_skl"] + elif self.loss_type == 'dice': + logits = F.sigmoid(logits) + terms["dice"] = 1 - (2 * (logits * ss.float()).sum() + 1) / (logits.sum() + ss.float().sum() + 1) + logits_skl = F.sigmoid(logits_skl) + terms["dice_skl"] = 1 - (2 * (logits_skl * ss_skl.float()).sum() + 1) / (logits_skl.sum() + ss_skl.float().sum() + 1) + terms["loss"] = terms["loss"] + terms["dice"] + terms["dice_skl"] + else: + raise ValueError(f'Invalid loss type {self.loss_type}') + + return terms, {} + + @torch.no_grad() + def snapshot(self, *args, **kwargs): + return super().snapshot(*args, **kwargs) + + @torch.no_grad() + def run_snapshot( + self, + num_samples: int, + batch_size: int, + disturbance: float = 0.0, + **kwargs + ) -> Dict: + dataloader = DataLoader( + copy.deepcopy(self.dataset), + batch_size=batch_size, + shuffle=True, + num_workers=0, + collate_fn=self.dataset.collate_fn if hasattr(self.dataset, 'collate_fn') else None, + ) + + # inference + gts = [] + recons = [] + gts_skl = [] + recons_skl = [] + for i in range(0, num_samples, batch_size): + batch = min(batch_size, num_samples - i) + data = next(iter(dataloader)) + args = {k: v[:batch].cuda() if isinstance(v, torch.Tensor) else v[:batch] for k, v in data.items()} + z, z_skl = self.models['encoder'](args['ss'].float(), args['ss_skl'].float(), sample_posterior=False) + if disturbance > 0.0: + noise = torch.randn_like(z) + t = torch.rand([z.shape[0], *[1] * (len(z.shape) -1)]).to(z) * disturbance + z = (1 - t) * z + t * noise + noise_skl = torch.randn_like(z_skl) + t_skl = torch.rand([z_skl.shape[0], *[1] * (len(z_skl.shape) -1)]).to(z_skl) * disturbance + z_skl = (1 - t_skl) * z_skl + t_skl * noise_skl + logits, logits_skl = self.models['decoder'](z, z_skl) + + recon = (logits > 0).long() + gts.append(args['ss']) + recons.append(recon) + + recon_skl = (logits_skl > 0).long() + gts_skl.append(args['ss_skl']) + recons_skl.append(recon_skl) + + sample_dict = { + 'gt': {'value': torch.cat(gts, dim=0), 'type': 'sample'}, + 'recon': {'value': torch.cat(recons, dim=0), 'type': 'sample'}, + 'gt_skl': {'value': torch.cat(gts_skl, dim=0), 'type': 'sample'}, + 'recon_skl': {'value': torch.cat(recons_skl, dim=0), 'type': 'sample'}, + } + return sample_dict diff --git a/anigen/utils/__init__.py b/anigen/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/anigen/utils/ckpt_utils.py b/anigen/utils/ckpt_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..4cb0c2af381738de806197c82a3c502dc81753e0 --- /dev/null +++ b/anigen/utils/ckpt_utils.py @@ -0,0 +1,35 @@ +import os + + +HF_REPO_ID = "VAST-AI/AniGen" +CKPTS_DIR = "ckpts" + + +REQUIRED_FILES = [ + "ckpts/dinov2/hubconf.py", + "ckpts/dinov2/dinov2/__init__.py", + "ckpts/dsine/dsine.pt", + "ckpts/vgg/vgg16-397923af.pth", +] + + +def ensure_ckpts(local_dir: str = ".") -> None: + missing = [ + path for path in REQUIRED_FILES + if not os.path.exists(os.path.join(local_dir, path)) + ] + if not missing: + return + + print(f"Missing checkpoint files: {missing}") + print(f"Downloading checkpoints from Hugging Face ({HF_REPO_ID}) ...") + + from huggingface_hub import snapshot_download + + snapshot_download( + repo_id=HF_REPO_ID, + allow_patterns=[f"{CKPTS_DIR}/**"], + local_dir=local_dir, + ) + + print("Checkpoint download complete.") \ No newline at end of file diff --git a/anigen/utils/data_utils.py b/anigen/utils/data_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..805b6cc118106857e7ef767ab4bfd133dbd78e6f --- /dev/null +++ b/anigen/utils/data_utils.py @@ -0,0 +1,226 @@ +from typing import * +import math +import torch +import numpy as np +from torch.utils.data import Sampler, Dataset, DataLoader, DistributedSampler +import torch.distributed as dist + + +def recursive_to_device( + data: Any, + device: torch.device, + non_blocking: bool = False, +) -> Any: + """ + Recursively move all tensors in a data structure to a device. + """ + if hasattr(data, "to"): + return data.to(device, non_blocking=non_blocking) + elif isinstance(data, (list, tuple)): + return type(data)(recursive_to_device(d, device, non_blocking) for d in data) + elif isinstance(data, dict): + return {k: recursive_to_device(v, device, non_blocking) for k, v in data.items()} + else: + return data + + +def load_balanced_group_indices( + load: List[int], + num_groups: int, + equal_size: bool = False, +) -> List[List[int]]: + """ + Split indices into groups with balanced load. + """ + if equal_size: + group_size = len(load) // num_groups + indices = np.argsort(load)[::-1] + groups = [[] for _ in range(num_groups)] + group_load = np.zeros(num_groups) + for idx in indices: + min_group_idx = np.argmin(group_load) + groups[min_group_idx].append(idx) + if equal_size and len(groups[min_group_idx]) == group_size: + group_load[min_group_idx] = float('inf') + else: + group_load[min_group_idx] += load[idx] + return groups + + +def cycle(data_loader: DataLoader) -> Iterator: + while True: + for data in data_loader: + if isinstance(data_loader.sampler, ResumableSampler): + data_loader.sampler.idx += data_loader.batch_size # type: ignore[attr-defined] + yield data + if isinstance(data_loader.sampler, DistributedSampler): + data_loader.sampler.epoch += 1 + if isinstance(data_loader.sampler, ResumableSampler): + data_loader.sampler.epoch += 1 + data_loader.sampler.idx = 0 + + +class ResumableSampler(Sampler): + """ + Distributed sampler that is resumable. + + Args: + dataset: Dataset used for sampling. + rank (int, optional): Rank of the current process within :attr:`num_replicas`. + By default, :attr:`rank` is retrieved from the current distributed + group. + shuffle (bool, optional): If ``True`` (default), sampler will shuffle the + indices. + seed (int, optional): random seed used to shuffle the sampler if + :attr:`shuffle=True`. This number should be identical across all + processes in the distributed group. Default: ``0``. + drop_last (bool, optional): if ``True``, then the sampler will drop the + tail of the data to make it evenly divisible across the number of + replicas. If ``False``, the sampler will add extra indices to make + the data evenly divisible across the replicas. Default: ``False``. + """ + + def __init__( + self, + dataset: Dataset, + shuffle: bool = True, + seed: int = 0, + drop_last: bool = False, + ) -> None: + self.dataset = dataset + self.epoch = 0 + self.idx = 0 + self.drop_last = drop_last + self.world_size = dist.get_world_size() if dist.is_initialized() else 1 + self.rank = dist.get_rank() if dist.is_initialized() else 0 + # If the dataset length is evenly divisible by # of replicas, then there + # is no need to drop any data, since the dataset will be split equally. + if self.drop_last and len(self.dataset) % self.world_size != 0: # type: ignore[arg-type] + # Split to nearest available length that is evenly divisible. + # This is to ensure each rank receives the same amount of data when + # using this Sampler. + self.num_samples = math.ceil( + (len(self.dataset) - self.world_size) / self.world_size # type: ignore[arg-type] + ) + else: + self.num_samples = math.ceil(len(self.dataset) / self.world_size) # type: ignore[arg-type] + self.total_size = self.num_samples * self.world_size + self.shuffle = shuffle + self.seed = seed + + def __iter__(self) -> Iterator: + if self.shuffle: + # deterministically shuffle based on epoch and seed + g = torch.Generator() + g.manual_seed(self.seed + self.epoch) + indices = torch.randperm(len(self.dataset), generator=g).tolist() # type: ignore[arg-type] + else: + indices = list(range(len(self.dataset))) # type: ignore[arg-type] + + if not self.drop_last: + # add extra samples to make it evenly divisible + padding_size = self.total_size - len(indices) + if padding_size <= len(indices): + indices += indices[:padding_size] + else: + indices += (indices * math.ceil(padding_size / len(indices)))[ + :padding_size + ] + else: + # remove tail of data to make it evenly divisible. + indices = indices[: self.total_size] + assert len(indices) == self.total_size + + # subsample + indices = indices[self.rank : self.total_size : self.world_size] + + # resume from previous state + indices = indices[self.idx:] + + return iter(indices) + + def __len__(self) -> int: + return self.num_samples + + def state_dict(self) -> dict[str, int]: + return { + 'epoch': self.epoch, + 'idx': self.idx, + } + + def load_state_dict(self, state_dict): + self.epoch = state_dict['epoch'] + self.idx = state_dict['idx'] + + +class BalancedResumableSampler(ResumableSampler): + """ + Distributed sampler that is resumable and balances the load among the processes. + + Args: + dataset: Dataset used for sampling. + rank (int, optional): Rank of the current process within :attr:`num_replicas`. + By default, :attr:`rank` is retrieved from the current distributed + group. + shuffle (bool, optional): If ``True`` (default), sampler will shuffle the + indices. + seed (int, optional): random seed used to shuffle the sampler if + :attr:`shuffle=True`. This number should be identical across all + processes in the distributed group. Default: ``0``. + drop_last (bool, optional): if ``True``, then the sampler will drop the + tail of the data to make it evenly divisible across the number of + replicas. If ``False``, the sampler will add extra indices to make + the data evenly divisible across the replicas. Default: ``False``. + """ + + def __init__( + self, + dataset: Dataset, + shuffle: bool = True, + seed: int = 0, + drop_last: bool = False, + batch_size: int = 1, + ) -> None: + assert hasattr(dataset, 'loads'), 'Dataset must have "loads" attribute to use BalancedResumableSampler' + super().__init__(dataset, shuffle, seed, drop_last) + self.batch_size = batch_size + self.loads = dataset.loads + + def __iter__(self) -> Iterator: + if self.shuffle: + # deterministically shuffle based on epoch and seed + g = torch.Generator() + g.manual_seed(self.seed + self.epoch) + indices = torch.randperm(len(self.dataset), generator=g).tolist() # type: ignore[arg-type] + else: + indices = list(range(len(self.dataset))) # type: ignore[arg-type] + + if not self.drop_last: + # add extra samples to make it evenly divisible + padding_size = self.total_size - len(indices) + if padding_size <= len(indices): + indices += indices[:padding_size] + else: + indices += (indices * math.ceil(padding_size / len(indices)))[ + :padding_size + ] + else: + # remove tail of data to make it evenly divisible. + indices = indices[: self.total_size] + assert len(indices) == self.total_size + + # balance load among processes + num_batches = len(indices) // (self.batch_size * self.world_size) + balanced_indices = [] + for i in range(num_batches): + start_idx = i * self.batch_size * self.world_size + end_idx = (i + 1) * self.batch_size * self.world_size + batch_indices = indices[start_idx:end_idx] + batch_loads = [self.loads[idx] for idx in batch_indices] + groups = load_balanced_group_indices(batch_loads, self.world_size, equal_size=True) + balanced_indices.extend([batch_indices[j] for j in groups[self.rank]]) + + # resume from previous state + indices = balanced_indices[self.idx:] + + return iter(indices) diff --git a/anigen/utils/dist_utils.py b/anigen/utils/dist_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..5cdbdabefcc59337fa76a344075b8e2a06d0afbf --- /dev/null +++ b/anigen/utils/dist_utils.py @@ -0,0 +1,93 @@ +import os +import io +from contextlib import contextmanager +import torch +import torch.distributed as dist +from torch.nn.parallel import DistributedDataParallel as DDP + + +def setup_dist(rank, local_rank, world_size, master_addr, master_port): + os.environ['MASTER_ADDR'] = master_addr + os.environ['MASTER_PORT'] = master_port + os.environ['WORLD_SIZE'] = str(world_size) + os.environ['RANK'] = str(rank) + os.environ['LOCAL_RANK'] = str(local_rank) + torch.cuda.set_device(local_rank) + dist.init_process_group('nccl', rank=rank, world_size=world_size) + + +def read_file_dist(path): + """ + Read the binary file distributedly. + File is only read once by the rank 0 process and broadcasted to other processes. + + Returns: + data (io.BytesIO): The binary data read from the file. + """ + if dist.is_initialized() and dist.get_world_size() > 1: + # read file + size = torch.LongTensor(1).cuda() + if dist.get_rank() == 0: + with open(path, 'rb') as f: + data = f.read() + data = torch.ByteTensor( + torch.UntypedStorage.from_buffer(data, dtype=torch.uint8) + ).cuda() + size[0] = data.shape[0] + # broadcast size + dist.broadcast(size, src=0) + if dist.get_rank() != 0: + data = torch.ByteTensor(size[0].item()).cuda() + # broadcast data + dist.broadcast(data, src=0) + # convert to io.BytesIO + data = data.cpu().numpy().tobytes() + data = io.BytesIO(data) + return data + else: + with open(path, 'rb') as f: + data = f.read() + data = io.BytesIO(data) + return data + + +def unwrap_dist(model): + """ + Unwrap the model from distributed training. + """ + if isinstance(model, DDP): + return model.module + return model + + +@contextmanager +def master_first(): + """ + A context manager that ensures master process executes first. + """ + if not dist.is_initialized(): + yield + else: + if dist.get_rank() == 0: + yield + dist.barrier() + else: + dist.barrier() + yield + + +@contextmanager +def local_master_first(): + """ + A context manager that ensures local master process executes first. + """ + if not dist.is_initialized(): + yield + else: + if dist.get_rank() % torch.cuda.device_count() == 0: + yield + dist.barrier() + else: + dist.barrier() + yield + \ No newline at end of file diff --git a/anigen/utils/elastic_utils.py b/anigen/utils/elastic_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..cba3cf83836e5b58f5bc3333e809ffc932375a04 --- /dev/null +++ b/anigen/utils/elastic_utils.py @@ -0,0 +1,228 @@ +from abc import abstractmethod +from contextlib import contextmanager +from typing import Tuple +import torch +import torch.nn as nn +import numpy as np + + +class MemoryController: + """ + Base class for memory management during training. + """ + + _last_input_size = None + _last_mem_ratio = [] + + @contextmanager + def record(self): + pass + + def update_run_states(self, input_size=None, mem_ratio=None): + if self._last_input_size is None: + self._last_input_size = input_size + elif self._last_input_size!= input_size: + raise ValueError(f'Input size should not change for different ElasticModules.') + self._last_mem_ratio.append(mem_ratio) + + @abstractmethod + def get_mem_ratio(self, input_size): + pass + + @abstractmethod + def state_dict(self): + pass + + @abstractmethod + def log(self): + pass + + +class LinearMemoryController(MemoryController): + """ + A simple controller for memory management during training. + The memory usage is modeled as a linear function of: + - the number of input parameters + - the ratio of memory the model use compared to the maximum usage (with no checkpointing) + memory_usage = k * input_size * mem_ratio + b + The controller keeps track of the memory usage and gives the + expected memory ratio to keep the memory usage under a target + """ + def __init__( + self, + buffer_size=1000, + update_every=500, + target_ratio=0.8, + available_memory=None, + max_mem_ratio_start=0.1, + params=None, + device=None + ): + self.buffer_size = buffer_size + self.update_every = update_every + self.target_ratio = target_ratio + self.device = device or torch.cuda.current_device() + self.available_memory = available_memory or torch.cuda.get_device_properties(self.device).total_memory / 1024**3 + + self._memory = np.zeros(buffer_size, dtype=np.float32) + self._input_size = np.zeros(buffer_size, dtype=np.float32) + self._mem_ratio = np.zeros(buffer_size, dtype=np.float32) + self._buffer_ptr = 0 + self._buffer_length = 0 + self._params = tuple(params) if params is not None else (0.0, 0.0) + self._max_mem_ratio = max_mem_ratio_start + self.step = 0 + + def __repr__(self): + return f'LinearMemoryController(target_ratio={self.target_ratio}, available_memory={self.available_memory})' + + def _add_sample(self, memory, input_size, mem_ratio): + self._memory[self._buffer_ptr] = memory + self._input_size[self._buffer_ptr] = input_size + self._mem_ratio[self._buffer_ptr] = mem_ratio + self._buffer_ptr = (self._buffer_ptr + 1) % self.buffer_size + self._buffer_length = min(self._buffer_length + 1, self.buffer_size) + + @contextmanager + def record(self): + torch.cuda.reset_peak_memory_stats(self.device) + self._last_input_size = None + self._last_mem_ratio = [] + yield + self._last_memory = torch.cuda.max_memory_allocated(self.device) / 1024**3 + self._last_mem_ratio = sum(self._last_mem_ratio) / len(self._last_mem_ratio) + self._add_sample(self._last_memory, self._last_input_size, self._last_mem_ratio) + self.step += 1 + if self.step % self.update_every == 0: + self._max_mem_ratio = min(1.0, self._max_mem_ratio + 0.1) + self._fit_params() + + def _fit_params(self): + memory_usage = self._memory[:self._buffer_length] + input_size = self._input_size[:self._buffer_length] + mem_ratio = self._mem_ratio[:self._buffer_length] + + x = input_size * mem_ratio + y = memory_usage + k, b = np.polyfit(x, y, 1) + self._params = (k, b) + # self._visualize() + + def _visualize(self): + import matplotlib.pyplot as plt + memory_usage = self._memory[:self._buffer_length] + input_size = self._input_size[:self._buffer_length] + mem_ratio = self._mem_ratio[:self._buffer_length] + k, b = self._params + + plt.scatter(input_size * mem_ratio, memory_usage, c=mem_ratio, cmap='viridis') + x = np.array([0.0, 20000.0]) + plt.plot(x, k * x + b, c='r') + plt.savefig(f'linear_memory_controller_{self.step}.png') + plt.cla() + + def get_mem_ratio(self, input_size): + k, b = self._params + if k == 0: return np.random.rand() * self._max_mem_ratio + pred = (self.available_memory * self.target_ratio - b) / (k * input_size) + return min(self._max_mem_ratio, max(0.0, pred)) + + def state_dict(self): + return { + 'params': self._params, + } + + def load_state_dict(self, state_dict): + self._params = tuple(state_dict['params']) + + def log(self): + return { + 'params/k': self._params[0], + 'params/b': self._params[1], + 'memory': self._last_memory, + 'input_size': self._last_input_size, + 'mem_ratio': self._last_mem_ratio, + } + + +class ElasticModule(nn.Module): + """ + Module for training with elastic memory management. + """ + def __init__(self): + super().__init__() + self._memory_controller: MemoryController = None + + @abstractmethod + def _get_input_size(self, *args, **kwargs) -> int: + """ + Get the size of the input data. + + Returns: + int: The size of the input data. + """ + pass + + @abstractmethod + def _forward_with_mem_ratio(self, *args, mem_ratio=0.0, **kwargs) -> Tuple[float, Tuple]: + """ + Forward with a given memory ratio. + """ + pass + + def register_memory_controller(self, memory_controller: MemoryController): + self._memory_controller = memory_controller + + def forward(self, *args, **kwargs): + if self._memory_controller is None or not torch.is_grad_enabled() or not self.training: + _, ret = self._forward_with_mem_ratio(*args, **kwargs) + else: + input_size = self._get_input_size(*args, **kwargs) + mem_ratio = self._memory_controller.get_mem_ratio(input_size) + mem_ratio, ret = self._forward_with_mem_ratio(*args, mem_ratio=mem_ratio, **kwargs) + self._memory_controller.update_run_states(input_size, mem_ratio) + return ret + + +class ElasticModuleMixin: + """ + Mixin for training with elastic memory management. + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._memory_controller: MemoryController = None + + @abstractmethod + def _get_input_size(self, *args, **kwargs) -> int: + """ + Get the size of the input data. + + Returns: + int: The size of the input data. + """ + pass + + @abstractmethod + @contextmanager + def with_mem_ratio(self, mem_ratio=1.0) -> float: + """ + Context manager for training with a reduced memory ratio compared to the full memory usage. + + Returns: + float: The exact memory ratio used during the forward pass. + """ + pass + + def register_memory_controller(self, memory_controller: MemoryController): + self._memory_controller = memory_controller + + def forward(self, *args, **kwargs): + if self._memory_controller is None or not torch.is_grad_enabled() or not self.training: + ret = super().forward(*args, **kwargs) + else: + input_size = self._get_input_size(*args, **kwargs) + mem_ratio = self._memory_controller.get_mem_ratio(input_size) + with self.with_mem_ratio(mem_ratio) as exact_mem_ratio: + ret = super().forward(*args, **kwargs) + self._memory_controller.update_run_states(input_size, exact_mem_ratio) + return ret diff --git a/anigen/utils/export_utils.py b/anigen/utils/export_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..8041854d2d873b5a68a18863e0a706b3913dc95c --- /dev/null +++ b/anigen/utils/export_utils.py @@ -0,0 +1,487 @@ +import io +import numpy as np +import torch +import trimesh +from PIL import Image as PILImage +from pygltflib import ( + GLTF2, Scene, Node, Mesh, Primitive, Attributes, Buffer, BufferView, Accessor, Asset, Skin, + Material, PbrMetallicRoughness, TextureInfo, + Image as GltfImage, Texture as GltfTexture, Sampler as GltfSampler, + FLOAT, UNSIGNED_SHORT, UNSIGNED_INT, VEC3, VEC2, VEC4, SCALAR, MAT4, ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER +) +from anigen.utils.skin_utils import repair_skeleton_parents + +_ROT_Z_UP_TO_Y_UP = np.array([[-1, 0, 0], [0, 0, 1], [0, 1, 0]], dtype=np.float32) + +def visualize_skeleton_as_mesh(joints, parents, joint_radius_ratio=0.02, bone_radius_ratio=0.01): + """ + Convert a skeleton into a trimesh object with spheres for joints and cones for bones. + The sizes are adaptive to the skeleton's bounding box. + """ + if len(joints) == 0: + return trimesh.Trimesh() + + joints = np.asarray(joints, dtype=np.float32) @ _ROT_Z_UP_TO_Y_UP + + # Calculate adaptive scale + min_bound = np.min(joints, axis=0) + max_bound = np.max(joints, axis=0) + scale = np.linalg.norm(max_bound - min_bound) + if scale < 1e-5: + scale = 1.0 + + joint_radius = scale * joint_radius_ratio + bone_radius = scale * bone_radius_ratio + + meshes = [] + + # Create joints + for i, joint in enumerate(joints): + sphere = trimesh.creation.icosphere(radius=joint_radius, subdivisions=2) + sphere.apply_translation(joint) + # Optional: add vertex colors for joints + sphere.visual.vertex_colors = [230, 180, 80, 255] + meshes.append(sphere) + + # Create bones + for i, parent_idx in enumerate(parents): + if parent_idx < 0 or parent_idx == i: + continue + + child = joints[i] + parent = joints[parent_idx] + + vec = child - parent + length = np.linalg.norm(vec) + if length < 1e-5: + continue + + # Create a cone pointing along Z axis by default + cone = trimesh.creation.cone(radius=bone_radius, height=length) + + # Align the cone's Z axis to the vector + z_axis = np.array([0, 0, 1]) + direction = vec / length + + # Calculate rotation matrix from Z axis to direction + rot_mat = trimesh.geometry.align_vectors(z_axis, direction) + + # Apply rotation + cone.apply_transform(rot_mat) + + # Translate to parent + cone.apply_translation(parent) + + # Optional: add vertex colors for bones + cone.visual.vertex_colors = [160, 180, 200, 255] + meshes.append(cone) + + if not meshes: + return trimesh.Trimesh() + + # Combine all meshes + skeleton_mesh = trimesh.util.concatenate(meshes) + return skeleton_mesh + +def convert_to_glb_from_data(mesh, joints, parents, skin_weights, output_path, vertex_colors=None, texture_image=None): + joints = np.asarray(joints, dtype=np.float32) @ _ROT_Z_UP_TO_Y_UP + num_joints = joints.shape[0] + num_verts = mesh.vertices.shape[0] + + # Basic sanity checks to avoid writing malformed GLB that can hang Blender. + if hasattr(mesh, 'faces'): + faces = np.asarray(mesh.faces) + if faces.size > 0: + if faces.min() < 0 or faces.max() >= num_verts: + raise ValueError(f"Mesh faces contain out-of-range indices (min={faces.min()}, max={faces.max()}, num_verts={num_verts}).") + + for name, arr in ( + ("mesh.vertices", getattr(mesh, 'vertices', None)), + ("joints", joints), + ("skin_weights", skin_weights), + ): + if arr is None: + continue + arr_np = np.asarray(arr) + if arr_np.size and not np.isfinite(arr_np).all(): + raise ValueError(f"Non-finite values detected in {name}; refusing to write GLB.") + + parents = np.asarray(parents).astype(np.int64, copy=False) + if parents.shape != (num_joints,): + parents = parents.reshape(-1) + if parents.shape[0] != num_joints: + raise ValueError(f"parents has wrong shape: expected ({num_joints},) got {parents.shape}") + + # Repair invalid/cyclic skeletons instead of exporting a GLB that hangs viewers. + parents = repair_skeleton_parents(joints=joints, parents=parents, verbose=True) + + if skin_weights.shape[0] != num_verts: + print(f"Warning: Mismatch in vertex count. Mesh: {num_verts}, Skin: {skin_weights.shape[0]}") + return + + # Prepare Binary Data + binary_data = bytearray() + + def align_to_4bytes(): + padding = len(binary_data) % 4 + if padding > 0: + binary_data.extend(b'\x00' * (4 - padding)) + + accessors = [] + buffer_views = [] + + def add_buffer_view(data_bytes, target=None): + align_to_4bytes() + byte_offset = len(binary_data) + binary_data.extend(data_bytes) + byte_length = len(data_bytes) + bv = BufferView(buffer=0, byteOffset=byte_offset, byteLength=byte_length, target=target) + buffer_views.append(bv) + return len(buffer_views) - 1 + + def add_accessor(buffer_view_idx, component_type, count, type_str, min_val=None, max_val=None): + acc = Accessor( + bufferView=buffer_view_idx, + componentType=component_type, + count=count, + type=type_str, + min=min_val, + max=max_val + ) + accessors.append(acc) + return len(accessors) - 1 + + # 1. Indices + if hasattr(mesh, 'faces'): + indices = mesh.faces.flatten().astype(np.uint32) + if indices.max() <= 65535: + indices = indices.astype(np.uint16) + component_type = UNSIGNED_SHORT + else: + component_type = UNSIGNED_INT + + indices_bytes = indices.tobytes() + bv_idx = add_buffer_view(indices_bytes, target=ELEMENT_ARRAY_BUFFER) + indices_acc_idx = add_accessor(bv_idx, component_type, len(indices), SCALAR, min_val=[int(indices.min())], max_val=[int(indices.max())]) + + # 2. Positions + positions = mesh.vertices.astype(np.float32) @ _ROT_Z_UP_TO_Y_UP + # GLTF requires min/max for POSITION + min_pos = positions.min(axis=0).tolist() + max_pos = positions.max(axis=0).tolist() + + pos_bytes = positions.tobytes() + bv_idx = add_buffer_view(pos_bytes, target=ARRAY_BUFFER) + pos_acc_idx = add_accessor(bv_idx, FLOAT, len(positions), VEC3, min_val=min_pos, max_val=max_pos) + + # 3. Normals + norm_acc_idx = None + if hasattr(mesh, 'vertex_normals'): + normals = mesh.vertex_normals.astype(np.float32) @ _ROT_Z_UP_TO_Y_UP + norm_bytes = normals.tobytes() + bv_idx = add_buffer_view(norm_bytes, target=ARRAY_BUFFER) + norm_acc_idx = add_accessor(bv_idx, FLOAT, len(normals), VEC3) + + # 4. UVs + tex_acc_idx = None + if hasattr(mesh.visual, 'uv') and mesh.visual.uv is not None: + uvs = mesh.visual.uv.astype(np.float32) + uvs[:, 1] = 1.0 - uvs[:, 1] # OpenGL -> glTF: flip V + uv_bytes = uvs.tobytes() + bv_idx = add_buffer_view(uv_bytes, target=ARRAY_BUFFER) + tex_acc_idx = add_accessor(bv_idx, FLOAT, len(uvs), VEC2) + + # 4.5 Vertex Colors (skipped when a texture image is provided, since glTF + # multiplies vertex colors with the texture which is not desired here) + color_acc_idx = None + if vertex_colors is not None and texture_image is None: + colors = np.asarray(vertex_colors) + if colors.shape[0] != num_verts: + print(f"Warning: Mismatch in vertex color count. Mesh: {num_verts}, Colors: {colors.shape[0]}") + else: + if colors.ndim != 2 or colors.shape[1] not in (3, 4): + print(f"Warning: Unexpected vertex_colors shape: {colors.shape}. Expected (N,3) or (N,4).") + else: + colors = colors.astype(np.float32, copy=False) + # Expect colors in [0,1]; clamp to be safe. + np.clip(colors, 0.0, 1.0, out=colors) + color_bytes = colors.tobytes() + bv_idx = add_buffer_view(color_bytes, target=ARRAY_BUFFER) + color_acc_idx = add_accessor(bv_idx, FLOAT, len(colors), VEC4 if colors.shape[1] == 4 else VEC3) + + # 4.6 Texture Image (embedded as PNG in the binary blob) + gltf_images = [] + gltf_textures = [] + gltf_samplers = [] + if texture_image is not None: + tex_arr = np.asarray(texture_image) + img_pil = PILImage.fromarray(tex_arr) + buf = io.BytesIO() + img_pil.save(buf, format='PNG') + png_bytes = buf.getvalue() + + align_to_4bytes() + img_bv_offset = len(binary_data) + binary_data.extend(png_bytes) + img_bv_len = len(png_bytes) + img_bv = BufferView(buffer=0, byteOffset=img_bv_offset, byteLength=img_bv_len) + buffer_views.append(img_bv) + img_bv_idx = len(buffer_views) - 1 + + gltf_images.append(GltfImage(bufferView=img_bv_idx, mimeType='image/png')) + gltf_samplers.append(GltfSampler(magFilter=9729, minFilter=9987, wrapS=10497, wrapT=10497)) + gltf_textures.append(GltfTexture(source=0, sampler=0)) + + # 5. Joints & Weights + if num_joints >= 4: + top_indices = np.argsort(skin_weights, axis=1)[:, -4:] + top_indices = np.flip(top_indices, axis=1) + top_weights = np.take_along_axis(skin_weights, top_indices, axis=1) + else: + top_indices = np.argsort(skin_weights, axis=1) + top_indices = np.flip(top_indices, axis=1) + top_weights = np.take_along_axis(skin_weights, top_indices, axis=1) + + pad_width = 4 - num_joints + top_indices = np.pad(top_indices, ((0,0), (0, pad_width)), mode='constant', constant_values=0) + top_weights = np.pad(top_weights, ((0,0), (0, pad_width)), mode='constant', constant_values=0.0) + + weight_sums = np.sum(top_weights, axis=1, keepdims=True) + weight_sums[weight_sums == 0] = 1.0 + top_weights = top_weights / weight_sums + + joints_0 = top_indices.astype(np.uint16) + weights_0 = top_weights.astype(np.float32) + + joints_bytes = joints_0.tobytes() + bv_idx = add_buffer_view(joints_bytes, target=ARRAY_BUFFER) + joints_acc_idx = add_accessor(bv_idx, UNSIGNED_SHORT, len(joints_0), VEC4) + + weights_bytes = weights_0.tobytes() + bv_idx = add_buffer_view(weights_bytes, target=ARRAY_BUFFER) + weights_acc_idx = add_accessor(bv_idx, FLOAT, len(weights_0), VEC4) + + # 6. Inverse Bind Matrices + ibms_list = [] + for i in range(num_joints): + mat = np.eye(4, dtype=np.float32) + mat[:3, 3] = joints[i] + inv_mat = np.linalg.inv(mat) + ibms_list.append(inv_mat.flatten('F')) + + ibms_data = np.concatenate(ibms_list) + ibms_bytes = ibms_data.tobytes() + bv_idx = add_buffer_view(ibms_bytes) + ibms_acc_idx = add_accessor(bv_idx, FLOAT, num_joints, MAT4) + + # Nodes + nodes = [] + + # Mesh Node (Node 0) + mesh_node = Node(name="Mesh", mesh=0, skin=0) + nodes.append(mesh_node) + + # Skeleton Nodes (Node 1 to M) + joint_nodes = [] + for i in range(num_joints): + parent_idx = parents[i] + pos = joints[i] + + if parent_idx == -1 or parent_idx == i: + local_pos = pos + else: + parent_pos = joints[parent_idx] + local_pos = pos - parent_pos + + node = Node(name=f"joint_{i}", translation=local_pos.tolist()) + joint_nodes.append(node) + + # Set children for skeleton nodes + for i in range(num_joints): + parent_idx = parents[i] + if parent_idx != -1 and parent_idx != i: + parent_node = joint_nodes[parent_idx] + if parent_node.children is None: + parent_node.children = [] + parent_node.children.append(i + 1) + + nodes.extend(joint_nodes) + + # Find root joint index + root_joint_indices = np.where(parents == -1)[0] + if len(root_joint_indices) == 0: + root_joint_indices = np.where(parents == np.arange(num_joints))[0] + + if len(root_joint_indices) == 0: + print("Error: No root joint found.") + return + + if len(root_joint_indices) > 1: + print(f"Warning: Found {len(root_joint_indices)} root joints. Creating a virtual root.") + virtual_root_node_idx = len(nodes) + virtual_root_node = Node(name="VirtualRoot", children=[int(i) + 1 for i in root_joint_indices]) + nodes.append(virtual_root_node) + root_node_idx = virtual_root_node_idx + else: + root_joint_idx = root_joint_indices[0] + root_node_idx = int(root_joint_idx) + 1 + + # Skin + skin = Skin( + inverseBindMatrices=ibms_acc_idx, + joints=[i + 1 for i in range(num_joints)], + skeleton=root_node_idx + ) + + # Mesh + attributes_dict = { + "POSITION": pos_acc_idx, + "JOINTS_0": joints_acc_idx, + "WEIGHTS_0": weights_acc_idx + } + if norm_acc_idx is not None: + attributes_dict["NORMAL"] = norm_acc_idx + if tex_acc_idx is not None: + attributes_dict["TEXCOORD_0"] = tex_acc_idx + if color_acc_idx is not None: + attributes_dict["COLOR_0"] = color_acc_idx + + primitive = Primitive( + attributes=Attributes(**attributes_dict), + indices=indices_acc_idx, + material=0, + ) + mesh_obj = Mesh(primitives=[primitive]) + + # Scene + scene = Scene(nodes=[0, root_node_idx]) + + # Ensure GLB BIN chunk is 4-byte aligned. + align_to_4bytes() + + # Buffer + buffer = Buffer(byteLength=len(binary_data)) + + # Material โ€” attach texture when available, otherwise plain white + if gltf_textures: + pbr = PbrMetallicRoughness( + baseColorTexture=TextureInfo(index=0), + metallicFactor=0.0, + roughnessFactor=1.0, + ) + else: + pbr = PbrMetallicRoughness( + baseColorFactor=[1.0, 1.0, 1.0, 1.0], + metallicFactor=0.0, + roughnessFactor=1.0, + ) + material = Material(pbrMetallicRoughness=pbr) + + gltf = GLTF2( + asset=Asset(version="2.0"), + scene=0, + scenes=[scene], + nodes=nodes, + meshes=[mesh_obj], + materials=[material], + skins=[skin], + accessors=accessors, + bufferViews=buffer_views, + buffers=[buffer], + images=gltf_images if gltf_images else None, + textures=gltf_textures if gltf_textures else None, + samplers=gltf_samplers if gltf_samplers else None, + ) + + gltf.set_binary_blob(bytes(binary_data)) + + # IMPORTANT: `save()` may write JSON `.gltf` even if the filename ends with `.glb`. + # Many viewers (Meshlab/Open3D) will then report โ€œglb not supportedโ€. + if str(output_path).lower().endswith('.glb'): + gltf.save_binary(output_path) + else: + gltf.save(output_path) + + # Quick sanity check: a real GLB starts with magic bytes b'glTF'. + if str(output_path).lower().endswith('.glb'): + try: + with open(output_path, 'rb') as f: + magic = f.read(4) + if magic != b'glTF': + print(f"Warning: output does not look like a valid GLB (magic={magic!r}).") + except Exception as e: + print(f"Warning: failed to validate GLB header: {e}") + print(f"Saved GLB to {output_path}") + +def save_colored_pcl(array, filename): + if isinstance(array, torch.Tensor): + array = array.detach().cpu().numpy() + points = array[:, :3] + if array.shape[1] >= 6: + colors = (array[:, 3:6] * 255).astype(np.uint8) + else: + colors = np.full((points.shape[0], 3), 255, dtype=np.uint8) + + # Combine points and colors into a single array + data = np.hstack((points, colors)) + # Define the .ply header + header = f"""ply\nformat ascii 1.0\nelement vertex {points.shape[0]}\nproperty float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header\n""" + # Write to the .ply file + with open(filename, 'w') as file: + file.write(header) + np.savetxt(file, data, fmt='%f %f %f %d %d %d') + +def _extract_vertex_rgb(vertex_attrs): + """Extract Nx3 RGB in [0,1] from vertex_attrs (torch/np), or return None.""" + if vertex_attrs is None: + return None + attrs = vertex_attrs + if isinstance(attrs, torch.Tensor): + attrs = attrs.detach().cpu().numpy() + attrs = np.asarray(attrs) + if attrs.ndim != 2 or attrs.shape[1] < 3: + return None + colors = attrs[:, :3].astype(np.float32, copy=False) + np.clip(colors, 0.0, 1.0, out=colors) + return colors + +def transfer_vertex_colors_nearest(src_vertices, src_colors, dst_vertices): + """Transfer per-vertex colors by nearest-vertex mapping. + + Args: + src_vertices: (Ns, 3) float + src_colors: (Ns, 3) float in [0,1] + dst_vertices: (Nd, 3) float + Returns: + (Nd, 3) float in [0,1] + """ + if src_vertices is None or src_colors is None or dst_vertices is None: + return None + src_vertices = np.asarray(src_vertices) + src_colors = np.asarray(src_colors) + dst_vertices = np.asarray(dst_vertices) + if src_vertices.ndim != 2 or src_vertices.shape[1] != 3: + return None + if dst_vertices.ndim != 2 or dst_vertices.shape[1] != 3: + return None + if src_colors.ndim != 2 or src_colors.shape[1] != 3 or src_colors.shape[0] != src_vertices.shape[0]: + return None + + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + src_v = torch.from_numpy(src_vertices).to(device=device, dtype=torch.float32) + dst_v = torch.from_numpy(dst_vertices).to(device=device, dtype=torch.float32) + src_c = torch.from_numpy(src_colors).to(device=device, dtype=torch.float32) + + # Prefer pytorch3d for KNN if available. + idx = None + try: + from pytorch3d.ops import knn_points + _, nn_idx, _ = knn_points(dst_v[None], src_v[None], K=1, return_nn=False) + idx = nn_idx[0, :, 0] + except Exception: + # Fallback: brute-force cdist. + dist = torch.cdist(dst_v, src_v) # (Nd, Ns) + idx = torch.argmin(dist, dim=1) + + out = src_c[idx].clamp_(0.0, 1.0) + return out.detach().cpu().numpy() diff --git a/anigen/utils/general_utils.py b/anigen/utils/general_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..f6fa3fdfb430e2c3c81fee28af03cac2a3ff3370 --- /dev/null +++ b/anigen/utils/general_utils.py @@ -0,0 +1,287 @@ +import re +import numpy as np +import cv2 +import torch +import contextlib + + +# Dictionary utils +def _dict_merge(dicta, dictb, prefix=''): + """ + Merge two dictionaries. + """ + assert isinstance(dicta, dict), 'input must be a dictionary' + assert isinstance(dictb, dict), 'input must be a dictionary' + dict_ = {} + all_keys = set(dicta.keys()).union(set(dictb.keys())) + for key in all_keys: + if key in dicta.keys() and key in dictb.keys(): + if isinstance(dicta[key], dict) and isinstance(dictb[key], dict): + dict_[key] = _dict_merge(dicta[key], dictb[key], prefix=f'{prefix}.{key}') + else: + raise ValueError(f'Duplicate key {prefix}.{key} found in both dictionaries. Types: {type(dicta[key])}, {type(dictb[key])}') + elif key in dicta.keys(): + dict_[key] = dicta[key] + else: + dict_[key] = dictb[key] + return dict_ + + +def dict_merge(dicta, dictb): + """ + Merge two dictionaries. + """ + return _dict_merge(dicta, dictb, prefix='') + + +def dict_foreach(dic, func, special_func={}): + """ + Recursively apply a function to all non-dictionary leaf values in a dictionary. + """ + assert isinstance(dic, dict), 'input must be a dictionary' + for key in dic.keys(): + if isinstance(dic[key], dict): + dic[key] = dict_foreach(dic[key], func) + else: + if key in special_func.keys(): + dic[key] = special_func[key](dic[key]) + else: + dic[key] = func(dic[key]) + return dic + + +def dict_reduce(dicts, func, special_func={}): + """ + Reduce a list of dictionaries. Leaf values must be scalars. + """ + assert isinstance(dicts, list), 'input must be a list of dictionaries' + assert all([isinstance(d, dict) for d in dicts]), 'input must be a list of dictionaries' + assert len(dicts) > 0, 'input must be a non-empty list of dictionaries' + all_keys = set([key for dict_ in dicts for key in dict_.keys()]) + reduced_dict = {} + for key in all_keys: + vlist = [dict_[key] for dict_ in dicts if key in dict_.keys()] + if isinstance(vlist[0], dict): + reduced_dict[key] = dict_reduce(vlist, func, special_func) + else: + if key in special_func.keys(): + reduced_dict[key] = special_func[key](vlist) + else: + reduced_dict[key] = func(vlist) + return reduced_dict + + +def dict_any(dic, func): + """ + Recursively apply a function to all non-dictionary leaf values in a dictionary. + """ + assert isinstance(dic, dict), 'input must be a dictionary' + for key in dic.keys(): + if isinstance(dic[key], dict): + if dict_any(dic[key], func): + return True + else: + if func(dic[key]): + return True + return False + + +def dict_all(dic, func): + """ + Recursively apply a function to all non-dictionary leaf values in a dictionary. + """ + assert isinstance(dic, dict), 'input must be a dictionary' + for key in dic.keys(): + if isinstance(dic[key], dict): + if not dict_all(dic[key], func): + return False + else: + if not func(dic[key]): + return False + return True + + +def _keep_largest_connected_component_3d(mask_3d: "np.ndarray") -> "np.ndarray": + """Keep only the largest connected component (6-neighborhood) in a 3D boolean mask.""" + if mask_3d is None: + return mask_3d + mask_3d = np.asarray(mask_3d).astype(bool) + if mask_3d.ndim != 3: + raise ValueError(f"mask_3d must be 3D, got shape={mask_3d.shape}") + if not mask_3d.any(): + return mask_3d + + # Fast path if SciPy is available. + try: + import scipy.ndimage as ndi # type: ignore + + structure = np.zeros((3, 3, 3), dtype=np.int8) + structure[1, 1, 1] = 1 + structure[0, 1, 1] = 1 + structure[2, 1, 1] = 1 + structure[1, 0, 1] = 1 + structure[1, 2, 1] = 1 + structure[1, 1, 0] = 1 + structure[1, 1, 2] = 1 + + labeled, num = ndi.label(mask_3d, structure=structure) + if num <= 1: + return mask_3d + counts = np.bincount(labeled.reshape(-1)) + counts[0] = 0 # background + keep = int(np.argmax(counts)) + return labeled == keep + except Exception: + pass + + # Fallback: BFS connected components (6-neighborhood). + from collections import deque + + d, h, w = mask_3d.shape + labels = np.full((d, h, w), -1, dtype=np.int32) + nbrs = ((-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)) + + cur_label = 0 + best_label = -1 + best_size = 0 + + seeds = np.argwhere(mask_3d) + for z0, y0, x0 in seeds: + if labels[z0, y0, x0] != -1: + continue + q = deque() + q.append((int(z0), int(y0), int(x0))) + labels[z0, y0, x0] = cur_label + size = 0 + while q: + z, y, x = q.popleft() + size += 1 + for dz, dy, dx in nbrs: + zz = z + dz + yy = y + dy + xx = x + dx + if zz < 0 or zz >= d or yy < 0 or yy >= h or xx < 0 or xx >= w: + continue + if not mask_3d[zz, yy, xx]: + continue + if labels[zz, yy, xx] != -1: + continue + labels[zz, yy, xx] = cur_label + q.append((zz, yy, xx)) + if size > best_size: + best_size = size + best_label = cur_label + cur_label += 1 + + if best_label < 0: + return mask_3d + return labels == best_label + + +def _final_joint_count(joints) -> int: + """Return joint count for common joint tensor/array shapes. + + Accepts: numpy arrays, torch tensors, lists. + Expected shapes: [J, 3/4], [1, J, 3/4]. + """ + if joints is None: + return 0 + if isinstance(joints, torch.Tensor): + j = joints.detach() + if j.ndim == 3 and j.shape[0] == 1: + return int(j.shape[1]) + if j.ndim >= 2: + return int(j.shape[0]) + return int(j.numel()) + + j = np.asarray(joints) + if j.ndim == 3 and j.shape[0] == 1: + return int(j.shape[1]) + if j.ndim >= 2: + return int(j.shape[0]) + return int(j.size) + + +# Context utils +@contextlib.contextmanager +def nested_contexts(*contexts): + with contextlib.ExitStack() as stack: + for ctx in contexts: + stack.enter_context(ctx()) + yield + + +# Image utils +def make_grid(images, nrow=None, ncol=None, aspect_ratio=None): + num_images = len(images) + if nrow is None and ncol is None: + if aspect_ratio is not None: + nrow = int(np.round(np.sqrt(num_images / aspect_ratio))) + else: + nrow = int(np.sqrt(num_images)) + ncol = (num_images + nrow - 1) // nrow + elif nrow is None and ncol is not None: + nrow = (num_images + ncol - 1) // ncol + elif nrow is not None and ncol is None: + ncol = (num_images + nrow - 1) // nrow + else: + assert nrow * ncol >= num_images, 'nrow * ncol must be greater than or equal to the number of images' + + if images[0].ndim == 2: + grid = np.zeros((nrow * images[0].shape[0], ncol * images[0].shape[1]), dtype=images[0].dtype) + else: + grid = np.zeros((nrow * images[0].shape[0], ncol * images[0].shape[1], images[0].shape[2]), dtype=images[0].dtype) + for i, img in enumerate(images): + row = i // ncol + col = i % ncol + grid[row * img.shape[0]:(row + 1) * img.shape[0], col * img.shape[1]:(col + 1) * img.shape[1]] = img + return grid + + +def notes_on_image(img, notes=None): + img = np.pad(img, ((0, 32), (0, 0), (0, 0)), 'constant', constant_values=0) + img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) + if notes is not None: + img = cv2.putText(img, notes, (0, img.shape[0] - 4), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1) + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + return img + + +def save_image_with_notes(img, path, notes=None): + """ + Save an image with notes. + """ + if isinstance(img, torch.Tensor): + img = img.cpu().numpy().transpose(1, 2, 0) + if img.dtype == np.float32 or img.dtype == np.float64: + img = np.clip(img * 255, 0, 255).astype(np.uint8) + img = notes_on_image(img, notes) + cv2.imwrite(path, cv2.cvtColor(img, cv2.COLOR_RGB2BGR)) + + +# debug utils + +def atol(x, y): + """ + Absolute tolerance. + """ + return torch.abs(x - y) + + +def rtol(x, y): + """ + Relative tolerance. + """ + return torch.abs(x - y) / torch.clamp_min(torch.maximum(torch.abs(x), torch.abs(y)), 1e-12) + + +# print utils +def indent(s, n=4): + """ + Indent a string. + """ + lines = s.split('\n') + for i in range(1, len(lines)): + lines[i] = ' ' * n + lines[i] + return '\n'.join(lines) + diff --git a/anigen/utils/grad_clip_utils.py b/anigen/utils/grad_clip_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..990a4352e24fc73bf732d8eb0f8ca9a07365b49e --- /dev/null +++ b/anigen/utils/grad_clip_utils.py @@ -0,0 +1,81 @@ +from typing import * +import torch +import numpy as np +import torch.utils + + +class AdaptiveGradClipper: + """ + Adaptive gradient clipping for training. + """ + def __init__( + self, + max_norm=None, + clip_percentile=95.0, + buffer_size=1000, + ): + self.max_norm = max_norm + self.clip_percentile = clip_percentile + self.buffer_size = buffer_size + + self._grad_norm = np.zeros(buffer_size, dtype=np.float32) + self._max_norm = max_norm + self._buffer_ptr = 0 + self._buffer_length = 0 + + def __repr__(self): + return f'AdaptiveGradClipper(max_norm={self.max_norm}, clip_percentile={self.clip_percentile})' + + def state_dict(self): + return { + 'grad_norm': self._grad_norm, + 'max_norm': self._max_norm, + 'buffer_ptr': self._buffer_ptr, + 'buffer_length': self._buffer_length, + } + + def load_state_dict(self, state_dict): + self._grad_norm = state_dict['grad_norm'] + self._max_norm = state_dict['max_norm'] + self._buffer_ptr = state_dict['buffer_ptr'] + self._buffer_length = state_dict['buffer_length'] + + def log(self): + return { + 'max_norm': self._max_norm, + } + + def __call__(self, parameters, norm_type=2.0, error_if_nonfinite=False, foreach=None): + """Clip the gradient norm of an iterable of parameters. + + The norm is computed over all gradients together, as if they were + concatenated into a single vector. Gradients are modified in-place. + + Args: + parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a + single Tensor that will have gradients normalized + norm_type (float): type of the used p-norm. Can be ``'inf'`` for + infinity norm. + error_if_nonfinite (bool): if True, an error is thrown if the total + norm of the gradients from :attr:`parameters` is ``nan``, + ``inf``, or ``-inf``. Default: False (will switch to True in the future) + foreach (bool): use the faster foreach-based implementation. + If ``None``, use the foreach implementation for CUDA and CPU native tensors and silently + fall back to the slow implementation for other device types. + Default: ``None`` + + Returns: + Total norm of the parameter gradients (viewed as a single vector). + """ + max_norm = self._max_norm if self._max_norm is not None else float('inf') + grad_norm = torch.nn.utils.clip_grad_norm_(parameters, max_norm=max_norm, norm_type=norm_type, error_if_nonfinite=error_if_nonfinite, foreach=foreach) + + if torch.isfinite(grad_norm): + self._grad_norm[self._buffer_ptr] = grad_norm + self._buffer_ptr = (self._buffer_ptr + 1) % self.buffer_size + self._buffer_length = min(self._buffer_length + 1, self.buffer_size) + if self._buffer_length == self.buffer_size: + self._max_norm = np.percentile(self._grad_norm, self.clip_percentile) + self._max_norm = min(self._max_norm, self.max_norm) if self.max_norm is not None else self._max_norm + + return grad_norm \ No newline at end of file diff --git a/anigen/utils/image_utils.py b/anigen/utils/image_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b2efe8f477907416db500ee06547534b42cf2f93 --- /dev/null +++ b/anigen/utils/image_utils.py @@ -0,0 +1,210 @@ +import os +import torch +import numpy as np +from PIL import Image +import torch.nn.functional as F +from torchvision import transforms +import rembg + +_SUPPORTED_IMAGE_EXTS = { + '.png', '.jpg', '.jpeg', '.webp', '.bmp', '.tif', '.tiff' +} + +def _expand_image_inputs(image_path: str) -> tuple[list[str], bool]: + """Return (image_paths, is_directory). + + If image_path is a directory, returns all supported images under it (non-recursive), + sorted by filename. Otherwise returns [image_path]. + """ + if image_path is None: + raise ValueError('image_path is None') + + image_path = str(image_path) + if os.path.isdir(image_path): + entries = [] + for name in sorted(os.listdir(image_path)): + full = os.path.join(image_path, name) + if not os.path.isfile(full): + continue + ext = os.path.splitext(name)[1].lower() + if ext in _SUPPORTED_IMAGE_EXTS: + entries.append(full) + return entries, True + + return [image_path], False + +def load_dsine(device='cuda'): + # Load DSINE model + # We need to import DSINE here to avoid circular imports or path issues if possible, + # but since we added sys.path, we can try importing. + # Based on test_minimal.py in dsine repo + from models.dsine.v02 import DSINE_v02 as DSINE + + # Manually define args since projects.dsine.config is missing + class Args: + def __init__(self): + self.NNET_architecture = 'v02' + self.NNET_encoder_B = 5 + self.NNET_decoder_NF = 2048 + self.NNET_decoder_BN = False + self.NNET_decoder_down = 8 + self.NNET_learned_upsampling = True + self.NRN_prop_ps = 5 + self.NRN_num_iter_train = 5 + self.NRN_num_iter_test = 5 + self.NRN_ray_relu = True + self.NNET_output_dim = 3 + self.NNET_output_type = 'R' + self.NNET_feature_dim = 64 + self.NNET_hidden_dim = 64 + + args = Args() + + model = DSINE(args).to(device) + + # Load checkpoint + ckpt_path = 'ckpts/dsine/dsine.pt' + if os.path.exists(ckpt_path): + print(f"Loading DSINE checkpoint from {ckpt_path}") + state_dict = torch.load(ckpt_path, map_location='cpu') + if 'model' in state_dict: + state_dict = state_dict['model'] + model.load_state_dict(state_dict, strict=True) + model.eval() + return model + else: + print(f"DSINE checkpoint not found at {ckpt_path}. Trying torch.hub...") + try: + # Fallback to torch.hub if local ckpt not found + # Note: This might fail if the hub model expects different args structure, + # but usually it handles it internally. + # However, since we are using local class definition, we should load weights into it. + # If we use torch.hub.load, it returns the model object directly. + model = torch.hub.load("hugoycj/DSINE-hub", "DSINE", trust_repo=True) + model.to(device) + model.eval() + return model + except Exception as e: + print(f"Failed to load DSINE from hub: {e}") + raise ValueError("Could not load DSINE model.") + +def intrins_from_fov(new_fov, H, W, device): + fov = torch.tensor(new_fov).to(device) + f = 0.5 * W / torch.tan(0.5 * fov * np.pi / 180.0) + cx = 0.5 * W + cy = 0.5 * H + intrins = torch.tensor([[f, 0, cx], [0, f, cy], [0, 0, 1]]).to(device) + return intrins + +def estimate_normal(image, model, device='cuda'): + # image: PIL Image RGB + w, h = image.size + + # Prepare input + im_tensor = torch.from_numpy(np.array(image)).float() / 255.0 + im_tensor = im_tensor.permute(2, 0, 1).unsqueeze(0).to(device) + + # Normalize + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + im_tensor = normalize(im_tensor) + + # Pad + pad_h = (32 - h % 32) % 32 + pad_w = (32 - w % 32) % 32 + im_tensor = F.pad(im_tensor, (0, pad_w, 0, pad_h), mode='constant', value=0) + + # Intrinsics (assume 60 deg FOV) + intrins = intrins_from_fov(60.0, h, w, device).unsqueeze(0) + intrins[:, 0, 2] += 0 # No left padding + intrins[:, 1, 2] += 0 # No top padding + + with torch.no_grad(): + pred_norm = model(im_tensor, intrins=intrins)[-1] + + # Crop padding + pred_norm = pred_norm[:, :, :h, :w] + + # Revert the X axis + pred_norm[:, 0, :, :] = -pred_norm[:, 0, :, :] + + # Convert to [0, 1] + pred_norm = (pred_norm + 1) / 2.0 + + return pred_norm # (1, 3, H, W) + +def preprocess_image(input_image, dsine_model=None, device='cuda'): + # 1. DSINE Normal Estimation on Original Image + input_rgb = input_image.convert('RGB') + if dsine_model is not None: + normal_tensor = estimate_normal(input_rgb, dsine_model, device) # (1, 3, H, W) + normal_np = normal_tensor.squeeze(0).permute(1, 2, 0).cpu().numpy() # (H, W, 3) + normal_image = Image.fromarray((normal_np * 255).astype(np.uint8)) + else: + normal_image = Image.new('RGB', input_image.size, (128, 128, 255)) + + has_alpha = False + if input_image.mode == 'RGBA': + alpha = np.array(input_image)[:, :, 3] + if not np.all(alpha == 255): + has_alpha = True + if has_alpha: + output = input_image + else: + input_image = input_image.convert('RGB') + max_size = max(input_image.size) + scale = min(1, 1024 / max_size) + if scale < 1: + input_image = input_image.resize((int(input_image.width * scale), int(input_image.height * scale)), Image.Resampling.LANCZOS) + # Also resize normal image if we resized input + normal_image = normal_image.resize((int(normal_image.width * scale), int(normal_image.height * scale)), Image.Resampling.LANCZOS) + + session = rembg.new_session('birefnet-general') + output = rembg.remove(input_image, session=session) + + output_np = np.array(output) + alpha = output_np[:, :, 3] + bbox = np.argwhere(alpha > 0.8 * 255) + if len(bbox) == 0: + bbox = [0, 0, output.height, output.width] + bbox_crop = (0, 0, output.width, output.height) + else: + bbox = np.min(bbox[:, 1]), np.min(bbox[:, 0]), np.max(bbox[:, 1]), np.max(bbox[:, 0]) + center = (bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2 + size = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) + size = int(size * 1.2) + bbox_crop = (int(center[0] - size // 2), int(center[1] - size // 2), int(center[0] + size // 2), int(center[1] + size // 2)) + + output = output.crop(bbox_crop) + output = output.resize((518, 518), Image.Resampling.LANCZOS) + output = np.array(output).astype(np.float32) / 255 + output = output[:, :, :3] * output[:, :, 3:4] + output = Image.fromarray((output * 255).astype(np.uint8)) + + # Process Normal + normal_rgba = normal_image.convert('RGBA') + + # Create alpha mask image + alpha_img = Image.fromarray(alpha) + normal_rgba.putalpha(alpha_img) + + normal_crop = normal_rgba.crop(bbox_crop) + normal_crop = normal_crop.resize((518, 518), Image.Resampling.LANCZOS) + + normal_np = np.array(normal_crop).astype(np.float32) / 255 + normal_np = normal_np[:, :, :3] * normal_np[:, :, 3:4] + normal_output = Image.fromarray((normal_np * 255).astype(np.uint8)) + + return output, normal_output + +def encode_image(image, image_cond_model, device): + transform = transforms.Compose([ + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + image_tensor = np.array(image.convert('RGB')).astype(np.float32) / 255 + image_tensor = torch.from_numpy(image_tensor).permute(2, 0, 1).float().unsqueeze(0).to(device) + image_tensor = transform(image_tensor) + + with torch.no_grad(): + features = image_cond_model(image_tensor, is_training=True)['x_prenorm'] + patchtokens = F.layer_norm(features, features.shape[-1:]) + return patchtokens diff --git a/anigen/utils/loss_utils.py b/anigen/utils/loss_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..a8384d240bf84ca0e9d577f5b3bcc677d83989b7 --- /dev/null +++ b/anigen/utils/loss_utils.py @@ -0,0 +1,113 @@ +import torch +import torch.nn.functional as F +from torch.autograd import Variable +from math import exp +from lpips import LPIPS + + +def smooth_l1_loss(pred, target, beta=1.0): + diff = torch.abs(pred - target) + loss = torch.where(diff < beta, 0.5 * diff ** 2 / beta, diff - 0.5 * beta) + return loss.mean() + + +def l1_loss(network_output, gt): + return torch.abs((network_output - gt)).mean() + + +def l2_loss(network_output, gt): + return ((network_output - gt) ** 2).mean() + + +def gaussian(window_size, sigma): + gauss = torch.Tensor([exp(-(x - window_size // 2) ** 2 / float(2 * sigma ** 2)) for x in range(window_size)]) + return gauss / gauss.sum() + + +def create_window(window_size, channel): + _1D_window = gaussian(window_size, 1.5).unsqueeze(1) + _2D_window = _1D_window.mm(_1D_window.t()).float().unsqueeze(0).unsqueeze(0) + window = Variable(_2D_window.expand(channel, 1, window_size, window_size).contiguous()) + return window + + +def psnr(img1, img2, max_val=1.0): + mse = F.mse_loss(img1, img2) + return 20 * torch.log10(max_val / torch.sqrt(mse)) + + +def ssim(img1, img2, window_size=11, size_average=True): + channel = img1.size(-3) + window = create_window(window_size, channel) + + if img1.is_cuda: + window = window.cuda(img1.get_device()) + window = window.type_as(img1) + + return _ssim(img1, img2, window, window_size, channel, size_average) + +def _ssim(img1, img2, window, window_size, channel, size_average=True): + mu1 = F.conv2d(img1, window, padding=window_size // 2, groups=channel) + mu2 = F.conv2d(img2, window, padding=window_size // 2, groups=channel) + + mu1_sq = mu1.pow(2) + mu2_sq = mu2.pow(2) + mu1_mu2 = mu1 * mu2 + + sigma1_sq = F.conv2d(img1 * img1, window, padding=window_size // 2, groups=channel) - mu1_sq + sigma2_sq = F.conv2d(img2 * img2, window, padding=window_size // 2, groups=channel) - mu2_sq + sigma12 = F.conv2d(img1 * img2, window, padding=window_size // 2, groups=channel) - mu1_mu2 + + C1 = 0.01 ** 2 + C2 = 0.03 ** 2 + + ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)) + + if size_average: + return ssim_map.mean() + else: + return ssim_map.mean(1).mean(1).mean(1) + + +def load_lpips_ckpt(lpip_model, vgg_path): + vgg_ckpt = torch.load(vgg_path) + fea_ckpt = {k: v for k, v in vgg_ckpt.items() if 'features' in k} + lpip_ckpt = {} + for k, v in fea_ckpt.items(): + if '.0.' in k or '.2.' in k: + lpip_ckpt[k.replace('features', 'net.slice1')] = v + elif '.5.' in k or '.7.' in k: + lpip_ckpt[k.replace('features', 'net.slice2')] = v + elif '.10.' in k or '.12.' in k or '.14.' in k: + lpip_ckpt[k.replace('features', 'net.slice3')] = v + elif '.17.' in k or '.19.' in k or '.21.' in k: + lpip_ckpt[k.replace('features', 'net.slice4')] = v + elif '.24.' in k or '.26.' in k or '.28.' in k: + lpip_ckpt[k.replace('features', 'net.slice5')] = v + print(f'Load LPIPS Model: Number of matching keys: {len(set(lpip_model.state_dict().keys()).intersection(set(lpip_ckpt.keys())))}') + lpip_model.load_state_dict(lpip_ckpt, strict=False) + return lpip_model + + +loss_fn_vgg = None +def lpips(img1, img2, value_range=(0, 1)): + global loss_fn_vgg + if loss_fn_vgg is None: + loss_fn_vgg = LPIPS(net='vgg', pnet_rand=True).cuda().eval() + load_lpips_ckpt(loss_fn_vgg, 'ckpts/vgg/vgg16-397923af.pth') + # normalize to [-1, 1] + img1 = (img1 - value_range[0]) / (value_range[1] - value_range[0]) * 2 - 1 + img2 = (img2 - value_range[0]) / (value_range[1] - value_range[0]) * 2 - 1 + return loss_fn_vgg(img1, img2).mean() + + +def normal_angle(pred, gt): + pred = pred * 2.0 - 1.0 + gt = gt * 2.0 - 1.0 + norms = pred.norm(dim=-1) * gt.norm(dim=-1) + cos_sim = (pred * gt).sum(-1) / (norms + 1e-9) + cos_sim = torch.clamp(cos_sim, -1.0, 1.0) + ang = torch.rad2deg(torch.acos(cos_sim[norms > 1e-9])).mean() + if ang.isnan(): + return -1 + return ang diff --git a/anigen/utils/mesh_part_splitting.py b/anigen/utils/mesh_part_splitting.py new file mode 100644 index 0000000000000000000000000000000000000000..b78bee5de431ecc8287a7f7cfb72b3a2ade1c559 --- /dev/null +++ b/anigen/utils/mesh_part_splitting.py @@ -0,0 +1,871 @@ +import sys +import struct +import numpy as np +from pathlib import Path +from typing import Dict, List, Tuple, Optional, Set +from collections import defaultdict + +# Third-party imports +try: + from pygltflib import GLTF2, BufferFormat, Accessor, BufferView + import networkx as nx +except ImportError as e: + print(f"Missing dependency: {e}") + print("Please install required packages:") + print(" pip install pygltflib networkx numpy") + sys.exit(1) + +try: + import open3d as o3d +except: + print("Missing dependency: open3d") + pass + +# Splitting parameters +GEODESIC_DISTANCE_THRESHOLD = 3 # Max allowed geodesic distance between bones +WEIGHT_THRESHOLD = 0.15 # Minimum weight to consider a joint as "influential" +SPREAD_WEIGHT_THRESHOLD = 0.1 # Minimum weight for spread detection +EDGE_SMOOTH_ITERATIONS = 5 # Iterations for smoothing edge vertex weights +EDGE_SMOOTH_ALPHA = 0.7 # Smoothing strength for edge vertices + + +# ============================================================================= +# glTF Data Access Utilities (reused from texture_transfer.py) +# ============================================================================= + +# Component type mapping for glTF accessors +COMPONENT_TYPES = { + 5120: ('b', 1, np.int8), # BYTE + 5121: ('B', 1, np.uint8), # UNSIGNED_BYTE + 5122: ('h', 2, np.int16), # SHORT + 5123: ('H', 2, np.uint16), # UNSIGNED_SHORT + 5125: ('I', 4, np.uint32), # UNSIGNED_INT + 5126: ('f', 4, np.float32), # FLOAT +} + +# Type to component count mapping +TYPE_COUNTS = { + 'SCALAR': 1, 'VEC2': 2, 'VEC3': 3, 'VEC4': 4, + 'MAT2': 4, 'MAT3': 9, 'MAT4': 16 +} + + +def get_binary_blob(gltf: GLTF2) -> bytes: + """Get the binary blob from a GLTF2 object.""" + binary_blob = gltf.binary_blob + if callable(binary_blob): + binary_blob = binary_blob() + return binary_blob if isinstance(binary_blob, bytes) else b'' + + +def set_binary_blob(gltf: GLTF2, data: bytes) -> None: + """Set the binary blob on a GLTF2 object.""" + if hasattr(gltf, 'set_binary_blob') and callable(gltf.set_binary_blob): + gltf.set_binary_blob(data) + else: + gltf.binary_blob = data + + if gltf.buffers: + gltf.buffers[0].byteLength = len(data) + + +def get_buffer_data(gltf: GLTF2) -> bytes: + """Get the binary buffer data from a GLB file.""" + gltf.convert_buffers(BufferFormat.BINARYBLOB) + binary_blob = get_binary_blob(gltf) + + if binary_blob is not None and len(binary_blob) > 0: + return binary_blob + + if hasattr(gltf, '_glb_data') and gltf._glb_data is not None: + return gltf._glb_data + + return b'' + + +def read_accessor_data(gltf: GLTF2, accessor_index: int, + buffer_data: Optional[bytes] = None) -> np.ndarray: + """Read data from a glTF accessor into a numpy array.""" + if buffer_data is None: + buffer_data = get_buffer_data(gltf) + + accessor = gltf.accessors[accessor_index] + buffer_view = gltf.bufferViews[accessor.bufferView] + + fmt_char, component_size, np_dtype = COMPONENT_TYPES[accessor.componentType] + component_count = TYPE_COUNTS[accessor.type] + element_size = component_size * component_count + + byte_offset = (buffer_view.byteOffset or 0) + (accessor.byteOffset or 0) + stride = buffer_view.byteStride or element_size + + values = [] + for i in range(accessor.count): + offset = byte_offset + i * stride + for j in range(component_count): + value = struct.unpack_from(fmt_char, buffer_data, offset + j * component_size)[0] + values.append(value) + + arr = np.array(values, dtype=np_dtype) + if accessor.type == 'SCALAR': + return arr + elif accessor.type in ('VEC2', 'VEC3', 'VEC4'): + return arr.reshape(-1, component_count) + elif accessor.type == 'MAT4': + return arr.reshape(-1, 4, 4) + + return arr + + +def read_mesh_data(gltf: GLTF2, mesh_index: int = 0, + buffer_data: Optional[bytes] = None) -> Tuple[np.ndarray, np.ndarray]: + """ + Read vertex positions and face indices from a mesh. + + Returns: + Tuple of (vertices, faces) where: + - vertices: (N, 3) array of vertex positions + - faces: (M, 3) array of triangle indices + """ + if buffer_data is None: + buffer_data = get_buffer_data(gltf) + + mesh = gltf.meshes[mesh_index] + all_vertices = [] + all_faces = [] + vertex_offset = 0 + + for primitive in mesh.primitives: + # Read vertices + pos_accessor_idx = primitive.attributes.POSITION + vertices = read_accessor_data(gltf, pos_accessor_idx, buffer_data) + all_vertices.append(vertices) + + # Read indices + if primitive.indices is not None: + indices = read_accessor_data(gltf, primitive.indices, buffer_data) + # Reshape to triangles and offset by vertex count + faces = indices.reshape(-1, 3) + vertex_offset + all_faces.append(faces) + + vertex_offset += len(vertices) + + vertices = np.vstack(all_vertices) if len(all_vertices) > 1 else all_vertices[0] + faces = np.vstack(all_faces) if len(all_faces) > 1 else all_faces[0] if all_faces else np.array([]) + + return vertices.astype(np.float32), faces.astype(np.int32) + + +def read_skinning_data(gltf: GLTF2, mesh_index: int = 0, + buffer_data: Optional[bytes] = None) -> Tuple[np.ndarray, np.ndarray]: + """ + Read JOINTS_0 and WEIGHTS_0 from a mesh. + + Returns: + Tuple of (joints, weights) arrays, each with shape (num_vertices, 4) + """ + if buffer_data is None: + buffer_data = get_buffer_data(gltf) + + mesh = gltf.meshes[mesh_index] + all_joints = [] + all_weights = [] + + for primitive in mesh.primitives: + attrs = primitive.attributes + + if hasattr(attrs, 'JOINTS_0') and attrs.JOINTS_0 is not None: + joints = read_accessor_data(gltf, attrs.JOINTS_0, buffer_data) + all_joints.append(joints.reshape(-1, 4)) + + if hasattr(attrs, 'WEIGHTS_0') and attrs.WEIGHTS_0 is not None: + weights = read_accessor_data(gltf, attrs.WEIGHTS_0, buffer_data) + all_weights.append(weights.reshape(-1, 4)) + + if not all_joints or not all_weights: + return None, None + + joints = np.vstack(all_joints) if len(all_joints) > 1 else all_joints[0] + weights = np.vstack(all_weights) if len(all_weights) > 1 else all_weights[0] + + return joints.astype(np.int32), weights.astype(np.float32) + + +# ============================================================================= +# Skeleton Graph Construction +# ============================================================================= + +def build_skeleton_graph(gltf: GLTF2) -> Tuple[nx.Graph, List[int]]: + """ + Build an undirected graph representing the skeleton structure. + + Args: + gltf: The GLTF2 object containing the skeleton + + Returns: + Tuple of (graph, joint_indices) where: + - graph: NetworkX graph with joints as nodes and bones as edges + - joint_indices: List of node indices that are joints + """ + if not gltf.skins: + raise ValueError("GLB file has no skin/skeleton data") + + skin = gltf.skins[0] + joint_indices = skin.joints + + # Create graph + G = nx.Graph() + + # Add all joints as nodes + for joint_idx in joint_indices: + node = gltf.nodes[joint_idx] + G.add_node(joint_idx, name=node.name or f"Joint_{joint_idx}") + + # Add edges based on parent-child relationships + for joint_idx in joint_indices: + node = gltf.nodes[joint_idx] + if node.children: + for child_idx in node.children: + if child_idx in joint_indices: + G.add_edge(joint_idx, child_idx, weight=1) + + return G, joint_indices + + +def compute_geodesic_distances(G: nx.Graph, joint_indices: List[int]) -> Dict[Tuple[int, int], int]: + """ + Compute geodesic distances (shortest path lengths) between all pairs of joints. + + Args: + G: The skeleton graph + joint_indices: List of joint node indices + + Returns: + Dictionary mapping (joint_i, joint_j) -> distance + """ + # Compute all pairs shortest paths + distances = dict(nx.all_pairs_shortest_path_length(G)) + + # Build distance dictionary + dist_dict = {} + for i in joint_indices: + for j in joint_indices: + if i in distances and j in distances[i]: + dist_dict[(i, j)] = distances[i][j] + else: + # If no path exists, set to infinity + dist_dict[(i, j)] = float('inf') + + return dist_dict + + +def get_primary_joint(joints: np.ndarray, weights: np.ndarray, vertex_idx: int) -> int: + """ + Get the primary (highest weight) joint for a vertex. + + Args: + joints: Joint indices array (N, 4) + weights: Weight values array (N, 4) + vertex_idx: Index of the vertex + + Returns: + Joint index with highest weight + """ + vertex_joints = joints[vertex_idx] + vertex_weights = weights[vertex_idx] + + max_idx = np.argmax(vertex_weights) + return int(vertex_joints[max_idx]) + + +def get_influential_joints(joints: np.ndarray, weights: np.ndarray, + vertex_idx: int, weight_threshold: float = WEIGHT_THRESHOLD) -> List[Tuple[int, float]]: + """ + Get all joints with weight above threshold for a vertex. + + Args: + joints: Joint indices array (N, 4) + weights: Weight values array (N, 4) + vertex_idx: Index of the vertex + weight_threshold: Minimum weight to consider + + Returns: + List of (joint_index, weight) tuples for influential joints + """ + vertex_joints = joints[vertex_idx] + vertex_weights = weights[vertex_idx] + + influential = [] + for i in range(4): + if vertex_weights[i] >= weight_threshold: + influential.append((int(vertex_joints[i]), float(vertex_weights[i]))) + + return influential + + +def is_vertex_spread_to_distant_bones(joints: np.ndarray, weights: np.ndarray, + vertex_idx: int, joint_indices: List[int], + geodesic_distances: Dict[Tuple[int, int], int], + distance_threshold: int = GEODESIC_DISTANCE_THRESHOLD, + weight_threshold: float = SPREAD_WEIGHT_THRESHOLD) -> bool: + """ + Check if a vertex has its weights spread across distant bones. + + A vertex is problematic if it has significant weights (>= weight_threshold) + on multiple bones that are far apart in the skeleton graph. + + Args: + joints: Joint indices array (N, 4) + weights: Weight values array (N, 4) + vertex_idx: Index of the vertex + joint_indices: List of valid joint node indices + geodesic_distances: Precomputed geodesic distances + distance_threshold: Maximum allowed geodesic distance + weight_threshold: Minimum weight to consider as "significant" + + Returns: + True if vertex has weights spread to distant bones + """ + vertex_joints = joints[vertex_idx] + vertex_weights = weights[vertex_idx] + + # Create mapping from skin joint index to node index + skin_to_node = {i: joint_indices[i] for i in range(len(joint_indices))} + + # Find all joints with significant weight + significant_joints = [] + for i in range(4): + if vertex_weights[i] >= weight_threshold: + skin_idx = int(vertex_joints[i]) + if skin_idx < len(joint_indices): + node_idx = skin_to_node[skin_idx] + significant_joints.append((node_idx, float(vertex_weights[i]))) + + # If only one or zero significant joints, not spread + if len(significant_joints) < 2: + return False + + # Check geodesic distance between all pairs of significant joints + for i in range(len(significant_joints)): + for j in range(i + 1, len(significant_joints)): + joint_i, weight_i = significant_joints[i] + joint_j, weight_j = significant_joints[j] + + dist = geodesic_distances.get((joint_i, joint_j), float('inf')) + + # If two joints are far apart and both have significant weight + if dist > distance_threshold: + # Additional check: the combined weight should be substantial + # This catches cases where weights are "balanced" between distant bones + combined_weight = weight_i + weight_j + if combined_weight >= 0.3: # At least 30% of weight on distant bones + return True + + return False + + +# ============================================================================= +# Edge Vertex Weight Cleaning +# ============================================================================= + +def find_edge_vertices(faces: np.ndarray, + triangles_to_remove: Set[int]) -> Tuple[Set[int], Set[int]]: + """ + Find vertices that are on the edge of removed regions. + + Edge vertices are those that: + - Belong to at least one removed triangle + - Also belong to at least one remaining triangle + + Args: + faces: Triangle indices (M, 3) + triangles_to_remove: Set of triangle indices to remove + + Returns: + Tuple of (edge_vertices, removed_only_vertices) + """ + removed_vertices = set() + remaining_vertices = set() + + for face_idx, face in enumerate(faces): + if face_idx in triangles_to_remove: + for v in face: + removed_vertices.add(int(v)) + else: + for v in face: + remaining_vertices.add(int(v)) + + # Edge vertices: in both removed and remaining triangles + edge_vertices = removed_vertices & remaining_vertices + + # Vertices only in removed triangles (will become orphaned) + removed_only_vertices = removed_vertices - remaining_vertices + + return edge_vertices, removed_only_vertices + + +def clean_edge_vertex_weights(joints: np.ndarray, weights: np.ndarray, + edge_vertices: Set[int], + joint_indices: List[int], + geodesic_distances: Dict[Tuple[int, int], int], + distance_threshold: int = GEODESIC_DISTANCE_THRESHOLD) -> np.ndarray: + """ + Clean weights of edge vertices by removing influence from distant bones. + + For each edge vertex, find its primary joint and remove weights from + joints that are too far away in the skeleton graph. + + Args: + joints: Joint indices array (N, 4) + weights: Weight values array (N, 4) + edge_vertices: Set of edge vertex indices + joint_indices: List of valid joint node indices + geodesic_distances: Precomputed geodesic distances + distance_threshold: Maximum allowed geodesic distance + + Returns: + Modified weights array + """ + new_weights = weights.copy() + skin_to_node = {i: joint_indices[i] for i in range(len(joint_indices))} + + cleaned_count = 0 + + for vertex_idx in edge_vertices: + vertex_joints = joints[vertex_idx] + vertex_weights = new_weights[vertex_idx] + + # Find primary joint (highest weight) + primary_idx = np.argmax(vertex_weights) + primary_skin_idx = int(vertex_joints[primary_idx]) + + if primary_skin_idx >= len(joint_indices): + continue + + primary_node_idx = skin_to_node[primary_skin_idx] + + # Check each joint and zero out distant ones + modified = False + for i in range(4): + if i == primary_idx: + continue + + skin_idx = int(vertex_joints[i]) + if skin_idx >= len(joint_indices): + continue + + node_idx = skin_to_node[skin_idx] + dist = geodesic_distances.get((primary_node_idx, node_idx), float('inf')) + + # If this joint is too far from the primary joint, zero its weight + if dist > distance_threshold: + vertex_weights[i] = 0.0 + modified = True + + if modified: + # Renormalize weights + weight_sum = vertex_weights.sum() + if weight_sum > 0: + vertex_weights /= weight_sum + cleaned_count += 1 + + print(f" Cleaned weights for {cleaned_count} edge vertices") + return new_weights + + +def find_neighbor_vertices(faces: np.ndarray, target_vertices: Set[int], + triangles_to_remove: Set[int], hops: int = 2) -> Set[int]: + """ + Find vertices within N hops of target vertices on the remaining mesh. + + Args: + faces: Triangle indices (M, 3) + target_vertices: Set of vertices to expand from + triangles_to_remove: Triangles to exclude + hops: Number of hops to expand + + Returns: + Set of vertices within N hops (including original targets) + """ + # Build adjacency from remaining triangles + adjacency = defaultdict(set) + for face_idx, face in enumerate(faces): + if face_idx in triangles_to_remove: + continue + v0, v1, v2 = int(face[0]), int(face[1]), int(face[2]) + adjacency[v0].update([v1, v2]) + adjacency[v1].update([v0, v2]) + adjacency[v2].update([v0, v1]) + + current = set(target_vertices) + all_vertices = set(target_vertices) + + for _ in range(hops): + next_ring = set() + for v in current: + next_ring.update(adjacency[v]) + next_ring -= all_vertices + all_vertices.update(next_ring) + current = next_ring + + return all_vertices + + +def update_weights_in_buffer(gltf: GLTF2, mesh_index: int, + new_weights: np.ndarray, + buffer_data: bytes) -> bytes: + """ + Update the WEIGHTS_0 data in the buffer. + + Args: + gltf: The GLTF2 object + mesh_index: Index of the mesh + new_weights: New weights array (N, 4) + buffer_data: Current buffer data + + Returns: + Updated buffer data + """ + mesh = gltf.meshes[mesh_index] + buffer_data = bytearray(buffer_data) + + vertex_offset = 0 + + for primitive in mesh.primitives: + attrs = primitive.attributes + + if not hasattr(attrs, 'WEIGHTS_0') or attrs.WEIGHTS_0 is None: + # Count vertices for offset + if hasattr(attrs, 'POSITION') and attrs.POSITION is not None: + accessor = gltf.accessors[attrs.POSITION] + vertex_offset += accessor.count + continue + + accessor = gltf.accessors[attrs.WEIGHTS_0] + buffer_view = gltf.bufferViews[accessor.bufferView] + + num_verts = accessor.count + byte_offset = (buffer_view.byteOffset or 0) + (accessor.byteOffset or 0) + + # Get stride (default to 16 bytes for VEC4 float) + stride = buffer_view.byteStride or 16 + + # Update weights in buffer + for i in range(num_verts): + offset = byte_offset + i * stride + w = new_weights[vertex_offset + i] + struct.pack_into('ffff', buffer_data, offset, + float(w[0]), float(w[1]), float(w[2]), float(w[3])) + + vertex_offset += num_verts + + return bytes(buffer_data) + + +# ============================================================================= +# Triangle Filtering +# ============================================================================= + +def identify_problematic_triangles(faces: np.ndarray, + joints: np.ndarray, + weights: np.ndarray, + joint_indices: List[int], + geodesic_distances: Dict[Tuple[int, int], int], + threshold: int = GEODESIC_DISTANCE_THRESHOLD) -> Tuple[Set[int], Set[int]]: + """ + Identify triangles that should be removed based on two criteria: + 1. Triangles with vertices bound to far-apart bones (original method) + 2. Triangles containing vertices with weights spread to distant bones (new method) + + Args: + faces: Triangle indices (M, 3) + joints: Joint indices per vertex (N, 4) + weights: Joint weights per vertex (N, 4) + joint_indices: List of valid joint indices + geodesic_distances: Precomputed geodesic distances + threshold: Maximum allowed geodesic distance + + Returns: + Tuple of (problematic_triangles, problematic_vertices) + """ + problematic_triangles = set() + problematic_vertices = set() + + # Create mapping from skin joint index to node index + skin_to_node = {i: joint_indices[i] for i in range(len(joint_indices))} + + num_vertices = len(joints) + + # First pass: identify vertices with weights spread to distant bones + print(" Checking vertices for weight spread to distant bones...") + for vertex_idx in range(num_vertices): + if is_vertex_spread_to_distant_bones(joints, weights, vertex_idx, + joint_indices, geodesic_distances, threshold): + problematic_vertices.add(vertex_idx) + + print(f" Vertices with spread weights: {len(problematic_vertices)} / {num_vertices} ({100*len(problematic_vertices)/num_vertices:.2f}%)") + + # Second pass: identify triangles + print(" Checking triangles...") + for face_idx, face in enumerate(faces): + # Method 1: Check if any vertex has spread weights + for vertex_idx in face: + if vertex_idx in problematic_vertices: + problematic_triangles.add(face_idx) + break + + if face_idx in problematic_triangles: + continue + + # Method 2: Check if vertices are bound to far-apart primary bones + primary_joints = [] + for vertex_idx in face: + skin_joint_idx = get_primary_joint(joints, weights, vertex_idx) + if skin_joint_idx < len(joint_indices): + node_idx = skin_to_node[skin_joint_idx] + primary_joints.append(node_idx) + else: + primary_joints.append(None) + + for i in range(3): + for j in range(i + 1, 3): + joint_i = primary_joints[i] + joint_j = primary_joints[j] + + if joint_i is None or joint_j is None: + continue + + dist = geodesic_distances.get((joint_i, joint_j), float('inf')) + + if dist > threshold: + problematic_triangles.add(face_idx) + break + + if face_idx in problematic_triangles: + break + + return problematic_triangles, problematic_vertices + + +# ============================================================================= +# Mesh Reconstruction +# ============================================================================= + +def rebuild_mesh_without_triangles(gltf: GLTF2, + mesh_index: int, + triangles_to_remove: Set[int], + buffer_data: bytes) -> bytes: + """ + Rebuild the mesh without the specified triangles. + + This function modifies the GLB in place, updating the indices buffer + to exclude the removed triangles. + + Args: + gltf: The GLTF2 object to modify + mesh_index: Index of the mesh to modify + triangles_to_remove: Set of triangle indices to remove + buffer_data: Original buffer data + + Returns: + Updated buffer data + """ + mesh = gltf.meshes[mesh_index] + buffer_data = bytearray(buffer_data) + + face_offset = 0 + + for primitive in mesh.primitives: + if primitive.indices is None: + continue + + # Read current indices + indices = read_accessor_data(gltf, primitive.indices, bytes(buffer_data)) + num_triangles = len(indices) // 3 + + # Filter out problematic triangles + new_indices = [] + for tri_idx in range(num_triangles): + global_tri_idx = face_offset + tri_idx + if global_tri_idx not in triangles_to_remove: + start = tri_idx * 3 + new_indices.extend(indices[start:start + 3]) + + face_offset += num_triangles + + if len(new_indices) == len(indices): + # No triangles removed from this primitive + continue + + new_indices = np.array(new_indices, dtype=np.uint32) + + # Get accessor and buffer view info + accessor = gltf.accessors[primitive.indices] + buffer_view = gltf.bufferViews[accessor.bufferView] + + # Determine the component type and size + _, component_size, _ = COMPONENT_TYPES[accessor.componentType] + + # Pack new indices + if accessor.componentType == 5123: # UNSIGNED_SHORT + new_indices_bytes = new_indices.astype(np.uint16).tobytes() + elif accessor.componentType == 5125: # UNSIGNED_INT + new_indices_bytes = new_indices.astype(np.uint32).tobytes() + else: + new_indices_bytes = new_indices.astype(np.uint16).tobytes() + + # Calculate offset + byte_offset = (buffer_view.byteOffset or 0) + (accessor.byteOffset or 0) + + # Update the buffer with new indices + # Note: This assumes the new indices are smaller or equal in size + old_size = accessor.count * component_size + new_size = len(new_indices) * component_size + + if new_size <= old_size: + # Write new indices in place + buffer_data[byte_offset:byte_offset + new_size] = new_indices_bytes + + # Update accessor count + accessor.count = len(new_indices) + + # Update buffer view length + buffer_view.byteLength = new_size + else: + # This shouldn't happen since we're removing triangles + print(f"Warning: New indices larger than old, skipping update") + + return bytes(buffer_data) + + +# ============================================================================= +# Main Processing Function +# ============================================================================= + +def split_mesh(input_path: Path, output_path: Path, + threshold: int = GEODESIC_DISTANCE_THRESHOLD) -> None: + """ + Split mesh by removing triangles that span far-apart bones. + + Args: + input_path: Path to input GLB file + output_path: Path to output GLB file + threshold: Maximum allowed geodesic distance between bones + """ + if type(input_path) == str: + input_path = Path(input_path) + if type(output_path) == str: + output_path = Path(output_path) + + print(f"Loading: {input_path}") + + # Load GLB + gltf = GLTF2().load(str(input_path)) + buffer_data = get_buffer_data(gltf) + + # Read mesh data + print("Reading mesh data...") + vertices, faces = read_mesh_data(gltf, 0, buffer_data) + print(f" Vertices: {len(vertices)}") + print(f" Triangles: {len(faces)}") + + # Read skinning data + print("Reading skinning data...") + joints, weights = read_skinning_data(gltf, 0, buffer_data) + + if joints is None or weights is None: + print("ERROR: No skinning data found in mesh") + return + + print(f" Skinning data: {joints.shape}") + + # Build skeleton graph + print("Building skeleton graph...") + skeleton_graph, joint_indices = build_skeleton_graph(gltf) + print(f" Joints: {len(joint_indices)}") + print(f" Bones (edges): {skeleton_graph.number_of_edges()}") + + # Print skeleton structure + print(" Skeleton hierarchy:") + for joint_idx in joint_indices: + node = gltf.nodes[joint_idx] + name = node.name or f"Joint_{joint_idx}" + children = node.children or [] + child_names = [gltf.nodes[c].name or f"Joint_{c}" for c in children if c in joint_indices] + if child_names: + print(f" {name} -> {', '.join(child_names)}") + + # Compute geodesic distances + print("Computing geodesic distances...") + geodesic_distances = compute_geodesic_distances(skeleton_graph, joint_indices) + + # Identify problematic triangles + print(f"Identifying problematic triangles (threshold={threshold})...") + problematic, problematic_verts = identify_problematic_triangles( + faces, joints, weights, joint_indices, geodesic_distances, threshold + ) + print(f" Problematic triangles: {len(problematic)} / {len(faces)} ({100*len(problematic)/len(faces):.2f}%)") + + # Debug: show some examples of problematic vertices + if problematic_verts: + print(f"\n Sample problematic vertices (showing up to 5):") + skin_to_node = {i: joint_indices[i] for i in range(len(joint_indices))} + for idx, vert_idx in enumerate(list(problematic_verts)[:5]): + vert_joints = joints[vert_idx] + vert_weights = weights[vert_idx] + joint_info = [] + for i in range(4): + if vert_weights[i] > 0.01: + skin_idx = int(vert_joints[i]) + if skin_idx < len(joint_indices): + node_idx = skin_to_node[skin_idx] + name = gltf.nodes[node_idx].name or f"Joint_{node_idx}" + joint_info.append(f"{name}:{vert_weights[i]:.2f}") + print(f" Vertex {vert_idx}: {', '.join(joint_info)}") + + if len(problematic) == 0: + print("No problematic triangles found, saving unchanged mesh...") + output_path.parent.mkdir(parents=True, exist_ok=True) + gltf.save(str(output_path)) + print(f"Saved to: {output_path}") + return + + # Find edge vertices (on the boundary of removed regions) + print("Finding edge vertices...") + edge_vertices, removed_only = find_edge_vertices(faces, problematic) + print(f" Edge vertices: {len(edge_vertices)}") + print(f" Orphaned vertices (in removed triangles only): {len(removed_only)}") + + # Expand to include neighbors for smoother transition + print("Expanding to neighbor vertices...") + vertices_to_clean = find_neighbor_vertices(faces, edge_vertices, problematic, hops=2) + print(f" Vertices to clean (including 2-hop neighbors): {len(vertices_to_clean)}") + + # Clean edge vertex weights + print("Cleaning edge vertex weights...") + new_weights = clean_edge_vertex_weights( + joints, weights, vertices_to_clean, joint_indices, geodesic_distances, threshold + ) + + # Update weights in buffer + print("Updating weights in buffer...") + buffer_data = update_weights_in_buffer(gltf, 0, new_weights, buffer_data) + + # Rebuild mesh without problematic triangles + print("Rebuilding mesh...") + new_buffer_data = rebuild_mesh_without_triangles(gltf, 0, problematic, buffer_data) + + # Update buffer + set_binary_blob(gltf, new_buffer_data) + + # Save result + output_path.parent.mkdir(parents=True, exist_ok=True) + gltf.save(str(output_path)) + print(f"Saved to: {output_path}") + + # Summary + remaining = len(faces) - len(problematic) + print(f"\nSummary:") + print(f" Original triangles: {len(faces)}") + print(f" Removed triangles: {len(problematic)}") + print(f" Remaining triangles: {remaining}") diff --git a/anigen/utils/model_utils.py b/anigen/utils/model_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..abbeed574ef9c4d695e5aa18d577cea09c61722c --- /dev/null +++ b/anigen/utils/model_utils.py @@ -0,0 +1,109 @@ +import os +import json +import torch +from easydict import EasyDict as edict +from anigen import models + +def load_model_from_path(path, model_name_in_config=None, device='cuda', use_ema=False): + if os.path.isdir(path): + config_path = os.path.join(path, 'config.json') + if not os.path.exists(config_path): + raise ValueError(f"Config file not found in {path}") + with open(config_path, 'r') as f: + config = json.load(f) + config = edict(config) + + ckpt_dir = os.path.join(path, 'ckpts') + if not os.path.exists(ckpt_dir): + raise ValueError(f"Checkpoints directory not found in {path}") + + files = os.listdir(ckpt_dir) + pt_files = [f for f in files if f.endswith('.pt')] + if not pt_files: + raise ValueError(f"No .pt files found in {ckpt_dir}") + + def get_step(name): + try: + return int(name.split('step')[-1].split('.')[0]) + except: + return -1 + + # Filter for EMA if requested + if use_ema: + ema_files = [f for f in pt_files if 'ema' in f] + if ema_files: + pt_files = ema_files + print("Selected EMA checkpoint.") + else: + print("Warning: EMA checkpoint requested but not found. Falling back to regular checkpoint.") + pt_files = [f for f in pt_files if 'ema' not in f and 'misc' not in f] + else: + # Exclude 'misc' checkpoints which contain optimizer state, not model weights + non_ema_files = [f for f in pt_files if 'ema' not in f and 'misc' not in f] + if non_ema_files: + pt_files = non_ema_files + print("Selected regular checkpoint.") + else: + print("Warning: Regular checkpoint not found. Falling back to EMA checkpoint.") + pt_files = [f for f in pt_files if 'ema' in f] + + pt_files.sort(key=get_step, reverse=True) + ckpt_path = os.path.join(ckpt_dir, pt_files[0]) + print(f"Loading checkpoint: {ckpt_path}") + + if model_name_in_config: + model_config = config.models[model_name_in_config] + else: + keys = list(config.models.keys()) + # Heuristic: prefer 'denoiser' or 'flow_model' + if 'denoiser' in keys: + model_config = config.models['denoiser'] + elif len(keys) == 1: + model_config = config.models[keys[0]] + else: + raise ValueError(f"Multiple models in config {keys}, please specify model_name_in_config") + + model = getattr(models, model_config.name)(**model_config.args) + state_dict = torch.load(ckpt_path, map_location='cpu') + + if list(state_dict.keys())[0].startswith('module.'): + state_dict = {k[7:]: v for k, v in state_dict.items()} + + model.load_state_dict(state_dict, strict=False) + model.to(device) + model.eval() + return model, config + else: + raise ValueError("Please provide a directory containing config.json and ckpts/") + +def load_decoder(path, ckpt_name, device): + if not os.path.exists(path): + raise ValueError(f"Decoder path not found: {path}") + + config_path = os.path.join(path, 'config.json') + if not os.path.exists(config_path): + raise ValueError(f"Config file not found in {path}") + + with open(config_path, 'r') as f: + cfg = json.load(f) + + if 'models' not in cfg or 'decoder' not in cfg['models']: + raise ValueError(f"Config at {path} does not have ['models']['decoder']") + + model_cfg = cfg['models']['decoder'] + decoder = getattr(models, model_cfg['name'])(**model_cfg['args']) + + ckpt_path = os.path.join(path, 'ckpts', f'decoder_{ckpt_name}.pt') + if not os.path.exists(ckpt_path): + # Fallback to just ckpt_name if decoder_ prefix not found + ckpt_path = os.path.join(path, 'ckpts', f'{ckpt_name}.pt') + if not os.path.exists(ckpt_path): + raise ValueError(f"Checkpoint not found: {ckpt_path}") + + print(f"Loading decoder from {ckpt_path}") + state_dict = torch.load(ckpt_path, map_location='cpu') + if list(state_dict.keys())[0].startswith('module.'): + state_dict = {k[7:]: v for k, v in state_dict.items()} + decoder.load_state_dict(state_dict, strict=False) + decoder.to(device).eval() + return decoder diff --git a/anigen/utils/optimizer_utils.py b/anigen/utils/optimizer_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..168a6f5540f9c2a58d32aa6a729783c795d9c2f7 --- /dev/null +++ b/anigen/utils/optimizer_utils.py @@ -0,0 +1,226 @@ +""" +Optimizer utilities for PyTorch Lightning systems. +""" + +import torch +import torch.nn as nn +from typing import Dict, List, Any + + +def create_muon_optimizer(models: Dict[str, nn.Module], optimizer_args: Dict[str, Any]): + """ + Create Muon optimizer with different learning rates for different parameters. + + Args: + models: Dictionary of models + optimizer_args: Optimizer configuration with muon_lr, muon_weight_decay, + other_lr, other_weight_decay + + Returns: + Configured optimizer + """ + muon_lr = optimizer_args.get('muon_lr', 0.02) + muon_weight_decay = optimizer_args.get('muon_weight_decay', 0.01) + other_lr = optimizer_args.get('other_lr', 1e-4) + other_weight_decay = optimizer_args.get('other_weight_decay', 0.01) + + # Separate parameters for Muon and other optimizers + muon_params = [] + other_params = [] + + for name, model in models.items(): + for param_name, param in model.named_parameters(): + if not param.requires_grad: + continue + + # Define which parameters should use Muon optimizer + # This is a heuristic - adjust based on your model architecture + if ('weight' in param_name and + param.dim() >= 2 and + param.numel() >= 1024): # Large weight matrices + muon_params.append(param) + else: + other_params.append(param) + + # Try to import and use Muon optimizer + try: + from muon import Muon + + # Create parameter groups + param_groups = [] + + if muon_params: + param_groups.append({ + 'params': muon_params, + 'lr': muon_lr, + 'weight_decay': muon_weight_decay, + 'momentum': 0.95, # Muon-specific parameter + }) + + if other_params: + param_groups.append({ + 'params': other_params, + 'lr': other_lr, + 'weight_decay': other_weight_decay, + }) + + return Muon(param_groups) + + except ImportError: + print("Warning: Muon optimizer not available. Falling back to AdamW.") + # Fallback to AdamW with combined parameters + all_params = muon_params + other_params + return torch.optim.AdamW(all_params, lr=other_lr, weight_decay=other_weight_decay) + + +def create_optimizer(models: Dict[str, nn.Module], optimizer_config: Dict[str, Any]): + """ + Create optimizer based on configuration. + + Args: + models: Dictionary of models + optimizer_config: Optimizer configuration + + Returns: + Configured optimizer + """ + optimizer_name = optimizer_config.get('name', 'Adam').lower() + optimizer_args = optimizer_config.get('args', {}) + + # Get all parameters + params = [] + for model in models.values(): + params.extend([p for p in model.parameters() if p.requires_grad]) + + if optimizer_name == 'adam': + return torch.optim.Adam(params, **optimizer_args) + elif optimizer_name == 'adamw': + return torch.optim.AdamW(params, **optimizer_args) + elif optimizer_name == 'sgd': + return torch.optim.SGD(params, **optimizer_args) + elif optimizer_name == 'muon': + return create_muon_optimizer(models, optimizer_args) + else: + raise ValueError(f"Unknown optimizer: {optimizer_name}") + + +def create_lr_scheduler(optimizer, lr_scheduler_config: Dict[str, Any]): + """ + Create learning rate scheduler based on configuration. + + Args: + optimizer: The optimizer to schedule + lr_scheduler_config: Scheduler configuration + + Returns: + Configured scheduler + """ + scheduler_name = lr_scheduler_config.get('name', 'CosineAnnealingLR') + scheduler_args = lr_scheduler_config.get('args', {}) + + if scheduler_name == 'CosineAnnealingLR': + return torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, **scheduler_args) + elif scheduler_name == 'LinearLR': + return torch.optim.lr_scheduler.LinearLR(optimizer, **scheduler_args) + elif scheduler_name == 'ExponentialLR': + return torch.optim.lr_scheduler.ExponentialLR(optimizer, **scheduler_args) + elif scheduler_name == 'StepLR': + return torch.optim.lr_scheduler.StepLR(optimizer, **scheduler_args) + elif scheduler_name == 'MultiStepLR': + return torch.optim.lr_scheduler.MultiStepLR(optimizer, **scheduler_args) + elif scheduler_name == 'SequentialLR': + # Handle sequential scheduler + schedulers = [] + for sched_config in lr_scheduler_config['schedulers']: + sched = create_single_scheduler(sched_config, optimizer) + schedulers.append(sched) + return torch.optim.lr_scheduler.SequentialLR( + optimizer, schedulers, **scheduler_args + ) + else: + raise ValueError(f"Unknown scheduler: {scheduler_name}") + + +def create_single_scheduler(scheduler_config: Dict[str, Any], optimizer): + """Create a single scheduler for SequentialLR.""" + name = scheduler_config['name'] + args = scheduler_config['args'] + + if name == 'LinearLR': + return torch.optim.lr_scheduler.LinearLR(optimizer, **args) + elif name == 'CosineAnnealingLR': + return torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, **args) + elif name == 'ExponentialLR': + return torch.optim.lr_scheduler.ExponentialLR(optimizer, **args) + elif name == 'StepLR': + return torch.optim.lr_scheduler.StepLR(optimizer, **args) + elif name == 'MultiStepLR': + return torch.optim.lr_scheduler.MultiStepLR(optimizer, **args) + else: + raise ValueError(f"Unknown scheduler: {name}") + + +class AdaptiveGradClipper: + """ + Adaptive gradient clipping based on percentile of gradient norms. + """ + + def __init__(self, max_norm: float = 1.0, clip_percentile: float = 95): + self.max_norm = max_norm + self.clip_percentile = clip_percentile + self.grad_norms_history = [] + self.history_size = 1000 + + def __call__(self, parameters): + """Apply adaptive gradient clipping.""" + if isinstance(parameters, torch.Tensor): + parameters = [parameters] + parameters = [p for p in parameters if p.grad is not None] + + if not parameters: + return torch.tensor(0.0) + + # Calculate gradient norm + total_norm = torch.norm( + torch.stack([torch.norm(p.grad.detach()) for p in parameters]) + ) + + # Update history + self.grad_norms_history.append(total_norm.item()) + if len(self.grad_norms_history) > self.history_size: + self.grad_norms_history.pop(0) + + # Calculate adaptive threshold + if len(self.grad_norms_history) >= 10: + threshold = torch.quantile( + torch.tensor(self.grad_norms_history), + self.clip_percentile / 100.0 + ) + clip_value = min(self.max_norm, threshold.item()) + else: + clip_value = self.max_norm + + # Apply clipping + if total_norm > clip_value: + clip_coef = clip_value / (total_norm + 1e-6) + for p in parameters: + p.grad.detach().mul_(clip_coef) + + return total_norm + + +def create_grad_clipper(grad_clip_config: Dict[str, Any]): + """Create gradient clipper based on configuration.""" + if grad_clip_config is None: + return None + + name = grad_clip_config.get('name', 'norm') + args = grad_clip_config.get('args', {}) + + if name.lower() == 'norm': + max_norm = args.get('max_norm', 1.0) + return lambda params: torch.nn.utils.clip_grad_norm_(params, max_norm) + elif name.lower() == 'adaptivegradclipper': + return AdaptiveGradClipper(**args) + else: + raise ValueError(f"Unknown gradient clipper: {name}") diff --git a/anigen/utils/outpainting.py b/anigen/utils/outpainting.py new file mode 100644 index 0000000000000000000000000000000000000000..faecfa70310dadbbe0be0682e7006ba230d54de2 --- /dev/null +++ b/anigen/utils/outpainting.py @@ -0,0 +1,38 @@ +import torch +import numpy as np + +def voxels_to_mesh(voxels): + """ + Convert voxel integer coordinates into a triangle mesh. + + Args: + voxels (torch.Tensor): Tensor of shape [N, 3] indicating voxel integer coordinates. + + Returns: + Tuple[np.ndarray, np.ndarray]: Vertices of shape [8*N, 3] and faces of shape [6*2*N, 3]. + """ + if isinstance(voxels, torch.Tensor): + voxels = voxels.cpu().numpy() + cube_vertices = np.array([ + [0, 0, 0], + [1, 0, 0], + [1, 1, 0], + [0, 1, 0], + [0, 0, 1], + [1, 0, 1], + [1, 1, 1], + [0, 1, 1], + ]) + cube_faces = np.array([ + [0, 1, 2], [0, 2, 3], # Bottom face + [4, 5, 6], [4, 6, 7], # Top face + [0, 1, 5], [0, 5, 4], # Front face + [2, 3, 7], [2, 7, 6], # Back face + [1, 2, 6], [1, 6, 5], # Right face + [0, 3, 7], [0, 7, 4], # Left face + ]) + N = voxels.shape[0] + voxel_vertices = (voxels[:, None, :] + cube_vertices[None, :, :]).reshape(-1, 3) + voxel_faces = (np.arange(N)[:, None, None] * 8 + cube_faces[None, :, :]).reshape(-1, 3) + return voxel_vertices, voxel_faces + diff --git a/anigen/utils/postprocessing_utils.py b/anigen/utils/postprocessing_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c46a6bd486a265d5ffe323cefa594d41c382c97b --- /dev/null +++ b/anigen/utils/postprocessing_utils.py @@ -0,0 +1,847 @@ +from typing import * +import numpy as np +import torch +import utils3d +import nvdiffrast.torch as dr +from tqdm import tqdm +import trimesh +import trimesh.visual +import xatlas +import pyvista as pv +from pymeshfix import _meshfix +import igraph +import cv2 +from PIL import Image +from .random_utils import sphere_hammersley_sequence +from .render_utils import render_multiview +from ..renderers import GaussianRenderer +from ..representations import Strivec, Gaussian, MeshExtractResult + + +@torch.no_grad() +def _fill_holes( + verts, + faces, + max_hole_size=0.04, + max_hole_nbe=32, + resolution=128, + num_views=500, + debug=False, + verbose=False +): + """ + Rasterize a mesh from multiple views and remove invisible faces. + Also includes postprocessing to: + 1. Remove connected components that are have low visibility. + 2. Mincut to remove faces at the inner side of the mesh connected to the outer side with a small hole. + + Args: + verts (torch.Tensor): Vertices of the mesh. Shape (V, 3). + faces (torch.Tensor): Faces of the mesh. Shape (F, 3). + max_hole_size (float): Maximum area of a hole to fill. + resolution (int): Resolution of the rasterization. + num_views (int): Number of views to rasterize the mesh. + verbose (bool): Whether to print progress. + """ + # Construct cameras + yaws = [] + pitchs = [] + for i in range(num_views): + y, p = sphere_hammersley_sequence(i, num_views) + yaws.append(y) + pitchs.append(p) + yaws = torch.tensor(yaws).cuda() + pitchs = torch.tensor(pitchs).cuda() + radius = 2.0 + fov = torch.deg2rad(torch.tensor(40)).cuda() + projection = utils3d.torch.perspective_from_fov_xy(fov, fov, 1, 3) + views = [] + for (yaw, pitch) in zip(yaws, pitchs): + orig = torch.tensor([ + torch.sin(yaw) * torch.cos(pitch), + torch.cos(yaw) * torch.cos(pitch), + torch.sin(pitch), + ]).cuda().float() * radius + view = utils3d.torch.view_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + views.append(view) + views = torch.stack(views, dim=0) + + # Rasterize + visblity = torch.zeros(faces.shape[0], dtype=torch.int32, device=verts.device) + rastctx = utils3d.torch.RastContext(backend='cuda') + for i in tqdm(range(views.shape[0]), total=views.shape[0], disable=not verbose, desc='Rasterizing'): + view = views[i] + buffers = utils3d.torch.rasterize_triangle_faces( + rastctx, verts[None], faces, resolution, resolution, view=view, projection=projection + ) + face_id = buffers['face_id'][0][buffers['mask'][0] > 0.95] - 1 + face_id = torch.unique(face_id).long() + visblity[face_id] += 1 + visblity = visblity.float() / num_views + + # Mincut + ## construct outer faces + edges, face2edge, edge_degrees = utils3d.torch.compute_edges(faces) + boundary_edge_indices = torch.nonzero(edge_degrees == 1).reshape(-1) + connected_components = utils3d.torch.compute_connected_components(faces, edges, face2edge) + outer_face_indices = torch.zeros(faces.shape[0], dtype=torch.bool, device=faces.device) + for i in range(len(connected_components)): + outer_face_indices[connected_components[i]] = visblity[connected_components[i]] > min(max(visblity[connected_components[i]].quantile(0.75).item(), 0.25), 0.5) + outer_face_indices = outer_face_indices.nonzero().reshape(-1) + + ## construct inner faces + inner_face_indices = torch.nonzero(visblity == 0).reshape(-1) + if verbose: + tqdm.write(f'Found {inner_face_indices.shape[0]} invisible faces') + if inner_face_indices.shape[0] == 0: + return verts, faces + + ## Construct dual graph (faces as nodes, edges as edges) + dual_edges, dual_edge2edge = utils3d.torch.compute_dual_graph(face2edge) + dual_edge2edge = edges[dual_edge2edge] + dual_edges_weights = torch.norm(verts[dual_edge2edge[:, 0]] - verts[dual_edge2edge[:, 1]], dim=1) + if verbose: + tqdm.write(f'Dual graph: {dual_edges.shape[0]} edges') + + ## solve mincut problem + ### construct main graph + g = igraph.Graph() + g.add_vertices(faces.shape[0]) + g.add_edges(dual_edges.cpu().numpy()) + g.es['weight'] = dual_edges_weights.cpu().numpy() + + ### source and target + g.add_vertex('s') + g.add_vertex('t') + + ### connect invisible faces to source + g.add_edges([(f, 's') for f in inner_face_indices], attributes={'weight': torch.ones(inner_face_indices.shape[0], dtype=torch.float32).cpu().numpy()}) + + ### connect outer faces to target + g.add_edges([(f, 't') for f in outer_face_indices], attributes={'weight': torch.ones(outer_face_indices.shape[0], dtype=torch.float32).cpu().numpy()}) + + ### solve mincut + cut = g.mincut('s', 't', (np.array(g.es['weight']) * 1000).tolist()) + remove_face_indices = torch.tensor([v for v in cut.partition[0] if v < faces.shape[0]], dtype=torch.long, device=faces.device) + if verbose: + tqdm.write(f'Mincut solved, start checking the cut') + + ### check if the cut is valid with each connected component + to_remove_cc = utils3d.torch.compute_connected_components(faces[remove_face_indices]) + if debug: + tqdm.write(f'Number of connected components of the cut: {len(to_remove_cc)}') + valid_remove_cc = [] + cutting_edges = [] + for cc in to_remove_cc: + #### check if the connected component has low visibility + visblity_median = visblity[remove_face_indices[cc]].median() + if debug: + tqdm.write(f'visblity_median: {visblity_median}') + if visblity_median > 0.25: + continue + + #### check if the cuting loop is small enough + cc_edge_indices, cc_edges_degree = torch.unique(face2edge[remove_face_indices[cc]], return_counts=True) + cc_boundary_edge_indices = cc_edge_indices[cc_edges_degree == 1] + cc_new_boundary_edge_indices = cc_boundary_edge_indices[~torch.isin(cc_boundary_edge_indices, boundary_edge_indices)] + if len(cc_new_boundary_edge_indices) > 0: + cc_new_boundary_edge_cc = utils3d.torch.compute_edge_connected_components(edges[cc_new_boundary_edge_indices]) + cc_new_boundary_edges_cc_center = [verts[edges[cc_new_boundary_edge_indices[edge_cc]]].mean(dim=1).mean(dim=0) for edge_cc in cc_new_boundary_edge_cc] + cc_new_boundary_edges_cc_area = [] + for i, edge_cc in enumerate(cc_new_boundary_edge_cc): + _e1 = verts[edges[cc_new_boundary_edge_indices[edge_cc]][:, 0]] - cc_new_boundary_edges_cc_center[i] + _e2 = verts[edges[cc_new_boundary_edge_indices[edge_cc]][:, 1]] - cc_new_boundary_edges_cc_center[i] + cc_new_boundary_edges_cc_area.append(torch.norm(torch.cross(_e1, _e2, dim=-1), dim=1).sum() * 0.5) + if debug: + cutting_edges.append(cc_new_boundary_edge_indices) + tqdm.write(f'Area of the cutting loop: {cc_new_boundary_edges_cc_area}') + if any([l > max_hole_size for l in cc_new_boundary_edges_cc_area]): + continue + + valid_remove_cc.append(cc) + + if debug: + face_v = verts[faces].mean(dim=1).cpu().numpy() + vis_dual_edges = dual_edges.cpu().numpy() + vis_colors = np.zeros((faces.shape[0], 3), dtype=np.uint8) + vis_colors[inner_face_indices.cpu().numpy()] = [0, 0, 255] + vis_colors[outer_face_indices.cpu().numpy()] = [0, 255, 0] + vis_colors[remove_face_indices.cpu().numpy()] = [255, 0, 255] + if len(valid_remove_cc) > 0: + vis_colors[remove_face_indices[torch.cat(valid_remove_cc)].cpu().numpy()] = [255, 0, 0] + utils3d.io.write_ply('dbg_dual.ply', face_v, edges=vis_dual_edges, vertex_colors=vis_colors) + + vis_verts = verts.cpu().numpy() + vis_edges = edges[torch.cat(cutting_edges)].cpu().numpy() + utils3d.io.write_ply('dbg_cut.ply', vis_verts, edges=vis_edges) + + + if len(valid_remove_cc) > 0: + remove_face_indices = remove_face_indices[torch.cat(valid_remove_cc)] + mask = torch.ones(faces.shape[0], dtype=torch.bool, device=faces.device) + mask[remove_face_indices] = 0 + faces = faces[mask] + faces, verts = utils3d.torch.remove_unreferenced_vertices(faces, verts) + if verbose: + tqdm.write(f'Removed {(~mask).sum()} faces by mincut') + else: + if verbose: + tqdm.write(f'Removed 0 faces by mincut') + + mesh = _meshfix.PyTMesh() + mesh.load_array(verts.cpu().numpy(), faces.cpu().numpy()) + mesh.fill_small_boundaries(nbe=max_hole_nbe, refine=True) + verts, faces = mesh.return_arrays() + verts, faces = torch.tensor(verts, device='cuda', dtype=torch.float32), torch.tensor(faces, device='cuda', dtype=torch.int32) + + return verts, faces + + +def postprocess_mesh( + vertices: np.array, + faces: np.array, + simplify: bool = True, + simplify_ratio: float = 0.9, + fill_holes: bool = True, + fill_holes_max_hole_size: float = 0.04, + fill_holes_max_hole_nbe: int = 32, + fill_holes_resolution: int = 1024, + fill_holes_num_views: int = 1000, + debug: bool = False, + verbose: bool = False, +): + """ + Postprocess a mesh by simplifying, removing invisible faces, and removing isolated pieces. + + Args: + vertices (np.array): Vertices of the mesh. Shape (V, 3). + faces (np.array): Faces of the mesh. Shape (F, 3). + simplify (bool): Whether to simplify the mesh, using quadric edge collapse. + simplify_ratio (float): Ratio of faces to keep after simplification. + fill_holes (bool): Whether to fill holes in the mesh. + fill_holes_max_hole_size (float): Maximum area of a hole to fill. + fill_holes_max_hole_nbe (int): Maximum number of boundary edges of a hole to fill. + fill_holes_resolution (int): Resolution of the rasterization. + fill_holes_num_views (int): Number of views to rasterize the mesh. + verbose (bool): Whether to print progress. + """ + + if verbose: + tqdm.write(f'Before postprocess: {vertices.shape[0]} vertices, {faces.shape[0]} faces') + + # Simplify + if simplify and simplify_ratio > 0: + mesh = pv.PolyData(vertices, np.concatenate([np.full((faces.shape[0], 1), 3), faces], axis=1)) + mesh = mesh.decimate(simplify_ratio, progress_bar=verbose) + vertices, faces = mesh.points, mesh.faces.reshape(-1, 4)[:, 1:] + if verbose: + tqdm.write(f'After decimate: {vertices.shape[0]} vertices, {faces.shape[0]} faces') + + # Remove invisible faces + if fill_holes: + vertices, faces = torch.tensor(vertices).cuda(), torch.tensor(faces.astype(np.int32)).cuda() + vertices, faces = _fill_holes( + vertices, faces, + max_hole_size=fill_holes_max_hole_size, + max_hole_nbe=fill_holes_max_hole_nbe, + resolution=fill_holes_resolution, + num_views=fill_holes_num_views, + debug=debug, + verbose=verbose, + ) + vertices, faces = vertices.cpu().numpy(), faces.cpu().numpy() + if verbose: + tqdm.write(f'After remove invisible faces: {vertices.shape[0]} vertices, {faces.shape[0]} faces') + + return vertices, faces + + +def barycentric_transfer_attributes( + src_mesh: trimesh.Trimesh, + src_attrs: np.ndarray, + dst_vertices: np.ndarray, +) -> np.ndarray: + """ + Transfer per-vertex attributes from a source mesh to new vertices via + barycentric interpolation on the closest triangle. + + Args: + src_mesh (trimesh.Trimesh): Source mesh (must have faces). + src_attrs (np.ndarray): Per-vertex attributes on the source mesh. Shape (V_src, C). + dst_vertices (np.ndarray): Destination vertex positions. Shape (V_dst, 3). + + Returns: + np.ndarray: Interpolated attributes for each destination vertex. Shape (V_dst, C). + """ + src_attrs = np.asarray(src_attrs, dtype=np.float64) + dst_vertices = np.asarray(dst_vertices, dtype=np.float64) + + closest_points, _, triangle_ids = trimesh.proximity.closest_point(src_mesh, dst_vertices) + + face_indices = src_mesh.faces[triangle_ids] # (N, 3) + v0 = src_mesh.vertices[face_indices[:, 0]].astype(np.float64) + v1 = src_mesh.vertices[face_indices[:, 1]].astype(np.float64) + v2 = src_mesh.vertices[face_indices[:, 2]].astype(np.float64) + + # Barycentric coordinates via dot-product method + e0 = v1 - v0 + e1 = v2 - v0 + w = closest_points.astype(np.float64) - v0 + + d00 = np.sum(e0 * e0, axis=1) + d01 = np.sum(e0 * e1, axis=1) + d11 = np.sum(e1 * e1, axis=1) + d20 = np.sum(w * e0, axis=1) + d21 = np.sum(w * e1, axis=1) + + denom = d00 * d11 - d01 * d01 + denom = np.where(np.abs(denom) < 1e-12, 1e-12, denom) + + b1 = (d11 * d20 - d01 * d21) / denom + b2 = (d00 * d21 - d01 * d20) / denom + b0 = 1.0 - b1 - b2 + + bary = np.stack([b0, b1, b2], axis=1) # (N, 3) + np.clip(bary, 0.0, None, out=bary) + bary_sum = bary.sum(axis=1, keepdims=True) + bary_sum = np.maximum(bary_sum, 1e-12) + bary /= bary_sum + + a0 = src_attrs[face_indices[:, 0]] + a1 = src_attrs[face_indices[:, 1]] + a2 = src_attrs[face_indices[:, 2]] + + result = bary[:, 0:1] * a0 + bary[:, 1:2] * a1 + bary[:, 2:3] * a2 + return result.astype(np.float32) + + +def parametrize_mesh(vertices: np.array, faces: np.array): + """ + Parametrize a mesh to a texture space, using xatlas. + + Args: + vertices (np.array): Vertices of the mesh. Shape (V, 3). + faces (np.array): Faces of the mesh. Shape (F, 3). + + Returns: + vertices, faces, uvs, vmapping + vmapping maps new vertex indices back to original vertex indices + (new vertices may be duplicated at UV seams). + """ + + vmapping, indices, uvs = xatlas.parametrize(vertices, faces) + + vertices = vertices[vmapping] + faces = indices + + return vertices, faces, uvs, vmapping + + +@torch.no_grad() +def bake_vertex_colors_to_texture( + dense_vertices: np.ndarray, + dense_faces: np.ndarray, + dense_vertex_colors: np.ndarray, + simp_vertices: np.ndarray, + simp_faces: np.ndarray, + simp_uvs: np.ndarray, + texture_size: int = 1024, +) -> np.ndarray: + """ + Bake per-vertex colors from a dense mesh into a UV-mapped texture on a + simplified mesh. + + For each texel covered by the simplified mesh in UV space, the 3D position + is computed via nvdiffrast interpolation, then the closest point on the + dense mesh is queried and its vertex color is barycentric-interpolated. + + Args: + dense_vertices (np.ndarray): Dense mesh vertices. Shape (Vd, 3). + dense_faces (np.ndarray): Dense mesh faces. Shape (Fd, 3). + dense_vertex_colors (np.ndarray): Per-vertex RGB in [0,1]. Shape (Vd, 3). + simp_vertices (np.ndarray): Simplified (UV-split) mesh vertices. Shape (Vs, 3). + simp_faces (np.ndarray): Simplified mesh faces. Shape (Fs, 3). + simp_uvs (np.ndarray): UV coordinates for simplified mesh. Shape (Vs, 2). + texture_size (int): Output texture resolution (square). + + Returns: + np.ndarray: Baked texture image, shape (texture_size, texture_size, 3), uint8. + """ + device = 'cuda' + verts_t = torch.tensor(simp_vertices, dtype=torch.float32, device=device) + faces_t = torch.tensor(simp_faces.astype(np.int32), dtype=torch.int32, device=device) + uvs_t = torch.tensor(simp_uvs, dtype=torch.float32, device=device) + + # Map UVs to clip space for nvdiffrast: [0,1] -> [-1,1], z=0, w=1 + uv_clip = torch.zeros(uvs_t.shape[0], 4, dtype=torch.float32, device=device) + uv_clip[:, 0] = uvs_t[:, 0] * 2.0 - 1.0 + uv_clip[:, 1] = uvs_t[:, 1] * 2.0 - 1.0 + uv_clip[:, 2] = 0.0 + uv_clip[:, 3] = 1.0 + + glctx = dr.RasterizeCudaContext() + rast_out, _ = dr.rasterize(glctx, uv_clip[None], faces_t, resolution=[texture_size, texture_size]) + + # Interpolate 3D positions at each texel + pos_map, _ = dr.interpolate(verts_t[None].contiguous(), rast_out, faces_t) + # pos_map: (1, H, W, 3) + + mask = (rast_out[0, :, :, 3] > 0) # (H, W) + positions = pos_map[0][mask].cpu().numpy() # (N, 3) + + # Query dense mesh for closest-point colors + dense_mesh = trimesh.Trimesh(vertices=dense_vertices, faces=dense_faces, process=False) + closest_pts, _, tri_ids = trimesh.proximity.closest_point(dense_mesh, positions) + + face_verts = dense_faces[tri_ids] # (N, 3) + v0 = dense_vertices[face_verts[:, 0]] + v1 = dense_vertices[face_verts[:, 1]] + v2 = dense_vertices[face_verts[:, 2]] + + e0 = v1 - v0 + e1 = v2 - v0 + w = closest_pts - v0 + d00 = np.sum(e0 * e0, axis=1) + d01 = np.sum(e0 * e1, axis=1) + d11 = np.sum(e1 * e1, axis=1) + d20 = np.sum(w * e0, axis=1) + d21 = np.sum(w * e1, axis=1) + denom = d00 * d11 - d01 * d01 + denom = np.where(np.abs(denom) < 1e-12, 1e-12, denom) + b1 = (d11 * d20 - d01 * d21) / denom + b2 = (d00 * d21 - d01 * d20) / denom + b0 = 1.0 - b1 - b2 + bary = np.stack([b0, b1, b2], axis=1) + np.clip(bary, 0.0, None, out=bary) + bary /= np.maximum(bary.sum(axis=1, keepdims=True), 1e-12) + + c0 = dense_vertex_colors[face_verts[:, 0]] + c1 = dense_vertex_colors[face_verts[:, 1]] + c2 = dense_vertex_colors[face_verts[:, 2]] + colors = bary[:, 0:1] * c0 + bary[:, 1:2] * c1 + bary[:, 2:3] * c2 + + # Write to texture (flip vertically to match image convention) + texture = np.zeros((texture_size, texture_size, 3), dtype=np.float32) + mask_np = mask.cpu().numpy() + texture[mask_np] = colors.astype(np.float32) + texture = np.flipud(texture) + mask_np = np.flipud(mask_np) + texture = np.clip(texture * 255, 0, 255).astype(np.uint8) + + inpaint_mask = (~mask_np).astype(np.uint8) + texture = cv2.inpaint(texture, inpaint_mask, 3, cv2.INPAINT_TELEA) + + return texture + + +@torch.no_grad() +def render_multiview_mesh_colors( + vertices: np.ndarray, + faces: np.ndarray, + vertex_colors: np.ndarray, + resolution: int = 1024, + nviews: int = 100, + near: float = 0.1, + far: float = 10.0, + verbose: bool = True, +): + """ + Render multiview color images from a mesh with per-vertex colors. + + Uses ``utils3d.torch.rasterize_triangle_faces`` โ€” the exact same + rasterisation path that :func:`bake_texture` uses internally โ€” so + the observations are guaranteed to be projection-aligned with the + bake-texture rasterisation. + + Returns: + observations: list of (H, W, 3) uint8 images in standard top-left origin + extrinsics: list of numpy (4, 4) + intrinsics: list of numpy (3, 3) + """ + from .render_utils import yaw_pitch_r_fov_to_extrinsics_intrinsics + + r, fov = 2, 40 + cams = [sphere_hammersley_sequence(i, nviews) for i in range(nviews)] + extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics( + [c[0] for c in cams], [c[1] for c in cams], r, fov, + ) + + verts_t = torch.tensor(vertices, dtype=torch.float32, device='cuda') + faces_t = torch.tensor(faces.astype(np.int32), dtype=torch.int32, device='cuda') + colors_t = torch.tensor(vertex_colors, dtype=torch.float32, device='cuda').clamp(0, 1) + + rastctx = utils3d.torch.RastContext(backend='cuda') + observations = [] + + for extr, intr in tqdm( + zip(extrinsics, intrinsics), total=nviews, + disable=not verbose, desc='Rendering multiview', + ): + view = utils3d.torch.extrinsics_to_view(extr) + proj = utils3d.torch.intrinsics_to_perspective(intr, near, far) + + rast = utils3d.torch.rasterize_triangle_faces( + rastctx, verts_t[None], faces_t, resolution, resolution, + uv=colors_t[None], view=view, projection=proj, + ) + color_img = rast['uv'][0] # (H, W, 3) interpolated vertex colors + mask = rast['mask'][0] > 0.5 + + # rasterisation is in OpenGL bottom-left origin; flip to top-left + color_img = color_img.flip(0).clamp(0, 1) + mask = mask.flip(0) + # zero out background so mask-based workflows stay correct + color_img[~mask] = 0 + + observations.append( + np.clip(color_img.cpu().numpy() * 255, 0, 255).astype(np.uint8) + ) + + extrinsics_np = [e.cpu().numpy() for e in extrinsics] + intrinsics_np = [i.cpu().numpy() for i in intrinsics] + return observations, extrinsics_np, intrinsics_np + + +def bake_texture( + vertices: np.array, + faces: np.array, + uvs: np.array, + observations: List[np.array], + masks: List[np.array], + extrinsics: List[np.array], + intrinsics: List[np.array], + texture_size: int = 2048, + near: float = 0.1, + far: float = 10.0, + mode: Literal['fast', 'opt'] = 'opt', + lambda_tv: float = 1e-2, + verbose: bool = False, +): + """ + Bake texture to a mesh from multiple observations. + + Args: + vertices (np.array): Vertices of the mesh. Shape (V, 3). + faces (np.array): Faces of the mesh. Shape (F, 3). + uvs (np.array): UV coordinates of the mesh. Shape (V, 2). + observations (List[np.array]): List of observations. Each observation is a 2D image. Shape (H, W, 3). + masks (List[np.array]): List of masks. Each mask is a 2D image. Shape (H, W). + extrinsics (List[np.array]): List of extrinsics. Shape (4, 4). + intrinsics (List[np.array]): List of intrinsics. Shape (3, 3). + texture_size (int): Size of the texture. + near (float): Near plane of the camera. + far (float): Far plane of the camera. + mode (Literal['fast', 'opt']): Mode of texture baking. + lambda_tv (float): Weight of total variation loss in optimization. + verbose (bool): Whether to print progress. + """ + vertices = torch.tensor(vertices).cuda() + faces = torch.tensor(faces.astype(np.int32)).cuda() + uvs = torch.tensor(uvs).cuda() + observations = [torch.tensor(obs / 255.0).float().cuda() for obs in observations] + masks = [torch.tensor(m>0).bool().cuda() for m in masks] + views = [utils3d.torch.extrinsics_to_view(torch.tensor(extr).cuda()) for extr in extrinsics] + projections = [utils3d.torch.intrinsics_to_perspective(torch.tensor(intr).cuda(), near, far) for intr in intrinsics] + + if mode == 'fast': + texture = torch.zeros((texture_size * texture_size, 3), dtype=torch.float32).cuda() + texture_weights = torch.zeros((texture_size * texture_size), dtype=torch.float32).cuda() + rastctx = utils3d.torch.RastContext(backend='cuda') + for observation, view, projection in tqdm(zip(observations, views, projections), total=len(observations), disable=not verbose, desc='Texture baking (fast)'): + with torch.no_grad(): + rast = utils3d.torch.rasterize_triangle_faces( + rastctx, vertices[None], faces, observation.shape[1], observation.shape[0], uv=uvs[None], view=view, projection=projection + ) + uv_map = rast['uv'][0].detach().flip(0) + mask = rast['mask'][0].detach().bool() & masks[0] + + # nearest neighbor interpolation + uv_map = (uv_map * texture_size).floor().long() + obs = observation[mask] + uv_map = uv_map[mask] + idx = uv_map[:, 0] + (texture_size - uv_map[:, 1] - 1) * texture_size + texture = texture.scatter_add(0, idx.view(-1, 1).expand(-1, 3), obs) + texture_weights = texture_weights.scatter_add(0, idx, torch.ones((obs.shape[0]), dtype=torch.float32, device=texture.device)) + + mask = texture_weights > 0 + texture[mask] /= texture_weights[mask][:, None] + texture = np.clip(texture.reshape(texture_size, texture_size, 3).cpu().numpy() * 255, 0, 255).astype(np.uint8) + + # inpaint + mask = (texture_weights == 0).cpu().numpy().astype(np.uint8).reshape(texture_size, texture_size) + texture = cv2.inpaint(texture, mask, 3, cv2.INPAINT_TELEA) + + elif mode == 'opt': + rastctx = utils3d.torch.RastContext(backend='cuda') + observations = [observations.flip(0) for observations in observations] + masks = [m.flip(0) for m in masks] + _uv = [] + _uv_dr = [] + for observation, view, projection in tqdm( + zip(observations, views, projections), + total=len(views), + disable=not verbose, + desc='Texture baking (opt): UV', + ): + with torch.no_grad(): + rast = utils3d.torch.rasterize_triangle_faces( + rastctx, + vertices[None], + faces, + observation.shape[1], + observation.shape[0], + uv=uvs[None], + view=view, + projection=projection, + ) + _uv.append(rast['uv'].detach()) + _uv_dr.append(rast['uv_dr'].detach()) + + texture = torch.nn.Parameter( + torch.zeros((1, texture_size, texture_size, 3), dtype=torch.float32).cuda() + ) + optimizer = torch.optim.Adam([texture], betas=(0.5, 0.9), lr=1e-2) + + def exp_anealing(optimizer, step, total_steps, start_lr, end_lr): + return start_lr * (end_lr / start_lr) ** (step / total_steps) + + def cosine_anealing(optimizer, step, total_steps, start_lr, end_lr): + return end_lr + 0.5 * (start_lr - end_lr) * (1 + np.cos(np.pi * step / total_steps)) + + def tv_loss(texture): + return torch.nn.functional.l1_loss( + texture[:, :-1, :, :], texture[:, 1:, :, :] + ) + torch.nn.functional.l1_loss( + texture[:, :, :-1, :], texture[:, :, 1:, :] + ) + + total_steps = 500 + with tqdm( + total=total_steps, + disable=not verbose, + desc='Texture baking (opt): optimizing', + ) as pbar: + for step in range(total_steps): + optimizer.zero_grad() + selected = np.random.randint(0, len(views)) + uv, uv_dr, observation, mask = ( + _uv[selected], + _uv_dr[selected], + observations[selected], + masks[selected], + ) + render = dr.texture(texture, uv, uv_dr)[0] + loss = torch.nn.functional.l1_loss(render[mask], observation[mask]) + if lambda_tv > 0: + loss += lambda_tv * tv_loss(texture) + loss.backward() + optimizer.step() + # annealing + optimizer.param_groups[0]['lr'] = cosine_anealing( + optimizer, step, total_steps, 1e-2, 1e-5 + ) + pbar.set_postfix({'loss': loss.item()}) + pbar.update() + + texture = np.clip( + texture[0].flip(0).detach().cpu().numpy() * 255, 0, 255 + ).astype(np.uint8) + mask = 1 - utils3d.torch.rasterize_triangle_faces( + rastctx, (uvs * 2 - 1)[None], faces, texture_size, texture_size + )['mask'][0].detach().cpu().numpy().astype(np.uint8) + texture = cv2.inpaint(texture, mask, 3, cv2.INPAINT_TELEA) + else: + raise ValueError(f'Unknown mode: {mode}') + + return texture + + +def to_glb( + app_rep: Union[Strivec, Gaussian], + mesh: MeshExtractResult, + simplify: float = 0.95, + fill_holes: bool = True, + fill_holes_max_size: float = 0.04, + texture_size: int = 1024, + debug: bool = False, + verbose: bool = True, +) -> trimesh.Trimesh: + """ + Convert a generated asset to a glb file. + + Args: + app_rep (Union[Strivec, Gaussian]): Appearance representation. + mesh (MeshExtractResult): Extracted mesh. + simplify (float): Ratio of faces to remove in simplification. + fill_holes (bool): Whether to fill holes in the mesh. + fill_holes_max_size (float): Maximum area of a hole to fill. + texture_size (int): Size of the texture. + debug (bool): Whether to print debug information. + verbose (bool): Whether to print progress. + """ + vertices = mesh.vertices.cpu().numpy() + faces = mesh.faces.cpu().numpy() + + # mesh postprocess + vertices, faces = postprocess_mesh( + vertices, faces, + simplify=simplify > 0, + simplify_ratio=simplify, + fill_holes=fill_holes, + fill_holes_max_hole_size=fill_holes_max_size, + fill_holes_max_hole_nbe=int(250 * np.sqrt(1-simplify)), + fill_holes_resolution=1024, + fill_holes_num_views=1000, + debug=debug, + verbose=verbose, + ) + + # parametrize mesh + vertices, faces, uvs, _vmapping = parametrize_mesh(vertices, faces) + + # bake texture + observations, extrinsics, intrinsics = render_multiview(app_rep, resolution=1024, nviews=100) + masks = [np.any(observation > 0, axis=-1) for observation in observations] + extrinsics = [extrinsics[i].cpu().numpy() for i in range(len(extrinsics))] + intrinsics = [intrinsics[i].cpu().numpy() for i in range(len(intrinsics))] + texture = bake_texture( + vertices, faces, uvs, + observations, masks, extrinsics, intrinsics, + texture_size=texture_size, mode='opt', + lambda_tv=0.01, + verbose=verbose + ) + texture = Image.fromarray(texture) + + # rotate mesh (from z-up to y-up) + vertices = vertices @ np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]]) + material = trimesh.visual.material.PBRMaterial( + roughnessFactor=1.0, + baseColorTexture=texture, + baseColorFactor=np.array([255, 255, 255, 255], dtype=np.uint8) + ) + mesh = trimesh.Trimesh(vertices, faces, visual=trimesh.visual.TextureVisuals(uv=uvs, material=material)) + return mesh + + +def simplify_gs( + gs: Gaussian, + simplify: float = 0.95, + verbose: bool = True, +): + """ + Simplify 3D Gaussians + NOTE: this function is not used in the current implementation for the unsatisfactory performance. + + Args: + gs (Gaussian): 3D Gaussian. + simplify (float): Ratio of Gaussians to remove in simplification. + """ + if simplify <= 0: + return gs + + # simplify + observations, extrinsics, intrinsics = render_multiview(gs, resolution=1024, nviews=100) + observations = [torch.tensor(obs / 255.0).float().cuda().permute(2, 0, 1) for obs in observations] + + # Following https://arxiv.org/pdf/2411.06019 + renderer = GaussianRenderer({ + "resolution": 1024, + "near": 0.8, + "far": 1.6, + "ssaa": 1, + "bg_color": (0,0,0), + }) + new_gs = Gaussian(**gs.init_params) + new_gs._features_dc = gs._features_dc.clone() + new_gs._features_rest = gs._features_rest.clone() if gs._features_rest is not None else None + new_gs._opacity = torch.nn.Parameter(gs._opacity.clone()) + new_gs._rotation = torch.nn.Parameter(gs._rotation.clone()) + new_gs._scaling = torch.nn.Parameter(gs._scaling.clone()) + new_gs._xyz = torch.nn.Parameter(gs._xyz.clone()) + + start_lr = [1e-4, 1e-3, 5e-3, 0.025] + end_lr = [1e-6, 1e-5, 5e-5, 0.00025] + optimizer = torch.optim.Adam([ + {"params": new_gs._xyz, "lr": start_lr[0]}, + {"params": new_gs._rotation, "lr": start_lr[1]}, + {"params": new_gs._scaling, "lr": start_lr[2]}, + {"params": new_gs._opacity, "lr": start_lr[3]}, + ], lr=start_lr[0]) + + def exp_anealing(optimizer, step, total_steps, start_lr, end_lr): + return start_lr * (end_lr / start_lr) ** (step / total_steps) + + def cosine_anealing(optimizer, step, total_steps, start_lr, end_lr): + return end_lr + 0.5 * (start_lr - end_lr) * (1 + np.cos(np.pi * step / total_steps)) + + _zeta = new_gs.get_opacity.clone().detach().squeeze() + _lambda = torch.zeros_like(_zeta) + _delta = 1e-7 + _interval = 10 + num_target = int((1 - simplify) * _zeta.shape[0]) + + with tqdm(total=2500, disable=not verbose, desc='Simplifying Gaussian') as pbar: + for i in range(2500): + # prune + if i % 100 == 0: + mask = new_gs.get_opacity.squeeze() > 0.05 + mask = torch.nonzero(mask).squeeze() + new_gs._xyz = torch.nn.Parameter(new_gs._xyz[mask]) + new_gs._rotation = torch.nn.Parameter(new_gs._rotation[mask]) + new_gs._scaling = torch.nn.Parameter(new_gs._scaling[mask]) + new_gs._opacity = torch.nn.Parameter(new_gs._opacity[mask]) + new_gs._features_dc = new_gs._features_dc[mask] + new_gs._features_rest = new_gs._features_rest[mask] if new_gs._features_rest is not None else None + _zeta = _zeta[mask] + _lambda = _lambda[mask] + # update optimizer state + for param_group, new_param in zip(optimizer.param_groups, [new_gs._xyz, new_gs._rotation, new_gs._scaling, new_gs._opacity]): + stored_state = optimizer.state[param_group['params'][0]] + if 'exp_avg' in stored_state: + stored_state['exp_avg'] = stored_state['exp_avg'][mask] + stored_state['exp_avg_sq'] = stored_state['exp_avg_sq'][mask] + del optimizer.state[param_group['params'][0]] + param_group['params'][0] = new_param + optimizer.state[param_group['params'][0]] = stored_state + + opacity = new_gs.get_opacity.squeeze() + + # sparisfy + if i % _interval == 0: + _zeta = _lambda + opacity.detach() + if opacity.shape[0] > num_target: + index = _zeta.topk(num_target)[1] + _m = torch.ones_like(_zeta, dtype=torch.bool) + _m[index] = 0 + _zeta[_m] = 0 + _lambda = _lambda + opacity.detach() - _zeta + + # sample a random view + view_idx = np.random.randint(len(observations)) + observation = observations[view_idx] + extrinsic = extrinsics[view_idx] + intrinsic = intrinsics[view_idx] + + color = renderer.render(new_gs, extrinsic, intrinsic)['color'] + rgb_loss = torch.nn.functional.l1_loss(color, observation) + loss = rgb_loss + \ + _delta * torch.sum(torch.pow(_lambda + opacity - _zeta, 2)) + + optimizer.zero_grad() + loss.backward() + optimizer.step() + + # update lr + for j in range(len(optimizer.param_groups)): + optimizer.param_groups[j]['lr'] = cosine_anealing(optimizer, i, 2500, start_lr[j], end_lr[j]) + + pbar.set_postfix({'loss': rgb_loss.item(), 'num': opacity.shape[0], 'lambda': _lambda.mean().item()}) + pbar.update() + + new_gs._xyz = new_gs._xyz.data + new_gs._rotation = new_gs._rotation.data + new_gs._scaling = new_gs._scaling.data + new_gs._opacity = new_gs._opacity.data + + return new_gs diff --git a/anigen/utils/random_utils.py b/anigen/utils/random_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c7f4acb3bbcc4308b3658e32d6a44158c7bf428b --- /dev/null +++ b/anigen/utils/random_utils.py @@ -0,0 +1,56 @@ +import numpy as np + +PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53] + +def radical_inverse(base, n): + val = 0 + inv_base = 1.0 / base + inv_base_n = inv_base + while n > 0: + digit = n % base + val += digit * inv_base_n + n //= base + inv_base_n *= inv_base + return val + +def halton_sequence(dim, n): + return [radical_inverse(PRIMES[dim], n) for dim in range(dim)] + +def hammersley_sequence(dim, n, num_samples): + return [n / num_samples] + halton_sequence(dim - 1, n) + +def sphere_hammersley_sequence(n, num_samples, offset=(0, 0), remap=False): + u, v = hammersley_sequence(2, n, num_samples) + u += offset[0] / num_samples + v += offset[1] + if remap: + u = 2 * u if u < 0.25 else 2 / 3 * u + 1 / 3 + theta = np.arccos(1 - 2 * u) - np.pi / 2 + phi = v * 2 * np.pi + return [phi, theta] + +def set_random_seed(seed: int, deterministic: bool = False) -> None: + """Best-effort seeding for reproducibility across common RNGs.""" + import os + import random + import torch + if seed is None: + return + seed = int(seed) + os.environ["PYTHONHASHSEED"] = str(seed) + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if torch.cuda.is_available(): + torch.cuda.manual_seed_all(seed) + + if deterministic: + torch.backends.cudnn.benchmark = False + torch.backends.cudnn.deterministic = True + try: + # warn_only keeps training/inference running if an op has no deterministic kernel. + torch.use_deterministic_algorithms(True, warn_only=True) + except TypeError: + torch.use_deterministic_algorithms(True) + except Exception: + pass \ No newline at end of file diff --git a/anigen/utils/render_utils.py b/anigen/utils/render_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..16243ad54ed85f1b7accdc7f70f9f384b51aaa97 --- /dev/null +++ b/anigen/utils/render_utils.py @@ -0,0 +1,131 @@ +import torch +import numpy as np +from tqdm import tqdm +import utils3d +from PIL import Image + +from ..renderers import OctreeRenderer, GaussianRenderer, MeshRenderer +from ..representations import Octree, Gaussian, MeshExtractResult, AniGenMeshExtractResult +from ..modules import sparse as sp +from .random_utils import sphere_hammersley_sequence + + +def yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, rs, fovs): + is_list = isinstance(yaws, list) + if not is_list: + yaws = [yaws] + pitchs = [pitchs] + if not isinstance(rs, list): + rs = [rs] * len(yaws) + if not isinstance(fovs, list): + fovs = [fovs] * len(yaws) + extrinsics = [] + intrinsics = [] + for yaw, pitch, r, fov in zip(yaws, pitchs, rs, fovs): + fov = torch.deg2rad(torch.tensor(float(fov))).cuda() + yaw = torch.tensor(float(yaw)).cuda() + pitch = torch.tensor(float(pitch)).cuda() + orig = torch.tensor([ + torch.sin(yaw) * torch.cos(pitch), + torch.cos(yaw) * torch.cos(pitch), + torch.sin(pitch), + ]).cuda() * r + extr = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda()) + intr = utils3d.torch.intrinsics_from_fov_xy(fov, fov) + extrinsics.append(extr) + intrinsics.append(intr) + if not is_list: + extrinsics = extrinsics[0] + intrinsics = intrinsics[0] + return extrinsics, intrinsics + + +def get_renderer(sample, **kwargs): + if isinstance(sample, Octree): + renderer = OctreeRenderer() + renderer.rendering_options.resolution = kwargs.get('resolution', 512) + renderer.rendering_options.near = kwargs.get('near', 0.8) + renderer.rendering_options.far = kwargs.get('far', 1.6) + renderer.rendering_options.bg_color = kwargs.get('bg_color', (0, 0, 0)) + renderer.rendering_options.ssaa = kwargs.get('ssaa', 4) + renderer.pipe.primitive = sample.primitive + elif isinstance(sample, Gaussian): + renderer = GaussianRenderer() + renderer.rendering_options.resolution = kwargs.get('resolution', 512) + renderer.rendering_options.near = kwargs.get('near', 0.8) + renderer.rendering_options.far = kwargs.get('far', 1.6) + renderer.rendering_options.bg_color = kwargs.get('bg_color', (0, 0, 0)) + renderer.rendering_options.ssaa = kwargs.get('ssaa', 1) + renderer.pipe.kernel_size = kwargs.get('kernel_size', 0.1) + renderer.pipe.use_mip_gaussian = True + elif isinstance(sample, MeshExtractResult) or isinstance(sample, AniGenMeshExtractResult): + renderer = MeshRenderer() + renderer.rendering_options.resolution = kwargs.get('resolution', 512) + renderer.rendering_options.near = kwargs.get('near', 1) + renderer.rendering_options.far = kwargs.get('far', 100) + renderer.rendering_options.ssaa = kwargs.get('ssaa', 4) + else: + raise ValueError(f'Unsupported sample type: {type(sample)}') + return renderer + + +def render_frames(sample, extrinsics, intrinsics, options={}, colors_overwrite=None, verbose=True, **kwargs): + renderer = get_renderer(sample, **options) + rets = {} + for j, (extr, intr) in tqdm(enumerate(zip(extrinsics, intrinsics)), desc='Rendering', disable=not verbose): + if isinstance(sample, (MeshExtractResult, AniGenMeshExtractResult)): + return_types = ["normal"] + has_color = ( + hasattr(sample, 'vertex_attrs') + and sample.vertex_attrs is not None + and sample.vertex_attrs.shape[-1] >= 3 + ) + if has_color: + return_types.append("color") + res = renderer.render(sample, extr, intr, return_types=return_types) + if 'normal' not in rets: rets['normal'] = [] + rets['normal'].append(np.clip(res['normal'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8)) + if 'color' in res: + if 'color' not in rets: rets['color'] = [] + rets['color'].append(np.clip(res['color'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8)) + else: + res = renderer.render(sample, extr, intr, colors_overwrite=colors_overwrite) + if 'color' not in rets: rets['color'] = [] + if 'depth' not in rets: rets['depth'] = [] + rets['color'].append(np.clip(res['color'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8)) + if 'percent_depth' in res: + rets['depth'].append(res['percent_depth'].detach().cpu().numpy()) + elif 'depth' in res: + rets['depth'].append(res['depth'].detach().cpu().numpy()) + else: + rets['depth'].append(None) + return rets + + +def render_video(sample, resolution=512, bg_color=(0, 0, 0), num_frames=300, r=2, fov=40, **kwargs): + yaws = torch.linspace(0, 2 * 3.1415, num_frames) + pitch = 0.25 + 0.5 * torch.sin(torch.linspace(0, 2 * 3.1415, num_frames)) + yaws = yaws.tolist() + pitch = pitch.tolist() + extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitch, r, fov) + return render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs) + + +def render_multiview(sample, resolution=512, nviews=30): + r = 2 + fov = 40 + cams = [sphere_hammersley_sequence(i, nviews) for i in range(nviews)] + yaws = [cam[0] for cam in cams] + pitchs = [cam[1] for cam in cams] + extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, r, fov) + res = render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': (0, 0, 0)}) + return res['color'], extrinsics, intrinsics + + +def render_snapshot(samples, resolution=512, bg_color=(0, 0, 0), offset=(-16 / 180 * np.pi, 20 / 180 * np.pi), r=10, fov=8, **kwargs): + yaw = [0, np.pi/2, np.pi, 3*np.pi/2] + yaw_offset = offset[0] + yaw = [y + yaw_offset for y in yaw] + pitch = [offset[1] for _ in range(4)] + extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaw, pitch, r, fov) + return render_frames(samples, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs) diff --git a/anigen/utils/skin_utils.py b/anigen/utils/skin_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..180df2a0b589b5747d8e3ffc84cc07e979a344b2 --- /dev/null +++ b/anigen/utils/skin_utils.py @@ -0,0 +1,339 @@ +import torch +import numpy as np +from sklearn.decomposition import PCA + + +def transform_np(data, pca, bounds): + x = data.reshape([-1, data.shape[-1]]) + x_pca = pca.transform(x)[..., -3:] + x_bd = (x_pca - bounds[0]) / (bounds[1] - bounds[0]) + x_bd = np.clip(x_bd, 0., 1.) + x_bd = x_bd.reshape([*data.shape[:-1], x_bd.shape[-1]]) + return x_bd + + +def get_transform_np(data): + x = data.reshape([-1, data.shape[-1]]) + pca = PCA(n_components=3) + pca.fit(x) + x_pca = pca.transform(x)[..., -3:] + bounds = np.stack([x_pca.min(axis=0), x_pca.max(axis=0)]) + trans_func = lambda a: transform_np(a, pca=pca, bounds=bounds) + return trans_func + + +def get_transform(data): + x = data.reshape([-1, data.shape[-1]]) + m, n = x.shape + if n < 3: + # Use normalization function if PCA cannot be applied + bmax, bmin = x.max(dim=0).values, x.min(dim=0).values + pad = 3 - n + trans_func = lambda a: torch.cat([((a - bmin) / (bmax - bmin)).clamp(0., 1.), torch.ones((*a.shape[:-1], pad), device=a.device)], dim=-1) + return trans_func + else: + U, _, V = torch.pca_lowrank(x, q=3) + bmax, bmin = U.max(dim=0).values, U.min(dim=0).values + trans_func = lambda a: ((torch.matmul(a, V) - bmin) / (bmax - bmin)).clamp(0., 1.) + return trans_func + +def _find_parent_cycles(parents: np.ndarray): + """Return list of cycles, each as an ordered list of node indices. + + parents is a length-N array of parent pointers. Values may be -1 (root) or self-parent. + """ + parents = np.asarray(parents).astype(np.int64, copy=False).reshape(-1) + n = parents.shape[0] + visited_global = np.zeros(n, dtype=bool) + cycles = [] + + for start in range(n): + if visited_global[start]: + continue + + order = [] + index_in_path = {} + cur = int(start) + + while 0 <= cur < n and not visited_global[cur]: + if cur in index_in_path: + cycle = order[index_in_path[cur]:] + if len(cycle) >= 2: + cycles.append(cycle) + break + + index_in_path[cur] = len(order) + order.append(cur) + + p = int(parents[cur]) + if p == -1 or p == cur: + break + cur = p + + for v in order: + visited_global[v] = True + + return cycles + +def _format_cycle(cycle, joints=None): + loop = cycle + [cycle[0]] + s = " -> ".join(str(i) for i in loop) + if joints is None: + return s + j = np.asarray(joints) + try: + coords = [j[i].tolist() for i in cycle] + return f"{s} | joints={coords}" + except Exception: + return s + +def repair_skeleton_parents(joints, parents, verbose: bool = True, max_iters: int | None = None): + """Repair cyclic/invalid parent pointers into an acyclic forest. + + Strategy (sensible + minimal change): + - First sanitize invalid parent indices to -1. + - Then iteratively detect cycles. + - For each cycle, break it by reparenting ONE joint in the cycle to the nearest joint + outside the cycle (using Euclidean distance in joint space). If no outside joint exists, + make that joint a root (parent = -1). + + This avoids merging joints (which would require updating skin weights), while achieving a + tree/forest that Blender and GLB viewers can load reliably. + """ + parents = np.asarray(parents).astype(np.int64, copy=True).reshape(-1) + n = parents.shape[0] + if n == 0: + return parents + + if max_iters is None: + max_iters = max(4, n) + + # Sanitize: out-of-range parents become roots. + invalid = ~((parents == -1) | ((parents >= 0) & (parents < n)) | (parents == np.arange(n))) + if np.any(invalid): + bad = np.where(invalid)[0] + if verbose: + print(f"Warning: invalid parent indices at {bad[:20].tolist()} (showing up to 20); setting them to -1.") + parents[invalid] = -1 + + joints_np = None + if joints is not None: + joints_np = np.asarray(joints, dtype=np.float32) + if joints_np.ndim != 2 or joints_np.shape[0] != n or joints_np.shape[1] < 3: + joints_np = None + + for it in range(int(max_iters)): + cycles = _find_parent_cycles(parents) + if not cycles: + return parents + + if verbose: + print(f"Warning: detected {len(cycles)} skeleton cycle(s); repairing (iter {it+1}/{max_iters}).") + + all_nodes = np.arange(n, dtype=np.int64) + for cycle in cycles: + if verbose: + print(" Cycle:", _format_cycle(cycle, joints=joints_np)) + + cyc = np.asarray(cycle, dtype=np.int64) + in_cycle = np.zeros(n, dtype=bool) + in_cycle[cyc] = True + outside = all_nodes[~in_cycle] + + if joints_np is None or outside.size == 0: + # Fallback: make the first node in the cycle a root. + cut_node = int(cyc[0]) + if verbose: + print(f" Fix: set parent[{cut_node}] = -1") + parents[cut_node] = -1 + continue + + # Pick the closest (cycle_node, outside_node) pair to break the cycle with minimal distortion. + cyc_pos = joints_np[cyc, :3] # (C,3) + out_pos = joints_np[outside, :3] # (O,3) + # squared distances + d2 = ((cyc_pos[:, None, :] - out_pos[None, :, :]) ** 2).sum(axis=-1) + flat = int(np.argmin(d2)) + ci, oi = divmod(flat, d2.shape[1]) + cut_node = int(cyc[ci]) + new_parent = int(outside[oi]) + if verbose: + print(f" Fix: set parent[{cut_node}] = {new_parent} (nearest outside)") + parents[cut_node] = new_parent + + # If we get here, we failed to fully repair cycles within the limit. + remaining = _find_parent_cycles(parents) + if remaining and verbose: + print(f"Error: remaining cycles after repair attempts: {len(remaining)}") + for cycle in remaining[:10]: + print(" Remaining cycle:", _format_cycle(cycle, joints=joints_np)) + return parents + +def _softmax(x: np.ndarray, axis: int = -1) -> np.ndarray: + x = np.asarray(x, dtype=np.float32) + x = x - np.max(x, axis=axis, keepdims=True) + np.exp(x, out=x) + s = np.sum(x, axis=axis, keepdims=True) + s = np.maximum(s, 1e-12) + return x / s + +def _joint_graph_all_pairs_hops(parents: np.ndarray) -> np.ndarray: + """All-pairs shortest path length in hop-count on skeleton graph. + + Skeleton treated as undirected graph with edges (i, parent[i]) for valid parents. + Returns an int32 matrix [M, M], where unreachable pairs are filled with a large value. + """ + parents = np.asarray(parents, dtype=np.int64).reshape(-1) + m = int(parents.shape[0]) + + # Build undirected adjacency. + adj: list[list[int]] = [[] for _ in range(m)] + for i in range(m): + p = int(parents[i]) + if p == -1 or p == i: + continue + if not (0 <= p < m): + continue + adj[i].append(p) + adj[p].append(i) + + inf_hop = np.int32(1 << 29) + hops = np.full((m, m), inf_hop, dtype=np.int32) + + for src in range(m): + d = hops[src] + d[src] = 0 + queue = [src] + q_head = 0 + while q_head < len(queue): + u = queue[q_head] + q_head += 1 + nd = int(d[u]) + 1 + for v in adj[u]: + if nd < int(d[v]): + d[v] = nd + queue.append(v) + + return hops + +def filter_skinning_weights( + mesh, + skin_weights: np.ndarray, + joints: np.ndarray, + parents: np.ndarray, + chunk_size: int = 8192, + eps: float = 1e-8, + anchor_mode: str = 'euclidean', # euclidean or skin +) -> np.ndarray: + """Prune/renormalize skinning weights with a 2-hop skeleton constraint. + + For each vertex v: + - anchor joint j* = argmax(skin_weights[v, :]) + - for joints k with hop_dist(j*, k) > 2 on the skeleton graph, set weight to 0 + - renormalize weights(v, :) to sum to 1 + """ + + if mesh is None or not hasattr(mesh, 'vertices'): + raise ValueError('mesh must have vertices') + + verts = np.asarray(mesh.vertices, dtype=np.float32) + skin_weights = np.asarray(skin_weights, dtype=np.float32) + joints = np.asarray(joints, dtype=np.float32) + parents = np.asarray(parents, dtype=np.int64).reshape(-1) + + num_verts = int(verts.shape[0]) + num_joints = int(joints.shape[0]) + if num_verts == 0 or num_joints == 0: + return np.zeros((num_verts, num_joints), dtype=np.float32) + + if skin_weights.ndim != 2 or skin_weights.shape[0] != num_verts or skin_weights.shape[1] != num_joints: + raise ValueError( + f"skin_weights has wrong shape: expected ({num_verts}, {num_joints}), got {tuple(skin_weights.shape)}" + ) + + # Ensure parents are valid/acyclic for graph construction. + parents = repair_skeleton_parents(joints=joints, parents=parents, verbose=False) + joint_hops = _joint_graph_all_pairs_hops(parents=parents) # [M, M] + out = np.empty_like(skin_weights, dtype=np.float32) + max_hops = 2 * max(1, int(joints.shape[0] // 10)) + + for start in range(0, num_verts, int(chunk_size)): + end = min(num_verts, start + int(chunk_size)) + + chunk_w = skin_weights[start:end, :].copy() # [B, M] + + if anchor_mode == 'euclidean': + d2 = ((verts[start:end, None, :] - joints[None, :, :]) ** 2).sum(axis=-1) # [B, M] + anchor = np.argmin(d2, axis=1).astype(np.int64) # [B] + elif anchor_mode == 'skin': + anchor = np.argmax(chunk_w, axis=1).astype(np.int64) # [B] + + # Keep only joints within max_hops from each anchor joint. + keep_mask = joint_hops[anchor, :] <= max_hops # [B, M] + chunk_w[~keep_mask] = 0.0 + + # Renormalize per vertex. + sums = np.sum(chunk_w, axis=1, keepdims=True) + bad = sums[:, 0] <= eps + if np.any(bad): + # Fallback to one-hot on anchor if row degenerates. + chunk_w[bad, :] = 0.0 + chunk_w[bad, anchor[bad]] = 1.0 + sums = np.sum(chunk_w, axis=1, keepdims=True) + out[start:end, :] = chunk_w / np.maximum(sums, eps) + + return out + +def smooth_skin_weights_on_mesh(mesh, skin_weights, iterations=10, alpha=0.5): + """Smooth per-vertex skin weights over the mesh surface. + + Uses iterative neighbor averaging over the undirected edge graph. + Keeps weights non-negative and renormalized per vertex. + """ + if iterations is None or iterations <= 0 or alpha is None or alpha <= 0: + return skin_weights + + if not hasattr(mesh, "edges_unique") or mesh.edges_unique is None: + return skin_weights + + w = np.asarray(skin_weights, dtype=np.float32) + if w.ndim != 2: + return skin_weights + + num_verts = mesh.vertices.shape[0] + if w.shape[0] != num_verts: + return skin_weights + + edges = np.asarray(mesh.edges_unique) + if edges.size == 0: + return skin_weights + + edges = edges.astype(np.int64, copy=False) + i = edges[:, 0] + j = edges[:, 1] + + # Clamp alpha to a sane range; alpha=1 becomes pure neighbor averaging. + alpha = float(alpha) + if alpha > 1.0: + alpha = 1.0 + + for _ in range(int(iterations)): + neighbor_sum = np.zeros_like(w) + np.add.at(neighbor_sum, i, w[j]) + np.add.at(neighbor_sum, j, w[i]) + + degree = np.zeros((num_verts, 1), dtype=np.float32) + np.add.at(degree, i, 1.0) + np.add.at(degree, j, 1.0) + + avg = neighbor_sum / np.maximum(degree, 1.0) + w = (1.0 - alpha) * w + alpha * avg + + # Keep weights valid. + np.clip(w, 0.0, None, out=w) + weight_sums = np.sum(w, axis=1, keepdims=True) + weight_sums[weight_sums == 0] = 1.0 + w = w / weight_sums + + return w + diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..95aa667d10a89e72c6d35e9b946e521588feb2df --- /dev/null +++ b/app.py @@ -0,0 +1,743 @@ +import os +import shutil +import sys +import traceback +import uuid +from pathlib import Path +from typing import * + +import gradio as gr +import numpy as np +import rembg +import spaces +import torch +import trimesh +from PIL import Image +from gradio_litmodel3d import LitModel3D + +sys.path.append(os.getcwd()) +sys.path.append(os.path.join(os.getcwd(), 'third_parties/dsine')) + +# IMPORTANT: Do NOT import anything from `anigen.*` or `third_parties.*` at +# module scope. `anigen/__init__.py` eagerly imports `anigen.models`, +# `anigen.modules`, `anigen.pipelines`, etc., which pulls in `warp` and other +# native libs. When warp imports it tries to init CUDA, and on ZeroGPU the main +# process has no GPU, so it sets a bad global CUDA state. Any subsequent +# `@spaces.GPU` forked worker then dies silently with "GPU task aborted" before +# the task body runs. Keeping the main process free of `anigen` imports avoids +# this. The worker imports `anigen` fresh and works correctly. + +MAX_SEED = 100 +TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp') +os.makedirs(TMP_DIR, exist_ok=True) + +SS_MODEL_CHOICES = ["ss_flow_duet", "ss_flow_solo", "ss_flow_epic"] +SLAT_MODEL_CHOICES = ["slat_flow_auto", "slat_flow_control"] +DEFAULT_SS_MODEL = "ss_flow_duet" +DEFAULT_SLAT_MODEL = "slat_flow_auto" + +current_ss_model_name = DEFAULT_SS_MODEL +current_slat_model_name = DEFAULT_SLAT_MODEL +pipeline = None +rembg_session = None + + +def get_runtime_device() -> str: + return "cuda" if torch.cuda.is_available() else "cpu" + + +def get_session_dir(session_id: Optional[str]) -> str: + target_session = session_id or uuid.uuid4().hex + user_dir = os.path.join(TMP_DIR, target_session) + os.makedirs(user_dir, exist_ok=True) + return user_dir + + +def get_pipeline(device: Optional[str] = None): + # NOTE: This function must only be called from inside a `@spaces.GPU` + # worker. The ZeroGPU pattern of pre-loading on CPU in the main process and + # then calling `.to("cuda")` inside the worker crashes silently for the + # AniGen pipeline (worker exits with "GPU task aborted" before any print). + # We therefore lazily create a fresh pipeline *inside* the worker and cache + # it in a module-level global so that subsequent reused workers skip the + # 40+s load. + global pipeline + + device = device or get_runtime_device() + + if pipeline is None: + from anigen.pipelines import AnigenImageTo3DPipeline + + print(f"[app_hf] Initializing pipeline on {device}...", flush=True) + pipeline = AnigenImageTo3DPipeline.from_pretrained( + ss_flow_path=f'ckpts/anigen/{DEFAULT_SS_MODEL}', + slat_flow_path=f'ckpts/anigen/{DEFAULT_SLAT_MODEL}', + device=device, + use_ema=False, + ) + print(f"[app_hf] Pipeline initialized on {device}.", flush=True) + elif pipeline.device.type != device: + print(f"[app_hf] Moving pipeline from {pipeline.device.type} to {device}...", flush=True) + pipeline.to(torch.device(device)) + print(f"[app_hf] Pipeline moved to {device}.", flush=True) + + return pipeline + + +def get_rembg_session(): + global rembg_session + if rembg_session is None: + print("[app_hf] Initializing rembg u2net session on CPU...", flush=True) + rembg_session = rembg.new_session("birefnet-general") + print("[app_hf] rembg session ready.", flush=True) + return rembg_session + + +def start_session(req: gr.Request): + get_session_dir(req.session_hash) + + +def end_session(req: gr.Request): + shutil.rmtree(get_session_dir(req.session_hash), ignore_errors=True) + + +def preprocess_for_display_and_inference(image: Optional[Image.Image]) -> Tuple[Optional[Image.Image], Optional[Image.Image]]: + if image is None: + return None, None + + has_alpha = False + if image.mode == 'RGBA': + alpha = np.array(image)[:, :, 3] + if not np.all(alpha == 255): + has_alpha = True + + if has_alpha: + rgba_output = image.convert('RGBA') + else: + input_image = image.convert('RGB') + max_size = max(input_image.size) + scale = min(1, 1024 / max_size) + if scale < 1: + input_image = input_image.resize( + (int(input_image.width * scale), int(input_image.height * scale)), + Image.Resampling.LANCZOS, + ) + rgba_output = rembg.remove(input_image, session=get_rembg_session()) + + output_np = np.array(rgba_output) + alpha = output_np[:, :, 3] + bbox = np.argwhere(alpha > 0.8 * 255) + if len(bbox) == 0: + bbox_crop = (0, 0, rgba_output.width, rgba_output.height) + else: + bbox = np.min(bbox[:, 1]), np.min(bbox[:, 0]), np.max(bbox[:, 1]), np.max(bbox[:, 0]) + center = (bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2 + size = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) + size = int(size * 1.2) + bbox_crop = ( + int(center[0] - size // 2), + int(center[1] - size // 2), + int(center[0] + size // 2), + int(center[1] + size // 2), + ) + + rgba_output = rgba_output.crop(bbox_crop) + rgba_output = rgba_output.resize((518, 518), Image.Resampling.LANCZOS) + + display_np = np.array(rgba_output).astype(np.float32) / 255 + display_np = display_np[:, :, :3] * display_np[:, :, 3:4] + display_image = Image.fromarray((display_np * 255).astype(np.uint8)) + return display_image, rgba_output + + +def save_processed_rgba(image: Optional[Image.Image], session_id: Optional[str] = None) -> Optional[str]: + if image is None: + return None + + file_path = os.path.join(get_session_dir(session_id), 'processed_input_rgba.png') + image.save(file_path) + return file_path + + +def load_processed_rgba(path: Optional[str]) -> Optional[Image.Image]: + if not path: + return None + file_path = Path(path) + if not file_path.exists(): + return None + return Image.open(file_path).convert('RGBA') + + +def prepare_input_for_generation(image: Optional[Image.Image], req: gr.Request = None) -> Tuple[Optional[str], Optional[Image.Image]]: + print('[app_hf] Preparing input on CPU before GPU stage...', flush=True) + processed_image, processed_rgba = preprocess_for_display_and_inference(image) + processed_rgba_path = save_processed_rgba(processed_rgba, req.session_hash if req else None) + print(f'[app_hf] CPU preprocessing completed. path={processed_rgba_path}', flush=True) + return processed_rgba_path, processed_image + + +def get_seed(randomize_seed: bool, seed: int) -> int: + return np.random.randint(0, MAX_SEED) if randomize_seed else seed + + +def on_slat_model_change(slat_model_name: str): + is_control = (slat_model_name == 'slat_flow_control') + return ( + gr.update(interactive=is_control), + gr.update(visible=not is_control), + ) + + +def save_generation_state(state: Dict[str, Any], session_id: Optional[str]) -> str: + state_path = os.path.join(get_session_dir(session_id), 'generation_state.pt') + torch.save(state, state_path) + return state_path + + +def load_generation_state(state_path: str) -> Dict[str, Any]: + return torch.load(state_path, map_location='cpu') + + +def export_preview_assets( + user_dir: str, + orig_vertices: np.ndarray, + orig_faces: np.ndarray, + joints: np.ndarray, + parents: np.ndarray, + skin_weights: np.ndarray, + vertex_colors: Optional[np.ndarray], +) -> Tuple[str, Optional[str]]: + # Lazy import: see the note at the top of the file about not importing + # anigen in the main process. + from anigen.utils.export_utils import convert_to_glb_from_data, visualize_skeleton_as_mesh + + preview_mesh_path = os.path.join(user_dir, 'preview_mesh.glb') + preview_skeleton_path = os.path.join(user_dir, 'preview_skeleton.glb') + + preview_mesh = trimesh.Trimesh(vertices=orig_vertices, faces=orig_faces, process=False) + convert_to_glb_from_data( + preview_mesh, + joints, + parents, + skin_weights, + preview_mesh_path, + vertex_colors=vertex_colors, + texture_image=None, + ) + + skeleton_mesh = visualize_skeleton_as_mesh(joints, parents) + if skeleton_mesh is not None and len(skeleton_mesh.vertices) > 0: + skeleton_mesh.export(preview_skeleton_path) + else: + preview_skeleton_path = None + + return preview_mesh_path, preview_skeleton_path + + +def get_user_dir_from_artifact_path(path: Optional[str]) -> str: + if not path: + raise gr.Error('Missing intermediate artifact path.') + return str(Path(path).resolve().parent) + + +def update_download_buttons(mesh_path: Optional[str], skel_path: Optional[str]): + return ( + gr.update(value=mesh_path, interactive=bool(mesh_path)), + gr.update(value=skel_path, interactive=bool(skel_path)), + ) + + +def disable_download_buttons(): + return ( + gr.update(value=None, interactive=False), + gr.update(value=None, interactive=False), + ) + + +def mark_generate_queued(ss_sampling_steps: int, slat_sampling_steps: int): + return ( + f'CPU preprocessing done. Waiting for ZeroGPU allocation for preview generation ' + f'(SS steps: {ss_sampling_steps}, SLat steps: {slat_sampling_steps}).' + ) + + +def mark_extract_queued(texture_size: int, simplify_ratio: float, fill_holes: bool): + return ( + f'Waiting for ZeroGPU allocation for final GLB extraction ' + f'(texture: {texture_size}, simplify: {simplify_ratio:.2f}, fill_holes: {fill_holes}).' + ) + + +@spaces.GPU(duration=120) +def generate_preview( + processed_input_rgba_path: Optional[str], + seed: int, + ss_model_name: str, + slat_model_name: str, + ss_guidance_strength: float, + ss_sampling_steps: int, + slat_guidance_strength: float, + slat_sampling_steps: int, + joints_density: int, + progress=gr.Progress(track_tqdm=False), +) -> Tuple[str, str, Optional[str], str]: + global current_ss_model_name, current_slat_model_name + + print('[app_hf] generate_preview: entered GPU function, requesting pipeline...', flush=True) + try: + from anigen.utils.skin_utils import repair_skeleton_parents + + device = get_runtime_device() + print(f'[app_hf] generate_preview started on device={device}', flush=True) + + processed_input_rgba = load_processed_rgba(processed_input_rgba_path) + if processed_input_rgba is None: + raise gr.Error('Missing processed input image. Please upload an image and click Generate again.') + + print('[app_hf] processed input loaded; initializing pipeline next.', flush=True) + pipe = get_pipeline(device) + + if ss_model_name != current_ss_model_name: + progress(0, desc=f'Loading SS model: {ss_model_name}...') + pipe.load_ss_flow_model(f'ckpts/anigen/{ss_model_name}', device=device, use_ema=False) + current_ss_model_name = ss_model_name + + if slat_model_name != current_slat_model_name: + progress(0, desc=f'Loading SLAT model: {slat_model_name}...') + pipe.load_slat_flow_model(f'ckpts/anigen/{slat_model_name}', device=device, use_ema=False) + current_slat_model_name = slat_model_name + + torch.manual_seed(seed) + np.random.seed(seed) + + progress(0.02, desc='Estimating normals...') + processed_image, processed_normal = pipe.preprocess_image(processed_input_rgba) + print('[app_hf] preprocessing on GPU worker finished.', flush=True) + + progress(0.08, desc='Encoding image conditions...') + cond_dict_ss, cond_dict_slat_rgb = pipe.get_cond(processed_image, processed_normal) + print('[app_hf] conditioning ready.', flush=True) + + def ss_progress_callback(step, total): + frac = (step + 1) / total + progress(0.10 + frac * 0.40, desc=f'SS Sampling: {step + 1}/{total}') + + def slat_progress_callback(step, total): + frac = (step + 1) / total + progress(0.50 + frac * 0.40, desc=f'SLat Sampling: {step + 1}/{total}') + + coords, coords_skl, _, _ = pipe.sample_sparse_structure( + cond_dict_ss, + strength=ss_guidance_strength, + steps=ss_sampling_steps, + progress_callback=ss_progress_callback, + ) + print('[app_hf] sparse structure sampled.', flush=True) + + slat, slat_skl = pipe.sample_slat( + cond_dict_slat_rgb, + coords, + coords_skl, + strength=slat_guidance_strength, + steps=slat_sampling_steps, + joint_density=joints_density, + progress_callback=slat_progress_callback, + ) + print('[app_hf] slat sampled.', flush=True) + + progress(0.92, desc='Decoding preview mesh...') + mesh_result, skeleton_result = pipe.decode_slat(slat, slat_skl) + print('[app_hf] decode finished.', flush=True) + + joints = skeleton_result.joints_grouped.detach().cpu().to(torch.float32) + parents = skeleton_result.parents_grouped.detach().cpu().to(torch.int32) + parents_np = repair_skeleton_parents( + joints=joints.numpy(), + parents=parents.numpy(), + verbose=False, + ).astype(np.int32) + parents = torch.from_numpy(parents_np) + skin_weights = skeleton_result.skin_pred.detach().cpu().to(torch.float32) + orig_vertices = mesh_result.vertices.detach().cpu().to(torch.float32) + orig_faces = mesh_result.faces.detach().cpu().to(torch.long) + vertex_attrs = None + if getattr(mesh_result, 'vertex_attrs', None) is not None: + vertex_attrs = mesh_result.vertex_attrs.detach().cpu().to(torch.float32) + + vertex_colors = None + if vertex_attrs is not None and vertex_attrs.shape[-1] >= 3: + vertex_colors = vertex_attrs[:, :3].numpy() + + user_dir = get_user_dir_from_artifact_path(processed_input_rgba_path) + preview_mesh_path, preview_skeleton_path = export_preview_assets( + user_dir=user_dir, + orig_vertices=orig_vertices.numpy(), + orig_faces=orig_faces.numpy(), + joints=joints.numpy(), + parents=parents.numpy(), + skin_weights=skin_weights.numpy(), + vertex_colors=vertex_colors, + ) + + state = { + 'orig_vertices': orig_vertices.contiguous(), + 'orig_faces': orig_faces.contiguous(), + 'vertex_attrs': vertex_attrs.contiguous() if vertex_attrs is not None else None, + 'joints': joints.contiguous(), + 'parents': parents.contiguous(), + 'skin_weights': skin_weights.contiguous(), + 'mesh_res': int(getattr(mesh_result, 'res', 64)), + } + state_path = os.path.join(user_dir, 'generation_state.pt') + torch.save(state, state_path) + print(f'[app_hf] Preview ready. State saved to {state_path}', flush=True) + + status = 'Preview ready. Click โ€œExtract GLBโ€ to run simplification and texture baking.' + return state_path, preview_mesh_path, preview_skeleton_path, status + except Exception as exc: + print(f'[app_hf] generate_preview failed: {exc}', flush=True) + print(traceback.format_exc(), flush=True) + raise + finally: + # Don't move pipeline back to CPU: the ZeroGPU worker is reused across + # calls, so keeping the pipeline on GPU lets subsequent calls skip the + # 40+s load. Moving to CPU and back has also been shown to trigger + # silent worker aborts for this pipeline. + if torch.cuda.is_available(): + torch.cuda.empty_cache() + + +@spaces.GPU(duration=120) +def extract_glb( + generation_state_path: Optional[str], + texture_size: int, + simplify_ratio: float, + fill_holes: bool, + progress=gr.Progress(track_tqdm=False), +) -> Tuple[str, Optional[str], str]: + try: + from anigen.representations.mesh.cube2mesh_skeleton import AniGenMeshExtractResult + from anigen.utils.export_utils import convert_to_glb_from_data, visualize_skeleton_as_mesh + from anigen.utils.postprocessing_utils import ( + bake_texture, + barycentric_transfer_attributes, + parametrize_mesh, + postprocess_mesh, + ) + from anigen.utils.render_utils import render_multiview + from anigen.utils.skin_utils import ( + filter_skinning_weights, + repair_skeleton_parents, + smooth_skin_weights_on_mesh, + ) + + if not generation_state_path or not os.path.exists(generation_state_path): + raise gr.Error('Please click Generate first to create a preview state.') + + device = get_runtime_device() + print(f'[app_hf] extract_glb started on device={device}', flush=True) + state = load_generation_state(generation_state_path) + + orig_vertices = state['orig_vertices'].numpy() + orig_faces = state['orig_faces'].numpy() + joints = state['joints'].numpy() + parents = repair_skeleton_parents( + joints=joints, + parents=state['parents'].numpy().astype(np.int32), + verbose=False, + ).astype(np.int32) + skin_weights = state['skin_weights'].numpy() + vertex_attrs_cpu = state.get('vertex_attrs') + vertex_colors = None + if vertex_attrs_cpu is not None and vertex_attrs_cpu.shape[-1] >= 3: + vertex_colors = vertex_attrs_cpu[:, :3].numpy() + + user_dir = get_user_dir_from_artifact_path(generation_state_path) + output_glb_path = os.path.join(user_dir, 'mesh.glb') + skeleton_glb_path = os.path.join(user_dir, 'skeleton.glb') + + progress(0.02, desc='Simplifying mesh...') + new_vertices, new_faces = postprocess_mesh( + orig_vertices, + orig_faces, + simplify=(simplify_ratio > 0), + simplify_ratio=simplify_ratio, + fill_holes=fill_holes, + verbose=True, + ) + + if new_vertices.shape[0] != orig_vertices.shape[0]: + orig_mesh = trimesh.Trimesh(vertices=orig_vertices, faces=orig_faces, process=False) + skin_weights = barycentric_transfer_attributes(orig_mesh, skin_weights, new_vertices) + if vertex_colors is not None: + vertex_colors = barycentric_transfer_attributes(orig_mesh, vertex_colors, new_vertices) + + mesh = trimesh.Trimesh(vertices=new_vertices, faces=new_faces, process=False) + + # progress(0.30, desc='Filtering skin weights...') + # skin_weights = filter_skinning_weights(mesh, skin_weights, joints, parents) + + progress(0.42, desc='Smoothing skin weights...') + skin_weights = smooth_skin_weights_on_mesh( + mesh, + skin_weights, + iterations=100, + alpha=1.0, + ) + + texture_image = None + if int(texture_size) > 0: + progress(0.55, desc='Parameterizing UVs...') + uv_vertices, uv_faces, uvs, vmapping = parametrize_mesh(new_vertices, new_faces) + skin_weights = skin_weights[vmapping] + if vertex_colors is not None: + vertex_colors = vertex_colors[vmapping] + + vertex_attrs = None + if vertex_attrs_cpu is not None: + vertex_attrs = vertex_attrs_cpu.to(device=device, dtype=torch.float32) + mesh_result = AniGenMeshExtractResult( + vertices=torch.as_tensor(orig_vertices, device=device, dtype=torch.float32), + faces=torch.as_tensor(orig_faces, device=device, dtype=torch.long), + vertex_attrs=vertex_attrs, + res=int(state.get('mesh_res', 64)), + ) + + progress(0.65, desc='Rendering teacher views...') + observations, extrinsics_mv, intrinsics_mv = render_multiview( + mesh_result, + resolution=1024, + nviews=100, + ) + masks = [np.any(obs > 0, axis=-1) for obs in observations] + extrinsics_np = [e.detach().cpu().numpy() for e in extrinsics_mv] + intrinsics_np = [i.detach().cpu().numpy() for i in intrinsics_mv] + + progress(0.78, desc='Baking texture...') + with torch.enable_grad(): + texture_image = bake_texture( + uv_vertices, + uv_faces, + uvs, + observations, + masks, + extrinsics_np, + intrinsics_np, + texture_size=int(texture_size), + mode='opt', + lambda_tv=0.01, + verbose=True, + ) + + mesh = trimesh.Trimesh( + vertices=uv_vertices, + faces=uv_faces, + visual=trimesh.visual.TextureVisuals(uv=uvs), + process=False, + ) + + progress(0.94, desc='Exporting GLB...') + convert_to_glb_from_data( + mesh, + joints, + parents, + skin_weights, + output_glb_path, + vertex_colors=vertex_colors, + texture_image=texture_image, + ) + + skeleton_mesh = visualize_skeleton_as_mesh(joints, parents) + if skeleton_mesh is not None and len(skeleton_mesh.vertices) > 0: + skeleton_mesh.export(skeleton_glb_path) + else: + skeleton_glb_path = None + + if torch.cuda.is_available(): + torch.cuda.empty_cache() + + print('[app_hf] Final GLB extraction completed.', flush=True) + return output_glb_path, skeleton_glb_path, 'Final GLB ready with mesh simplification and texture baking.' + except Exception as exc: + print(f'[app_hf] extract_glb failed: {exc}', flush=True) + print(traceback.format_exc(), flush=True) + raise + + +with gr.Blocks(delete_cache=(600, 600)) as demo: + gr.Markdown( + """ + ## Image to 3D Asset with [AniGen] + * Click **Generate** for a fast preview, then click **Extract GLB** for the full textured glb file export. + * [AniGen GitHub Repository](https://github.com/VAST-AI-Research/AniGen) + * [Tripo: Your 3D Workspace with AI](https://www.tripo3d.ai) + """ + ) + + gr.HTML(""" + +
+ 💡 Tip  + Not satisfied with the geometry or skeleton? + Try switching the SS Model to ss_flow_solo or ss_flow_duet in Generation Settings. +
+""") + + with gr.Row(): + with gr.Column(): + processed_input_path_state = gr.State(value=None) + generation_state_path = gr.State(value=None) + image_prompt = gr.Image(label='Image Prompt', format='png', image_mode='RGBA', type='pil', height=300) + + with gr.Accordion(label='Generation Settings', open=True): + seed = gr.Slider(0, MAX_SEED, label='Seed', value=42, step=1) + randomize_seed = gr.Checkbox(label='Randomize Seed', value=False) + + gr.Markdown('**Model Selection**') + with gr.Row(): + ss_model_dropdown = gr.Dropdown( + choices=SS_MODEL_CHOICES, + value=DEFAULT_SS_MODEL, + label='SS Model (Sparse Structure)', + ) + slat_model_dropdown = gr.Dropdown( + choices=SLAT_MODEL_CHOICES, + value=DEFAULT_SLAT_MODEL, + label='SLAT Model (Structured Latent)', + ) + + gr.Markdown('Stage 1: Sparse Structure Generation') + with gr.Row(): + ss_guidance_strength = gr.Slider(0.0, 15.0, label='Guidance Strength', value=7.5, step=0.1) + ss_sampling_steps = gr.Slider(1, 50, label='Sampling Steps', value=25, step=1) + + gr.Markdown('Stage 2: Structured Latent Generation') + with gr.Row(): + slat_guidance_strength = gr.Slider(0.0, 10.0, label='Guidance Strength', value=3.0, step=0.1) + slat_sampling_steps = gr.Slider(1, 50, label='Sampling Steps', value=25, step=1) + + gr.Markdown('Skeleton & Skinning Settings') + joints_density = gr.Slider(0, 4, label='Joints Density', value=1, step=1, interactive=False) + density_hint = gr.Markdown( + '*Switch `SLAT Model` to `slat_flow_control` to enable joint density control.*', + visible=True, + ) + + with gr.Accordion(label='Extraction Settings', open=False): + simplify_ratio = gr.Slider(0.0, 0.99, label='Mesh Simplification Ratio', value=0.95, step=0.01) + fill_holes = gr.Checkbox(label='Fill Holes', value=True) + texture_size = gr.Slider(256, 2048, label='Texture Resolution', value=1024, step=256) + + with gr.Row(): + generate_btn = gr.Button('Generate') + extract_btn = gr.Button('Extract GLB') + + with gr.Column(): + mesh_output = gr.Model3D(label="Generated Mesh", height=300, interactive=False) + download_mesh = gr.DownloadButton(label='Download Mesh GLB', interactive=False) + skeleton_output = LitModel3D(label='Skeleton Preview / Final GLB', exposure=5.0, height=300, interactive=False) + download_skeleton = gr.DownloadButton(label='Download Skeleton GLB', interactive=False) + processed_image_output = gr.Image(label='Processed Image', type='pil', height=300) + status_output = gr.Markdown('Upload an image, click **Generate**, then click **Extract GLB**.') + + with gr.Row() as single_image_example: + gr.Examples( + examples=[ + f'assets/cond_images/{image}' + for image in os.listdir('assets/cond_images') + ], + inputs=[image_prompt], + examples_per_page=64, + ) + + demo.load(start_session) + demo.unload(end_session) + + slat_model_dropdown.change( + on_slat_model_change, + inputs=[slat_model_dropdown], + outputs=[joints_density, density_hint], + ) + + generate_btn.click( + get_seed, + inputs=[randomize_seed, seed], + outputs=[seed], + ).then( + prepare_input_for_generation, + inputs=[image_prompt], + outputs=[processed_input_path_state, processed_image_output], + ).then( + mark_generate_queued, + inputs=[ss_sampling_steps, slat_sampling_steps], + outputs=[status_output], + ).then( + generate_preview, + inputs=[ + processed_input_path_state, + seed, + ss_model_dropdown, + slat_model_dropdown, + ss_guidance_strength, + ss_sampling_steps, + slat_guidance_strength, + slat_sampling_steps, + joints_density, + ], + outputs=[ + generation_state_path, + mesh_output, + skeleton_output, + status_output, + ], + ).then( + disable_download_buttons, + outputs=[download_mesh, download_skeleton], + ) + + extract_btn.click( + mark_extract_queued, + inputs=[texture_size, simplify_ratio, fill_holes], + outputs=[status_output], + ).then( + extract_glb, + inputs=[generation_state_path, texture_size, simplify_ratio, fill_holes], + outputs=[mesh_output, skeleton_output, status_output], + ).then( + update_download_buttons, + inputs=[mesh_output, skeleton_output], + outputs=[download_mesh, download_skeleton], + ) + + +# Pre-download any missing checkpoints at module load so the first request +# doesn't pay the download cost. The pipeline itself is NOT instantiated here: +# AniGen's module tree crashes the ZeroGPU forked worker when it tries to move +# the CPU-preloaded pipeline to cuda. We instead load the pipeline lazily +# inside `generate_preview` (which runs inside the spaces.GPU worker); because +# ZeroGPU reuses the worker process across calls, the 40+s load only happens +# on the very first request per worker. +# +# We import `ensure_ckpts` by loading the file directly, rather than doing +# `from anigen.utils.ckpt_utils import ensure_ckpts`, because the latter runs +# `anigen/__init__.py` which eagerly imports `anigen.models`, `warp`, spconv +# etc. and leaves the main process in a bad CUDA state. See the note at the +# top of this file. +import importlib.util as _iu +_spec = _iu.spec_from_file_location( + 'anigen_ckpt_utils_isolated', + os.path.join(os.path.dirname(os.path.abspath(__file__)), 'anigen/utils/ckpt_utils.py'), +) +_mod = _iu.module_from_spec(_spec) +_spec.loader.exec_module(_mod) +_mod.ensure_ckpts() +del _iu, _spec, _mod + + +if __name__ == '__main__': + demo.launch(server_name='0.0.0.0', share=True) diff --git a/assets/cond_images/brickbob.png b/assets/cond_images/brickbob.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d8f8247c1d37ce559675875f93f8de778e0c45 --- /dev/null +++ b/assets/cond_images/brickbob.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8839343b2631cd157c7809cff37bbe16eb023e7e4e3cf76319bb1452d9ad944f +size 697001 diff --git a/assets/cond_images/bruno_star.png b/assets/cond_images/bruno_star.png new file mode 100644 index 0000000000000000000000000000000000000000..efd7e3cb9559e6eb4dc781ef5bb080b92f54d78e --- /dev/null +++ b/assets/cond_images/bruno_star.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb6abf42bc1ec54f6a481c1d4c420d256f0f4e501dd461a159555783f12e896d +size 1855807 diff --git a/assets/cond_images/child.webp b/assets/cond_images/child.webp new file mode 100644 index 0000000000000000000000000000000000000000..5ca2b4c229ac9c1c8bf0ed6a5edd46b31e2e998f Binary files /dev/null and b/assets/cond_images/child.webp differ diff --git a/assets/cond_images/dog.png b/assets/cond_images/dog.png new file mode 100644 index 0000000000000000000000000000000000000000..7b79e4552a3a7d2e15d21d1bc537f185fd03399e --- /dev/null +++ b/assets/cond_images/dog.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19607c3b45070bfbabb8fa2569c84451ef965d7f90a09d51caa58ae16ddcf8f6 +size 201650 diff --git a/assets/cond_images/evo.png b/assets/cond_images/evo.png new file mode 100644 index 0000000000000000000000000000000000000000..42671d364c4c59725dcf26efa4430f45a17af632 --- /dev/null +++ b/assets/cond_images/evo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3988f478cdddacb52cb05ba912bece1a378d53dda55784f4db7e237fb5ddeff8 +size 978729 diff --git a/assets/cond_images/iron_boy.png b/assets/cond_images/iron_boy.png new file mode 100644 index 0000000000000000000000000000000000000000..c69f9b10e25c9be2401d2fe48b9b088f6b4ee01d --- /dev/null +++ b/assets/cond_images/iron_boy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2738b32c425f681162f65efb5aaea6bda8f3ef0f3bf9becc0452d33dbf0b539 +size 869577 diff --git a/assets/cond_images/lamp.png b/assets/cond_images/lamp.png new file mode 100644 index 0000000000000000000000000000000000000000..b75c43a320ad201c3cb1747cf1204326ecc544cb --- /dev/null +++ b/assets/cond_images/lamp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15e089408a99d588c7ec3f6a42192743796f736158a80ba259601ef733807539 +size 1078079 diff --git a/assets/cond_images/machine_arm.png b/assets/cond_images/machine_arm.png new file mode 100644 index 0000000000000000000000000000000000000000..4f515e75a105229787c8f6729bcad552ac31f165 --- /dev/null +++ b/assets/cond_images/machine_arm.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d376157ed2e36989a92daa3bae2a93a3e8c7b855aaa78f45ad8ce69248a46bb5 +size 442575 diff --git a/assets/cond_images/machine_dog.png b/assets/cond_images/machine_dog.png new file mode 100644 index 0000000000000000000000000000000000000000..903e9bbee32f3bbe6a657775e54cd62d9ca219c7 --- /dev/null +++ b/assets/cond_images/machine_dog.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ef85802950b7d6e3fba25c59509017a1ed7edbc26d25f47501dcf9e7b8e8d6a +size 112986 diff --git a/assets/cond_images/owl.png b/assets/cond_images/owl.png new file mode 100644 index 0000000000000000000000000000000000000000..e8bd2515a7b9e30d5f606a16cb5c71393c8a4399 --- /dev/null +++ b/assets/cond_images/owl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2956d253d7846dcc0b0222884817afc081cc0d10b5e2f754b90bab618a7ccaa8 +size 204647 diff --git a/assets/cond_images/plant.jpeg b/assets/cond_images/plant.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..2df1e1e1652d46916fe50b59710b2fe3f129918f Binary files /dev/null and b/assets/cond_images/plant.jpeg differ diff --git a/assets/cond_images/trex.png b/assets/cond_images/trex.png new file mode 100644 index 0000000000000000000000000000000000000000..763d5fbc8e1af441d7c2f0351debb016716f48b8 --- /dev/null +++ b/assets/cond_images/trex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7e0dc88864dcad1226452b6f62f167d0c1ba727e828c86620315c2f15baf7b3 +size 1701899 diff --git a/assets/cond_images/whale.png b/assets/cond_images/whale.png new file mode 100644 index 0000000000000000000000000000000000000000..7a44d05ea2775058fd3762e006bc2af220c1626a --- /dev/null +++ b/assets/cond_images/whale.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29dbd2dd53f3ee183080e04b2a1e0363b3bc13e6f4878ac2dad15e3b82338893 +size 1163259 diff --git a/assets/gifs/eagle.gif b/assets/gifs/eagle.gif new file mode 100644 index 0000000000000000000000000000000000000000..dcab84288b656e11ef1ea92fb802e36837ddcda3 --- /dev/null +++ b/assets/gifs/eagle.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2836445f692fb2fb77f56170f382434c52cd54c9d0a48f76bccd799ab2cf86b8 +size 516603 diff --git a/assets/gifs/evo.gif b/assets/gifs/evo.gif new file mode 100644 index 0000000000000000000000000000000000000000..12a04abda5b0fd6eea5a5a7db7ac2c1a497a04cb --- /dev/null +++ b/assets/gifs/evo.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5da3750e8236887752e6c66ab9ddd4f38d9fe9325cf5e8568133bbf59c08e475 +size 923877 diff --git a/assets/gifs/horse.gif b/assets/gifs/horse.gif new file mode 100644 index 0000000000000000000000000000000000000000..40d95da5429450fa7cd5cf3d14fd0dd39ca240c9 --- /dev/null +++ b/assets/gifs/horse.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01a74ed8c0089c257f17297f50dd2323e2047165793c1eadc728f9ebcb781aed +size 1038550 diff --git a/assets/gifs/iron_boy.gif b/assets/gifs/iron_boy.gif new file mode 100644 index 0000000000000000000000000000000000000000..3c1dad162576628d37cde4e7d9d698c2e5fe861b --- /dev/null +++ b/assets/gifs/iron_boy.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d35178e0845b571400c896aeb99ee568e2f850d85cc955a4b60d4c602b2ca897 +size 966157 diff --git a/assets/gifs/machine_arm.gif b/assets/gifs/machine_arm.gif new file mode 100644 index 0000000000000000000000000000000000000000..f43687b383412414ee01f87464819e6ef278f96b --- /dev/null +++ b/assets/gifs/machine_arm.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d3efa434680669bc54b12e96288612d53c25e29225f6ef322c201cb58a74821 +size 968497 diff --git a/assets/gifs/machine_dog.gif b/assets/gifs/machine_dog.gif new file mode 100644 index 0000000000000000000000000000000000000000..a36af4a11e7813c5a1eb26188c981089d983023d --- /dev/null +++ b/assets/gifs/machine_dog.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2387356020eff1f6f14ac09c4e776c593717cdab46bdd4d5c48d98f2ef68e6f +size 801526 diff --git a/assets/gifs/mairo.gif b/assets/gifs/mairo.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8864a2f5033f1b31c2b8789ba6cb2a831456292 --- /dev/null +++ b/assets/gifs/mairo.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:699c775fb07392cae74b5ac0614d527521fc20e8534dc3eea8e76c1078b42c27 +size 1494915 diff --git a/assets/gifs/money_tree.gif b/assets/gifs/money_tree.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec5ee63aa56bdeda7d30500c48a85a4a4d3fec1b --- /dev/null +++ b/assets/gifs/money_tree.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a938c76d06a590d13a4c86e453be18d1f3cc8a5ca28fafa748d6490d9cdc9e0 +size 722469 diff --git a/assets/images/teaser.png b/assets/images/teaser.png new file mode 100644 index 0000000000000000000000000000000000000000..dbdefa2d2cea3a2809ea512058a455c090c75138 --- /dev/null +++ b/assets/images/teaser.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee15692c36bc8b0f101da0c610b1143e25daaef768c05e5d0cda8017db36799c +size 1617302 diff --git a/example.py b/example.py new file mode 100644 index 0000000000000000000000000000000000000000..a4ce554739879806c38359ddf797258facb7db3d --- /dev/null +++ b/example.py @@ -0,0 +1,116 @@ +import os +import torch +import argparse +from PIL import Image + +# Add current directory to path to allow imports +import sys +sys.path.append(os.getcwd()) +sys.path.append(os.path.join(os.getcwd(), 'third_parties/dsine')) + +from anigen.pipelines import AnigenImageTo3DPipeline +from anigen.utils.random_utils import set_random_seed +from anigen.utils.image_utils import _expand_image_inputs +from anigen.utils.ckpt_utils import ensure_ckpts + + +@torch.no_grad() +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument('--image_path', type=str, required=True, help='Path to input image or a folder of images') + parser.add_argument('--ss_flow_path', type=str, required=False, default='ckpts/anigen/ss_flow_duet', help='Path to SS Flow model directory') + parser.add_argument('--slat_flow_path', type=str, required=False, default='ckpts/anigen/slat_flow_auto', help='Path to SLat Flow model directory') + parser.add_argument('--output_dir', type=str, default='results/', help='Output directory') + parser.add_argument('--seed', type=int, default=42) + parser.add_argument('--cfg_scale_ss', type=float, default=7.5, help='Classifier-free guidance scale') + parser.add_argument('--cfg_scale', type=float, default=3.0, help='Classifier-free guidance scale') + parser.add_argument('--deterministic', action='store_true', help='Enable mostly-deterministic torch behavior (may be slower)') + parser.add_argument('--device', type=str, default='cuda') + parser.add_argument('--use_ema', action='store_true', help='Use EMA checkpoint if available') + + parser.add_argument( + '--output_name', + type=str, + default=None, + help='Optional subfolder name to save outputs under `--output_dir`. If not provided, the image filename stem is used.', + ) + + parser.add_argument('--no_smooth_skin_weights', action='store_true', help='Disable skin-weight smoothing') + parser.add_argument('--smooth_skin_weights_iters', type=int, default=100, help='Number of smoothing iterations (default: 100)') + parser.add_argument('--smooth_skin_weights_alpha', type=float, default=1.0, help='Smoothing alpha (default: 1.0)') + + parser.add_argument( + '--no_filter_skin_weights', + action='store_true', + help='Use geodesic distribution to filter mesh skinning weights.', + ) + + parser.add_argument( + '--joints_density', '--joint_density', + type=int, + default=1, + help='Optional joint density level for Slat flow (from 0 to 4, higher means more joints)', + ) + args = parser.parse_args() + + base_output_dir = args.output_dir + input_image_paths, is_dir = _expand_image_inputs(args.image_path) + if is_dir and len(input_image_paths) == 0: + raise ValueError(f"No supported images found under directory: {args.image_path}") + + # For directory input, group outputs under a batch folder. + # For single-image input, keep original behavior: output under `/`. + batch_folder_name = None + if is_dir: + batch_folder_name = args.output_name if (args.output_name is not None and str(args.output_name).strip() != '') else os.path.basename(os.path.normpath(args.image_path)) + set_random_seed(args.seed, deterministic=args.deterministic) + + ensure_ckpts() + + print("Loading models...") + pipeline = AnigenImageTo3DPipeline.from_pretrained( + ss_flow_path=args.ss_flow_path, + slat_flow_path=args.slat_flow_path, + device=args.device, + use_ema=args.use_ema + ) + pipeline.cuda() + + for idx, cur_image_path in enumerate(input_image_paths): + # Per-image output directory. + image_stem = os.path.splitext(os.path.basename(cur_image_path))[0] + if is_dir: + args.output_dir = os.path.join(base_output_dir, str(batch_folder_name), image_stem) + else: + # Allow user to override the saved folder name via --output_name. Fallback to image stem. + folder_name = args.output_name if (args.output_name is not None and str(args.output_name).strip() != '') else image_stem + args.output_dir = os.path.join(base_output_dir, folder_name) + os.makedirs(args.output_dir, exist_ok=True) + + # Keep args.image_path aligned for any downstream logging/debug usage. + args.image_path = cur_image_path + print(f"Processing image {idx + 1}/{len(input_image_paths)}: {cur_image_path}") + image = Image.open(cur_image_path) + + # Run pipeline + output_glb_path = os.path.join(args.output_dir, 'mesh.glb') + outputs = pipeline.run( + image, + seed=args.seed, + cfg_scale_ss=args.cfg_scale_ss, + cfg_scale_slat=args.cfg_scale, + joints_density=args.joints_density, + no_smooth_skin_weights=args.no_smooth_skin_weights, + no_filter_skin_weights=args.no_filter_skin_weights, + smooth_skin_weights_iters=args.smooth_skin_weights_iters, + smooth_skin_weights_alpha=args.smooth_skin_weights_alpha, + output_glb=output_glb_path + ) + + # Save processed images + outputs['processed_image'].save(os.path.join(args.output_dir, 'processed_image.png')) + + +if __name__ == '__main__': + main() diff --git a/extensions/CUBVH/LICENSE b/extensions/CUBVH/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..63b1150db3641ece0445ee44786c0fe6f8f444e1 --- /dev/null +++ b/extensions/CUBVH/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 yihua + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions/CUBVH/LICENSE_NVIDIA b/extensions/CUBVH/LICENSE_NVIDIA new file mode 100644 index 0000000000000000000000000000000000000000..944146295e9c815763027485a593d7a4f3afb766 --- /dev/null +++ b/extensions/CUBVH/LICENSE_NVIDIA @@ -0,0 +1,97 @@ +Copyright (c) 2022, NVIDIA Corporation & affiliates. All rights reserved. + + +NVIDIA Source Code License for instant neural graphics primitives + + +======================================================================= + +1. Definitions + +"Licensor" means any person or entity that distributes its Work. + +"Software" means the original work of authorship made available under +this License. + +"Work" means the Software and any additions to or derivative works of +the Software that are made available under this License. + +The terms "reproduce," "reproduction," "derivative works," and +"distribution" have the meaning as provided under U.S. copyright law; +provided, however, that for the purposes of this License, derivative +works shall not include works that remain separable from, or merely +link (or bind by name) to the interfaces of, the Work. + +Works, including the Software, are "made available" under this License +by including in or with the Work either (a) a copyright notice +referencing the applicability of this License to the Work, or (b) a +copy of this License. + +2. License Grants + + 2.1 Copyright Grant. Subject to the terms and conditions of this + License, each Licensor grants to you a perpetual, worldwide, + non-exclusive, royalty-free, copyright license to reproduce, + prepare derivative works of, publicly display, publicly perform, + sublicense and distribute its Work and any resulting derivative + works in any form. + +3. Limitations + + 3.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. + + 3.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 3.3 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. + + 3.3 Use Limitation. The Work and any derivative works thereof only + may be used or intended for use non-commercially. Notwithstanding + the foregoing, NVIDIA and its affiliates may use the Work and any + derivative works commercially. As used herein, "non-commercially" + means for research or evaluation purposes only. + + 3.4 Patent Claims. If you bring or threaten to bring a patent claim + against any Licensor (including any claim, cross-claim or + counterclaim in a lawsuit) to enforce any patents that you allege + are infringed by any Work, then your rights under this License from + such Licensor (including the grant in Section 2.1) will terminate + immediately. + + 3.5 Trademarks. This License does not grant any rights to use any + Licensorโ€™s or its affiliatesโ€™ names, logos, or trademarks, except + as necessary to reproduce the notices described in this License. + + 3.6 Termination. If you violate any term of this License, then your + rights under this License (including the grant in Section 2.1) will + terminate immediately. + +4. Disclaimer of Warranty. + +THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER +THIS LICENSE. + +5. Limitation of Liability. + +EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL +THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE +SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF +OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK +(INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, +LOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER +COMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES. + +======================================================================= diff --git a/extensions/CUBVH/cubvh/__init__.py b/extensions/CUBVH/cubvh/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..39c9f2d2f78061202a6e0f9d3caf3e9c8a63fc50 --- /dev/null +++ b/extensions/CUBVH/cubvh/__init__.py @@ -0,0 +1,12 @@ +from .api import ( + cuBVH, + HashTable, + cuHashTable, + sparse_marching_cubes, + sparse_marching_cubes_cpu, + floodfill, + fill_holes, + merge_vertices, + decimate, + parallel_decimate, +) \ No newline at end of file diff --git a/extensions/CUBVH/cubvh/api.py b/extensions/CUBVH/cubvh/api.py new file mode 100644 index 0000000000000000000000000000000000000000..f6e2afc1623f2bf7329daaf500e22c41ab1e6ceb --- /dev/null +++ b/extensions/CUBVH/cubvh/api.py @@ -0,0 +1,774 @@ +import contextlib +import numpy as np +import torch + +# CUDA extension +import _cubvh as _backend + +_sdf_mode_to_id = { + 'watertight': 0, + 'raystab': 1, +} + +class cuBVH: + def __init__(self, vertices=None, triangles=None, *, state=None, device=None): + if state is None and (vertices is None or triangles is None): + raise ValueError("cuBVH requires either vertices/triangles or a serialized state.") + + self._impl = None + self._impl_device = None + self._state = None + self._exhaustive = None + self._is_exhaustive = False + self.device = torch.device('cpu') + + target_device = self._parse_device(device) + + if state is not None: + self._load_state(state) + else: + self._build_from_mesh(vertices, triangles, target_device) + + try: + self.to(target_device) + except RuntimeError: + if target_device.type != 'cpu': + self.to(torch.device('cpu')) + else: + raise + + @staticmethod + def _parse_device(device): + if device is None: + return torch.device('cpu') + return torch.device(device) + + def _build_from_mesh(self, vertices, triangles, build_device): + if torch.is_tensor(vertices): + vertices_arr = vertices.detach().cpu().numpy() + else: + vertices_arr = np.asarray(vertices, dtype=np.float32) + + if torch.is_tensor(triangles): + triangles_arr = triangles.detach().cpu().numpy() + else: + triangles_arr = np.asarray(triangles, dtype=np.int32) + + vertices_arr = np.asarray(vertices_arr, dtype=np.float32) + triangles_arr = np.asarray(triangles_arr, dtype=np.int32) + + if triangles_arr.shape[0] == 0: + raise ValueError("cuBVH requires at least one triangle.") + + if triangles_arr.shape[0] < 8: + self._build_exhaustive(vertices_arr, triangles_arr) + return + + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is required to build a cuBVH from mesh data.") + + if build_device.type == 'cuda': + build_cuda = build_device + else: + index = torch.cuda.current_device() + build_cuda = torch.device('cuda', index) + + with self._cuda_device_guard(build_cuda): + impl = _backend.create_cuBVH(vertices_arr, triangles_arr) + tri_pos, tri_ids, node_mins, node_maxs, node_children = impl.export_state() + + self._state = { + "mode": torch.tensor(0, dtype=torch.int32), + "triangles": tri_pos.detach().clone().cpu().contiguous(), + "triangle_ids": tri_ids.detach().clone().cpu().contiguous(), + "node_mins": node_mins.detach().clone().cpu().contiguous(), + "node_maxs": node_maxs.detach().clone().cpu().contiguous(), + "node_children": node_children.detach().clone().cpu().contiguous(), + } + + self._impl = impl + self._impl_device = build_cuda + self._is_exhaustive = False + self.device = build_cuda + + def _build_exhaustive(self, vertices_arr, triangles_arr): + vertices_tensor = torch.as_tensor(vertices_arr, dtype=torch.float32).contiguous().clone() + faces_tensor = torch.as_tensor(triangles_arr, dtype=torch.long).contiguous().clone() + tri_positions = torch.as_tensor(vertices_arr[triangles_arr], dtype=torch.float32).contiguous().clone() + triangle_ids = torch.arange(triangles_arr.shape[0], dtype=torch.long).contiguous() + node_mins = torch.zeros((0, 3), dtype=torch.float32) + node_maxs = torch.zeros((0, 3), dtype=torch.float32) + node_children = torch.zeros((0, 2), dtype=torch.int32) + + self._state = { + "mode": torch.tensor(1, dtype=torch.int32), + "vertices": vertices_tensor, + "faces": faces_tensor, + "triangles": tri_positions, + "triangle_ids": triangle_ids, + "node_mins": node_mins, + "node_maxs": node_maxs, + "node_children": node_children, + } + + self._exhaustive = ExaustiveSearcher(vertices_tensor, faces_tensor, torch.device('cpu')) + self._impl = None + self._impl_device = None + self._is_exhaustive = True + self.device = torch.device('cpu') + + def _pull_state_from_impl(self): + if self._is_exhaustive: + return {key: value.clone() for key, value in self._state.items()} + + with self._cuda_device_guard(self._impl_device): + tri_pos, tri_ids, node_mins, node_maxs, node_children = self._impl.export_state() + return { + "mode": torch.tensor(0, dtype=torch.int32), + "triangles": tri_pos.detach().clone().cpu().contiguous(), + "triangle_ids": tri_ids.detach().clone().cpu().contiguous(), + "node_mins": node_mins.detach().clone().cpu().contiguous(), + "node_maxs": node_maxs.detach().clone().cpu().contiguous(), + "node_children": node_children.detach().clone().cpu().contiguous(), + } + + def _load_state(self, state): + mode_value = state.get("mode", None) + if mode_value is None: + mode_tensor = torch.tensor(0, dtype=torch.int32) + else: + mode_tensor = torch.as_tensor(mode_value, dtype=torch.int32, device='cpu').contiguous().clone() + + mode = int(mode_tensor.item()) + + if mode == 1: + required = {"vertices", "faces"} + missing = required.difference(state.keys()) + if missing: + raise ValueError(f"Serialized state is missing keys for exhaustive mode: {sorted(missing)}") + + vertices = torch.as_tensor(state["vertices"], dtype=torch.float32, device='cpu').contiguous().clone() + faces = torch.as_tensor(state["faces"], dtype=torch.long, device='cpu').contiguous().clone() + triangles = torch.as_tensor( + state.get("triangles", vertices[faces]), + dtype=torch.float32, + device='cpu', + ).contiguous().clone() + triangle_ids = torch.as_tensor( + state.get("triangle_ids", torch.arange(faces.shape[0], dtype=torch.long)), + dtype=torch.long, + device='cpu', + ).contiguous().clone() + node_mins = torch.as_tensor( + state.get("node_mins", torch.empty((0, 3), dtype=torch.float32)), + dtype=torch.float32, + device='cpu', + ).contiguous().clone() + node_maxs = torch.as_tensor( + state.get("node_maxs", torch.empty((0, 3), dtype=torch.float32)), + dtype=torch.float32, + device='cpu', + ).contiguous().clone() + node_children = torch.as_tensor( + state.get("node_children", torch.empty((0, 2), dtype=torch.int32)), + dtype=torch.int32, + device='cpu', + ).contiguous().clone() + + self._state = { + "mode": mode_tensor, + "vertices": vertices, + "faces": faces, + "triangles": triangles, + "triangle_ids": triangle_ids, + "node_mins": node_mins, + "node_maxs": node_maxs, + "node_children": node_children, + } + + self._impl = None + self._impl_device = None + self._is_exhaustive = True + self._exhaustive = ExaustiveSearcher(vertices, faces, torch.device('cpu')) + self.device = torch.device('cpu') + return + + required = {"triangles", "triangle_ids", "node_mins", "node_maxs", "node_children"} + missing = required.difference(state.keys()) + if missing: + raise ValueError(f"Serialized state is missing keys: {sorted(missing)}") + + self._state = { + "mode": mode_tensor, + "triangles": torch.as_tensor(state["triangles"], dtype=torch.float32, device='cpu').contiguous().clone(), + "triangle_ids": torch.as_tensor(state["triangle_ids"], dtype=torch.long, device='cpu').contiguous().clone(), + "node_mins": torch.as_tensor(state["node_mins"], dtype=torch.float32, device='cpu').contiguous().clone(), + "node_maxs": torch.as_tensor(state["node_maxs"], dtype=torch.float32, device='cpu').contiguous().clone(), + "node_children": torch.as_tensor(state["node_children"], dtype=torch.int32, device='cpu').contiguous().clone(), + } + + self._impl = None + self._impl_device = None + self._is_exhaustive = False + self._exhaustive = None + self.device = torch.device('cpu') + + def _release_impl(self): + if self._impl is None: + return + + if self._impl_device is not None and self._impl_device.type == 'cuda': + with self._cuda_device_guard(self._impl_device): + torch.cuda.synchronize() + + self._impl = None + self._impl_device = None + + def _instantiate_impl(self, cuda_device): + triangles = self._state["triangles"].contiguous() + triangle_ids = self._state["triangle_ids"].contiguous() + node_mins = self._state["node_mins"].contiguous() + node_maxs = self._state["node_maxs"].contiguous() + node_children = self._state["node_children"].contiguous() + + with self._cuda_device_guard(cuda_device): + self._impl = _backend.create_cuBVH_from_state( + triangles, + triangle_ids, + node_mins, + node_maxs, + node_children, + ) + + self._impl_device = cuda_device + self.device = cuda_device + + def to(self, device, *args, **kwargs): + device = self._parse_device(device) + + if self._is_exhaustive: + if device.type == 'cuda' and not torch.cuda.is_available(): + raise RuntimeError("CUDA is not available for cuBVH.to().") + if device.type not in ('cpu', 'cuda'): + raise ValueError(f"Unsupported device for cuBVH: {device}") + + vertices = self._state["vertices"].detach() + faces = self._state["faces"].detach() + if self._exhaustive is None: + self._exhaustive = ExaustiveSearcher(vertices, faces, device) + else: + self._exhaustive = self._exhaustive.to(device) + self.device = device + return self + + if device.type == 'cuda': + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is not available for cuBVH.to().") + index = device.index if device.index is not None else torch.cuda.current_device() + cuda_device = torch.device('cuda', index) + if self._impl is not None and self._impl_device == cuda_device: + self.device = cuda_device + return self + self._release_impl() + self._instantiate_impl(cuda_device) + elif device.type == 'cpu': + self._release_impl() + self.device = torch.device('cpu') + else: + raise ValueError(f"Unsupported device for cuBVH: {device}") + + return self + + def _require_impl(self): + if self._is_exhaustive: + raise RuntimeError("cuBVH was built with fewer than 8 triangles; only unsigned_distance is supported.") + if self._impl is None: + raise RuntimeError("cuBVH is on CPU; call cuBVH.to('cuda') before querying.") + return self._impl + + def ray_trace(self, rays_o, rays_d): + impl = self._require_impl() + if self.device.type != 'cuda': + raise RuntimeError("cuBVH must be on a CUDA device to trace rays.") + + target_device = self.device + rays_o = rays_o.to(device=target_device, dtype=torch.float32, non_blocking=True).contiguous() + rays_d = rays_d.to(device=target_device, dtype=torch.float32, non_blocking=True).contiguous() + + prefix = rays_o.shape[:-1] + rays_o = rays_o.view(-1, 3) + rays_d = rays_d.view(-1, 3) + + n_rays = rays_o.shape[0] + + with self._cuda_device_guard(target_device): + positions = torch.empty(n_rays, 3, dtype=torch.float32, device=target_device) + face_id = torch.empty(n_rays, dtype=torch.int64, device=target_device) + depth = torch.empty(n_rays, dtype=torch.float32, device=target_device) + + impl.ray_trace(rays_o, rays_d, positions, face_id, depth) + + positions = positions.view(*prefix, 3) + face_id = face_id.view(*prefix) + depth = depth.view(*prefix) + + return positions, face_id, depth + + def unsigned_distance(self, positions, return_uvw=False): + target_device = self.device + positions = positions.to(device=target_device, dtype=torch.float32, non_blocking=True).contiguous() + + prefix = positions.shape[:-1] + positions = positions.view(-1, 3) + + n_points = positions.shape[0] + + if self._is_exhaustive: + if self._exhaustive is None: + raise RuntimeError("Exhaustive searcher not initialized.") + + distances, face_id, uvw = self._exhaustive.unsigned_distance(positions, return_uvw) + else: + impl = self._require_impl() + if self.device.type != 'cuda': + raise RuntimeError("cuBVH must be on a CUDA device to query distances.") + + with self._cuda_device_guard(target_device): + distances = torch.empty(n_points, dtype=torch.float32, device=target_device) + face_id = torch.empty(n_points, dtype=torch.int64, device=target_device) + + if return_uvw: + uvw = torch.empty(n_points, 3, dtype=torch.float32, device=target_device) + else: + uvw = None + + impl.unsigned_distance(positions, distances, face_id, uvw) + + distances = distances.view(*prefix) + face_id = face_id.view(*prefix) + if uvw is not None: + uvw = uvw.view(*prefix, 3) + + return distances, face_id, uvw + + def signed_distance(self, positions, return_uvw=False, mode='watertight'): + impl = self._require_impl() + if self.device.type != 'cuda': + raise RuntimeError("cuBVH must be on a CUDA device to query distances.") + + target_device = self.device + positions = positions.to(device=target_device, dtype=torch.float32, non_blocking=True).contiguous() + + prefix = positions.shape[:-1] + positions = positions.view(-1, 3) + + n_points = positions.shape[0] + + with self._cuda_device_guard(target_device): + distances = torch.empty(n_points, dtype=torch.float32, device=target_device) + face_id = torch.empty(n_points, dtype=torch.int64, device=target_device) + + if return_uvw: + uvw = torch.empty(n_points, 3, dtype=torch.float32, device=target_device) + else: + uvw = None + + impl.signed_distance(positions, distances, face_id, uvw, _sdf_mode_to_id[mode]) + + distances = distances.view(*prefix) + face_id = face_id.view(*prefix) + if uvw is not None: + uvw = uvw.view(*prefix, 3) + + return distances, face_id, uvw + + def export_state(self): + return {key: value.clone() for key, value in self._state.items()} + + @property + def triangles_cpu(self): + if self._is_exhaustive: + vertices = self._state["vertices"].detach().cpu() + faces = self._state["faces"].detach().cpu().long() + return vertices[faces].contiguous().clone().numpy() + return self._state["triangles"].detach().cpu().clone().numpy() + + @property + def bvh_nodes_cpu(self): + if self._is_exhaustive: + raise RuntimeError("Exhaustive search mode does not have BVH nodes.") + return { + "mins": self._state["node_mins"].detach().cpu().clone().numpy(), + "maxs": self._state["node_maxs"].detach().cpu().clone().numpy(), + "children": self._state["node_children"].detach().cpu().clone().numpy(), + } + + def __getstate__(self): + return { + "state": self.export_state(), + "device": "cpu", + } + + def __setstate__(self, state): + serialized_state = state["state"] + load_device = state.get("device", "cpu") + if isinstance(load_device, torch.device): + if load_device.type == "cuda": + load_device = "cpu" + elif isinstance(load_device, str) and load_device.startswith("cuda"): + load_device = "cpu" + self.__init__(state=serialized_state, device=load_device) + + @contextlib.contextmanager + def _cuda_device_guard(self, device): + if device is None or device.type != 'cuda': + yield + else: + with torch.cuda.device(device): + yield + +def floodfill(grid): + # grid: torch.Tensor, uint8, [B, H, W, D] or [H, W, D] + # return: torch.Tensor, int32, [B, H, W, D] or [H, W, D], label of the connected component (value can be 0 to H*W*D-1, not remapped!) + + grid = grid.contiguous() + if not grid.is_cuda: grid = grid.cuda() + + if grid.dim() == 3: + mask = _backend.floodfill(grid.unsqueeze(0)).squeeze(0) + else: + mask = _backend.floodfill(grid) + + return mask + + +class cuHashTable: + """ + Python wrapper around the CUDA ND integer hash table. + + - Default dimensionality is 3; can be changed via num_dims argument or set_num_dims. + - Static table: prefer a single build() call; repeated insert() calls overwrite indices. + """ + + def __init__(self, num_dims: int = 3): + # create implementation via factory (mirrors cuBVH style) + self.impl = _backend.create_cuHashTable() + self.impl.set_num_dims(int(num_dims)) + + @property + def num_dims(self) -> int: + return int(self.impl.get_num_dims()) + + def build(self, coords): + """Build table from coordinates: coords [N,D] int32/cuda. + Auto-sets capacity to max(16, 2*N).""" + if coords.shape[1] != self.num_dims: + self.impl.set_num_dims(int(coords.size(1))) + self.impl.build(coords) + + def search(self, queries) -> torch.Tensor: + """Search queries [M,D] -> indices [M] int32 on CUDA; -1 if not found.""" + assert queries.shape[1] == self.num_dims, f"queries must be {self.num_dims}D" + return self.impl.search(queries) + + +def sparse_marching_cubes(coords, corners, iso, ensure_consistency=False): + # coords: torch.Tensor, int32, [N, 3] + # corners: torch.Tensor, float32, [N, 8] + # iso: float + # ensure_consistency: bool, whether to ensure shared corner values are consistent + + coords = coords.int().contiguous() + corners = corners.float().contiguous() + + if not coords.is_cuda: coords = coords.cuda() + if not corners.is_cuda: corners = corners.cuda() + + verts, tris = _backend.sparse_marching_cubes(coords, corners, iso, ensure_consistency) + + return verts, tris + +# CPU hole filling numpy API +def fill_holes(vertices: np.ndarray, faces: np.ndarray, return_added: bool = False, check_containment: bool = True, eps: float = 1e-7, verbose: bool = False) -> np.ndarray: + """ + Fill small holes in a triangular mesh using a CPU ear-clipping strategy. + + Args: + vertices (np.ndarray float32 [N,3]) + faces (np.ndarray int32 [M,3]) + return_added: if True, return only newly added triangles; else full face list + check_containment: avoid creating triangles containing other boundary verts + eps: numeric epsilon + verbose: print detailed logs from C++ + Returns: + np.ndarray int32 [...,3] + """ + assert vertices.ndim == 2 and vertices.shape[1] == 3 + assert faces.ndim == 2 and faces.shape[1] == 3 + vertices = np.asarray(vertices, dtype=np.float32) + faces = np.asarray(faces, dtype=np.int32) + faces = _backend.fill_holes(vertices, faces, return_added, check_containment, float(eps), bool(verbose)) + return np.asarray(faces, dtype=np.int32) + +def merge_vertices(vertices: np.ndarray, faces: np.ndarray, threshold: float = 1e-3): + """Merge vertices closer than threshold. + Args: + vertices (np.ndarray float32 [N,3]) + faces (np.ndarray int32 [M,3]) + threshold (float): distance threshold + Returns: + (vertices, faces) after merging + """ + vertices = np.asarray(vertices, dtype=np.float32) + faces = np.asarray(faces, dtype=np.int32) + assert vertices.ndim==2 and vertices.shape[1]==3 + assert faces.ndim==2 and faces.shape[1]==3 + v_new, f_new = _backend.merge_vertices(vertices, faces, float(threshold)) + return np.asarray(v_new, dtype=np.float32), np.asarray(f_new, dtype=np.int32) + + +class HashTable: + """ + CPU ND integer hash table (static, open-addressed). Mirrors cuHashTable but on host. + """ + def __init__(self, num_dims: int = 3): + # constructed directly from backend class + self.impl = _backend.HashTable() + self.impl.set_num_dims(int(num_dims)) + + @property + def num_dims(self) -> int: + return int(self.impl.get_num_dims()) + + def build(self, coords): + """Build table from coordinates: coords [N,D] int32/CPU. + Auto-sets capacity to max(16, 2*N).""" + if coords.shape[1] != self.num_dims: + self.impl.set_num_dims(int(coords.shape[1])) + coords = coords.int().contiguous().cpu() + self.impl.build(coords) + + def search(self, queries): + """Search queries [M,D] -> indices [M] int32/CPU; -1 if not found.""" + assert queries.shape[1] == self.num_dims, f"queries must be {self.num_dims}D" + queries = queries.int().contiguous().cpu() + return self.impl.search(queries) + +def sparse_marching_cubes_cpu(coords, corners, iso: float, ensure_consistency: bool = False): + """CPU sparse marching cubes wrapper. + Args: + coords: (N,3) int32 voxel coordinates (torch.Tensor or np.ndarray) + corners: (N,8) float32 corner SDF values (torch.Tensor or np.ndarray) + iso: isovalue + ensure_consistency: average shared corners across voxels before extraction + Returns: + (vertices, faces): np.ndarray float32 [M,3], np.ndarray int32 [T,3] + """ + if torch.is_tensor(coords): + coords = coords.detach().cpu().numpy() + if torch.is_tensor(corners): + corners = corners.detach().cpu().numpy() + coords = np.asarray(coords, dtype=np.int32) + corners = np.asarray(corners, dtype=np.float32) + assert coords.ndim == 2 and coords.shape[1] == 3, "coords must be [N,3]" + assert corners.ndim == 2 and corners.shape[1] == 8, "corners must be [N,8]" + v, f = _backend.sparse_marching_cubes_cpu(coords, corners, float(iso), bool(ensure_consistency)) + return np.asarray(v, dtype=np.float32), np.asarray(f, dtype=np.int32) + + +def decimate(vertices: np.ndarray, faces: np.ndarray, target_vertices: int): + """CPU quadric-error simplification to target number of vertices. + Args: + vertices: np.ndarray float32 or float64 [N,3] + faces: np.ndarray int32 [M,3] + target_vertices: desired vertex count after decimation + Returns: + (vertices, faces): simplified mesh + """ + assert vertices.ndim == 2 and vertices.shape[1] == 3 + assert faces.ndim == 2 and faces.shape[1] == 3 + faces = faces.astype(np.int32) + v, f = _backend.decimate(vertices, faces, int(target_vertices)) + return v, f + + +def parallel_decimate(vertices: np.ndarray, faces: np.ndarray, target_vertices: int): + """CPU batch-parallel decimation to target number of vertices. + Args: + vertices: np.ndarray float32 or float64 [N,3] + faces: np.ndarray int32 [M,3] + target_vertices: desired vertex count after decimation + Returns: + (vertices, faces): simplified mesh + """ + assert vertices.ndim == 2 and vertices.shape[1] == 3 + assert faces.ndim == 2 and faces.shape[1] == 3 + faces = faces.astype(np.int32) + v, f = _backend.parallel_decimate(vertices, faces, int(target_vertices)) + return v, f + + +class ExaustiveSearcher: + """Fallback distance queries via exhaustive point-triangle search.""" + def __init__(self, vertices, triangles, device): + if device is None: + device = torch.device('cpu') + else: + device = torch.device(device) + + if device.type == 'cuda' and not torch.cuda.is_available(): + raise RuntimeError("CUDA is not available for ExaustiveSearcher.") + + vertices_tensor = torch.as_tensor(vertices, dtype=torch.float32) + faces_tensor = torch.as_tensor(triangles, dtype=torch.long) + + if faces_tensor.numel() == 0: + raise ValueError("ExaustiveSearcher requires at least one triangle.") + + self.device = device + self.vertices = vertices_tensor.to(device=device, dtype=torch.float32).contiguous().clone() + self.faces = faces_tensor.to(device=device, dtype=torch.long).contiguous().clone() + + self._refresh_triangle_vertices() + + def _refresh_triangle_vertices(self): + if self.faces.numel() == 0: + self._triangle_vertices = self.vertices.new_zeros((0, 3, 3)) + else: + self._triangle_vertices = self.vertices[self.faces] + + def to(self, device): + device = torch.device(device) + if device.type == 'cuda' and not torch.cuda.is_available(): + raise RuntimeError("CUDA is not available for ExaustiveSearcher.to().") + if device == self.device: + return self + + self.vertices = self.vertices.to(device=device, non_blocking=True) + self.faces = self.faces.to(device=device) + self.device = device + self._refresh_triangle_vertices() + return self + + def unsigned_distance(self, positions, return_uvw=False): + if self._triangle_vertices.numel() == 0: + raise RuntimeError("ExaustiveSearcher requires triangles to compute distances.") + + points = positions.to(device=self.device, dtype=torch.float32, non_blocking=True).contiguous() + n_points = points.shape[0] + + best_sqdist = torch.full((n_points,), float('inf'), dtype=torch.float32, device=self.device) + best_face = torch.full((n_points,), -1, dtype=torch.int64, device=self.device) + best_bary = torch.zeros((n_points, 3), dtype=torch.float32, device=self.device) if return_uvw else None + + for idx in range(self._triangle_vertices.shape[0]): + tri = self._triangle_vertices[idx] + sq_dist, bary = self._point_triangle_distance(points, tri) + better = sq_dist < best_sqdist + if better.any(): + best_sqdist[better] = sq_dist[better] + best_face[better] = idx + if return_uvw: + best_bary[better] = bary[better] + + distances = torch.sqrt(best_sqdist.clamp_min(0.0)) + if return_uvw: + return distances, best_face, best_bary + return distances, best_face, None + + @staticmethod + def _point_triangle_distance(points, tri): + eps = 1e-12 + + a, b, c = tri[0], tri[1], tri[2] + ab = b - a + ac = c - a + ap = points - a + d1 = (ab * ap).sum(dim=-1) + d2 = (ac * ap).sum(dim=-1) + + bp = points - b + d3 = (ab * bp).sum(dim=-1) + d4 = (ac * bp).sum(dim=-1) + + cp = points - c + d5 = (ab * cp).sum(dim=-1) + d6 = (ac * cp).sum(dim=-1) + + bary = torch.zeros(points.shape[0], 3, dtype=points.dtype, device=points.device) + assigned = torch.zeros(points.shape[0], dtype=torch.bool, device=points.device) + + mask = (d1 <= 0) & (d2 <= 0) + if mask.any(): + bary[mask, 0] = 1 + assigned |= mask + + mask = (d3 >= 0) & (d4 <= d3) & (~assigned) + if mask.any(): + bary[mask, 1] = 1 + assigned |= mask + + mask = (d6 >= 0) & (d5 <= d6) & (~assigned) + if mask.any(): + bary[mask, 2] = 1 + assigned |= mask + + vc = d1 * d4 - d3 * d2 + mask = (vc <= 0) & (d1 >= 0) & (d3 <= 0) & (~assigned) + if mask.any(): + denom = (d1 - d3)[mask] + v = d1[mask] / (denom + eps) + bary[mask, 0] = 1 - v + bary[mask, 1] = v + assigned |= mask + + vb = d5 * d2 - d1 * d6 + mask = (vb <= 0) & (d2 >= 0) & (d6 <= 0) & (~assigned) + if mask.any(): + denom = (d2 - d6)[mask] + w = d2[mask] / (denom + eps) + bary[mask, 0] = 1 - w + bary[mask, 2] = w + assigned |= mask + + va = d3 * d6 - d5 * d4 + mask = (va <= 0) & ((d4 - d3) >= 0) & ((d5 - d6) >= 0) & (~assigned) + if mask.any(): + numerator = (d4 - d3)[mask] + denom = (d4 - d3 + d5 - d6)[mask] + w = numerator / (denom + eps) + bary[mask, 1] = 1 - w + bary[mask, 2] = w + assigned |= mask + + mask = ~assigned + if mask.any(): + denom = (va + vb + vc)[mask] + v = vb[mask] / (denom + eps) + w = vc[mask] / (denom + eps) + bary[mask, 0] = 1 - v - w + bary[mask, 1] = v + bary[mask, 2] = w + assigned |= mask + + if not assigned.all(): + remaining = ~assigned + if remaining.any(): + verts = torch.stack([a, b, c], dim=0) + diff = points[remaining].unsqueeze(1) - verts.unsqueeze(0) + sq = (diff * diff).sum(dim=-1) + _, min_idx = sq.min(dim=-1) + bary_fallback = torch.zeros((min_idx.shape[0], 3), dtype=points.dtype, device=points.device) + bary_fallback.scatter_(1, min_idx.unsqueeze(1), 1.0) + bary[remaining] = bary_fallback + assigned[remaining] = True + + closest = ( + bary[:, 0:1] * a.unsqueeze(0) + + bary[:, 1:2] * b.unsqueeze(0) + + bary[:, 2:3] * c.unsqueeze(0) + ) + diff = closest - points + sq_dist = (diff * diff).sum(dim=-1) + + return sq_dist, bary diff --git a/extensions/CUBVH/docs/bvh_state_device_log.md b/extensions/CUBVH/docs/bvh_state_device_log.md new file mode 100644 index 0000000000000000000000000000000000000000..288a3aaf96f3cb26a6e8c2c7d80a4dc87631bf99 --- /dev/null +++ b/extensions/CUBVH/docs/bvh_state_device_log.md @@ -0,0 +1,45 @@ +# cuBVH State & Device Management Update Log + +This document describes the code changes that enable cuBVH instances to be serialized with `torch.save`, restored with `torch.load`, moved across devices via `.to(...)`, and released cleanly when they go out of scope. + +## Python Front-End (`cubvh/api.py`) + +- Replaced the eager GPU-only implementation handle with a lazily-instantiated backend plus a CPU-resident state cache (`self._state`). +- Added `_pull_state_from_impl()` to copy triangles, triangle ids, and BVH node tensors from CUDA memory to CPU tensors immediately after BVH construction. +- Added `_load_state()` to reconstruct the CPU state from serialized tensors, validating required keys and type expectations. +- Introduced `_instantiate_impl()` and `_release_impl()` to create and destroy the CUDA backend on demand, ensuring GPU memory is only held when the BVH resides on a CUDA device. +- Implemented `to(...)` to support `cpu` โ‡„ `cuda` transfers. Moving to CUDA reconstructs the backend from the cached CPU tensors; moving to CPU frees the CUDA handle. +- Added safeguards so every query (`ray_trace`, `unsigned_distance`, `signed_distance`) ensures the BVH lives on a CUDA device before use. +- Exposed convenience accessors (`triangles_cpu`, `bvh_nodes_cpu`) and `export_state()` for retrieving CPU copies of the serialized data. +- Implemented Python-side pickling helpers (`__getstate__`, `__setstate__`) leveraging the new CPU state, enabling `torch.save` / `torch.load` round-trips. +- Wrapped all CUDA interactions within a `_cuda_device_guard` helper so building, serialization, and query kernels execute on the cuBVH instance's own `device`, eliminating the need for callers to manage global CUDA context and fixing multi-threaded multi-GPU usage. + +## CUDA Binding Layer (`src/api_gpu.cu`, `include/gpu/api_gpu.h`, `src/bindings.cpp`) + +- Augmented `cuBVH::export_state()` to emit tensors for triangle vertices/ids and the BVH node bounding boxes & child indices. +- Added a constructor overload that recreates a CUDA BVH directly from CPU vectors of `Triangle` and `TriangleBvhNode` objects, bypassing the costly rebuild step. +- Plumbed new C++ factory bindings: `create_cuBVH_from_state(...)` mirrors the CPU tensors produced by `export_state()` so Python can lazily rebuild GPU state on demand. +- Updated `include/gpu/api_gpu.h` with the new factory signature and exposed host-node accessors via `TriangleBvh::host_nodes()` / `set_nodes(...)`. +- Ensured BVH node escape-link threading remains available by including `` in `src/bvh.cu`. + +## BVH Core (`src/bvh.cu`, `include/gpu/bvh.cuh`) + +- Exposed host node storage (`host_nodes()`) and setter (`set_nodes(...)`) to allow rehydrating the BVH structure from serialized data. +- Guaranteed that GPU buffers mirror the host nodes after both rebuilds and deserialization by invoking `resize_and_copy_from_host(...)` in the appropriate locations. +- Added the missing `` include required for the threading lambda used during BVH construction. + +## Testing (`test/test_bvh_serialization.py`) + +- Added an executable test that constructs a BVH on CUDA, serializes it with `torch.save`, restores it via `torch.load`, and verifies ray distance results match bit-for-bit. +- Exercised device transitions (`cuda โ†’ cpu โ†’ cuda`) to confirm lazy instantiation works and GPU memory is released when the BVH is moved off-device. +- Validated exported numpy views (`triangles_cpu`, `bvh_nodes_cpu`) and state dictionary contents to ensure downstream tooling can consume serialized data. +- Added a multi-threaded multi-device smoke test (`test/test_bvh_thread_device.py`) that spawns one thread per GPU, builds cuBVH instances, moves them across devices, synchronizes results, and verifies no illegal memory access occurs, confirming the new device guard strategy works without manual CUDA context management. + +## Documentation (`readme.md`) + +- Documented the new `.to(device)` semantics, serialization workflow, and CPU export utilities with a concrete example using `trimesh`. + +## Installation & Evaluation + +- Rebuilt and installed the package locally using `pip install . --no-build-isolation` to pick up the updated extension code. +- Ran the new serialization test script to verify correctness on CUDA hardware. diff --git a/extensions/CUBVH/include/cpu/api_cpu.h b/extensions/CUBVH/include/cpu/api_cpu.h new file mode 100644 index 0000000000000000000000000000000000000000..82acee0497703b296107126dcf1aaeaa7cb95c72 --- /dev/null +++ b/extensions/CUBVH/include/cpu/api_cpu.h @@ -0,0 +1,324 @@ +#pragma once +#include +#include +#include +#include +#include +// CPU sparse marching cubes +#include +#include +// CPU mesh decimator +#include + +#include +#include + +namespace py = pybind11; + +namespace cubvh { + +static py::array_t fill_holes( + py::array_t vertices, + py::array_t faces, + bool return_added, + bool check_containment, + double eps_d, + bool verbose) { + // Validate shapes + auto vbuf = vertices.request(); + auto fbuf = faces.request(); + if (!(vbuf.ndim == 2 && vbuf.shape[1] == 3)) { + throw std::runtime_error("vertices must be of shape [N,3]"); + } + if (!(fbuf.ndim == 2 && fbuf.shape[1] == 3)) { + throw std::runtime_error("faces must be of shape [M,3]"); + } + + const size_t N = static_cast(vbuf.shape[0]); + const size_t M = static_cast(fbuf.shape[0]); + + const float* vptr = static_cast(vbuf.ptr); + const int* fptr = static_cast(fbuf.ptr); + + std::vector V(N); + for (size_t i = 0; i < N; ++i) { + V[i] = Eigen::Vector3f(vptr[3*i+0], vptr[3*i+1], vptr[3*i+2]); + } + + std::vector F(M); + for (size_t i = 0; i < M; ++i) { + F[i] = Eigen::Vector3i(fptr[3*i+0], fptr[3*i+1], fptr[3*i+2]); + } + + cubvh::cpu::HoleFillOptions opt; + opt.checkContainment = check_containment; + opt.eps = static_cast(eps_d); + opt.verbose = verbose; + + if (return_added) { + auto added = cubvh::cpu::fill_holes(V, F, opt); + py::array_t out({(py::ssize_t)added.size(), (py::ssize_t)3}); + auto obuf = out.request(); + int* optr = static_cast(obuf.ptr); + for (size_t i = 0; i < added.size(); ++i) { + optr[3*i+0] = added[i][0]; + optr[3*i+1] = added[i][1]; + optr[3*i+2] = added[i][2]; + } + return out; + } else { + cubvh::cpu::fill_holes_inplace(V, F, opt); + py::array_t out({(py::ssize_t)F.size(), (py::ssize_t)3}); + auto obuf = out.request(); + int* optr = static_cast(obuf.ptr); + for (size_t i = 0; i < F.size(); ++i) { + optr[3*i+0] = F[i][0]; + optr[3*i+1] = F[i][1]; + optr[3*i+2] = F[i][2]; + } + return out; + } +} + +// merge_vertices binding: returns (vertices, faces) after merge +static std::pair, py::array_t> merge_vertices( + py::array_t vertices, + py::array_t faces, + double threshold_d) { + auto vbuf = vertices.request(); + auto fbuf = faces.request(); + if (!(vbuf.ndim == 2 && vbuf.shape[1] == 3)) { + throw std::runtime_error("vertices must be of shape [N,3]"); + } + if (!(fbuf.ndim == 2 && fbuf.shape[1] == 3)) { + throw std::runtime_error("faces must be of shape [M,3]"); + } + const size_t N = static_cast(vbuf.shape[0]); + const size_t M = static_cast(fbuf.shape[0]); + const float* vptr = static_cast(vbuf.ptr); + const int* fptr = static_cast(fbuf.ptr); + + std::vector V(N); + for (size_t i=0;i F(M); + for (size_t i=0;i V_out; std::vector F_out; + cubvh::cpu::merge_vertices(V, F, static_cast(threshold_d), V_out, F_out); + + py::array_t v_out({(py::ssize_t)V_out.size(), (py::ssize_t)3}); + py::array_t f_out({(py::ssize_t)F_out.size(), (py::ssize_t)3}); + auto vObuf = v_out.request(); auto fObuf = f_out.request(); + float* vO = static_cast(vObuf.ptr); + int* fO = static_cast(fObuf.ptr); + for (size_t i=0;i, py::array_t> sparse_marching_cubes_cpu( + py::array_t coords, + py::array_t corners, + double iso_d, + bool ensure_consistency = false) { + + auto cbuf = coords.request(); + auto vbuf = corners.request(); + if (!(cbuf.ndim == 2 && cbuf.shape[1] == 3)) { + throw std::runtime_error("coords must be of shape [N,3] (int32)"); + } + if (!(vbuf.ndim == 2 && vbuf.shape[1] == 8)) { + throw std::runtime_error("corners must be of shape [N,8] (float32)"); + } + if (cbuf.shape[0] != vbuf.shape[0]) { + throw std::runtime_error("coords and corners must have the same first dimension N"); + } + + const int N = static_cast(cbuf.shape[0]); + const int* cptr = static_cast(cbuf.ptr); + const float* fptr = static_cast(vbuf.ptr); + const float iso = static_cast(iso_d); + + auto mesh = cubvh::cpu::sparse_marching_cubes(cptr, fptr, N, iso, ensure_consistency); + const auto& V = mesh.first; + const auto& F = mesh.second; + + // Allocate outputs + py::array_t v_out({(py::ssize_t)V.size(), (py::ssize_t)3}); + py::array_t f_out({(py::ssize_t)F.size(), (py::ssize_t)3}); + auto vObuf = v_out.request(); + auto fObuf = f_out.request(); + float* vO = static_cast(vObuf.ptr); + int* fO = static_cast(fObuf.ptr); + + for (size_t i = 0; i < V.size(); ++i) { + vO[3*i+0] = V[i].x; + vO[3*i+1] = V[i].y; + vO[3*i+2] = V[i].z; + } + for (size_t i = 0; i < F.size(); ++i) { + fO[3*i+0] = F[i].v0; + fO[3*i+1] = F[i].v1; + fO[3*i+2] = F[i].v2; + } + + return {v_out, f_out}; +} + +// CPU decimator bindings +template +static cubvh::cpu::qd::MeshT _mesh_from_numpy_typed( + py::array_t vertices, + py::array_t faces) +{ + if (vertices.ndim() != 2 || vertices.shape(1) != 3) + throw std::runtime_error("vertices must be (N,3) array"); + if (faces.ndim() != 2 || faces.shape(1) != 3) + throw std::runtime_error("faces must be (M,3) int32 array"); + + cubvh::cpu::qd::MeshT m; + m.vertices.reserve(vertices.shape(0)); + auto vbuf = vertices.template unchecked<2>(); + for (ssize_t i = 0; i < vertices.shape(0); ++i) { + m.vertices.emplace_back(vbuf(i,0), vbuf(i,1), vbuf(i,2)); + } + m.faces.reserve(faces.shape(0)); + auto fbuf = faces.template unchecked<2>(); + for (ssize_t i = 0; i < faces.shape(0); ++i) { + m.faces.push_back({ fbuf(i,0), fbuf(i,1), fbuf(i,2) }); + } + return m; +} + +template +static std::pair, py::array_t> _mesh_to_numpy_typed(const cubvh::cpu::qd::MeshT& m) +{ + py::array_t V({ (ssize_t)m.vertices.size(), (ssize_t)3 }); + py::array_t F({ (ssize_t)m.faces.size(), (ssize_t)3 }); + auto vbuf = V.template mutable_unchecked<2>(); + for (ssize_t i = 0; i < (ssize_t)m.vertices.size(); ++i) { + vbuf(i,0) = m.vertices[i].x; + vbuf(i,1) = m.vertices[i].y; + vbuf(i,2) = m.vertices[i].z; + } + auto fbuf = F.template mutable_unchecked<2>(); + for (ssize_t i = 0; i < (ssize_t)m.faces.size(); ++i) { + fbuf(i,0) = m.faces[i][0]; + fbuf(i,1) = m.faces[i][1]; + fbuf(i,2) = m.faces[i][2]; + } + return { V, F }; +} + +static py::tuple decimate(py::array vertices, + py::array faces, + int target_vertices) +{ + py::dtype dt = vertices.dtype(); + if (dt.is(py::dtype::of())){ + auto v = vertices.cast>(); + auto f = faces.cast>(); + auto mesh = _mesh_from_numpy_typed(v, f); + cubvh::cpu::qd::DecimatorT dec(mesh); + dec.decimate(target_vertices); + auto out = _mesh_to_numpy_typed(dec.mesh()); + return py::make_tuple(out.first, out.second); + } else if (dt.is(py::dtype::of())){ + auto v = vertices.cast>(); + auto f = faces.cast>(); + auto mesh = _mesh_from_numpy_typed(v, f); + cubvh::cpu::qd::DecimatorT dec(mesh); + dec.decimate(target_vertices); + auto out = _mesh_to_numpy_typed(dec.mesh()); + return py::make_tuple(out.first, out.second); + } else { + throw std::runtime_error("vertices must be float32 or float64 array"); + } +} + +static py::tuple parallel_decimate(py::array vertices, + py::array faces, + int target_vertices) +{ + py::dtype dt = vertices.dtype(); + if (dt.is(py::dtype::of())){ + auto v = vertices.cast>(); + auto f = faces.cast>(); + auto mesh = _mesh_from_numpy_typed(v, f); + cubvh::cpu::qd::DecimatorT dec(mesh); + dec.parallelDecimate(target_vertices); + auto out = _mesh_to_numpy_typed(dec.mesh()); + return py::make_tuple(out.first, out.second); + } else if (dt.is(py::dtype::of())){ + auto v = vertices.cast>(); + auto f = faces.cast>(); + auto mesh = _mesh_from_numpy_typed(v, f); + cubvh::cpu::qd::DecimatorT dec(mesh); + dec.parallelDecimate(target_vertices); + auto out = _mesh_to_numpy_typed(dec.mesh()); + return py::make_tuple(out.first, out.second); + } else { + throw std::runtime_error("vertices must be float32 or float64 array"); + } +} + +// CPU Hash Table bindings +class HashTable { +public: + HashTable() {} + + void set_num_dims(int d) { ht.set_num_dims(d); } + int get_num_dims() const { return ht.get_num_dims(); } + void resize(int capacity) { ht.resize(capacity); } + void prepare() { ht.prepare(); } + + void insert(at::Tensor coords) { + TORCH_CHECK(!coords.is_cuda(), "coords must reside on CPU"); + TORCH_CHECK(coords.dtype() == at::kInt, "coords must be int32"); + TORCH_CHECK(coords.dim() == 2, "coords must be 2D [N,D]"); + coords_ref_ = coords.contiguous(); + const int N = (int)coords_ref_.size(0); + const int D = (int)coords_ref_.size(1); + ht.set_num_dims(D); + ht.insert(coords_ref_.data_ptr(), N); + } + + void build(at::Tensor coords) { + TORCH_CHECK(!coords.is_cuda(), "coords must reside on CPU"); + TORCH_CHECK(coords.dtype() == at::kInt, "coords must be int32"); + TORCH_CHECK(coords.dim() == 2, "coords must be 2D [N,D]"); + coords_ref_ = coords.contiguous(); + const int N = (int)coords_ref_.size(0); + const int D = (int)coords_ref_.size(1); + ht.set_num_dims(D); + ht.build(coords_ref_.data_ptr(), N); + } + + at::Tensor search(at::Tensor queries) const { + TORCH_CHECK(!queries.is_cuda(), "queries must reside on CPU"); + TORCH_CHECK(queries.dtype() == at::kInt, "queries must be int32"); + TORCH_CHECK(queries.dim() == 2, "queries must be 2D [M,D]"); + TORCH_CHECK(ht.capacity > 0, "hash table is not built"); + at::Tensor q = queries.contiguous(); + const int M = (int)q.size(0); + auto opts_i = torch::TensorOptions().dtype(torch::kInt32).device(q.device()); + at::Tensor out = at::empty({M}, opts_i); + ht.search(q.data_ptr(), M, out.data_ptr()); + return out; + } + +private: + mutable HashTableIntCPU ht; + at::Tensor coords_ref_; +}; + +} // namespace cubvh \ No newline at end of file diff --git a/extensions/CUBVH/include/cpu/decimation.h b/extensions/CUBVH/include/cpu/decimation.h new file mode 100644 index 0000000000000000000000000000000000000000..82d59363510264591d05a59323fd03a183081ef6 --- /dev/null +++ b/extensions/CUBVH/include/cpu/decimation.h @@ -0,0 +1,696 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cubvh { +namespace cpu { +namespace qd { + +// Basic 3D vector (templated) +template +struct Vec3T { + T x, y, z; + Vec3T() : x(T(0)), y(T(0)), z(T(0)) {} + Vec3T(T X, T Y, T Z) : x(X), y(Y), z(Z) {} + T& operator[](int i) { return i==0?x:(i==1?y:z); } + T operator[](int i) const { return i==0?x:(i==1?y:z); } + Vec3T operator+(const Vec3T& o) const { return Vec3T(x+o.x,y+o.y,z+o.z); } + Vec3T operator-(const Vec3T& o) const { return Vec3T(x-o.x,y-o.y,z-o.z); } + Vec3T operator*(T s) const { return Vec3T(x*s,y*s,z*s); } + Vec3T operator/(T s) const { return Vec3T(x/s,y/s,z/s); } + Vec3T& operator+=(const Vec3T& o){ x+=o.x;y+=o.y;z+=o.z; return *this; } + Vec3T& operator-=(const Vec3T& o){ x-=o.x;y-=o.y;z-=o.z; return *this; } + bool operator==(const Vec3T& o) const { return x==o.x && y==o.y && z==o.z; } +}; + +template +inline T dot(const Vec3T& a, const Vec3T& b){ return a.x*b.x + a.y*b.y + a.z*b.z; } +template +inline Vec3T cross(const Vec3T& a, const Vec3T& b){ + return Vec3T(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); +} +template +inline T norm(const Vec3T& v){ return std::sqrt(dot(v,v)); } +template +inline T squared_norm(const Vec3T& v){ return dot(v,v); } +template +inline Vec3T normalize(const Vec3T& v){ T n=norm(v); return n>T(0)? v/n : Vec3T(); } + +// Basic 3x3 matrix (full, templated) +template +struct Mat3T { + // Row-major storage + T m[9]; + Mat3T(){ for(int i=0;i<9;++i) m[i]=T(0); } + static Mat3T identity(){ Mat3T A; A(0,0)=A(1,1)=A(2,2)=T(1); return A; } + T& operator()(int r,int c){ return m[r*3+c]; } + T operator()(int r,int c) const{ return m[r*3+c]; } + Mat3T& operator+=(const Mat3T& B){ for(int i=0;i<9;++i) m[i]+=B.m[i]; return *this; } + Mat3T operator+(const Mat3T& B) const{ Mat3T C=*this; C+=B; return C; } + Mat3T operator*(T s) const{ Mat3T C; for(int i=0;i<9;++i) C.m[i]=m[i]*s; return C; } + Vec3T operator*(const Vec3T& v) const{ + return Vec3T( + m[0]*v.x + m[1]*v.y + m[2]*v.z, + m[3]*v.x + m[4]*v.y + m[5]*v.z, + m[6]*v.x + m[7]*v.y + m[8]*v.z + ); + } + Mat3T transpose() const{ + Mat3T Tt; for(int r=0;r<3;++r) for(int c=0;c<3;++c) Tt(r,c)=(*this)(c,r); return Tt; + } +}; + +template +inline Mat3T outer(const Vec3T& a, const Vec3T& b){ + Mat3T A; A(0,0)=a.x*b.x; A(0,1)=a.x*b.y; A(0,2)=a.x*b.z; + A(1,0)=a.y*b.x; A(1,1)=a.y*b.y; A(1,2)=a.y*b.z; + A(2,0)=a.z*b.x; A(2,1)=a.z*b.y; A(2,2)=a.z*b.z; return A; +} + +template +inline T det(const Mat3T& A){ + return A(0,0)*(A(1,1)*A(2,2)-A(1,2)*A(2,1)) + - A(0,1)*(A(1,0)*A(2,2)-A(1,2)*A(2,0)) + + A(0,2)*(A(1,0)*A(2,1)-A(1,1)*A(2,0)); +} + +template +inline Mat3T adjugate(const Mat3T& A){ + Mat3T C; + C(0,0) = (A(1,1)*A(2,2) - A(1,2)*A(2,1)); + C(0,1) = -(A(1,0)*A(2,2) - A(1,2)*A(2,0)); + C(0,2) = (A(1,0)*A(2,1) - A(1,1)*A(2,0)); + C(1,0) = -(A(0,1)*A(2,2) - A(0,2)*A(2,1)); + C(1,1) = (A(0,0)*A(2,2) - A(0,2)*A(2,0)); + C(1,2) = -(A(0,0)*A(2,1) - A(0,1)*A(2,0)); + C(2,0) = (A(0,1)*A(1,2) - A(0,2)*A(1,1)); + C(2,1) = -(A(0,0)*A(1,2) - A(0,2)*A(1,0)); + C(2,2) = (A(0,0)*A(1,1) - A(0,1)*A(1,0)); + return C.transpose(); +} + +template +inline bool invert(const Mat3T& A, Mat3T& inv){ + T d = det(A); + if (std::fabs(d) < T(1e-12)) return false; + Mat3T adj = adjugate(A); + inv = adj * (T(1)/d); + return true; +} + +// Symmetric quadric: Q(x) = x^T A x + 2 b^T x + c, with A symmetric (templated) +template +struct QuadricT { + // Store upper triangular of A (a00, a01, a02, a11, a12, a22), b(3), c + T a00=T(0),a01=T(0),a02=T(0),a11=T(0),a12=T(0),a22=T(0); + T b0=T(0),b1=T(0),b2=T(0); + T c=T(0); + + QuadricT() = default; + explicit QuadricT(T C) : c(C) {} + QuadricT(const Mat3T& A, const Vec3T& b, T C){ + a00=A(0,0); a01=A(0,1); a02=A(0,2); + a11=A(1,1); a12=A(1,2); a22=A(2,2); + b0=b.x; b1=b.y; b2=b.z; c=C; + } + + Mat3T A() const{ + Mat3T M; M(0,0)=a00; M(0,1)=a01; M(0,2)=a02; + M(1,0)=a01; M(1,1)=a11; M(1,2)=a12; + M(2,0)=a02; M(2,1)=a12; M(2,2)=a22; return M; + } + Vec3T b() const{ return Vec3T(b0,b1,b2); } + T operator()(const Vec3T& x) const{ + Vec3T Ax = A()*x; + return dot(x,Ax) + T(2)*dot(b(),x) + c; + } + bool isZero() const{ + return std::fabs(a00)+std::fabs(a01)+std::fabs(a02)+std::fabs(a11)+std::fabs(a12)+std::fabs(a22)+ + std::fabs(b0)+std::fabs(b1)+std::fabs(b2)+std::fabs(c) < T(1e-15); + } + QuadricT& operator+=(const QuadricT& q){ + a00+=q.a00; a01+=q.a01; a02+=q.a02; a11+=q.a11; a12+=q.a12; a22+=q.a22; + b0+=q.b0; b1+=q.b1; b2+=q.b2; c+=q.c; return *this; + } + QuadricT operator+(const QuadricT& q) const{ QuadricT r=*this; r+=q; return r; } + QuadricT operator*(T s) const{ + QuadricT r; r.a00=a00*s; r.a01=a01*s; r.a02=a02*s; r.a11=a11*s; r.a12=a12*s; r.a22=a22*s; + r.b0=b0*s; r.b1=b1*s; r.b2=b2*s; r.c=c*s; return r; + } + T trace() const{ return a00 + a11 + a22; } +}; + +template +inline QuadricT planeQuadric(const Vec3T& n_unit, const Vec3T& p){ + // distance to plane: nยทx - d, with d = nยทp + T d = dot(n_unit, p); + Mat3T A = outer(n_unit, n_unit); + Vec3T b = n_unit * (-d); + T c = d*d; + return QuadricT(A,b,c); +} + +template +inline QuadricT pointQuadric(const Vec3T& p){ + Mat3T I = Mat3T::identity(); + Vec3T b = Vec3T(-p.x, -p.y, -p.z); + T c = dot(p,p); + return QuadricT(I,b,c); +} + +template +inline bool minimizer(const QuadricT& q, const std::vector>& choices, Vec3T& x_out, T& cost_out){ + Mat3T A = q.A(); + Mat3T Ai; + Vec3T rhs = Vec3T(-q.b0, -q.b1, -q.b2); + bool ok = invert(A, Ai); + if (ok){ + // x = A^{-1} * (-b) + x_out = Ai * rhs; + cost_out = q(x_out); + return true; + } + // fallback: choose best among provided points + x_out = choices.empty() ? Vec3T() : choices[0]; + cost_out = q(x_out); + for(size_t i=1;i +struct MeshT { + std::vector> vertices; + std::vector> faces; // CCW +}; + +// Internal helpers (templated) +template +inline Vec3T faceNormal(const MeshT& m, const std::array& f){ + const Vec3T& a = m.vertices[f[0]]; + const Vec3T& b = m.vertices[f[1]]; + const Vec3T& c = m.vertices[f[2]]; + return cross(b-a, c-a); +} + +template +inline T triangleArea(const MeshT& m, const std::array& f){ + return T(0.5) * norm(faceNormal(m,f)); +} + +inline bool validFace(const std::array& f){ + return f[0]!=f[1] && f[1]!=f[2] && f[2]!=f[0]; +} + +// Edge key utility +struct EdgeKey { + int a,b; + EdgeKey() : a(-1), b(-1) {} + EdgeKey(int i, int j){ if (i +struct EdgeInfo { + int v0, v1; // endpoints (unordered stored with v0 adjacent_faces; // indices into mesh.faces + Vec3T collapse_pos; + T cost; + bool valid = true; +}; + +// Decimator: simple greedy QEM-based +template +class DecimatorT { +public: + explicit DecimatorT(MeshT mesh) : m(mesh) {} + + // Reduce mesh to target vertex count (or until no improvement). + void decimate(int target_vertices){ + target_vertices = std::max(0, target_vertices); + // Build adjacency and initial structures + buildAdjacency(); + buildVertexQuadrics(); + buildEdgeMap(); + // Priority queue with lazy updates + using QEntry = std::pair; + auto cmp = [](const QEntry& a, const QEntry& b){ return a.first > b.first; }; + std::priority_queue, decltype(cmp)> pq(cmp); + for (const auto& kv : edges) { + const EdgeInfo& e = kv.second; + if (e.valid) + pq.emplace(e.cost, kv.first); + } + // Greedy collapses until target or no candidates + while ((int)activeVertexCount() > target_vertices && !pq.empty()) { + auto [cost, key] = pq.top(); pq.pop(); + auto it = edges.find(key); + if (it == edges.end()) continue; + EdgeInfo& e = it->second; + if (!e.valid) continue; + // Recheck stale cost + if (std::fabs(e.cost - cost) > T(1e-9)) { + pq.emplace(e.cost, key); + continue; + } + // Collapse feasibility + if (!canCollapse(e)) { e.valid=false; continue; } + // Apply collapse + if (!applyCollapse(e)) { e.valid=false; continue; } + // Mark this edge invalid + e.valid = false; + // Recompute QEM for affected vertices and update incident edges + updateAroundVertex(e.v0, pq); + } + compact(); + } + + // Parallel-style decimator: selects a vertex-disjoint independent set per + // iteration, collapses, then rebuilds adjacency and costs. + void parallelDecimate(int target_vertices){ + // Initialize + target_vertices = std::max(0, target_vertices); + buildAdjacency(); + buildVertexQuadrics(); + buildEdgeMap(); + + for (int iter = 0; iter < 256; ++iter){ + if ((int)activeVertexCount() <= target_vertices) break; + // Build candidate list (valid edges) and sort by cost + std::vector candidates; candidates.reserve(edges.size()); + for (const auto& kv : edges){ if (kv.second.valid) candidates.push_back(kv.first); } + if (candidates.empty()) break; + std::sort(candidates.begin(), candidates.end(), [&](const EdgeKey& a, const EdgeKey& b){ return edges[a].cost < edges[b].cost; }); + + // Select independent set (vertex-disjoint) with simple topology filter + std::vector used(m.vertices.size(), 0); + std::vector batch; batch.reserve(candidates.size()/4 + 1); + for (const EdgeKey& key : candidates){ + auto it = edges.find(key); + EdgeInfo& e = it->second; + if (!e.valid) continue; + if (used[e.v0] || used[e.v1]) continue; + if (tooManyCommonNeighbors(e)) continue; + if (!canCollapse(e)) continue; + batch.push_back(key); + used[e.v0] = used[e.v1] = 1; + } + + if (batch.empty()) break; + + // Collapse batch sequentially (they are vertex-disjoint) + std::unordered_set deleted_vertices; deleted_vertices.reserve(batch.size()); + for (const EdgeKey& key : batch){ + auto it = edges.find(key); + if (it == edges.end()) continue; + EdgeInfo& e = it->second; + if (!e.valid) continue; + int v1 = e.v1; + if (!applyCollapse(e)) { e.valid=false; continue; } + e.valid = false; + if (v1>=0) deleted_vertices.insert(v1); + } + // Rebuild adjacency and costs for correctness and speed + buildAdjacency(); + buildVertexQuadrics(); + buildEdgeMap(); + } + + compact(); + } + // Count common neighbors of an edgeโ€™s endpoints; reject if too many. + bool tooManyCommonNeighbors(const EdgeInfo& e) const { + // Collect neighbor sets for v0 and v1, excluding the opposite endpoint + // and excluding the third vertices of faces incident to this edge. + std::unordered_set n0; n0.reserve(16); + std::unordered_set n1; n1.reserve(16); + + // Determine third vertices of faces adjacent to this edge + std::unordered_set third; third.reserve(4); + for (int fi : e.adjacent_faces){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + for (int k=0;k<3;++k){ + int vk = f[k]; + if (vk!=e.v0 && vk!=e.v1) third.insert(vk); + } + } + + auto collect = [&](int v, std::unordered_set& out){ + for (int fi : v_faces[v]){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + for (int k=0;k<3;++k){ + int u = f[k]; + if (u==v) continue; + if (u==e.v0 || u==e.v1) continue; // exclude edge endpoints + if (third.find(u) != third.end()) continue; // exclude third vertices + out.insert(u); + } + } + }; + collect(e.v0, n0); + collect(e.v1, n1); + + // Count intersection + int common = 0; + if (n0.size() < n1.size()){ + for (int u : n0) common += (n1.find(u) != n1.end()); + } else { + for (int u : n1) common += (n0.find(u) != n0.end()); + } + // Boundary edges should have <=1 common neighbor; interior <=2 + int max_common = (int)e.adjacent_faces.size() == 1 ? 1 : 2; + return common > max_common; + } + + const MeshT& mesh() const { return m; } + +private: + MeshT m; + std::vector> vq; // per-vertex quadrics + std::vector> v_faces; // incident face indices + std::unordered_map, EdgeKeyHash> edges; + std::vector v_deleted; // 1 if removed + std::vector v_boundary; // 1 if boundary vertex + + size_t currentVertexCount() const { return m.vertices.size(); } + size_t activeVertexCount() const { + std::vector used(m.vertices.size(), 0); + for (const auto& f : m.faces){ + if (!validFace(f)) continue; + if (f[0]>=0 && f[0]<(int)used.size()) used[f[0]] = 1; + if (f[1]>=0 && f[1]<(int)used.size()) used[f[1]] = 1; + if (f[2]>=0 && f[2]<(int)used.size()) used[f[2]] = 1; + } + size_t cnt=0; for(char u: used) if(u) ++cnt; return cnt; + } + + void buildAdjacency(){ + v_faces.assign(m.vertices.size(), {}); + v_deleted.assign(m.vertices.size(), 0); + for (int fi=0; fi<(int)m.faces.size(); ++fi){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + v_faces[f[0]].push_back(fi); + v_faces[f[1]].push_back(fi); + v_faces[f[2]].push_back(fi); + } + } + + void buildVertexQuadrics(){ + vq.assign(m.vertices.size(), QuadricT()); + for (size_t v=0; v qsum; + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + Vec3T a = m.vertices[f[0]]; + Vec3T b = m.vertices[f[1]]; + Vec3T c = m.vertices[f[2]]; + Vec3T n = faceNormal(m, f); + T area = T(0.5)*norm(n); + if (area <= T(0)) continue; + Vec3T nu = normalize(n); + // quadric through the specific vertex position + Vec3T xi = m.vertices[v]; + qsum += planeQuadric(nu, xi) * area; + } + vq[v] = qsum; + } + } + + void buildEdgeMap(){ + edges.clear(); + edges.reserve(m.faces.size()*2); + auto add_edge = [&](int i, int j, int fi){ + if (i==j) return; + EdgeKey key(i,j); + auto it = edges.find(key); + if (it==edges.end()){ + EdgeInfo info; info.v0 = std::min(i,j); info.v1 = std::max(i,j); + info.cost = std::numeric_limits::infinity(); + info.adjacent_faces.clear(); info.collapse_pos = Vec3T(); info.valid=true; + it = edges.emplace(key, info).first; + } + it->second.adjacent_faces.push_back(fi); + }; + for (int fi=0; fi<(int)m.faces.size(); ++fi){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + add_edge(f[0], f[1], fi); + add_edge(f[1], f[2], fi); + add_edge(f[2], f[0], fi); + } + // mark boundary vertices + v_boundary.assign(m.vertices.size(), 0); + for (const auto& kv : edges){ + const EdgeInfo& e = kv.second; + if ((int)e.adjacent_faces.size() == 1){ + if (e.v0 >=0 && e.v0 < (int)v_boundary.size()) v_boundary[e.v0] = 1; + if (e.v1 >=0 && e.v1 < (int)v_boundary.size()) v_boundary[e.v1] = 1; + } + } + // compute initial costs + for (auto& kv : edges){ updateEdgeCost(kv.second); } + } + + void updateEdgeCost(EdgeInfo& e){ + if (v_deleted[e.v0] || v_deleted[e.v1]) { e.valid=false; return; } + QuadricT q = vq[e.v0] + vq[e.v1]; + Vec3T x0 = m.vertices[e.v0]; + Vec3T x1 = m.vertices[e.v1]; + Vec3T xm = (x0 + x1) * T(0.5); + if (q.trace() <= T(1e-12)) { + // Stabilize with area-scaled point quadric at midpoint + T area_sum = T(0); + for (int fi : e.adjacent_faces){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + area_sum += triangleArea(m, f); + } + T scale = std::max(T(1e-12), area_sum) * T(1e-9); + q = q + pointQuadric(xm) * scale; + } + Vec3T x; T cost; + minimizer(q, {x0,x1,xm}, x, cost); + e.collapse_pos = x; e.cost = cost; + e.valid = true; + } + + bool canCollapse(const EdgeInfo& e){ + // Keep openings intact: forbid collapsing any edge incident to a boundary vertex + if (isBoundaryVertex(e.v0) || isBoundaryVertex(e.v1)) return false; + // Prevent drastic normal flips: for each adjacent face, simulate collapse + Vec3T x = e.collapse_pos; + for (int fi : e.adjacent_faces){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + std::array,3> P = { m.vertices[f[0]], m.vertices[f[1]], m.vertices[f[2]] }; + if (f[0]==e.v0 || f[0]==e.v1) P[0] = x; + if (f[1]==e.v0 || f[1]==e.v1) P[1] = x; + if (f[2]==e.v0 || f[2]==e.v1) P[2] = x; + Vec3T e0 = P[1]-P[0]; + Vec3T e1 = P[2]-P[0]; + if (squared_norm(e0) < T(1e-24) || squared_norm(e1) < T(1e-24)) continue; + Vec3T n_before = faceNormal(m, f); + Vec3T n_after = cross(e0, e1); + T nb2 = squared_norm(n_before); + T na2 = squared_norm(n_after); + if (nb2>T(0) && na2>T(0)){ + T ndot = dot(n_before, n_after); + // Reject flips + if (ndot < T(0)) return false; + // Reject large rotations: cos(theta) < 0.5 + if (ndot*ndot < T(0.25) * nb2 * na2) return false; + } + } + return true; + } + + bool applyCollapse(const EdgeInfo& e){ + // Merge v1 into v0, set position to collapse_pos + int v0 = e.v0, v1 = e.v1; + if (v_deleted[v0] || v_deleted[v1]) return false; + m.vertices[v0] = e.collapse_pos; + // Gather affected faces: union of v_faces[v0] and v_faces[v1] + std::vector affected = v_faces[v0]; + affected.insert(affected.end(), v_faces[v1].begin(), v_faces[v1].end()); + // Update faces: replace v1 with v0; mark degenerate faces invalid as {-1,-1,-1} + for (int fi : affected){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + auto& f = m.faces[fi]; + for (int k=0;k<3;++k){ if (f[k]==v1) f[k]=v0; } + if (!validFace(f)) { f = { -1,-1,-1 }; } + } + // Update adjacency: clear v_faces[v0], rebuild by scanning affected faces + v_faces[v0].clear(); + for (int fi : affected){ + if (fi < 0 || fi >= (int)m.faces.size()) continue; + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + if (f[0]==v0 || f[1]==v0 || f[2]==v0) v_faces[v0].push_back(fi); + } + // Mark v1 deleted + v_deleted[v1] = 1; + v_faces[v1].clear(); + // Remove edges incident to v1 + // We leave them invalid; theyโ€™ll be skipped lazily + return true; + } + + void compact(){ + // Remove isolated vertices and reindex + std::vector used(m.vertices.size(), 0); + for (auto& f : m.faces){ + if (!validFace(f)) continue; + for(int k=0;k<3;++k) if (f[k]>=0 && f[k]<(int)used.size()) used[f[k]] = 1; + } + + std::vector newIndex(m.vertices.size(), -1); + std::vector> nv; nv.reserve(m.vertices.size()); + for (size_t i=0;i> nf; nf.reserve(m.faces.size()); + for (auto& f : m.faces){ + if (!validFace(f)) continue; + std::array g = { newIndex[f[0]], newIndex[f[1]], newIndex[f[2]] }; + if (validFace(g)) nf.push_back(g); + } + m.vertices.swap(nv); + m.faces.swap(nf); + } + + bool isBoundaryVertex(int v) const { + if (v < 0 || v >= (int)v_boundary.size()) return false; + return v_boundary[v] != 0; + } + + void updateVertexQEM(int v){ + QuadricT qsum; + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + Vec3T n = faceNormal(m,f); + T area = T(0.5)*norm(n); + if (area <= T(0)) continue; + Vec3T nu = normalize(n); + qsum += planeQuadric(nu, m.vertices[v]) * area; + } + vq[v] = qsum; + } + + template + void updateAroundVertex(int v, PQ &pq){ + // Recompute QEM for v and neighbors, update incident edges in queue + updateVertexQEM(v); + // Collect neighbor vertices from incident faces + std::unordered_set nbr; + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + for (int k=0;k<3;++k){ if (f[k]!=v) nbr.insert(f[k]); } + } + for (int u : nbr){ updateVertexQEM(u); } + // Update edges (v,u) + for (int u : nbr){ + if (v_deleted[u]) continue; + EdgeKey key(v,u); + auto it = edges.find(key); + if (it == edges.end()){ + // create edge if faces define it + EdgeInfo info; info.v0 = std::min(v,u); info.v1 = std::max(v,u); info.valid=true; + // find adjacency faces with both v and u + info.adjacent_faces.clear(); + // scan v_faces[v] + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + bool hasu = (f[0]==u || f[1]==u || f[2]==u); + bool hasv = (f[0]==v || f[1]==v || f[2]==v); + if (hasu && hasv) info.adjacent_faces.push_back(fi); + } + edges.emplace(key, info); + updateEdgeCost(edges.find(key)->second); + pq.emplace(edges.find(key)->second.cost, key); + } else { + updateEdgeCost(it->second); + if (it->second.valid) pq.emplace(it->second.cost, key); + } + } + } + + void updateAroundVertexLocal(int v){ + // Recompute QEM for v and neighbors, update incident edges without queue + updateVertexQEM(v); + std::unordered_set nbr; + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + for (int k=0;k<3;++k){ if (f[k]!=v) nbr.insert(f[k]); } + } + for (int u : nbr){ updateVertexQEM(u); } + // Update or create edges (v,u) + for (int u : nbr){ + if (v_deleted[u]) continue; + EdgeKey key(v,u); + auto it = edges.find(key); + if (it == edges.end()){ + EdgeInfo info; info.v0 = std::min(v,u); info.v1 = std::max(v,u); info.valid=true; + info.adjacent_faces.clear(); + // scan v_faces[v] + for (int fi : v_faces[v]){ + const auto& f = m.faces[fi]; + if (!validFace(f)) continue; + bool hasu = (f[0]==u || f[1]==u || f[2]==u); + bool hasv = (f[0]==v || f[1]==v || f[2]==v); + if (hasu && hasv) info.adjacent_faces.push_back(fi); + } + edges.emplace(key, info); + updateEdgeCost(edges.find(key)->second); + } else { + updateEdgeCost(it->second); + } + } + } +}; + +// Backward-compatible double-precision aliases and float alternatives +using Vec3d = Vec3T; +using Vec3f = Vec3T; +using Mat3d = Mat3T; +using Mat3f = Mat3T; +using Quadricd = QuadricT; +using Quadricf = QuadricT; +using Meshd = MeshT; +using Meshf = MeshT; +using Decimatord = DecimatorT; +using Decimatorf = DecimatorT; + +// Preserve previous non-templated type names as double-precision defaults +using Vec3 = Vec3d; +using Mat3 = Mat3d; +using Quadric = Quadricd; +using Mesh = Meshd; +using Decimator = Decimatord; + +} // namespace qd +} // namespace cpu +} // namespace cubvh diff --git a/extensions/CUBVH/include/cpu/fill_holes.h b/extensions/CUBVH/include/cpu/fill_holes.h new file mode 100644 index 0000000000000000000000000000000000000000..78f0500897f3aae96c00fdd6bd3feeafe1c3c628 --- /dev/null +++ b/extensions/CUBVH/include/cpu/fill_holes.h @@ -0,0 +1,430 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cubvh { +namespace cpu { + +using Vec3f = Eigen::Vector3f; +using Vec3i = Eigen::Vector3i; + +struct HoleFillOptions { + // If true, run a point-in-triangle test to avoid creating triangles + // that contain other boundary vertices. Slightly slower but safer. + bool checkContainment = true; + // Numerical tolerance when checking convexity/containment in 2D. + float eps = 1e-8f; + // Safety bound to avoid infinite loops on degenerate inputs. + int maxWalk = 100000; + // If true, print summary and per-ear logs during hole filling. + bool verbose = false; +}; + +namespace detail { + +inline uint64_t pack_undirected(int a, int b) { + if (a > b) std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); +} + +inline uint64_t pack_directed(int a, int b) { + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); +} + +// Build boundary adjacency (outgoing directed boundary edges per vertex) and list of all boundary directed edges. +inline void build_boundary(const std::vector& F, + std::unordered_map>& out_adj, + std::vector>& boundary_dir_edges) { + std::unordered_map undirected_count; + undirected_count.reserve(F.size() * 3); + + // First pass: count undirected edges + for (const auto& f : F) { + int a = f[0], b = f[1], c = f[2]; + uint64_t kab = pack_undirected(a,b); + uint64_t kbc = pack_undirected(b,c); + uint64_t kca = pack_undirected(c,a); + ++undirected_count[kab]; + ++undirected_count[kbc]; + ++undirected_count[kca]; + } + + // Second pass: collect boundary directed edges + out_adj.clear(); + boundary_dir_edges.clear(); + out_adj.reserve(undirected_count.size()); + + auto add_dir_if_boundary = [&](int u, int v) { + if (undirected_count[pack_undirected(u,v)] == 1) { + out_adj[u].push_back(v); + boundary_dir_edges.emplace_back(u, v); + } + }; + + for (const auto& f : F) { + int a = f[0], b = f[1], c = f[2]; + add_dir_if_boundary(a,b); + add_dir_if_boundary(b,c); + add_dir_if_boundary(c,a); + } +} + +// Extract closed boundary loops by walking boundary directed edges. +inline std::vector> extract_loops( + const std::unordered_map>& out_adj, + const std::vector>& boundary_dir_edges, + const HoleFillOptions& opt) { + + std::unordered_set visited; + visited.reserve(boundary_dir_edges.size()*2); + std::vector> loops; + loops.reserve(boundary_dir_edges.size() / 3); + + for (const auto& e : boundary_dir_edges) { + int start = e.first; + int next = e.second; + uint64_t key = pack_directed(start, next); + if (visited.find(key) != visited.end()) continue; + + std::vector loop; + loop.reserve(64); + loop.push_back(start); + + int prev = start; + int curr = next; + visited.insert(key); + + int steps = 0; + bool closed = false; + while (steps++ < opt.maxWalk) { + loop.push_back(curr); + if (curr == start) { closed = true; break; } + + auto it = out_adj.find(curr); + if (it == out_adj.end() || it->second.empty()) break; // dead end + + // Prefer edge that doesn't go back to prev; if multiple exist, pick the first unvisited. + const auto& outs = it->second; + int pick = -1; + for (int v : outs) { + if (v == prev) continue; + uint64_t k2 = pack_directed(curr, v); + if (visited.find(k2) == visited.end()) { pick = v; break; } + } + if (pick == -1) { + // fallback: if only back edge available, use it once to try to close + for (int v : outs) { pick = v; break; } + } + if (pick == -1) break; + + visited.insert(pack_directed(curr, pick)); + prev = curr; + curr = pick; + } + + if (closed && loop.size() > 2) { + // Remove duplicated last == first if present + if (!loop.empty() && loop.front() == loop.back()) loop.pop_back(); + // Filter out tiny loops or degenerate duplicates + bool ok = true; + if ((int)loop.size() < 3) ok = false; + if (ok) loops.emplace_back(std::move(loop)); + } + } + + return loops; +} + +// Fit a best-fit plane and project points to 2D +inline void project_to_plane(const std::vector& V, const std::vector& loop, + std::vector& P2, Eigen::Vector3f& n_out) { + // Compute centroid + Eigen::Vector3f c(0,0,0); + for (int vid : loop) c += V[vid]; + c /= float(loop.size()); + + // Covariance + Eigen::Matrix3f C = Eigen::Matrix3f::Zero(); + for (int vid : loop) { + Eigen::Vector3f d = V[vid] - c; + C += d * d.transpose(); + } + Eigen::SelfAdjointEigenSolver es(C); + // Normal is eigenvector with smallest eigenvalue + Eigen::Vector3f n = es.eigenvectors().col(0); + n.normalize(); + n_out = n; + + // Build an orthonormal basis (u,v) on the plane + Eigen::Vector3f t = (std::abs(n.x()) < 0.9f) ? Eigen::Vector3f(1,0,0) : Eigen::Vector3f(0,1,0); + Eigen::Vector3f u = (t - t.dot(n) * n).normalized(); + Eigen::Vector3f v = n.cross(u); + + P2.resize(loop.size()); + for (size_t i = 0; i < loop.size(); ++i) { + const Eigen::Vector3f& p = V[loop[i]]; + Eigen::Vector3f d = p - c; + P2[i] = Eigen::Vector2f(d.dot(u), d.dot(v)); + } +} + +inline float polygon_signed_area_2d(const std::vector& P) { + double a = 0.0; + size_t n = P.size(); + for (size_t i = 0, j = n - 1; i < n; j = i++) { + a += double(P[j].x()) * double(P[i].y()) - double(P[i].x()) * double(P[j].y()); + } + return float(0.5 * a); +} + +inline bool point_in_triangle_2d(const Eigen::Vector2f& p, + const Eigen::Vector2f& a, + const Eigen::Vector2f& b, + const Eigen::Vector2f& c, + float eps) { + // Barycentric technique + Eigen::Vector2f v0 = b - a; + Eigen::Vector2f v1 = c - a; + Eigen::Vector2f v2 = p - a; + float d00 = v0.dot(v0); + float d01 = v0.dot(v1); + float d11 = v1.dot(v1); + float d20 = v2.dot(v0); + float d21 = v2.dot(v1); + float denom = d00 * d11 - d01 * d01; + if (std::abs(denom) < eps) return false; // degenerate + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + return u >= -eps && v >= -eps && w >= -eps; +} + +inline float angle_score(const Eigen::Vector2f& pm, + const Eigen::Vector2f& p, + const Eigen::Vector2f& pp) { + Eigen::Vector2f d0 = p - pm; + Eigen::Vector2f d1 = pp - p; + float cross_z = d0.x() * d1.y() - d0.y() * d1.x(); + float dot = d0.dot(d1); + return std::atan2(std::abs(cross_z), -dot); +} + +} // namespace detail + +// Fill holes in-place: append new triangles to F using indices into V. +inline void fill_holes_inplace(const std::vector& V, + std::vector& F, + const HoleFillOptions& opt = {}) { + using namespace detail; + + // 1) Build boundary adjacency & collect directed boundary edges + std::unordered_map> out_adj; + std::vector> boundary_dir_edges; + build_boundary(F, out_adj, boundary_dir_edges); + if (boundary_dir_edges.empty()) { + if (opt.verbose) { + std::cout << "[fill_holes] No boundary edges found. Nothing to fill.\n"; + } + return; + } + + // Build directed edge -> face index map and face normals for orientation alignment + std::unordered_map edge2face; + edge2face.reserve(F.size() * 3); + std::vector face_normals(F.size()); + for (size_t fi = 0; fi < F.size(); ++fi) { + const auto& f = F[fi]; + int a = f[0], b = f[1], c = f[2]; + Eigen::Vector3f n = (V[b] - V[a]).cross(V[c] - V[a]); // respect input winding + face_normals[fi] = n; + edge2face[pack_directed(a,b)] = (int)fi; + edge2face[pack_directed(b,c)] = (int)fi; + edge2face[pack_directed(c,a)] = (int)fi; + } + + // 2) Extract closed loops + auto loops = extract_loops(out_adj, boundary_dir_edges, opt); + if (opt.verbose) { + std::cout << "[fill_holes] Found " << loops.size() << " boundary loop(s).\n"; + } + if (loops.empty()) return; + + // 3) Triangulate each loop with ear clipping prioritizing sharp convex ears + for (size_t li = 0; li < loops.size(); ++li) { + const auto& loop = loops[li]; + if (opt.verbose) { + std::cout << "[fill_holes] Loop " << li << " size: " << loop.size() << "\n"; + } + if (loop.size() < 3) continue; + + // Project to 2D for robust ear clipping + std::vector P2; + Eigen::Vector3f n_plane; + project_to_plane(V, loop, P2, n_plane); + + float area = polygon_signed_area_2d(P2); + // if (std::abs(area) < opt.eps) { + // if (opt.verbose) { + // std::cout << "[fill_holes] Loop " << li << " nearly degenerate. Skipping.\n"; + // } + // continue; // nearly degenerate + // } + float orient = (area > 0.0f) ? 1.0f : -1.0f; // CCW positive + + // Estimate desired orientation from adjacent face normals along the boundary loop + Eigen::Vector3f target_n(0,0,0); + int L = (int)loop.size(); + for (int i = 0; i < L; ++i) { + int u = loop[i]; + int v = loop[(i + 1) % L]; + auto it = edge2face.find(pack_directed(u, v)); + if (it != edge2face.end()) { + target_n += face_normals[it->second]; + } else { + auto it2 = edge2face.find(pack_directed(v, u)); + if (it2 != edge2face.end()) target_n += face_normals[it2->second]; + } + } + if (target_n.squaredNorm() == 0.0f) target_n = n_plane; + target_n.normalize(); + + auto fix_winding = [&](Vec3i& tri) { + const Eigen::Vector3f& A = V[tri[0]]; + const Eigen::Vector3f& B = V[tri[1]]; + const Eigen::Vector3f& C = V[tri[2]]; + Eigen::Vector3f ntri = (B - A).cross(C - A); + if (ntri.dot(target_n) < 0.0f) std::swap(tri[1], tri[2]); + }; + + // Indices into 'loop' / P2 for current polygon boundary + std::vector idx(loop.size()); + for (size_t i = 0; i < loop.size(); ++i) idx[i] = int(i); + + auto is_convex = [&](int i)->bool { + int nvert = (int)idx.size(); + int i0 = idx[(i - 1 + nvert) % nvert]; + int i1 = idx[i]; + int i2 = idx[(i + 1) % nvert]; + const auto& a = P2[i0]; + const auto& b = P2[i1]; + const auto& c = P2[i2]; + Eigen::Vector2f ab = b - a; + Eigen::Vector2f bc = c - b; + float cz = ab.x() * bc.y() - ab.y() * bc.x(); + return orient * cz > 0.0f; // same sign as polygon orientation + }; + + auto triangle_contains_no_other = [&](int i)->bool { + if (!opt.checkContainment) return true; + int nvert = (int)idx.size(); + int i0 = idx[(i - 1 + nvert) % nvert]; + int i1 = idx[i]; + int i2 = idx[(i + 1) % nvert]; + const auto& a = P2[i0]; + const auto& b = P2[i1]; + const auto& c = P2[i2]; + for (int k = 0; k < nvert; ++k) { + if (k == (i - 1 + nvert) % nvert || k == i || k == (i + 1) % nvert) continue; + if (point_in_triangle_2d(P2[idx[k]], a, b, c, opt.eps)) return false; + } + return true; + }; + + // Repeatedly clip ears + int guard = 0; + while (idx.size() >= 3 && guard++ < opt.maxWalk) { + if (idx.size() == 3) { + // Final triangle + Vec3i tri(loop[idx[0]], loop[idx[1]], loop[idx[2]]); + fix_winding(tri); + F.emplace_back(tri); + if (opt.verbose) { + std::cout << "[fill_holes] Loop " << li << " add final tri: (" + << tri[0] << ", " << tri[1] << ", " << tri[2] << ")\n"; + } + break; + } + + int nvert = (int)idx.size(); + int best_i = -1; + float best_score = std::numeric_limits::infinity(); + + for (int i = 0; i < nvert; ++i) { + if (!is_convex(i)) continue; + if (!triangle_contains_no_other(i)) continue; + int ip = idx[(i - 1 + nvert) % nvert]; + int ic = idx[i]; + int in = idx[(i + 1) % nvert]; + float score = angle_score(P2[ip], P2[ic], P2[in]); + if (score < best_score) { best_score = score; best_i = i; } + } + + if (best_i == -1) { + // Fallback: allow any convex vertex (skip containment) + for (int i = 0; i < nvert; ++i) { + if (!is_convex(i)) continue; + int ip = idx[(i - 1 + nvert) % nvert]; + int ic = idx[i]; + int in = idx[(i + 1) % nvert]; + float score = angle_score(P2[ip], P2[ic], P2[in]); + if (score < best_score) { best_score = score; best_i = i; } + } + } + + if (best_i == -1) { + // As a last resort, clip the first available ear to make progress + int i = 0; + int ip = idx[(i - 1 + nvert) % nvert]; + int ic = idx[i]; + int in = idx[(i + 1) % nvert]; + Vec3i tri(loop[ip], loop[ic], loop[in]); + fix_winding(tri); + F.emplace_back(tri); + if (opt.verbose) { + std::cout << "[fill_holes] Loop " << li << " add fallback tri: (" + << tri[0] << ", " << tri[1] << ", " << tri[2] << ")\n"; + } + idx.erase(idx.begin() + i); + continue; + } + + int ip = idx[(best_i - 1 + nvert) % nvert]; + int ic = idx[best_i]; + int in = idx[(best_i + 1) % nvert]; + Vec3i tri(loop[ip], loop[ic], loop[in]); + fix_winding(tri); + F.emplace_back(tri); + if (opt.verbose) { + std::cout << "[fill_holes] Loop " << li << " add tri: (" + << tri[0] << ", " << tri[1] << ", " << tri[2] << ")\n"; + } + idx.erase(idx.begin() + best_i); + } + } +} + +// Return the new triangles that would be added (without modifying input F) +inline std::vector fill_holes(const std::vector& V, + const std::vector& F, + const HoleFillOptions& opt = {}) { + std::vector F_all = F; // copy + fill_holes_inplace(V, F_all, opt); + // Return only the newly-added ones + std::vector added; + if (F_all.size() > F.size()) { + added.insert(added.end(), F_all.begin() + (ptrdiff_t)F.size(), F_all.end()); + } + return added; +} + +} // namespace cpu +} // namespace cubvh diff --git a/extensions/CUBVH/include/cpu/hashtable.h b/extensions/CUBVH/include/cpu/hashtable.h new file mode 100644 index 0000000000000000000000000000000000000000..85cf92892782d0575055b225b44008f313124cdd --- /dev/null +++ b/extensions/CUBVH/include/cpu/hashtable.h @@ -0,0 +1,153 @@ +#pragma once + +#include +#include +#include + +namespace cubvh { + +// --- N-dim integer static hash table (CPU) --- +// This mirrors the CUDA version in include/gpu/hashtable.cuh, but operates on host memory. +// Notes: +// - Static, open-addressed table with linear probing. +// - Keys are rows of int32 of length num_dims in a contiguous buffer. +// - Table storage layout: table_kvs[2 * capacity] +// table_kvs[2*s + 0] = slot marker (-1 empty; any other value => occupied) +// table_kvs[2*s + 1] = row index into coords (0..N-1) or -1 + +// --- Hash helper (CityHash-like mix for 32-bit ints) --- +inline uint32_t _hash_city32_step_cpu(uint32_t hash_val, uint32_t key) { + hash_val += key * 0x9E3779B9u; + hash_val ^= hash_val >> 16; + hash_val *= 0x85EBCA6Bu; + hash_val ^= hash_val >> 13; + hash_val *= 0xC2B2AE35u; + hash_val ^= hash_val >> 16; + return hash_val; +} + +struct CityHashCPU { + inline static int hash(const int* key, int key_dim, int capacity) { + uint32_t h = 0u; + for (int i = 0; i < key_dim; ++i) { + h = _hash_city32_step_cpu(h, static_cast(key[i])); + } + int signed_h = static_cast(h); + int slot = signed_h % capacity; + if (slot < 0) slot += capacity; + return slot; + } +}; + +inline bool _vec_equal_cpu(const int* a, const int* b, int dim) { + // Fast-path common small dimensions + if (dim == 3) { + return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]; + } + if (dim == 4) { + return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]; + } + for (int i = 0; i < dim; ++i) { + if (a[i] != b[i]) return false; + } + return true; +} + +inline int _search_hash_table_cpu( + const int* table_kvs, // [capacity * 2] + const int* coords, // [N * num_dims] + const int* query_key, // [num_dims] + int table_capacity, + int num_dims +) { + int slot = CityHashCPU::hash(query_key, num_dims, table_capacity); + const int begin = slot; + int attempts = 0; + while (attempts < table_capacity) { + const int marker = table_kvs[slot * 2 + 0]; + if (marker == -1) { + return -1; // empty => absent + } + const int vec_idx = table_kvs[slot * 2 + 1]; + if (vec_idx != -1) { + const int* candidate = &coords[vec_idx * num_dims]; + if (_vec_equal_cpu(candidate, query_key, num_dims)) { + return vec_idx; + } + } + slot = (slot + 1) % table_capacity; + if (slot == begin) return -1; // full cycle + ++attempts; + } + return -1; +} + +struct HashTableIntCPU { + std::vector table_kvs; // length = 2 * capacity + int capacity = 0; + const int* h_coords = nullptr; // external storage [num_coords * num_dims] + int num_coords = 0; + int num_dims = 3; + + inline void set_num_dims(int d) { num_dims = d; } + inline int get_num_dims() const { return num_dims; } + + void resize(int new_capacity) { + capacity = new_capacity; + table_kvs.assign(static_cast(capacity) * 2, -1); + } + + void prepare() { + if (capacity <= 0) return; + std::fill(table_kvs.begin(), table_kvs.end(), -1); + } + + void insert(const int* h_coords_in, int n_keys) { + h_coords = h_coords_in; + num_coords = n_keys; + if (capacity <= 0 || n_keys <= 0) return; + + // For efficiency, keep local raw ptr + int* kv = table_kvs.data(); + const int D = num_dims; + for (int idx = 0; idx < n_keys; ++idx) { + const int* key = &h_coords[idx * D]; + int slot = CityHashCPU::hash(key, D, capacity); + const int begin = slot; + int attempts = 0; + while (attempts < capacity) { + int& marker = kv[slot * 2 + 0]; + if (marker == -1) { + marker = slot; // claim + kv[slot * 2 + 1] = idx; // publish index + break; + } + slot = (slot + 1) % capacity; + if (slot == begin) break; // table full + ++attempts; + } + } + } + + void build(const int* h_coords_in, int n_keys) { + int desired_capacity = n_keys * 2; + if (desired_capacity < 16) desired_capacity = 16; + resize(desired_capacity); + prepare(); + insert(h_coords_in, n_keys); + } + + void search(const int* h_queries, int n_queries, int* h_out_indices) const { + if (capacity <= 0 || n_queries <= 0) return; + const int D = num_dims; + const int* kv = table_kvs.data(); + for (int i = 0; i < n_queries; ++i) { + const int* q = &h_queries[i * D]; + h_out_indices[i] = _search_hash_table_cpu(kv, h_coords, q, capacity, D); + } + } +}; + +} // namespace cubvh + + diff --git a/extensions/CUBVH/include/cpu/merge_vertices.h b/extensions/CUBVH/include/cpu/merge_vertices.h new file mode 100644 index 0000000000000000000000000000000000000000..2e5a1602e6370a6df0409f621681bc93fb4702d2 --- /dev/null +++ b/extensions/CUBVH/include/cpu/merge_vertices.h @@ -0,0 +1,127 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cubvh { +namespace cpu { + +using Vec3f = Eigen::Vector3f; +using Vec3i = Eigen::Vector3i; + +// Merge vertices of a mesh that are closer than a given threshold. +// Simple uniform grid hashing + Union-Find. Produces averaged vertex positions. +// Degenerate faces (with repeated vertex indices) are removed; duplicate faces (unordered) removed. +inline void merge_vertices( + const std::vector& V_in, + const std::vector& F_in, + float threshold, + std::vector& V_out, + std::vector& F_out) { + + const size_t N = V_in.size(); + if (N == 0) { V_out.clear(); F_out.clear(); return; } + if (threshold <= 0.0f) { V_out = V_in; F_out = F_in; return; } + const float thresh2 = threshold * threshold; + + // DSU + std::vector parent(N), rankv(N,0); + std::iota(parent.begin(), parent.end(), 0); + auto find = [&](int x){ while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } return x; }; + auto unite = [&](int a, int b){ a = find(a); b = find(b); if (a==b) return; if (rankv[a] < rankv[b]) std::swap(a,b); parent[b]=a; if (rankv[a]==rankv[b]) ++rankv[a]; }; + + // Spatial hashing (uniform grid cells of size = threshold) + struct KeyHash { size_t operator()(const int64_t k) const noexcept { return std::hash()(k); } }; + std::unordered_map, KeyHash> grid; grid.reserve(N*2); + auto cell_key = [&](int ix, int iy, int iz)->int64_t { + // Large primes mixing + return int64_t(ix) * 73856093LL ^ int64_t(iy) * 19349663LL ^ int64_t(iz) * 83492791LL; + }; + + std::vector ix(N), iy(N), iz(N); + const float inv = 1.0f / threshold; + for (int i=0;i<(int)N;++i) { + ix[i] = (int)std::floor(V_in[i].x() * inv); + iy[i] = (int)std::floor(V_in[i].y() * inv); + iz[i] = (int)std::floor(V_in[i].z() * inv); + } + + for (int i=0;i<(int)N;++i) { + // Check neighbor cells (27) + for (int dx=-1; dx<=1; ++dx) for (int dy=-1; dy<=1; ++dy) for (int dz=-1; dz<=1; ++dz) { + int64_t key = cell_key(ix[i]+dx, iy[i]+dy, iz[i]+dz); + auto it = grid.find(key); + if (it == grid.end()) continue; + for (int j : it->second) { + if (j >= i) continue; // only previous vertices + float d2 = (V_in[i]-V_in[j]).squaredNorm(); + if (d2 <= thresh2) unite(i,j); + } + } + // Insert this vertex into its own cell + grid[cell_key(ix[i],iy[i],iz[i])].push_back(i); + } + + // Aggregate clusters: root -> new index + std::unordered_map root2new; root2new.reserve(N); + std::vector accum; accum.reserve(N); + std::vector counts; counts.reserve(N); + + for (int i=0;i<(int)N;++i) { + int r = find(i); + auto it = root2new.find(r); + if (it == root2new.end()) { + int idx = (int)root2new.size(); + root2new[r] = idx; + accum.push_back(V_in[i]); + counts.push_back(1); + } else { + int idx = it->second; + accum[idx] += V_in[i]; + counts[idx]++; + } + } + + // Compute centroids + V_out.resize(accum.size()); + for (size_t i=0;i new + std::vector map_old2new(N); + for (int i=0;i<(int)N;++i) map_old2new[i] = root2new[find(i)]; + + // Remap faces, remove degenerates, remove duplicates + F_out.clear(); F_out.reserve(F_in.size()); + struct TriHash { + size_t operator()(const std::array& t) const noexcept { + return (size_t)(t[0]*73856093) ^ (size_t)(t[1]*19349663) ^ (size_t)(t[2]*83492791); + } + }; + std::unordered_set, TriHash> seen; + seen.reserve(F_in.size()*2); + + for (const auto& f : F_in) { + int a = map_old2new[f[0]]; + int b = map_old2new[f[1]]; + int c = map_old2new[f[2]]; + if (a==b || b==c || c==a) continue; // degenerate + // Avoid duplicates disregarding orientation but keep original winding + std::array key = {a,b,c}; + std::array key_sorted = key; + std::sort(key_sorted.begin(), key_sorted.end()); + if (seen.insert(key_sorted).second) { + F_out.emplace_back(a,b,c); + } + } +} + +} // namespace cpu +} // namespace cubvh diff --git a/extensions/CUBVH/include/cpu/spmc.h b/extensions/CUBVH/include/cpu/spmc.h new file mode 100644 index 0000000000000000000000000000000000000000..0b74ba23f16bcb6a7e1eb3649f4d43947d11a43d --- /dev/null +++ b/extensions/CUBVH/include/cpu/spmc.h @@ -0,0 +1,469 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +// CPU implementation of the same sparse marching cubes algorithm +// as include/cubvh/spcumc.cuh, but using standard C++ containers. + +namespace cubvh { +namespace cpu { + +// Types mirroring CUDA version +struct V3f { float x, y, z; }; +struct Tri { int v0, v1, v2; }; + +// Lookup tables copied from CUDA version +static const int edgeTable[256] = { + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 +}; + +static const int triTable[256][16] = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, + {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, + {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, + {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, + {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, + {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, + {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, + {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, + {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, + {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, + {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, + {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, + {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, + {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, + {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, + {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, + {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, + {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, + {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, + {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, + {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, + {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, + {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, + {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, + {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, + {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, + {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, + {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, + {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, + {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, + {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, + {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, + {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, + {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, + {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, + {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, + {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, + {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, + {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, + {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, + {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, + {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, + {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, + {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, + {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, + {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, + {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, + {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, + {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, + {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, + {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, + {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, + {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, + {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, + {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, + {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, + {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, + {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, + {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, + {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, + {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, + {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, + {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, + {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, + {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, + {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, + {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, + {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, + {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, + {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, + {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, + {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, + {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, + {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, + {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, + {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, + {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, + {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, + {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, + {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, + {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, + {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, + {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, + {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, + {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, + {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, + {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, + {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, + {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, + {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, + {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, + {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, + {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, + {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, + {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, + {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, + {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +}; + +// Corner offsets and edge endpoints +struct Int3 { int x, y, z; }; +static const Int3 cornerOffset[8] = { + {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0}, + {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} +}; + +static const int EDGE_CORNERS[12][2] = { + {0,1},{1,2},{2,3},{3,0}, // bottom square + {4,5},{5,6},{6,7},{7,4}, // top square + {0,4},{1,5},{2,6},{3,7} // vertical edges +}; + +// Key for deduplicating edge vertices +struct EdgeKey { + int x, y, z; unsigned char axis; + bool operator==(const EdgeKey& o) const { + return x==o.x && y==o.y && z==o.z && axis==o.axis; + } + bool operator<(const EdgeKey& o) const { + if (x != o.x) return x < o.x; + if (y != o.y) return y < o.y; + if (z != o.z) return z < o.z; + return axis < o.axis; + } +}; + +// Corner data used when ensure_consistency=true +struct CornerData { int x,y,z; float value; int count; }; + +inline int popcnt12(int m) { + // mask already 12-bit, use builtin if available + #if defined(__GNUC__) || defined(__clang__) + return __builtin_popcount(static_cast(m & 0xFFF)); + #else + m &= 0xFFF; int c=0; while(m){ m &= (m-1); ++c; } return c; + #endif +} + +// CPU sparse marching cubes core +inline std::pair, std::vector> +sparse_marching_cubes(const int* coords, const float* corners, int N, float iso, bool ensure_consistency) +{ + std::vector vertices; + std::vector triangles; + if (N <= 0) return {vertices, triangles}; + + // Hash helpers for fast maps + struct EdgeKeyHash { + std::size_t operator()(const EdgeKey& k) const noexcept { + // Simple mix of 4 ints + std::size_t h = 1469598103934665603ull; // FNV offset basis + auto mix = [&](std::uint64_t v){ h ^= v + 0x9e3779b97f4a7c15ull + (h<<6) + (h>>2); }; + mix(static_cast(static_cast(k.x))); + mix(static_cast(static_cast(k.y))); + mix(static_cast(static_cast(k.z))); + mix(static_cast(k.axis)); + return h; + } + }; + struct CornerKey { int x,y,z; bool operator==(const CornerKey& o) const { return x==o.x&&y==o.y&&z==o.z; } }; + struct CornerKeyHash { + std::size_t operator()(const CornerKey& k) const noexcept { + std::size_t h = 1469598103934665603ull; + auto mix = [&](std::uint64_t v){ h ^= v + 0x9e3779b97f4a7c15ull + (h<<6) + (h>>2); }; + mix(static_cast(static_cast(k.x))); + mix(static_cast(static_cast(k.y))); + mix(static_cast(static_cast(k.z))); + return h; + } + }; + + // Optional: average duplicated corner samples across voxels using a hashmap in O(K) + std::unordered_map, CornerKeyHash> cornerStats; // sum,count + if (ensure_consistency) { + cornerStats.reserve(static_cast(N) * 8u); + for (int i=0;i(corners[i*8+k]); + ++sc.second; + } + } + } + + // Single-pass: create vertices lazily and build triangles directly + std::unordered_map edge2idx; + edge2idx.reserve(static_cast(N) * 3u); // heuristic + vertices.reserve(static_cast(N) * 3u); // heuristic + triangles.reserve(static_cast(N) * 2u); // heuristic + + auto get_avg = [&](int x,int y,int z, float fallback)->float{ + if (!ensure_consistency) return fallback; + auto it = cornerStats.find(CornerKey{x,y,z}); + if (it == cornerStats.end()) return fallback; + return static_cast(it->second.first / std::max(1, it->second.second)); + }; + + for (int i=0;iint { + int a = EDGE_CORNERS[e][0], b = EDGE_CORNERS[e][1]; + Int3 offA = cornerOffset[a], offB = cornerOffset[b]; + EdgeKey key; key.x = (offA.x < offB.x ? vx+offA.x : vx+offB.x); + key.y = (offA.y < offB.y ? vy+offA.y : vy+offB.y); + key.z = (offA.z < offB.z ? vz+offA.z : vz+offB.z); + key.axis = (offA.x != offB.x) ? 0 : (offA.y != offB.y ? 1 : 2); + auto it = edge2idx.find(key); + if (it != edge2idx.end()) return it->second; + // Create new vertex + float va=v[a], vb=v[b]; float denom = vb - va; float t; + if (std::fabs(denom) < 1e-30f) t = 0.5f; else { t = (iso - va) / denom; t = std::min(std::max(t, 0.0f), 1.0f); } + float pAx = float(vx + offA.x), pAy = float(vy + offA.y), pAz = float(vz + offA.z); + float pBx = float(vx + offB.x), pBy = float(vy + offB.y), pBz = float(vz + offB.z); + V3f P{ pAx + t*(pBx-pAx), pAy + t*(pBy-pAy), pAz + t*(pBz-pAz) }; + int idx = static_cast(vertices.size()); + vertices.push_back(P); + edge2idx.emplace(key, idx); + return idx; + }; + + for (int t=0;t<15;t+=3) { + int e0 = triTable[ci][t]; if (e0 == -1) break; + int e1 = triTable[ci][t+1]; int e2 = triTable[ci][t+2]; + Tri tri; + // Maintain CCW like original: v0=e0, v1=e2, v2=e1 + tri.v0 = edge_index(e0); + tri.v1 = edge_index(e2); + tri.v2 = edge_index(e1); + triangles.push_back(tri); + } + } + + return {std::move(vertices), std::move(triangles)}; +} + +} // namespace cpu +} // namespace cubvh \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/api_gpu.h b/extensions/CUBVH/include/gpu/api_gpu.h new file mode 100644 index 0000000000000000000000000000000000000000..673368d888170a019a97a742e00d1c3ecffe6520 --- /dev/null +++ b/extensions/CUBVH/include/gpu/api_gpu.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +using namespace Eigen; + +using Verts = Matrix; +using Trigs = Matrix; + +namespace cubvh { + +// abstract class of raytracer +class cuBVH { +public: + cuBVH() {} + virtual ~cuBVH() {} + + virtual void ray_trace(at::Tensor rays_o, at::Tensor rays_d, at::Tensor positions, at::Tensor face_id, at::Tensor depth) = 0; + virtual void unsigned_distance(at::Tensor positions, at::Tensor distances, at::Tensor face_id, at::optional uvw) = 0; + virtual void signed_distance(at::Tensor positions, at::Tensor distances, at::Tensor face_id, at::optional uvw, uint32_t mode) = 0; + virtual std::tuple export_state() const = 0; +}; + +// function to create an implementation of cuBVH +cuBVH* create_cuBVH(Ref vertices, Ref triangles); +cuBVH* create_cuBVH_from_state(at::Tensor triangle_vertices, at::Tensor triangle_ids, at::Tensor node_mins, at::Tensor node_maxs, at::Tensor node_children); +std::tuple build_cuBVH_state(Ref vertices, Ref triangles); +// floodfill +at::Tensor floodfill(at::Tensor grid); + +// sparse marching cubes +std::tuple sparse_marching_cubes(at::Tensor coords, at::Tensor corners, double iso_d, bool ensure_consistency = false); + +// GPU ND integer hash table (default D=3) - abstract interface +class cuHashTable { +public: + cuHashTable() {} + virtual ~cuHashTable() {} + virtual void set_num_dims(int d) = 0; + virtual int get_num_dims() const = 0; + virtual void resize(int capacity) = 0; + virtual void prepare() = 0; + virtual void insert(at::Tensor coords) = 0; + virtual void build(at::Tensor coords) = 0; + virtual at::Tensor search(at::Tensor queries) const = 0; +}; + +// Factory to create an implementation of cuHashTable +cuHashTable* create_cuHashTable(); + +} // namespace cubvh \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/bounding_box.cuh b/extensions/CUBVH/include/gpu/bounding_box.cuh new file mode 100644 index 0000000000000000000000000000000000000000..a1e9551362f9e9ba77729b01f0792be24da06b86 --- /dev/null +++ b/extensions/CUBVH/include/gpu/bounding_box.cuh @@ -0,0 +1,246 @@ +#pragma once + +#include +#include + +namespace cubvh { + +template +__host__ __device__ inline void project(Eigen::Vector3f points[N_POINTS], const Eigen::Vector3f& axis, float& min, float& max) { + min = std::numeric_limits::infinity(); + max = -std::numeric_limits::infinity(); + + #pragma unroll + for (uint32_t i = 0; i < N_POINTS; ++i) { + float val = axis.dot(points[i]); + + if (val < min) { + min = val; + } + + if (val > max) { + max = val; + } + } +} + +struct BoundingBox { + + Eigen::Vector3f min = Eigen::Vector3f::Constant(std::numeric_limits::infinity()); + Eigen::Vector3f max = Eigen::Vector3f::Constant(-std::numeric_limits::infinity()); + + __host__ __device__ BoundingBox() {} + + __host__ __device__ BoundingBox(const Eigen::Vector3f& a, const Eigen::Vector3f& b) : min{a}, max{b} {} + + __host__ __device__ explicit BoundingBox(const Triangle& tri) { + min = max = tri.a; + enlarge(tri.b); + enlarge(tri.c); + } + + BoundingBox(std::vector::iterator begin, std::vector::iterator end) { + min = max = begin->a; + for (auto it = begin; it != end; ++it) { + enlarge(*it); + } + } + + __host__ __device__ void enlarge(const BoundingBox& other) { + min = min.cwiseMin(other.min); + max = max.cwiseMax(other.max); + } + + __host__ __device__ void enlarge(const Triangle& tri) { + enlarge(tri.a); + enlarge(tri.b); + enlarge(tri.c); + } + + __host__ __device__ void enlarge(const Eigen::Vector3f& point) { + min = min.cwiseMin(point); + max = max.cwiseMax(point); + } + + __host__ __device__ void inflate(float amount) { + min -= Eigen::Vector3f::Constant(amount); + max += Eigen::Vector3f::Constant(amount); + } + + __host__ __device__ Eigen::Vector3f diag() const { + return max - min; + } + + __host__ __device__ Eigen::Vector3f relative_pos(const Eigen::Vector3f& pos) const { + return (pos - min).cwiseQuotient(diag()); + } + + __host__ __device__ Eigen::Vector3f center() const { + return 0.5f * (max + min); + } + + __host__ __device__ BoundingBox intersection(const BoundingBox& other) const { + BoundingBox result = *this; + result.min = result.min.cwiseMax(other.min); + result.max = result.max.cwiseMin(other.max); + return result; + } + + __host__ __device__ bool intersects(const BoundingBox& other) const { + return !intersection(other).is_empty(); + } + + // Based on the separating axis theorem + // (https://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/code/tribox_tam.pdf) + // Code adapted from a C# implementation at stack overflow + // https://stackoverflow.com/a/17503268 + __host__ __device__ bool intersects(const Triangle& triangle) const { + float triangle_min, triangle_max; + float box_min, box_max; + + // Test the box normals (x-, y- and z-axes) + Eigen::Vector3f box_normals[3] = { + Eigen::Vector3f{1.0f, 0.0f, 0.0f}, + Eigen::Vector3f{0.0f, 1.0f, 0.0f}, + Eigen::Vector3f{0.0f, 0.0f, 1.0f}, + }; + + Eigen::Vector3f triangle_normal = triangle.normal(); + Eigen::Vector3f triangle_verts[3]; + triangle.get_vertices(triangle_verts); + + for (int i = 0; i < 3; i++) { + project<3>(triangle_verts, box_normals[i], triangle_min, triangle_max); + if (triangle_max < min[i] || triangle_min > max[i]) { + return false; // No intersection possible. + } + } + + Eigen::Vector3f verts[8]; + get_vertices(verts); + + // Test the triangle normal + float triangle_offset = triangle_normal.dot(triangle.a); + project<8>(verts, triangle_normal, box_min, box_max); + if (box_max < triangle_offset || box_min > triangle_offset) { + return false; // No intersection possible. + } + + // Test the nine edge cross-products + Eigen::Vector3f edges[3] = { + triangle.a - triangle.b, + triangle.a - triangle.c, + triangle.b - triangle.c, + }; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + // The box normals are the same as it's edge tangents + Eigen::Vector3f axis = edges[i].cross(box_normals[j]); + project<8>(verts, axis, box_min, box_max); + project<3>(triangle_verts, axis, triangle_min, triangle_max); + if (box_max < triangle_min || box_min > triangle_max) + return false; // No intersection possible + } + } + + // No separating axis found. + return true; + } + + __host__ __device__ Eigen::Vector2f ray_intersect(Eigen::Ref pos, Eigen::Ref dir) const { + float tmin = safe_divide(min.x() - pos.x(), dir.x()); + float tmax = safe_divide(max.x() - pos.x(), dir.x()); + + if (tmin > tmax) { + host_device_swap(tmin, tmax); + } + + float tymin = safe_divide(min.y() - pos.y(), dir.y()); + float tymax = safe_divide(max.y() - pos.y(), dir.y()); + + if (tymin > tymax) { + host_device_swap(tymin, tymax); + } + + if (tmin > tymax || tymin > tmax) { + return { std::numeric_limits::max(), std::numeric_limits::max() }; + } + + if (tymin > tmin) { + tmin = tymin; + } + + if (tymax < tmax) { + tmax = tymax; + } + + float tzmin = safe_divide(min.z() - pos.z(), dir.z()); + float tzmax = safe_divide(max.z() - pos.z(), dir.z()); + + if (tzmin > tzmax) { + host_device_swap(tzmin, tzmax); + } + + if (tmin > tzmax || tzmin > tmax) { + return { std::numeric_limits::max(), std::numeric_limits::max() }; + } + + if (tzmin > tmin) { + tmin = tzmin; + } + + if (tzmax < tmax) { + tmax = tzmax; + } + + return { tmin, tmax }; + } + + __host__ __device__ bool is_empty() const { + return (max.array() < min.array()).any(); + } + + __host__ __device__ bool contains(const Eigen::Vector3f& p) const { + return + p.x() >= min.x() && p.x() <= max.x() && + p.y() >= min.y() && p.y() <= max.y() && + p.z() >= min.z() && p.z() <= max.z(); + } + + /// Calculate the squared point-AABB distance + __host__ __device__ float distance(const Eigen::Vector3f& p) const { + return sqrt(distance_sq(p)); + } + + __host__ __device__ float distance_sq(const Eigen::Vector3f& p) const { + return (min - p).cwiseMax(p - max).cwiseMax(0.0f).squaredNorm(); + } + + __host__ __device__ float signed_distance(const Eigen::Vector3f& p) const { + Eigen::Vector3f q = (p - min).cwiseAbs() - diag(); + return q.cwiseMax(0.0f).norm() + std::min(std::max(q.x(), std::max(q.y(), q.z())), 0.0f); + } + + __host__ __device__ void get_vertices(Eigen::Vector3f v[8]) const { + v[0] = {min.x(), min.y(), min.z()}; + v[1] = {min.x(), min.y(), max.z()}; + v[2] = {min.x(), max.y(), min.z()}; + v[3] = {min.x(), max.y(), max.z()}; + v[4] = {max.x(), min.y(), min.z()}; + v[5] = {max.x(), min.y(), max.z()}; + v[6] = {max.x(), max.y(), min.z()}; + v[7] = {max.x(), max.y(), max.z()}; + } + +}; + +inline std::ostream& operator<< (std::ostream& os, const cubvh::BoundingBox& bb) { + os << "["; + os << "min=[" << bb.min.x() << "," << bb.min.y() << "," << bb.min.z() << "], "; + os << "max=[" << bb.max.x() << "," << bb.max.y() << "," << bb.max.z() << "]"; + os << "]"; + return os; +} + +} \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/bvh.cuh b/extensions/CUBVH/include/gpu/bvh.cuh new file mode 100644 index 0000000000000000000000000000000000000000..452094c15647adde992f6e430cca45ea125babfc --- /dev/null +++ b/extensions/CUBVH/include/gpu/bvh.cuh @@ -0,0 +1,93 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace cubvh { + +struct TriangleBvhNode { + BoundingBox bb; + int left_idx; // negative values indicate leaves + int right_idx; + // Threaded BVH escape index for stackless traversal: index of the next node + // to visit after finishing this node's subtree. -1 indicates termination. + int escape_idx; +}; + + +template +class FixedStack { +public: + __host__ __device__ void push(T val) { + // If overflowing, flag and drop the push; a stackless fallback will be used. + if (m_count >= MAX_SIZE) { + if (!m_overflowed) { +#ifdef CUBVH_DEBUG_STACK_OVERFLOW + printf("WARNING TOO BIG (stack overflow)\n"); +#endif + } + m_overflowed = true; + return; + } + m_elems[m_count++] = val; + } + + __host__ __device__ T pop() { + return m_elems[--m_count]; + } + + __host__ __device__ bool empty() const { + return m_count <= 0; + } + + __host__ __device__ bool overflowed() const { + return m_overflowed; + } + +private: + T m_elems[MAX_SIZE]; + int m_count = 0; + bool m_overflowed = false; +}; + +// Chosen to accommodate extremely unbalanced BVHs without spilling to the +// stackless fallback for typical production meshes. +static constexpr int kBVHMaxStackSize = 32; +using FixedIntStack = FixedStack; + + +class TriangleBvh { + +protected: + std::vector m_nodes; + GPUMemory m_nodes_gpu; + TriangleBvh() {}; + +public: + virtual void build(std::vector& triangles, uint32_t n_primitives_per_leaf) = 0; + + virtual void signed_distance_gpu(uint32_t n_elements, uint32_t mode, const float* positions, float* distances, int64_t* face_id, float* uvw, const Triangle* gpu_triangles, uint32_t n_triangles, cudaStream_t stream) = 0; + virtual void unsigned_distance_gpu(uint32_t n_elements, const float* positions, float* distances, int64_t* face_id, float* uvw, const Triangle* gpu_triangles, uint32_t n_triangles, cudaStream_t stream) = 0; + virtual void ray_trace_gpu(uint32_t n_elements, const float* rays_o, const float* rays_d, float* positions, int64_t* face_id, float* depth, const Triangle* gpu_triangles, cudaStream_t stream) = 0; + + // KIUI: not supported now. + // virtual bool touches_triangle(const BoundingBox& bb, const Triangle* __restrict__ triangles) const = 0; + // virtual void build_optix(const GPUMemory& triangles, cudaStream_t stream) = 0; + + static std::unique_ptr make(); + + TriangleBvhNode* nodes_gpu() const { + return m_nodes_gpu.data(); + } + + const std::vector& host_nodes() const; + void set_nodes(const std::vector& nodes); + +}; + +} \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/common.h b/extensions/CUBVH/include/gpu/common.h new file mode 100644 index 0000000000000000000000000000000000000000..517fa9f93e628ea9d050aa523af4fd7c48eeedb2 --- /dev/null +++ b/extensions/CUBVH/include/gpu/common.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +namespace cubvh { + +static constexpr float PI = 3.14159265358979323846f; +static constexpr float SQRT2 = 1.41421356237309504880f; + + +// enum class EMeshSdfMode : int { +// Watertight, +// Raystab, +// PathEscape, +// }; +// static constexpr const char* MeshSdfModeStr = "Watertight\0Raystab\0PathEscape\0\0"; + +template +__host__ __device__ T div_round_up(T val, T divisor) { + return (val + divisor - 1) / divisor; +} + +constexpr uint32_t n_threads_linear = 128; + +template +constexpr uint32_t n_blocks_linear(T n_elements) { + return (uint32_t)div_round_up(n_elements, (T)n_threads_linear); +} + +template +inline void linear_kernel(K kernel, uint32_t shmem_size, cudaStream_t stream, T n_elements, Types ... args) { + if (n_elements <= 0) { + return; + } + kernel<<>>((uint32_t)n_elements, args...); +} + +inline __host__ __device__ float sign(float x) { + return copysignf(1.0, x); +} + +template +__host__ __device__ T clamp(T val, T lower, T upper) { + return val < lower ? lower : (upper < val ? upper : val); +} + +template +__host__ __device__ void host_device_swap(T& a, T& b) { + T c(a); a=b; b=c; +} + +inline __host__ __device__ Eigen::Vector3f cylindrical_to_dir(const Eigen::Vector2f& p) { + const float cos_theta = -2.0f * p.x() + 1.0f; + const float phi = 2.0f * PI * (p.y() - 0.5f); + + const float sin_theta = sqrtf(fmaxf(1.0f - cos_theta * cos_theta, 0.0f)); + float sin_phi, cos_phi; + sincosf(phi, &sin_phi, &cos_phi); + + return {sin_theta * cos_phi, sin_theta * sin_phi, cos_theta}; +} + +inline __host__ __device__ float fractf(float x) { + return x - floorf(x); +} + +template +__device__ __host__ Eigen::Vector3f fibonacci_dir(uint32_t i, const Eigen::Vector2f& offset) { + // Fibonacci lattice with offset + float epsilon; + if (N_DIRS >= 11000) { + epsilon = 27; + } else if (N_DIRS >= 890) { + epsilon = 10; + } else if (N_DIRS >= 177) { + epsilon = 3.33; + } else if (N_DIRS >= 24) { + epsilon = 1.33; + } else { + epsilon = 0.33; + } + + static constexpr float GOLDEN_RATIO = 1.6180339887498948482045868343656f; + return cylindrical_to_dir(Eigen::Vector2f{fractf((i+epsilon) / (N_DIRS-1+2*epsilon) + offset.x()), fractf(i / GOLDEN_RATIO + offset.y())}); +} + +inline __host__ __device__ float safe_divide(float numerator, float denominator, float epsilon = 1e-6f) { + if (fabs(denominator) < epsilon) { + if (denominator <= 0) + return -(numerator / epsilon); + else + return numerator / epsilon; + } + return numerator / denominator; +} + +} \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/floodfill.cuh b/extensions/CUBVH/include/gpu/floodfill.cuh new file mode 100644 index 0000000000000000000000000000000000000000..359e8a0004340f3ef0f6b073294db40ea1a5f069 --- /dev/null +++ b/extensions/CUBVH/include/gpu/floodfill.cuh @@ -0,0 +1,272 @@ +#include +#include + +#include +#include + +#define THREADS_PER_BLOCK 256 + +/* ------------------------------------------------------------------------- */ +/* K E R N E L S */ +/* ------------------------------------------------------------------------- */ + +// Initialise: label[i] = i for free voxels, -1 for blocked +__global__ void initLabels(const bool* __restrict__ grid, int * __restrict__ labels, int Ntot) +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx < Ntot) { + // Only free voxels get valid labels, blocked voxels get -1 + labels[idx] = grid[idx] ? -1 : idx; + } +} + +/* + * Hook step for batched volumes. + * - Nvol := H * W * D (size of ONE volume) + * - Ntot := B * Nvol (size of the whole batch) + * + * The only difference to the single-volume version is that we build the + * voxel coordinates (x,y,z) from the *local* index inside the volume + * instead of the global thread index. + */ +__global__ void hookBatch( + const bool* __restrict__ grid, + int* __restrict__ labels, + int* __restrict__ changed, + int H, int W, int D, + int Nvol, // stride between consecutive batches + int Ntot) // total number of voxels +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx >= Ntot) return; + if (grid[idx] != 0) return; // blocked voxel + + /* ---------- local coordinates inside the current volume -------------- */ + int batch_idx = idx / Nvol; // which batch this voxel belongs to + int local = idx % Nvol; // 0 โ€ฆ Nvol-1 + int x = local % W; + int y = (local / W) % H; + int z = local / (W * H); + + // Base index of current batch + int batch_base = batch_idx * Nvol; + + /* ----------------------- six-neighbour search with bounds checking ---- */ + int best = labels[idx]; + + // X-direction neighbors (ensure we stay within the same batch) + if (x > 0) { + int n = idx - 1; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + if (x < W - 1) { + int n = idx + 1; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + + // Y-direction neighbors + if (y > 0) { + int n = idx - W; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + if (y < H - 1) { + int n = idx + W; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + + // Z-direction neighbors + if (z > 0) { + int n = idx - W * H; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + if (z < D - 1) { + int n = idx + W * H; + if (n >= batch_base && n < batch_base + Nvol && !grid[n] && labels[n] >= 0) + best = min(best, labels[n]); + } + + /* --------------------------- atomic update --------------------------- */ + int current_label = labels[idx]; + if (current_label >= 0 && best < current_label) { + // Use atomic compare-and-swap to avoid race conditions + int old_val = atomicCAS(&labels[idx], current_label, best); + if (old_val == current_label) { + // Successfully updated, mark as changed + // Use atomic exchange instead of OR to reduce contention + atomicExch(changed, 1); + } + } +} + +/* Safe pointer-jump compression with bounds checking */ +__global__ void compress(int * __restrict__ labels, int Ntot) +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx >= Ntot || labels[idx] < 0) return; // Skip invalid labels + + // Find root with bounds checking + int current = idx; + int root = labels[current]; + + // Traverse to find root (with cycle detection) + int steps = 0; + const int MAX_STEPS = 1000; // Prevent infinite loops + + while (root != current && root >= 0 && root < Ntot && steps < MAX_STEPS) { + current = root; + root = labels[current]; + steps++; + } + + if (steps >= MAX_STEPS) { + // Corrupted data detected, reset to self-reference + labels[idx] = idx; + return; + } + + // Path compression with bounds checking + current = idx; + steps = 0; + while (current != root && current >= 0 && current < Ntot && steps < MAX_STEPS) { + int next = labels[current]; + labels[current] = root; + current = next; + steps++; + } +} + +/* ------------------------------------------------------------------------- */ +/* H O S T U T I L I T Y */ +/* ------------------------------------------------------------------------- */ + +static int divUp(int a, int b) { return (a + b - 1) / b; } + +/* ------------------------------------------------------------------------- */ +/* P U B L I C A P I */ +/* ------------------------------------------------------------------------- */ + +/* + * grid : pointer to BยทHยทWยทD bools (0 = free, 1 = blocked) + * mask : output, BยทHยทWยทD int32 labels + */ +extern "C" +void _floodfill_batch( + const bool *grid, + int B, int H, int W, int D, + int32_t *mask) +{ + const int Nvol = H * W * D; // size of one volume + const int Ntot = B * Nvol; // size of entire batch + + const size_t bytesGrid = Ntot * sizeof(bool); + const size_t bytesLabel = Ntot * sizeof(int); + + /* --------------------------- allocate -------------------------------- */ + bool *d_grid = nullptr; + int *d_labels = nullptr; + int *d_changed = nullptr; + + cudaMalloc(&d_grid, bytesGrid); + cudaMalloc(&d_labels, bytesLabel); + cudaMalloc(&d_changed, sizeof(int)); + + cudaMemcpy(d_grid, grid, bytesGrid, cudaMemcpyHostToDevice); + + /* --------------------------- init ------------------------------------ */ + { + int blocks = divUp(Ntot, THREADS_PER_BLOCK); + initLabels<<>>(d_grid, d_labels, Ntot); + cudaDeviceSynchronize(); + + // Check for kernel launch errors + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf("CUDA Error in initLabels: %s\n", cudaGetErrorString(err)); + cudaFree(d_grid); + cudaFree(d_labels); + cudaFree(d_changed); + return; + } + } + + /* -------------------- iterated hook / compress with bounds ----------- */ + // Improved iteration limit: account for diagonal propagation distance and batch size + const int diagonal_dist = (int)ceil(sqrt((double)(H*H + W*W + D*D))); + // For small grids (like 3x3x3 batches), use a smaller limit + const int base_limit = (H <= 4 && W <= 4 && D <= 4) ? 20 : diagonal_dist + 50; + const int MAX_ITERATIONS = min(base_limit, 10 * max(H, max(W, D))); // More realistic upper bound + int h_changed = 1; + int iteration = 0; + int no_change_count = 0; // Track consecutive iterations with no changes + + while (h_changed && iteration < MAX_ITERATIONS) { + cudaMemset(d_changed, 0, sizeof(int)); + + /* hook */ + { + int blocks = divUp(Ntot, THREADS_PER_BLOCK); + hookBatch<<>>( + d_grid, d_labels, d_changed, + H, W, D, Nvol, Ntot); + } + + /* compress - only run every few iterations to reduce overhead */ + if (iteration % 5 == 4 || iteration < 10) { // Compress more frequently early on + int blocks = divUp(Ntot, THREADS_PER_BLOCK); + compress<<>>(d_labels, Ntot); + } + + cudaDeviceSynchronize(); + + // Check for kernel errors + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf("CUDA Error in iteration %d: %s\n", iteration, cudaGetErrorString(err)); + break; + } + + cudaMemcpy(&h_changed, d_changed, sizeof(int), cudaMemcpyDeviceToHost); + iteration++; + + // Early termination: if no changes for several iterations, we've likely converged + if (h_changed == 0) { + no_change_count++; + if (no_change_count >= 3) { // No changes for 3 consecutive iterations + break; // Early convergence detected + } + } else { + no_change_count = 0; + } + + // Progress reporting for very long runs + // if (iteration % 50 == 0) { // Report more frequently + // printf("Flood fill iteration %d/%d (grid: %dx%dx%d, batches: %d)\n", + // iteration, MAX_ITERATIONS, H, W, D, B); + // } + } + + if (iteration >= MAX_ITERATIONS) { + printf("WARNING: Flood fill did not converge after %d iterations!\n", MAX_ITERATIONS); + printf("Grid info: %dx%dx%d, %d batches. This may indicate a bug.\n", H, W, D, B); + } + + /* final flatten */ + { + int blocks = divUp(Ntot, THREADS_PER_BLOCK); + compress<<>>(d_labels, Ntot); + cudaDeviceSynchronize(); + } + + /* copy back */ + cudaMemcpy(mask, d_labels, bytesLabel, cudaMemcpyDeviceToHost); + + /* cleanup */ + cudaFree(d_grid); + cudaFree(d_labels); + cudaFree(d_changed); +} diff --git a/extensions/CUBVH/include/gpu/gpu_memory.h b/extensions/CUBVH/include/gpu/gpu_memory.h new file mode 100644 index 0000000000000000000000000000000000000000..8510da5167540ce0e5801ee5460f01042584ee2d --- /dev/null +++ b/extensions/CUBVH/include/gpu/gpu_memory.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 NVIDIA CORPORATION 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 TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *//* + */ + +/** @file gpu_memory.h + * @author Nikolaus Binder and Thomas Mรผller, NVIDIA + * @brief Managed memory on the GPU. Like a std::vector, memory is alocated either explicitly (resize/enlarge) + * or implicitly (resize_and_copy_from_host etc). Memory is always and automatically released in the destructor. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +/// Checks the result of a cudaXXXXXX call and throws an error on failure +#define CUDA_CHECK_THROW(x) \ + do { \ + cudaError_t result = x; \ + if (result != cudaSuccess) \ + throw std::runtime_error(std::string("CUDA Error: " #x " failed with error ") + cudaGetErrorString(result)); \ + } while(0) + + +namespace cubvh { + +#define DEBUG_GUARD_SIZE 0 + +inline std::atomic& total_n_bytes_allocated() { + static std::atomic s_total_n_bytes_allocated{0}; + return s_total_n_bytes_allocated; +} + +/// Managed memory on the Device +template +class GPUMemory { +private: + T* m_data = nullptr; + size_t m_size = 0; // Number of elements + bool m_owned = true; + +public: + GPUMemory() {} + + GPUMemory& operator=(GPUMemory&& other) { + std::swap(m_data, other.m_data); + std::swap(m_size, other.m_size); + return *this; + } + + GPUMemory(GPUMemory&& other) { + *this = std::move(other); + } + + __host__ __device__ GPUMemory(const GPUMemory &other) : m_data{other.m_data}, m_size{other.m_size}, m_owned{false} {} + + void check_guards() const { +#if DEBUG_GUARD_SIZE > 0 + if (!m_data) + return; + uint8_t buf[DEBUG_GUARD_SIZE]; + const uint8_t *rawptr=(const uint8_t *)m_data; + cudaMemcpy(buf, rawptr-DEBUG_GUARD_SIZE, DEBUG_GUARD_SIZE, cudaMemcpyDeviceToHost); + for (int i=0;i 0 + CUDA_CHECK_THROW(cudaMemset(rawptr , 0xff, DEBUG_GUARD_SIZE)); + CUDA_CHECK_THROW(cudaMemset(rawptr+n_bytes+DEBUG_GUARD_SIZE , 0xfe, DEBUG_GUARD_SIZE)); +#endif + if (rawptr) rawptr+=DEBUG_GUARD_SIZE; + m_data=(T*)(rawptr); + total_n_bytes_allocated() += n_bytes; + } + + void free_memory() { + if (!m_data) { + return; + } + + uint8_t *rawptr = (uint8_t*)m_data; + if (rawptr) rawptr-=DEBUG_GUARD_SIZE; + CUDA_CHECK_THROW(cudaFree(rawptr)); + + total_n_bytes_allocated() -= get_bytes(); + + m_data = nullptr; + } + + /// Allocates memory for size items of type T + GPUMemory(const size_t size) { + resize(size); + } + + /// Frees memory again + __host__ __device__ ~GPUMemory() { +#ifndef __CUDA_ARCH__ + if (!m_owned) { + return; + } + + try { + if (m_data) { + free_memory(); + m_size = 0; + } + } catch (std::runtime_error error) { + // Don't need to report on memory-free problems when the driver is shutting down. + if (std::string{error.what()}.find("driver shutting down") == std::string::npos) { + fprintf(stderr, "Could not free memory: %s\n", error.what()); + } + } +#endif + } + + /** @name Resizing/enlargement + * @{ + */ + /// Resizes the array to the exact new size, even if it is already larger + void resize(const size_t size) { + if (!m_owned) { + throw std::runtime_error("Cannot resize non-owned memory."); + } + + if (m_size != size) { + if (m_size) { + try { + free_memory(); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not free memory: ") + error.what()); + } + } + + if (size > 0) { + try { + allocate_memory(size * sizeof(T)); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not allocate memory: ") + error.what()); + } + } + + m_size = size; + } + } + + /// Enlarges the array if its size is smaller + void enlarge(const size_t size) { + if (size > m_size) { + resize(size); + } + } + /** @} */ + + /** @name Memset + * @{ + */ + /// Sets the memory of the first num_elements to value + void memset(const int value, const size_t num_elements, const size_t offset = 0) { + if (num_elements + offset > m_size) { + throw std::runtime_error("Could not set memory: Number of elements larger than allocated memory"); + } + + try { + CUDA_CHECK_THROW(cudaMemset(m_data + offset, value, num_elements * sizeof(T))); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not set memory: ") + error.what()); + } + } + + /// Sets the memory of the all elements to value + void memset(const int value) { + memset(value, m_size); + } + /** @} */ + + /** @name Copy operations + * @{ + */ + /// Copy data of num_elements from the raw pointer on the host + void copy_from_host(const T* host_data, const size_t num_elements) { + try { + CUDA_CHECK_THROW(cudaMemcpy(data(), host_data, num_elements * sizeof(T), cudaMemcpyHostToDevice)); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not copy from host: ") + error.what()); + } + } + + /// Copy num_elements from the host vector + void copy_from_host(const std::vector& data, const size_t num_elements) { + if (data.size() < num_elements) { + throw std::runtime_error(std::string("Trying to copy ") + std::to_string(num_elements) + std::string(" elements, but vector size is only ") + std::to_string(data.size())); + } + copy_from_host(data.data(), num_elements); + } + + /// Copies data from the raw host pointer to fill the entire array + void copy_from_host(const T* data) { + copy_from_host(data, m_size); + } + + /// Copies num_elements of data from the raw host pointer after enlarging the array so that everything fits in + void enlarge_and_copy_from_host(const T* data, const size_t num_elements) { + enlarge(num_elements); + copy_from_host(data, num_elements); + } + + /// Copies num_elements from the host vector after enlarging the array so that everything fits in + void enlarge_and_copy_from_host(const std::vector& data, const size_t num_elements) { + enlarge_and_copy_from_host(data.data(), num_elements); + } + + /// Copies the entire host vector after enlarging the array so that everything fits in + void enlarge_and_copy_from_host(const std::vector& data) { + enlarge_and_copy_from_host(data.data(), data.size()); + } + + /// Copies num_elements of data from the raw host pointer after resizing the array + void resize_and_copy_from_host(const T* data, const size_t num_elements) { + resize(num_elements); + copy_from_host(data, num_elements); + } + + /// Copies num_elements from the host vector after resizing the array + void resize_and_copy_from_host(const std::vector& data, const size_t num_elements) { + resize_and_copy_from_host(data.data(), num_elements); + } + + /// Copies the entire host vector after resizing the array + void resize_and_copy_from_host(const std::vector& data) { + resize_and_copy_from_host(data.data(), data.size()); + } + + /// Copies the entire host vector to the device. Fails if there is not enough space available. + void copy_from_host(const std::vector& data) { + if (data.size() < m_size) { + throw std::runtime_error(std::string("Trying to copy ") + std::to_string(m_size) + std::string(" elements, but vector size is only ") + std::to_string(data.size())); + } + copy_from_host(data.data(), m_size); + } + + /// Copies num_elements of data from the raw host pointer to the device. Fails if there is not enough space available. + void copy_to_host(T* host_data, const size_t num_elements) const { + if (num_elements > m_size) { + throw std::runtime_error(std::string("Trying to copy ") + std::to_string(num_elements) + std::string(" elements, but vector size is only ") + std::to_string(m_size)); + } + try { + CUDA_CHECK_THROW(cudaMemcpy(host_data, data(), num_elements * sizeof(T), cudaMemcpyDeviceToHost)); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not copy to host: ") + error.what()); + } + } + + /// Copies num_elements from the device to a vector on the host + void copy_to_host(std::vector& data, const size_t num_elements) const { + if (data.size() < num_elements) { + throw std::runtime_error(std::string("Trying to copy ") + std::to_string(num_elements) + std::string(" elements, but vector size is only ") + std::to_string(data.size())); + } + copy_to_host(data.data(), num_elements); + } + + /// Copies num_elements from the device to a raw pointer on the host + void copy_to_host(T* data) const { + copy_to_host(data, m_size); + } + + /// Copies all elements from the device to a vector on the host + void copy_to_host(std::vector& data) const { + if (data.size() < m_size) { + throw std::runtime_error(std::string("Trying to copy ") + std::to_string(m_size) + std::string(" elements, but vector size is only ") + std::to_string(data.size())); + } + copy_to_host(data.data(), m_size); + } + + /// Copies data from another device array to this one, automatically resizing it + void copy_from_device(const GPUMemory &other) { + if (m_size != other.m_size) { + resize(other.m_size); + } + + try { + CUDA_CHECK_THROW(cudaMemcpy(m_data, other.m_data, m_size * sizeof(T), cudaMemcpyDeviceToDevice)); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not copy from device: ") + error.what()); + } + } + + /// Copies size elements from another device array to this one, automatically resizing it + void copy_from_device(const GPUMemory &other, const size_t size) { + if (m_size < size) { + resize(size); + } + + try { + CUDA_CHECK_THROW(cudaMemcpy(m_data, other.m_data, size * sizeof(T), cudaMemcpyDeviceToDevice)); + } catch (std::runtime_error error) { + throw std::runtime_error(std::string("Could not copy from device: ") + error.what()); + } + } + + // Created an (owned) copy of the data + GPUMemory copy() const { + GPUMemory result{m_size}; + result.copy_from_device(*this); + return result; + } + + T* data() const { + check_guards(); + return m_data; + } + + __host__ __device__ T& operator[](size_t idx) const { +#ifdef DEBUG_BUFFER_OVERRUN + if (idx > m_size) { + printf("WARNING: buffer overrun of %p at idx %zu\n", idx); + } +#endif + return m_data[idx]; + } + + __host__ __device__ T& operator[](uint32_t idx) const { +#ifdef DEBUG_BUFFER_OVERRUN + if (idx > m_size) { + printf("WARNING: buffer overrun of %p at idx %u\n", idx); + } +#endif + return m_data[idx]; + } + + size_t get_num_elements() const { + return m_size; + } + + size_t size() const { + return get_num_elements(); + } + + size_t get_bytes() const { + return m_size * sizeof(T); + } + + size_t bytes() const { + return get_bytes(); + } +}; + +} \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/hashtable.cuh b/extensions/CUBVH/include/gpu/hashtable.cuh new file mode 100644 index 0000000000000000000000000000000000000000..3fd2d250956756d9b9de09906d491403282645aa --- /dev/null +++ b/extensions/CUBVH/include/gpu/hashtable.cuh @@ -0,0 +1,218 @@ +#pragma once + +#include +#include + +namespace cubvh { + +// --- N-dim integer static hash table --- +// This module implements a minimal open-addressed hash table for integer ND coordinates on CUDA. +// Note: this is a STATIC hashtable, only build it once and use it for queries! +// +// Shapes and conventions (all buffers are device pointers with int32 entries unless stated otherwise): +// - coords: [N * D] layout contiguous as D-tuple per row (default D=3 for 3D). +// - queries: [M * D] layout contiguous as D-tuple per row. +// - table_kvs: [capacity * 2]; for slot s: +// table_kvs[2*s + 0] = slot marker (-1 means empty; any other value means occupied) +// table_kvs[2*s + 1] = row index into coords (0..N-1), or -1 if not set +// - out_indices: [M]; contains row index into coords or -1 if not found. + +// Table layout: flattened array of length 2 * capacity (int32) +// - table_kvs[2*slot + 0]: slot marker; -1 means empty; any other value means occupied +// - table_kvs[2*slot + 1]: index into coords (row index) + + +// --- Hash helper (CityHash-like mix for 32-bit ints) --- +// Used to map a small fixed-length integer key to a slot in [0, capacity). +__device__ inline uint32_t _hash_city32_step(uint32_t hash_val, uint32_t key) { + hash_val += key * 0x9E3779B9u; + hash_val ^= hash_val >> 16; + hash_val *= 0x85EBCA6Bu; + hash_val ^= hash_val >> 13; + hash_val *= 0xC2B2AE35u; + hash_val ^= hash_val >> 16; + return hash_val; +} + +struct CityHash { + // key: pointer to first element; key_dim: number of ints (here 3 in practice) + // capacity: table capacity (number of slots) + __device__ inline static int hash(const int* key, int key_dim, int capacity) { + uint32_t h = 0u; + for (int i = 0; i < key_dim; ++i) { + h = _hash_city32_step(h, (uint32_t)key[i]); + } + int signed_h = (int)h; + // ensure non-negative modulo + int slot = signed_h % capacity; + if (slot < 0) slot += capacity; + return slot; + } +}; + +__device__ inline bool _vec_equal(const int* a, const int* b, int dim) { + for (int i = 0; i < dim; ++i) { + if (a[i] != b[i]) return false; + } + return true; +} + +// N-D key search in the hash table (default D=3) +__device__ inline int _search_hash_table( + const int* __restrict__ table_kvs, + const int* __restrict__ coords, + const int* __restrict__ query_key, + int table_capacity, + int num_dims +) { + // query_key: [D] + // coords: [N * D] + // table_kvs: [capacity * 2] + int slot = CityHash::hash(query_key, num_dims, table_capacity); + const int begin = slot; + int attempts = 0; + while (attempts < table_capacity) { + const int marker = table_kvs[slot * 2 + 0]; + if (marker == -1) { + return -1; // empty slot encountered => not present + } + const int vec_idx = table_kvs[slot * 2 + 1]; + if (vec_idx != -1) { + const int* candidate = &coords[vec_idx * num_dims]; + if (_vec_equal(candidate, query_key, num_dims)) { + return vec_idx; + } + } + slot = (slot + 1) % table_capacity; + if (slot == begin) return -1; // full cycle + ++attempts; + } + return -1; +} + +// --- Kernels --- + +// Initialize table: set both key marker and value index to -1 +// table_kvs: [capacity * 2] +__global__ void prepare_key_value_pairs_kernel(int* table_kvs, int capacity) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + if (tid < capacity) { + table_kvs[2 * tid + 0] = -1; + table_kvs[2 * tid + 1] = -1; + } +} + +// Insert a batch of N-D coords (default D=3) +// table_kvs: [capacity * 2] +// coords: [num_keys * num_dims] +// num_keys: N (rows in coords) +__global__ void insert_kernel( + int* __restrict__ table_kvs, + const int* __restrict__ coords, + int num_keys, + int num_dims, + int table_capacity +) { + const int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx >= num_keys) return; + const int* key = &coords[idx * num_dims]; + int slot = CityHash::hash(key, num_dims, table_capacity); + const int begin = slot; + int attempts = 0; + while (attempts < table_capacity) { + int* marker_ptr = &table_kvs[slot * 2 + 0]; + const int prev = atomicCAS(marker_ptr, -1, slot); + if (prev == -1) { + table_kvs[slot * 2 + 1] = idx; // publish index + return; + } + slot = (slot + 1) % table_capacity; + if (slot == begin) return; // table full or no free slot + ++attempts; + } +} + + +// Search kernel for arbitrary queries (N-D; default D=3) +// table_kvs: [capacity * 2] +// coords: [N * num_dims] +// queries: [M * num_dims] +// out_indices: [M] +__global__ void search_kernel( + const int* __restrict__ table_kvs, + const int* __restrict__ coords, + const int* __restrict__ queries, + int num_queries, + int table_capacity, + int num_dims, + int* __restrict__ out_indices +) { + const int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx >= num_queries) return; + const int* q = &queries[idx * num_dims]; + out_indices[idx] = _search_hash_table(table_kvs, coords, q, table_capacity, num_dims); +} + + +// Lightweight RAII helper for a device hash table backing storage +struct HashTableInt { + // Device-side storage for the hash table key-value slots. + // Layout: [capacity * 2] (see top-level description for meaning of each entry) + GPUMemory table_kvs; // length = 2 * capacity + int capacity = 0; + const int* d_coords = nullptr; // external storage of keys [num_coords * num_dims] + int num_coords = 0; + int num_dims = 3; // default dimension + + void resize(int new_capacity) { + capacity = new_capacity; + table_kvs.resize((size_t)capacity * 2); + } + + // Set number of dimensions D (default 3) + void set_num_dims(int d) { num_dims = d; } + + // Initialize/prepare table (set all slots to -1) + // table_kvs: [capacity * 2] + void prepare(cudaStream_t stream) { + if (capacity <= 0) return; + const uint32_t tpb = 256u; + const uint32_t blocks = (uint32_t)div_round_up(capacity, (int)tpb); + prepare_key_value_pairs_kernel<<>>(table_kvs.data(), capacity); + } + + // Insert a batch of coords + // d_coords_in: [n_keys * num_dims] + void insert(const int* d_coords_in, int n_keys, cudaStream_t stream) { + d_coords = d_coords_in; + num_coords = n_keys; + if (capacity <= 0 || n_keys <= 0) return; + const uint32_t tpb = 256u; + const uint32_t blocks = (uint32_t)div_round_up(n_keys, (int)tpb); + insert_kernel<<>>(table_kvs.data(), d_coords, n_keys, num_dims, capacity); + } + + + // Build convenience: set capacity, prepare, then insert in one call + // d_coords_in: [n_keys * num_dims] + void build(const int* d_coords_in, int n_keys, cudaStream_t stream) { + // initialize capacity = max(16, 2 * n_keys) + int desired_capacity = n_keys * 2; + if (desired_capacity < 16) desired_capacity = 16; + resize(desired_capacity); + prepare(stream); + insert(d_coords_in, n_keys, stream); + } + + // Search a batch of queries; writes index or -1 per query + // d_queries: [n_queries * num_dims] + // d_out_indices: [n_queries] + void search(const int* d_queries, int n_queries, int* d_out_indices, cudaStream_t stream) const { + if (capacity <= 0 || n_queries <= 0) return; + const uint32_t tpb = 256u; + const uint32_t blocks = (uint32_t)div_round_up(n_queries, (int)tpb); + search_kernel<<>>(table_kvs.data(), d_coords, d_queries, n_queries, capacity, num_dims, d_out_indices); + } +}; + +} // namespace cubvh \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/pcg32.h b/extensions/CUBVH/include/gpu/pcg32.h new file mode 100644 index 0000000000000000000000000000000000000000..a135ce1a9329e78692a0c8d34c473d61ecb103f3 --- /dev/null +++ b/extensions/CUBVH/include/gpu/pcg32.h @@ -0,0 +1,207 @@ +/* + * Tiny self-contained version of the PCG Random Number Generation for C++ + * put together from pieces of the much larger C/C++ codebase. + * Wenzel Jakob, February 2015 + * + * The PCG random number generator was developed by Melissa O'Neill + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, visit + * + * http://www.pcg-random.org + * + * Note: This code was modified to work with CUDA by the tiny-cuda-nn authors. + */ + +#pragma once + +// #include + +#define PCG32_DEFAULT_STATE 0x853c49e6748fea9bULL +#define PCG32_DEFAULT_STREAM 0xda3e39cb94b95bdbULL +#define PCG32_MULT 0x5851f42d4c957f2dULL + +#include +#include + + +namespace cubvh { + +/// PCG32 Pseudorandom number generator +struct pcg32 { + /// Initialize the pseudorandom number generator with default seed + __host__ __device__ pcg32() : state(PCG32_DEFAULT_STATE), inc(PCG32_DEFAULT_STREAM) {} + + /// Initialize the pseudorandom number generator with the \ref seed() function + __host__ __device__ pcg32(uint64_t initstate, uint64_t initseq = 1u) { seed(initstate, initseq); } + + /** + * \brief Seed the pseudorandom number generator + * + * Specified in two parts: a state initializer and a sequence selection + * constant (a.k.a. stream id) + */ + __host__ __device__ void seed(uint64_t initstate, uint64_t initseq = 1) { + state = 0U; + inc = (initseq << 1u) | 1u; + next_uint(); + state += initstate; + next_uint(); + } + + /// Generate a uniformly distributed unsigned 32-bit random number + __host__ __device__ uint32_t next_uint() { + uint64_t oldstate = state; + state = oldstate * PCG32_MULT + inc; + uint32_t xorshifted = (uint32_t) (((oldstate >> 18u) ^ oldstate) >> 27u); + uint32_t rot = (uint32_t) (oldstate >> 59u); + return (xorshifted >> rot) | (xorshifted << ((~rot + 1u) & 31)); + } + + /// Generate a uniformly distributed number, r, where 0 <= r < bound + __host__ __device__ uint32_t next_uint(uint32_t bound) { + // To avoid bias, we need to make the range of the RNG a multiple of + // bound, which we do by dropping output less than a threshold. + // A naive scheme to calculate the threshold would be to do + // + // uint32_t threshold = 0x100000000ull % bound; + // + // but 64-bit div/mod is slower than 32-bit div/mod (especially on + // 32-bit platforms). In essence, we do + // + // uint32_t threshold = (0x100000000ull-bound) % bound; + // + // because this version will calculate the same modulus, but the LHS + // value is less than 2^32. + + uint32_t threshold = (~bound+1u) % bound; + + // Uniformity guarantees that this loop will terminate. In practice, it + // should usually terminate quickly; on average (assuming all bounds are + // equally likely), 82.25% of the time, we can expect it to require just + // one iteration. In the worst case, someone passes a bound of 2^31 + 1 + // (i.e., 2147483649), which invalidates almost 50% of the range. In + // practice, bounds are typically small and only a tiny amount of the range + // is eliminated. + for (;;) { + uint32_t r = next_uint(); + if (r >= threshold) + return r % bound; + } + } + + /// Generate a single precision floating point value on the interval [0, 1) + __host__ __device__ float next_float() { + /* Trick from MTGP: generate an uniformly distributed + single precision number in [1,2) and subtract 1. */ + union { + uint32_t u; + float f; + } x; + x.u = (next_uint() >> 9) | 0x3f800000u; + return x.f - 1.0f; + } + + /** + * \brief Generate a double precision floating point value on the interval [0, 1) + * + * \remark Since the underlying random number generator produces 32 bit output, + * only the first 32 mantissa bits will be filled (however, the resolution is still + * finer than in \ref next_float(), which only uses 23 mantissa bits) + */ + __host__ __device__ double next_double() { + /* Trick from MTGP: generate an uniformly distributed + double precision number in [1,2) and subtract 1. */ + union { + uint64_t u; + double d; + } x; + x.u = ((uint64_t) next_uint() << 20) | 0x3ff0000000000000ULL; + return x.d - 1.0; + } + + /** + * \brief Multi-step advance function (jump-ahead, jump-back) + * + * The method used here is based on Brown, "Random Number Generation + * with Arbitrary Stride", Transactions of the American Nuclear + * Society (Nov. 1994). The algorithm is very similar to fast + * exponentiation. + * + * The default value of 2^32 ensures that the PRNG is advanced + * sufficiently far that there is (likely) no overlap with + * previously drawn random numbers, even if small advancements. + * are made inbetween. + */ + __host__ __device__ void advance(int64_t delta_ = (1ll<<32)) { + uint64_t + cur_mult = PCG32_MULT, + cur_plus = inc, + acc_mult = 1u, + acc_plus = 0u; + + /* Even though delta is an unsigned integer, we can pass a signed + integer to go backwards, it just goes "the long way round". */ + uint64_t delta = (uint64_t) delta_; + + while (delta > 0) { + if (delta & 1) { + acc_mult *= cur_mult; + acc_plus = acc_plus * cur_mult + cur_plus; + } + cur_plus = (cur_mult + 1) * cur_plus; + cur_mult *= cur_mult; + delta /= 2; + } + state = acc_mult * state + acc_plus; + } + + /// Compute the distance between two PCG32 pseudorandom number generators + __host__ __device__ int64_t operator-(const pcg32 &other) const { + assert(inc == other.inc); + + uint64_t + cur_mult = PCG32_MULT, + cur_plus = inc, + cur_state = other.state, + the_bit = 1u, + distance = 0u; + + while (state != cur_state) { + if ((state & the_bit) != (cur_state & the_bit)) { + cur_state = cur_state * cur_mult + cur_plus; + distance |= the_bit; + } + assert((state & the_bit) == (cur_state & the_bit)); + the_bit <<= 1; + cur_plus = (cur_mult + 1ULL) * cur_plus; + cur_mult *= cur_mult; + } + + return (int64_t) distance; + } + + /// Equality operator + __host__ __device__ bool operator==(const pcg32 &other) const { return state == other.state && inc == other.inc; } + + /// Inequality operator + __host__ __device__ bool operator!=(const pcg32 &other) const { return state != other.state || inc != other.inc; } + + uint64_t state; // RNG state. All values are possible. + uint64_t inc; // Controls which RNG sequence (stream) is selected. Must *always* be odd. +}; + +} \ No newline at end of file diff --git a/extensions/CUBVH/include/gpu/spcumc.cuh b/extensions/CUBVH/include/gpu/spcumc.cuh new file mode 100644 index 0000000000000000000000000000000000000000..1821b66288e34e5a230086837ba7961bc6fb0cce --- /dev/null +++ b/extensions/CUBVH/include/gpu/spcumc.cuh @@ -0,0 +1,868 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// Added for memory-optimized pipeline +#include +#include +#include +#include +#include + +// Alias for 3D point (float3 is a built-in CUDA vector type) +using V3f = float3; +// Triangle index structure +struct Tri { int v0, v1, v2; }; + +// Lookup tables (partial placeholder). +__device__ __constant__ int edgeTable[256] = { + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 +}; + +__device__ __constant__ int triTable[256][16] = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, + {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, + {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, + {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, + {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, + {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, + {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, + {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, + {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, + {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, + {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, + {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, + {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, + {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, + {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, + {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, + {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, + {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, + {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, + {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, + {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, + {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, + {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, + {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, + {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, + {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, + {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, + {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, + {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, + {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, + {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, + {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, + {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, + {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, + {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, + {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, + {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, + {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, + {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, + {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, + {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, + {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, + {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, + {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, + {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, + {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, + {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, + {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, + {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, + {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, + {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, + {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, + {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, + {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, + {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, + {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, + {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, + {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, + {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, + {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, + {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, + {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, + {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, + {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, + {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, + {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, + {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, + {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, + {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, + {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, + {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, + {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, + {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, + {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, + {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, + {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, + {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, + {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, + {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, + {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, + {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, + {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, + {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, + {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, + {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, + {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, + {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, + {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, + {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, + {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, + {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, + {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, + {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, + {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, + {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, + {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, + {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +}; + +// Device helper: corner offset vectors for a voxel (assuming voxel coordinate = corner 0 position). +__device__ __constant__ int3 cornerOffset[8] = { + {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0}, + {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} +}; + +// Edge i connects EDGE_CORNERS[i][0] โ†” EDGE_CORNERS[i][1] +// Matches the edge order required by edgeTable & triTable +__device__ __constant__ int EDGE_CORNERS[12][2] = { + {0,1},{1,2},{2,3},{3,0}, // 0โ€“3 bottom square, X Y X Y + {4,5},{5,6},{6,7},{7,4}, // 4โ€“7 top square + {0,4},{1,5},{2,6},{3,7} // 8โ€“11 vertical edges (Z) +}; + + +// Device struct to represent an edge-vertex key (to deduplicate vertices) +struct EdgeKey { + int x, y, z; + unsigned char axis; + __host__ __device__ bool operator==(const EdgeKey& o) const { + return x == o.x && y == o.y && z == o.z && axis == o.axis; + } + __host__ __device__ bool operator<(const EdgeKey& o) const { + if (x < o.x) return true; if (x > o.x) return false; + if (y < o.y) return true; if (y > o.y) return false; + if (z < o.z) return true; if (z > o.z) return false; + return axis < o.axis; + } +}; + +// Functors to avoid device-only lambdas with Thrust templates +struct HeadFlagFunctor { + const EdgeKey* keys; + __host__ __device__ int operator()(int i) const { + if (i == 0) return 1; + EdgeKey a = keys[i]; + EdgeKey b = keys[i - 1]; + return (a == b) ? 0 : 1; + } +}; + +struct IsNonZero { + __host__ __device__ bool operator()(int x) const { return x != 0; } +}; + +struct MinusOne { + __host__ __device__ int operator()(int x) const { return x - 1; } +}; + +struct RemapTri { + const int* map; + __host__ __device__ void operator()(Tri& tri) const { + tri.v0 = map[tri.v0]; + tri.v1 = map[tri.v1]; + tri.v2 = map[tri.v2]; + } +}; + +// CUDA kernel: classify voxels, count intersections and triangles +__global__ void classifyVoxels(const int* coords, const float* corners, + int N, float iso, + int* vertCount, int* triCount) { + int i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= N) return; + // Load the 8 corner values for voxel i + float v[8]; + #pragma unroll + for (int j = 0; j < 8; ++j) { + v[j] = corners[i*8 + j]; + } + // Determine cube index (bitmask of corners < iso) + int cubeIndex = 0; + if (v[0] < iso) cubeIndex |= 1; + if (v[1] < iso) cubeIndex |= 2; + if (v[2] < iso) cubeIndex |= 4; + if (v[3] < iso) cubeIndex |= 8; + if (v[4] < iso) cubeIndex |= 16; + if (v[5] < iso) cubeIndex |= 32; + if (v[6] < iso) cubeIndex |= 64; + if (v[7] < iso) cubeIndex |= 128; + // Lookup intersected edges + int mask = edgeTable[cubeIndex]; + // Count set bits in mask (number of intersection vertices) + // __popc is efficient built-in for counting bits in an int. + int numVerts = __popc(mask & 0xFFF); // mask is 12-bit at most + vertCount[i] = numVerts; + // Count triangles for this cube configuration using triTable + int numTris = 0; + // triTable[cubeIndex][...] contains groups of 3 edge indices for each triangle, terminated by -1 + for (int t = 0; t < 15; t += 3) { + if (triTable[cubeIndex][t] == -1) break; + numTris++; + } + triCount[i] = numTris; +} + +__global__ void generateVertices(const int* coords, const float* corners, + const int* prefixVert, int N, float iso, + EdgeKey* outKeys, V3f* outVerts) +{ + int i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= N) return; + + int base = prefixVert[i]; // first vertex slot for this voxel + int vx = coords[i*3+0]; + int vy = coords[i*3+1]; + int vz = coords[i*3+2]; + + float v[8]; + #pragma unroll + for (int c = 0; c < 8; ++c) v[c] = corners[i*8 + c]; + + // --- cube index & edge mask --------------------------------------------- + int ci = 0; + if (v[0] < iso) ci |= 1; if (v[1] < iso) ci |= 2; + if (v[2] < iso) ci |= 4; if (v[3] < iso) ci |= 8; + if (v[4] < iso) ci |= 16; if (v[5] < iso) ci |= 32; + if (v[6] < iso) ci |= 64; if (v[7] < iso) ci |= 128; + int mask = edgeTable[ci]; + if (mask == 0) return; + + int outOfs = 0; // how many verts already emitted for this voxel + + // ------------------------------------------------------------------------ + #pragma unroll + for (int e = 0; e < 12; ++e) + { + if (!(mask & (1 << e))) continue; + + int a = EDGE_CORNERS[e][0]; + int b = EDGE_CORNERS[e][1]; + + float va = v[a], vb = v[b]; + float denom = vb - va; + float t; + if (fabsf(denom) < 1e-30f) + t = 0.5f; // degenerate edge โ†’ midpoint + else { + t = (iso - va) / denom; // interpolate + t = fminf(fmaxf(t, 0.f), 1.f); // clamp numerical noise + } + + int3 offA = cornerOffset[a]; + int3 offB = cornerOffset[b]; + float3 pA = make_float3(vx + offA.x, vy + offA.y, vz + offA.z); + float3 pB = make_float3(vx + offB.x, vy + offB.y, vz + offB.z); + float3 P = { pA.x + t*(pB.x-pA.x), + pA.y + t*(pB.y-pA.y), + pA.z + t*(pB.z-pA.z) }; + + // ------------ build dedup key (lower corner + axis) ------------------ + EdgeKey key; + key.x = (offA.x < offB.x ? vx+offA.x : vx+offB.x); + key.y = (offA.y < offB.y ? vy+offA.y : vy+offB.y); + key.z = (offA.z < offB.z ? vz+offA.z : vz+offB.z); + key.axis = (offA.x != offB.x) ? 0 : (offA.y != offB.y ? 1 : 2); + + outVerts[base + outOfs] = P; + outKeys [base + outOfs] = key; + ++outOfs; + } + // now outOfs == __popc(mask) โœ” +} + +// CUDA kernel: generate triangles (with *old* vertex indices, will remap later) +__global__ void generateTriangles(const int* coords, const float* corners, + const int* prefixVert, const int* prefixTri, + int N, float iso, Tri* outTris) { + int i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= N) return; + int triStart = prefixTri[i]; // starting index in triangle array for voxel i + int baseVert = prefixVert[i]; // starting index of this voxel's vertices in vertex array + // Load corner values + float v[8]; + #pragma unroll + for (int j = 0; j < 8; ++j) { + v[j] = corners[i*8 + j]; + } + // Compute cubeIndex and edge mask again + int cubeIndex = 0; + if (v[0] < iso) cubeIndex |= 1; + if (v[1] < iso) cubeIndex |= 2; + if (v[2] < iso) cubeIndex |= 4; + if (v[3] < iso) cubeIndex |= 8; + if (v[4] < iso) cubeIndex |= 16; + if (v[5] < iso) cubeIndex |= 32; + if (v[6] < iso) cubeIndex |= 64; + if (v[7] < iso) cubeIndex |= 128; + int mask = edgeTable[cubeIndex]; + if (mask == 0) return; + // Iterate over triangle entries in triTable + int outIdx = 0; + for (int t = 0; t < 15; t += 3) { + int e0 = triTable[cubeIndex][t]; + if (e0 == -1) break; // end of list + int e1 = triTable[cubeIndex][t+1]; + int e2 = triTable[cubeIndex][t+2]; + // Compute original (pre-deduplication) vertex indices for each edge + // Count how many intersection vertices in this voxel come before the one on edge e + // i.e., popcount of all lower-numbered edges in the mask. + int off0 = __popc(mask & ((1 << e0) - 1)); + int off1 = __popc(mask & ((1 << e1) - 1)); + int off2 = __popc(mask & ((1 << e2) - 1)); + Tri tri; + tri.v0 = baseVert + off0; + tri.v1 = baseVert + off2; // flip to make sure the triangle is counter-clockwise + tri.v2 = baseVert + off1; + outTris[triStart + outIdx] = tri; + outIdx++; + } +} + +// Device kernel to ensure corner consistency using atomic operations +__global__ void collectCornerContributions(const int* coords, const float* corners, int N, + int* corner_x, int* corner_y, int* corner_z, float* corner_vals, int* corner_counts) { + int tid = blockIdx.x * blockDim.x + threadIdx.x; + if (tid >= N * 8) return; + + int voxel_id = tid / 8; + int corner_id = tid % 8; + + // Get voxel position + int vx = coords[voxel_id * 3 + 0]; + int vy = coords[voxel_id * 3 + 1]; + int vz = coords[voxel_id * 3 + 2]; + + // Get corner position + int3 offset = cornerOffset[corner_id]; + int cx = vx + offset.x; + int cy = vy + offset.y; + int cz = vz + offset.z; + + // Store corner data + corner_x[tid] = cx; + corner_y[tid] = cy; + corner_z[tid] = cz; + corner_vals[tid] = corners[voxel_id * 8 + corner_id]; + corner_counts[tid] = 1; +} + +__global__ void updateCornerValues(const int* coords, float* corners, int N, + const int* unique_x, const int* unique_y, const int* unique_z, + const float* avg_vals, int num_unique) { + int tid = blockIdx.x * blockDim.x + threadIdx.x; + if (tid >= N * 8) return; + + int voxel_id = tid / 8; + int corner_id = tid % 8; + + // Get voxel position + int vx = coords[voxel_id * 3 + 0]; + int vy = coords[voxel_id * 3 + 1]; + int vz = coords[voxel_id * 3 + 2]; + + // Get corner position + int3 offset = cornerOffset[corner_id]; + int cx = vx + offset.x; + int cy = vy + offset.y; + int cz = vz + offset.z; + + // Binary search for this corner coordinate + int left = 0, right = num_unique - 1; + while (left <= right) { + int mid = (left + right) / 2; + int mx = unique_x[mid]; + int my = unique_y[mid]; + int mz = unique_z[mid]; + + if (cx < mx || (cx == mx && cy < my) || (cx == mx && cy == my && cz < mz)) { + right = mid - 1; + } else if (cx > mx || (cx == mx && cy > my) || (cx == mx && cy == my && cz > mz)) { + left = mid + 1; + } else { + // Found exact match, update corner value + corners[voxel_id * 8 + corner_id] = avg_vals[mid]; + break; + } + } +} + +// Helper structure for corner data sorting +struct CornerData { + int x, y, z; + float value; + int count; + + __host__ __device__ bool operator<(const CornerData& other) const { + if (x != other.x) return x < other.x; + if (y != other.y) return y < other.y; + return z < other.z; + } + + __host__ __device__ bool operator==(const CornerData& other) const { + return x == other.x && y == other.y && z == other.z; + } +}; + +// Reduction operator for averaging +struct CornerAverage { + __host__ __device__ CornerData operator()(const CornerData& a, const CornerData& b) const { + CornerData result; + result.x = a.x; // coordinates should be same + result.y = a.y; + result.z = a.z; + result.value = a.value + b.value; // sum values + result.count = a.count + b.count; // sum counts + return result; + } +}; + +// Host function: sparse marching cubes +inline std::pair, thrust::device_vector> +_sparse_marching_cubes(const int* d_coords, const float* d_corners, int N, float iso, bool ensure_consistency, cudaStream_t stream) { + // Output containers + thrust::device_vector vertices; + thrust::device_vector triangles; + if (N <= 0) { + // No voxels, return empty mesh + return {vertices, triangles}; + } + + // Create a copy of corners data if we need to ensure consistency + thrust::device_vector corners_copy; + const float* d_corners_to_use = d_corners; + + if (ensure_consistency) { + // Copy original corner data + corners_copy.resize(N * 8); + thrust::copy(thrust::cuda::par.on(stream), + d_corners, d_corners + N * 8, + corners_copy.begin()); + + // Total number of corner instances (8 per voxel) + const int total_corners = N * 8; + + // Create arrays to store corner data + thrust::device_vector corner_x(total_corners); + thrust::device_vector corner_y(total_corners); + thrust::device_vector corner_z(total_corners); + thrust::device_vector corner_vals(total_corners); + thrust::device_vector corner_counts(total_corners); + + // Collect all corner contributions + int threads_corner = 256; + int blocks_corner = (total_corners + threads_corner - 1) / threads_corner; + collectCornerContributions<<>>( + d_coords, d_corners, N, + thrust::raw_pointer_cast(corner_x.data()), + thrust::raw_pointer_cast(corner_y.data()), + thrust::raw_pointer_cast(corner_z.data()), + thrust::raw_pointer_cast(corner_vals.data()), + thrust::raw_pointer_cast(corner_counts.data())); + + // Create corner data structure for sorting and averaging + thrust::device_vector corner_data(total_corners); + thrust::transform(thrust::cuda::par.on(stream), + thrust::counting_iterator(0), + thrust::counting_iterator(total_corners), + corner_data.begin(), + [corner_x_ptr = thrust::raw_pointer_cast(corner_x.data()), + corner_y_ptr = thrust::raw_pointer_cast(corner_y.data()), + corner_z_ptr = thrust::raw_pointer_cast(corner_z.data()), + corner_vals_ptr = thrust::raw_pointer_cast(corner_vals.data()), + corner_counts_ptr = thrust::raw_pointer_cast(corner_counts.data())] __device__ (int i) { + CornerData data; + data.x = corner_x_ptr[i]; + data.y = corner_y_ptr[i]; + data.z = corner_z_ptr[i]; + data.value = corner_vals_ptr[i]; + data.count = corner_counts_ptr[i]; + return data; + }); + + // Sort by corner coordinates + thrust::sort(thrust::cuda::par.on(stream), corner_data.begin(), corner_data.end()); + + // Reduce by key to get average for each unique corner + thrust::device_vector unique_corners(total_corners); + thrust::device_vector corner_sums(total_corners); + + auto new_end = thrust::reduce_by_key( + thrust::cuda::par.on(stream), + corner_data.begin(), corner_data.end(), + corner_data.begin(), + unique_corners.begin(), + corner_sums.begin(), + [] __device__ (const CornerData& a, const CornerData& b) { + return a.x == b.x && a.y == b.y && a.z == b.z; + }, + CornerAverage()); + + int num_unique = new_end.first - unique_corners.begin(); + unique_corners.resize(num_unique); + corner_sums.resize(num_unique); + + // Compute averages and create coordinate arrays + thrust::device_vector unique_x(num_unique); + thrust::device_vector unique_y(num_unique); + thrust::device_vector unique_z(num_unique); + thrust::device_vector avg_vals(num_unique); + + thrust::transform(thrust::cuda::par.on(stream), + thrust::counting_iterator(0), + thrust::counting_iterator(num_unique), + thrust::make_zip_iterator(thrust::make_tuple( + unique_x.begin(), unique_y.begin(), unique_z.begin(), avg_vals.begin())), + [unique_corners_ptr = thrust::raw_pointer_cast(unique_corners.data()), + corner_sums_ptr = thrust::raw_pointer_cast(corner_sums.data())] __device__ (int i) { + const CornerData& corner = unique_corners_ptr[i]; + const CornerData& sum = corner_sums_ptr[i]; + float avg = sum.value / sum.count; + return thrust::make_tuple(corner.x, corner.y, corner.z, avg); + }); + + // Update corner values using the simpler kernel + updateCornerValues<<>>( + d_coords, + thrust::raw_pointer_cast(corners_copy.data()), + N, + thrust::raw_pointer_cast(unique_x.data()), + thrust::raw_pointer_cast(unique_y.data()), + thrust::raw_pointer_cast(unique_z.data()), + thrust::raw_pointer_cast(avg_vals.data()), + num_unique); + + d_corners_to_use = thrust::raw_pointer_cast(corners_copy.data()); + } + + // Temporary arrays for counts and prefix sums + thrust::device_vector vertCount(N); + thrust::device_vector triCount(N); + + int threads = 256; + int blocks = (N + threads - 1) / threads; + classifyVoxels<<>>(d_coords, d_corners_to_use, N, iso, + thrust::raw_pointer_cast(vertCount.data()), + thrust::raw_pointer_cast(triCount.data())); + + thrust::device_vector prefixVert(N); + thrust::device_vector prefixTri(N); + thrust::exclusive_scan(thrust::cuda::par.on(stream), + vertCount.begin(), vertCount.end(), prefixVert.begin()); + thrust::exclusive_scan(thrust::cuda::par.on(stream), + triCount.begin(), triCount.end(), prefixTri.begin()); + + // Compute totals + int M = vertCount.empty() ? 0 : (prefixVert.back() + vertCount.back()); + int T = triCount.empty() ? 0 : (prefixTri.back() + triCount.back()); + + // Free counts early to lower peak memory + thrust::device_vector().swap(vertCount); + thrust::device_vector().swap(triCount); + + // Allocate space for all intersection vertices (M) and their keys + thrust::device_vector keys(M); + thrust::device_vector verts(M); + + // Generate vertices in parallel + blocks = (N + threads - 1) / threads; + generateVertices<<>>(d_coords, d_corners_to_use, + thrust::raw_pointer_cast(prefixVert.data()), + N, iso, + thrust::raw_pointer_cast(keys.data()), + thrust::raw_pointer_cast(verts.data())); + + // Create index array [0, 1, ..., M-1] to track original positions + thrust::device_vector indices(M); + if (M > 0) { + thrust::sequence(thrust::cuda::par.on(stream), indices.begin(), indices.end()); + + // Sort by key and reorder verts and indices in one pass (no extra vertsSorted buffer) + auto zipped_vals = thrust::make_zip_iterator(thrust::make_tuple(verts.begin(), indices.begin())); + thrust::sort_by_key(thrust::cuda::par.on(stream), keys.begin(), keys.end(), zipped_vals); + + // Build head flags using a transform iterator functor + EdgeKey* d_keys = thrust::raw_pointer_cast(keys.data()); + auto count_begin = thrust::make_counting_iterator(0); + auto head_flags = thrust::make_transform_iterator(count_begin, HeadFlagFunctor{d_keys}); + + // Compute inclusive scan of head flags directly into group ids (1-based) + thrust::device_vector mapSortedToUnique(M); + thrust::inclusive_scan(thrust::cuda::par.on(stream), head_flags, head_flags + M, mapSortedToUnique.begin()); + + // Number of unique vertices + int uniqueCount = 0; + cudaMemcpyAsync(&uniqueCount, thrust::raw_pointer_cast(mapSortedToUnique.data()) + (M - 1), + sizeof(int), cudaMemcpyDeviceToHost, stream); + cudaStreamSynchronize(stream); + vertices.resize(uniqueCount); + + // Emit unique vertices by copying only the heads + thrust::copy_if(thrust::cuda::par.on(stream), + verts.begin(), verts.end(), + head_flags, + vertices.begin(), + IsNonZero()); + + // Build mapping from original vertex index -> new unique index + thrust::device_vector mapOrigToNew(M); + // Convert to 0-based ids in-place and scatter back to original order + thrust::transform(thrust::cuda::par.on(stream), + mapSortedToUnique.begin(), mapSortedToUnique.end(), + mapSortedToUnique.begin(), + MinusOne()); + thrust::scatter(thrust::cuda::par.on(stream), + mapSortedToUnique.begin(), mapSortedToUnique.end(), + indices.begin(), + mapOrigToNew.begin()); + + // Free temporaries no longer needed before allocating triangles + thrust::device_vector().swap(keys); + thrust::device_vector().swap(verts); + thrust::device_vector().swap(indices); + thrust::device_vector().swap(mapSortedToUnique); + + // Generate triangles (old indices) + triangles.resize(T); + blocks = (N + threads - 1) / threads; + generateTriangles<<>>(d_coords, d_corners_to_use, + thrust::raw_pointer_cast(prefixVert.data()), + thrust::raw_pointer_cast(prefixTri.data()), + N, iso, + thrust::raw_pointer_cast(triangles.data())); + // Remap triangle vertex indices to the new deduplicated indices + if (T > 0) { + int* d_map = thrust::raw_pointer_cast(mapOrigToNew.data()); + thrust::for_each(thrust::cuda::par.on(stream), + triangles.begin(), triangles.end(), + RemapTri{d_map}); + } + // mapOrigToNew freed on scope exit + } else { + // No intersections; still need to size triangles correctly + triangles.resize(T); + if (T > 0) { + blocks = (N + threads - 1) / threads; + generateTriangles<<>>(d_coords, d_corners_to_use, + thrust::raw_pointer_cast(prefixVert.data()), + thrust::raw_pointer_cast(prefixTri.data()), + N, iso, + thrust::raw_pointer_cast(triangles.data())); + // No remap needed; M==0 implies T should also be 0 for standard MC, but keep safe + } + } + + cudaStreamSynchronize(stream); + return { std::move(vertices), std::move(triangles) }; +} diff --git a/extensions/CUBVH/include/gpu/triangle.cuh b/extensions/CUBVH/include/gpu/triangle.cuh new file mode 100644 index 0000000000000000000000000000000000000000..03a82c31e401acdfc634171c6345a15ada43d8fb --- /dev/null +++ b/extensions/CUBVH/include/gpu/triangle.cuh @@ -0,0 +1,227 @@ +#pragma once + +#include + +namespace cubvh { + +// Triangle data structure +struct Triangle { + + __host__ __device__ Eigen::Vector3f sample_uniform_position(const Eigen::Vector2f& sample) const { + float sqrt_x = std::sqrt(sample.x()); + float factor0 = 1.0f - sqrt_x; + float factor1 = sqrt_x * (1.0f - sample.y()); + float factor2 = sqrt_x * sample.y(); + + return factor0 * a + factor1 * b + factor2 * c; + } + + __host__ __device__ float surface_area() const { + return 0.5f * Eigen::Vector3f((b - a).cross(c - a)).norm(); + } + + __host__ __device__ Eigen::Vector3f normal() const { + Eigen::Vector3f n = (b - a).cross(c - a); + float norm = n.norm(); + if (norm > 1e-12f) { + return n / norm; + } + return Eigen::Vector3f::Zero(); + } + + __host__ __device__ float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd, Eigen::Vector3f& n) const { // based on https://www.iquilezles.org/www/articles/intersectors/intersectors.htm + Eigen::Vector3f v1v0 = b - a; + Eigen::Vector3f v2v0 = c - a; + Eigen::Vector3f rov0 = ro - a; + n = v1v0.cross( v2v0 ); + Eigen::Vector3f q = rov0.cross( rd ); + float d = safe_divide(1.0f, rd.dot(n)); + float u = d*-q.dot( v2v0 ); + float v = d* q.dot( v1v0 ); + float t = d*-n.dot( rov0 ); + if( u<0.0f || u>1.0f || v<0.0f || (u+v)>1.0f || t<0.0f) t = 1e6f; + return t; // Eigen::Vector3f( t, u, v ); + } + + __host__ __device__ float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd) const { + Eigen::Vector3f n; + return ray_intersect(ro, rd, n); + } + + __host__ __device__ float distance_sq(const Eigen::Vector3f& pos) const { + // prepare data + Eigen::Vector3f v21 = b - a; Eigen::Vector3f p1 = pos - a; + Eigen::Vector3f v32 = c - b; Eigen::Vector3f p2 = pos - b; + Eigen::Vector3f v13 = a - c; Eigen::Vector3f p3 = pos - c; + Eigen::Vector3f nor = v21.cross(v13); + + return + // inside/outside test + (sign(v21.cross(nor).dot(p1)) + sign(v32.cross(nor).dot(p2)) + sign(v13.cross(nor).dot(p3)) < 2.0f) + ? + // 3 edges + std::min( + std::min( + (v21 * clamp(v21.dot(p1) / v21.squaredNorm(), 0.0f, 1.0f)-p1).squaredNorm(), + (v32 * clamp(v32.dot(p2) / v32.squaredNorm(), 0.0f, 1.0f)-p2).squaredNorm() + ), + (v13 * clamp(v13.dot(p3) / v13.squaredNorm(), 0.0f, 1.0f)-p3).squaredNorm() + ) + : + // 1 face + nor.dot(p1)*nor.dot(p1)/nor.squaredNorm(); + } + + __host__ __device__ float distance(const Eigen::Vector3f& pos) const { + return std::sqrt(distance_sq(pos)); + } + + __host__ __device__ bool point_in_triangle(const Eigen::Vector3f& p) const { + // Move the triangle so that the point becomes the + // triangles origin + Eigen::Vector3f local_a = a - p; + Eigen::Vector3f local_b = b - p; + Eigen::Vector3f local_c = c - p; + + // The point should be moved too, so they are both + // relative, but because we don't use p in the + // equation anymore, we don't need it! + // p -= p; + + // Compute the normal vectors for triangles: + // u = normal of PBC + // v = normal of PCA + // w = normal of PAB + + Eigen::Vector3f u = local_b.cross(local_c); + Eigen::Vector3f v = local_c.cross(local_a); + Eigen::Vector3f w = local_a.cross(local_b); + + // Test to see if the normals are facing + // the same direction, return false if not + if (u.dot(v) < 0.0f) { + return false; + } + if (u.dot(w) < 0.0f) { + return false; + } + + // All normals facing the same way, return true + return true; + } + + __host__ __device__ Eigen::Vector3f closest_point_to_line(const Eigen::Vector3f& a, const Eigen::Vector3f& b, const Eigen::Vector3f& c) const { + Eigen::Vector3f ab = b - a; + float denom = ab.squaredNorm(); + if (denom <= 1e-12f) { + return a; + } + float t = (c - a).dot(ab) / denom; + t = clamp(t, 0.0f, 1.0f); + return a + t * ab; + } + + __host__ __device__ Eigen::Vector3f closest_point(Eigen::Vector3f point) const { + Eigen::Vector3f ab = b - a; + Eigen::Vector3f ac = c - a; + Eigen::Vector3f n = ab.cross(ac); + float norm_sq = n.squaredNorm(); + if (norm_sq > 1e-12f) { + float dist = n.dot(point - a) / norm_sq; + point -= dist * n; + } + + if (point_in_triangle(point)) { + return point; + } + + Eigen::Vector3f c1 = closest_point_to_line(a, b, point); + Eigen::Vector3f c2 = closest_point_to_line(b, c, point); + Eigen::Vector3f c3 = closest_point_to_line(c, a, point); + + float mag1 = (point - c1).squaredNorm(); + float mag2 = (point - c2).squaredNorm(); + float mag3 = (point - c3).squaredNorm(); + + float min = std::min(mag1, mag2); + min = std::min(min, mag3); + + if (min == mag1) { + return c1; + } + else if (min == mag2) { + return c2; + } + return c3; + } + + __host__ __device__ Eigen::Vector3f barycentric(const Eigen::Vector3f& p) const { + Eigen::Vector3f v0 = b - a; + Eigen::Vector3f v1 = c - a; + Eigen::Vector3f v2 = p - a; + + float d00 = v0.dot(v0); + float d01 = v0.dot(v1); + float d11 = v1.dot(v1); + float d20 = v2.dot(v0); + float d21 = v2.dot(v1); + + float denom = d00 * d11 - d01 * d01; + if (fabsf(denom) < 1e-12f) { + float ab = (b - a).squaredNorm(); + float bc = (c - b).squaredNorm(); + float ca = (a - c).squaredNorm(); + const float eps = 1e-12f; + + if (ab >= bc && ab >= ca && ab > eps) { + float t = clamp((p - a).dot(b - a) / ab, 0.0f, 1.0f); + return Eigen::Vector3f(1.0f - t, t, 0.0f); + } + if (bc >= ca && bc > eps) { + float t = clamp((p - b).dot(c - b) / bc, 0.0f, 1.0f); + return Eigen::Vector3f(0.0f, 1.0f - t, t); + } + if (ca > eps) { + float t = clamp((p - c).dot(a - c) / ca, 0.0f, 1.0f); + return Eigen::Vector3f(t, 0.0f, 1.0f - t); + } + return Eigen::Vector3f(1.0f, 0.0f, 0.0f); + } + + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + + return Eigen::Vector3f(u, v, w); + } + + __host__ __device__ Eigen::Vector3f centroid() const { + return (a + b + c) / 3.0f; + } + + __host__ __device__ float centroid(int axis) const { + return (a[axis] + b[axis] + c[axis]) / 3; + } + + __host__ __device__ void get_vertices(Eigen::Vector3f v[3]) const { + v[0] = a; + v[1] = b; + v[2] = c; + } + + Eigen::Vector3f a, b, c; + int64_t id; +}; + + +inline std::ostream& operator<<(std::ostream& os, const Triangle& triangle) { + os << "["; + os << "a=[" << triangle.a.x() << "," << triangle.a.y() << "," << triangle.a.z() << "], "; + os << "b=[" << triangle.b.x() << "," << triangle.b.y() << "," << triangle.b.z() << "], "; + os << "c=[" << triangle.c.x() << "," << triangle.c.y() << "," << triangle.c.z() << "]"; + os << "]"; + return os; +} + + +} \ No newline at end of file diff --git a/extensions/CUBVH/install.sh b/extensions/CUBVH/install.sh new file mode 100644 index 0000000000000000000000000000000000000000..222e34d1d2acef25e88b30fcb3279f7ce05e6c11 --- /dev/null +++ b/extensions/CUBVH/install.sh @@ -0,0 +1 @@ +python setup.py install && pip install --no-build-isolation . \ No newline at end of file diff --git a/extensions/CUBVH/pyproject.toml b/extensions/CUBVH/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..d85d50b3c9f12d3c936bfb5339ae4042ae616292 --- /dev/null +++ b/extensions/CUBVH/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = [ + "setuptools>=69", + "wheel", + "ninja", + "pybind11", +] +build-backend = "setuptools.build_meta" + +[project] +name = "cubvh" +version = "0.1.2" +description = "CUDA BVH implementation" +readme = "readme.md" +requires-python = ">=3.8" +authors = [{ name = "yihua", email = "huangyihua16@mails.ucas.ac.cn" }] +license = { file = "LICENSE" } +dependencies = [ + "ninja", + "pybind11", + "trimesh", + "torch", + "numpy", + "kiui", +] + +[project.urls] +Repository = "https://github.com/yihua7/cubvh" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = ["cubvh"] \ No newline at end of file diff --git a/extensions/CUBVH/readme.md b/extensions/CUBVH/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..208cb26340a844a5b8ad0b89625b64ec807fbfe3 --- /dev/null +++ b/extensions/CUBVH/readme.md @@ -0,0 +1,155 @@ +# cuBVH + +A CUDA Mesh BVH acceleration toolkit. + +### Highlights + +- Build acceleration structures from `numpy` or `torch` arrays on either CPU or CUDA. +- Save and reload BVHs without rebuilding via `torch.save`, `torch.load`, or `export_state`. +- Move a BVH between any Torch-visible devices with `.to(device)`, allocating GPU memory lazily. +- Run multi-GPU workloads safely; internal device guards keep each query on the intended GPU. + +### Install + +Make sure `torch` and CUDA are installed first. + +```bash +pip install git+https://github.com/yihua7/cubvh --no-build-isolation + +# or locally +git clone --recursive https://github.com/yihua7/cubvh +cd cubvh +pip install . --no-build-isolation +``` +It will take several minutes to build the CUDA dependency. + +#### Trouble Shooting +**`fatal error: eigen/matrix.h: No such file or directory`** + +This is a known issue for `torch==2.1.0` and `torch==2.1.1` (https://github.com/pytorch/pytorch/issues/112841). +To patch up these two versions, clone this repository, and copy `patch/eigen` to your pytorch include directory: +```bash +# for example, if you are using anaconda (assume base env) +cp -r patch/eigen ~/anaconda3/lib/python3.9/site-packages/torch/include/pybind11/ +``` + +**`fatal error: Eigen/Dense: No such file or directory`** + +Please make sure [`eigen >= 3.3`](https://eigen.tuxfamily.org/index.php?title=Main_Page) is installed. +We have included it as a submodule in this repository, but you can also install it in your system include path. +(For example, ubuntu systems can use `sudo apt install libeigen3-dev`.) + +### Usage + +**Basics:** + +```python +import numpy as np +import trimesh +import torch + +import cubvh + +### build BVH from mesh +mesh = trimesh.load('example.ply') +# NOTE: you need to normalize the mesh first, since the max distance is hard-coded to 100. +BVH = cubvh.cuBVH(mesh.vertices, mesh.faces) # build with numpy.ndarray/torch.Tensor + +### query ray-mesh intersection +rays_o, rays_d = get_ray(pose, intrinsics, H, W) # [N, 3], [N, 3], query with torch.Tensor (cuda) +intersections, face_id, depth = BVH.ray_trace(rays_o, rays_d) # [N, 3], [N,], [N,] + +### query unsigned distance +points # [N, 3] +# uvw is the barycentric corrdinates of the closest point on the closest face (None if `return_uvw` is False). +distances, face_id, uvw = BVH.unsigned_distance(points, return_uvw=True) # [N], [N], [N, 3] + +### query signed distance (INNER is NEGATIVE!) +# for watertight meshes (default) +distances, face_id, uvw = BVH.signed_distance(points, return_uvw=True, mode='watertight') # [N], [N], [N, 3] +# for non-watertight meshes: +distances, face_id, uvw = BVH.signed_distance(points, return_uvw=True, mode='raystab') # [N], [N], [N, 3] +``` + +**Serialization and Device Placement:** + +cuBVH behaves like a Torch module: you can checkpoint it, reload it later, and migrate the +instance between CPU and CUDA devices without rebuilding the acceleration structure. + +```python +import torch +import trimesh +import cubvh + +mesh = trimesh.load('example.ply') +vertices, triangles = mesh.vertices, mesh.faces + +# build directly on a target device (defaults to CUDA when available) +bvh = cubvh.cuBVH(vertices=vertices, triangles=triangles, device='cuda') + +# move between CPU and CUDA like any other torch module +bvh_cpu = bvh.to('cpu') +bvh_cuda = bvh_cpu.to('cuda:0') + +# persist to disk via torch.save / torch.load +torch.save(bvh_cuda, "mesh_bvh.pt") +reloaded = torch.load("mesh_bvh.pt") # restored on CPU by default +reloaded = reloaded.to('cuda') # lazily reinstantiates GPU buffers + +# direct access to CPU copies of the acceleration data +triangles_np = reloaded.triangles_cpu # (N, 3, 3) float32 array +nodes_np = reloaded.bvh_nodes_cpu # dict with mins/maxs/children arrays +state_dict = reloaded.export_state() # tensors for custom checkpoints +``` + +When a serialized BVH is first loaded, it resides on the CPU. Calling `.to('cuda:N')` lazily +reinstantiates the GPU buffers on the requested device and keeps subsequent queries there. +Advanced users can stash the `export_state()` tensors for custom checkpoint formats or stream +them to other processes. + +**Robust Mesh Occupancy:** + +UDF + flood-fill for possibly non-watertight/single-layer meshes: + +```python +import torch +import cubvh +import numpy as np + +resolution = 512 +device = torch.device('cuda') + +BVH = cubvh.cuBVH(vertices, faces) + +grid_points = torch.stack( + torch.meshgrid( + torch.linspace(-1, 1, resolution, device=device), + torch.linspace(-1, 1, resolution, device=device), + torch.linspace(-1, 1, resolution, device=device), + indexing="ij", + ), dim=-1, +) # [N, N, N, 3] + +# query dense UDF +udf, _, _ = BVH.unsigned_distance(grid_points.view(-1, 3), return_uvw=False) +udf = udf.view(opt.res, opt.res, opt.res).contiguous() + +# floodfill to get SDF +occ = udf < 2 / resolution # tolerance 2 voxel +floodfill_mask = cubvh.floodfill(occ) +empty_label = floodfill_mask[0, 0, 0].item() +empty_mask = (floodfill_mask == empty_label) +occ_mask = ~empty_mask +sdf = udf - eps # inner is negative +inner_mask = occ_mask & (sdf > 0) +sdf[inner_mask] *= -1 + +sdf = sdf.cpu().numpy() + +``` +Check [`test/extract_mesh_watertight.py`](test/extract_mesh_watertight.py) for more details. + + +### Acknowledgement + +* Credits to [Thomas Mรผller](https://tom94.net/)'s amazing [tiny-cuda-nn](https://github.com/NVlabs/tiny-cuda-nn) and [instant-ngp](https://github.com/NVlabs/instant-ngp)! diff --git a/extensions/CUBVH/setup.py b/extensions/CUBVH/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..0b633919b876fe7f65e76fd51d3d9b5b1b3b7272 --- /dev/null +++ b/extensions/CUBVH/setup.py @@ -0,0 +1,83 @@ +import os +from setuptools import setup +from torch.utils.cpp_extension import BuildExtension, CUDAExtension + +_src_path = os.path.dirname(os.path.abspath(__file__)) + +if os.name == "nt": + + # find cl.exe + def find_cl_path(): + import glob + for executable in ["Program Files (x86)", "Program Files"]: + for edition in ["Enterprise", "Professional", "BuildTools", "Community"]: + paths = sorted(glob.glob(f"C:\\{executable}\\Microsoft Visual Studio\\*\\{edition}\\VC\\Tools\\MSVC\\*\\bin\\Hostx64\\x64"), reverse=True) + if paths: + return paths[0] + + # If cl.exe is not on path, try to find it. + if os.system("where cl.exe >nul 2>nul") != 0: + cl_path = find_cl_path() + if cl_path is None: + raise RuntimeError("Could not locate a supported Microsoft Visual C++ installation") + os.environ["PATH"] += ";" + cl_path + else: + # cl.exe was found in PATH, so we can assume that the user is already in a developer command prompt + # In this case, BuildExtensions requires the following environment variable to be set such that it + # won't try to activate a developer command prompt a second time. + os.environ["DISTUTILS_USE_SDK"] = "1" + +cpp_standard = 17 + +base_nvcc_flags = [ + "-O3", + f"-std=c++{cpp_standard}", + "--extended-lambda", + "--expt-relaxed-constexpr", + # The following definitions must be undefined + # since we need half-precision operation. + "-U__CUDA_NO_HALF_OPERATORS__", + "-U__CUDA_NO_HALF_CONVERSIONS__", + "-U__CUDA_NO_HALF2_OPERATORS__", +] + +if os.name == "posix": + base_cflags = ["-O3", f"-std=c++{cpp_standard}"] + base_nvcc_flags += [ + "-Xcompiler=-Wno-float-conversion", + "-Xcompiler=-fno-strict-aliasing", + ] +elif os.name == "nt": + base_cflags = ["/O2", f"/std:c++{cpp_standard}"] + +''' +Usage: +python setup.py build_ext --inplace # build extensions locally, do not install (only can be used from the parent directory) +python setup.py install # build extensions and install (copy) to PATH. +pip install . # ditto but better (e.g., dependency & metadata handling) +python setup.py develop # build extensions and install (symbolic) to PATH. +pip install -e . # ditto but better (e.g., dependency & metadata handling) +''' +setup( + ext_modules=[ + CUDAExtension( + name='_cubvh', + sources=[os.path.join('src', f) for f in [ + 'bvh.cu', + 'api_gpu.cu', + 'bindings.cpp', + ]], + include_dirs=[ + os.path.join(_src_path, 'include'), + os.path.join(_src_path, 'third_party', 'eigen'), + ], + extra_compile_args={ + 'cxx': base_cflags, + 'nvcc': base_nvcc_flags, + } + ), + ], + cmdclass={ + 'build_ext': BuildExtension, + }, +) diff --git a/extensions/CUBVH/src/api_gpu.cu b/extensions/CUBVH/src/api_gpu.cu new file mode 100644 index 0000000000000000000000000000000000000000..07377e8c57b963580579a7d4551f7a95f1c82110 --- /dev/null +++ b/extensions/CUBVH/src/api_gpu.cu @@ -0,0 +1,526 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +using namespace Eigen; + +using Verts = Matrix; +using Trigs = Matrix; + +namespace cubvh { + +namespace { + +std::tuple pack_state( + const std::vector& triangles_cpu, + const std::vector& nodes_cpu) { + + auto float_opts = at::TensorOptions().dtype(at::kFloat).device(at::kCPU); + auto long_opts = at::TensorOptions().dtype(at::kLong).device(at::kCPU); + auto int_opts = at::TensorOptions().dtype(at::kInt).device(at::kCPU); + + const int64_t n_triangles = static_cast(triangles_cpu.size()); + at::Tensor triangle_vertices = at::empty({n_triangles, 3, 3}, float_opts); + at::Tensor triangle_ids = at::empty({n_triangles}, long_opts); + + auto verts_acc = triangle_vertices.accessor(); + auto ids_acc = triangle_ids.accessor(); + + for (int64_t i = 0; i < n_triangles; ++i) { + const Triangle& tri = triangles_cpu[i]; + ids_acc[i] = tri.id; + const Eigen::Vector3f verts[3] = {tri.a, tri.b, tri.c}; + for (int v = 0; v < 3; ++v) { + verts_acc[i][v][0] = verts[v].x(); + verts_acc[i][v][1] = verts[v].y(); + verts_acc[i][v][2] = verts[v].z(); + } + } + + const int64_t n_nodes = static_cast(nodes_cpu.size()); + at::Tensor node_mins = at::empty({n_nodes, 3}, float_opts); + at::Tensor node_maxs = at::empty({n_nodes, 3}, float_opts); + at::Tensor node_children = at::empty({n_nodes, 3}, int_opts); + + auto mins_acc = node_mins.accessor(); + auto maxs_acc = node_maxs.accessor(); + auto child_acc = node_children.accessor(); + + for (int64_t i = 0; i < n_nodes; ++i) { + const TriangleBvhNode& node = nodes_cpu[i]; + mins_acc[i][0] = node.bb.min.x(); + mins_acc[i][1] = node.bb.min.y(); + mins_acc[i][2] = node.bb.min.z(); + + maxs_acc[i][0] = node.bb.max.x(); + maxs_acc[i][1] = node.bb.max.y(); + maxs_acc[i][2] = node.bb.max.z(); + + child_acc[i][0] = node.left_idx; + child_acc[i][1] = node.right_idx; + child_acc[i][2] = node.escape_idx; + } + + return {triangle_vertices, triangle_ids, node_mins, node_maxs, node_children}; +} + +constexpr uint32_t kBranchingFactor = 4; + +std::vector build_nodes_cpu(std::vector& triangles, uint32_t n_primitives_per_leaf) { + std::vector nodes; + if (triangles.empty()) { + return nodes; + } + + nodes.emplace_back(); + nodes.front().bb = BoundingBox(std::begin(triangles), std::end(triangles)); + + struct BuildNode { + int node_idx; + std::vector::iterator begin; + std::vector::iterator end; + }; + + std::stack build_stack; + build_stack.push({0, std::begin(triangles), std::end(triangles)}); + + while (!build_stack.empty()) { + BuildNode curr = build_stack.top(); + build_stack.pop(); + + std::array children; + children[0].begin = curr.begin; + children[0].end = curr.end; + + int n_children = 1; + while (n_children < static_cast(kBranchingFactor)) { + for (int i = n_children - 1; i >= 0; --i) { + auto& child = children[i]; + + const auto span = std::distance(child.begin, child.end); + if (span <= 0) { + continue; + } + const float inv_count = 1.0f / static_cast(span); + + Vector3f mean = Vector3f::Zero(); + for (auto it = child.begin; it != child.end; ++it) { + mean += it->centroid(); + } + mean *= inv_count; + + Vector3f var = Vector3f::Zero(); + for (auto it = child.begin; it != child.end; ++it) { + Vector3f diff = it->centroid() - mean; + var += diff.cwiseProduct(diff); + } + var *= inv_count; + + Vector3f::Index axis; + var.maxCoeff(&axis); + + auto mid = child.begin + span / 2; + std::nth_element(child.begin, mid, child.end, [axis](const Triangle& tri1, const Triangle& tri2) { + return tri1.centroid(axis) < tri2.centroid(axis); + }); + + children[i * 2].begin = child.begin; + children[i * 2].end = mid; + children[i * 2 + 1].begin = mid; + children[i * 2 + 1].end = child.end; + } + n_children *= 2; + } + + nodes[curr.node_idx].left_idx = static_cast(nodes.size()); + for (uint32_t i = 0; i < kBranchingFactor; ++i) { + auto& child = children[i]; + if (child.begin == child.end) { + continue; + } + + child.node_idx = static_cast(nodes.size()); + nodes.emplace_back(); + nodes.back().bb = BoundingBox(child.begin, child.end); + + const auto span = std::distance(child.begin, child.end); + if (span <= static_cast(n_primitives_per_leaf)) { + nodes.back().left_idx = -static_cast(std::distance(std::begin(triangles), child.begin)) - 1; + nodes.back().right_idx = -static_cast(std::distance(std::begin(triangles), child.end)) - 1; + } else { + build_stack.push(child); + } + } + nodes[curr.node_idx].right_idx = static_cast(nodes.size()); + } + + for (auto& node : nodes) { + node.escape_idx = -1; + } + + std::function thread_bvh = [&](int node_idx, int escape_idx) { + TriangleBvhNode& node = nodes[node_idx]; + node.escape_idx = escape_idx; + if (node.left_idx < 0) { + return; + } + int first_child = node.left_idx; + int end_child = node.right_idx; + for (int c = first_child; c < end_child; ++c) { + int next_escape = (c + 1 < end_child) ? (c + 1) : escape_idx; + thread_bvh(c, next_escape); + } + }; + + if (!nodes.empty()) { + thread_bvh(0, -1); + } + + return nodes; +} + +} // namespace + +class cuBVHImpl : public cuBVH { +public: + + // accept numpy array (cpu) to init + cuBVHImpl(Ref vertices, Ref triangles) : cuBVH() { + + const size_t n_triangles = triangles.rows(); + + triangles_cpu.resize(n_triangles); + + for (size_t i = 0; i < n_triangles; i++) { + triangles_cpu[i] = {vertices.row(triangles(i, 0)), vertices.row(triangles(i, 1)), vertices.row(triangles(i, 2)), (int64_t)i}; + } + + triangle_bvh = TriangleBvh::make(); + triangle_bvh->build(triangles_cpu, 8); + nodes_cpu = triangle_bvh->host_nodes(); + + triangles_gpu.resize_and_copy_from_host(triangles_cpu); + + // TODO: need OPTIX + // triangle_bvh->build_optix(triangles_gpu, m_inference_stream); + + } + + cuBVHImpl(std::vector&& triangles, std::vector&& nodes) : cuBVH() { + triangles_cpu = std::move(triangles); + nodes_cpu = std::move(nodes); + + triangle_bvh = TriangleBvh::make(); + triangle_bvh->set_nodes(nodes_cpu); + nodes_cpu = triangle_bvh->host_nodes(); + + triangles_gpu.resize_and_copy_from_host(triangles_cpu); + } + + void ray_trace(at::Tensor rays_o, at::Tensor rays_d, at::Tensor positions, at::Tensor face_id, at::Tensor depth) { + + const uint32_t n_elements = rays_o.size(0); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + triangle_bvh->ray_trace_gpu(n_elements, rays_o.data_ptr(), rays_d.data_ptr(), positions.data_ptr(), face_id.data_ptr(), depth.data_ptr(), triangles_gpu.data(), stream); + } + + void unsigned_distance(at::Tensor positions, at::Tensor distances, at::Tensor face_id, at::optional uvw) { + + const uint32_t n_elements = positions.size(0); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + triangle_bvh->unsigned_distance_gpu( + n_elements, + positions.data_ptr(), + distances.data_ptr(), + face_id.data_ptr(), + uvw.has_value() ? uvw.value().data_ptr() : nullptr, + triangles_gpu.data(), + static_cast(triangles_gpu.size()), + stream + ); + + } + + void signed_distance(at::Tensor positions, at::Tensor distances, at::Tensor face_id, at::optional uvw, uint32_t mode) { + + const uint32_t n_elements = positions.size(0); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + triangle_bvh->signed_distance_gpu( + n_elements, + mode, + positions.data_ptr(), + distances.data_ptr(), + face_id.data_ptr(), + uvw.has_value() ? uvw.value().data_ptr() : nullptr, + triangles_gpu.data(), + static_cast(triangles_gpu.size()), + stream + ); + } + + std::tuple export_state() const override { + return pack_state(triangles_cpu, nodes_cpu); + } + + std::vector triangles_cpu; + std::vector nodes_cpu; + GPUMemory triangles_gpu; + std::shared_ptr triangle_bvh; +}; + +std::tuple build_cuBVH_state( + Ref vertices, + Ref triangles) { + + const size_t n_triangles = triangles.rows(); + std::vector triangles_cpu; + triangles_cpu.resize(n_triangles); + + for (size_t i = 0; i < n_triangles; ++i) { + triangles_cpu[i] = { + vertices.row(triangles(i, 0)), + vertices.row(triangles(i, 1)), + vertices.row(triangles(i, 2)), + static_cast(i) + }; + } + + auto nodes_cpu = build_nodes_cpu(triangles_cpu, 8); + + return pack_state(triangles_cpu, nodes_cpu); +} + +cuBVH* create_cuBVH(Ref vertices, Ref triangles) { + return new cuBVHImpl{vertices, triangles}; +} + +cuBVH* create_cuBVH_from_state( + at::Tensor triangle_vertices, + at::Tensor triangle_ids, + at::Tensor node_mins, + at::Tensor node_maxs, + at::Tensor node_children) { + + TORCH_CHECK(!triangle_vertices.is_cuda(), "triangle_vertices must reside on CPU"); + TORCH_CHECK(!triangle_ids.is_cuda(), "triangle_ids must reside on CPU"); + TORCH_CHECK(!node_mins.is_cuda(), "node_mins must reside on CPU"); + TORCH_CHECK(!node_maxs.is_cuda(), "node_maxs must reside on CPU"); + TORCH_CHECK(!node_children.is_cuda(), "node_children must reside on CPU"); + + TORCH_CHECK(triangle_vertices.dtype() == at::kFloat, "triangle_vertices must be float32"); + TORCH_CHECK(triangle_vertices.dim() == 3 && triangle_vertices.size(1) == 3 && triangle_vertices.size(2) == 3, "triangle_vertices must have shape [N,3,3]"); + + TORCH_CHECK(triangle_ids.dtype() == at::kLong, "triangle_ids must be int64"); + TORCH_CHECK(triangle_ids.dim() == 1 && triangle_ids.size(0) == triangle_vertices.size(0), "triangle_ids must have shape [N]"); + + TORCH_CHECK(node_mins.dtype() == at::kFloat && node_mins.dim() == 2 && node_mins.size(1) == 3, "node_mins must have shape [M,3]"); + TORCH_CHECK(node_maxs.dtype() == at::kFloat && node_maxs.dim() == 2 && node_maxs.size(1) == 3, "node_maxs must have shape [M,3]"); + TORCH_CHECK(node_children.dtype() == at::kInt && node_children.dim() == 2 && node_children.size(1) == 3, "node_children must have shape [M,3]"); + TORCH_CHECK(node_mins.size(0) == node_maxs.size(0) && node_mins.size(0) == node_children.size(0), "node tensor shapes must match"); + + triangle_vertices = triangle_vertices.contiguous(); + triangle_ids = triangle_ids.contiguous(); + node_mins = node_mins.contiguous(); + node_maxs = node_maxs.contiguous(); + node_children = node_children.contiguous(); + + const int64_t n_triangles = triangle_vertices.size(0); + std::vector triangles; + triangles.resize(n_triangles); + + auto verts_acc = triangle_vertices.accessor(); + auto ids_acc = triangle_ids.accessor(); + + for (int64_t i = 0; i < n_triangles; ++i) { + Triangle tri; + tri.a = Eigen::Vector3f(verts_acc[i][0][0], verts_acc[i][0][1], verts_acc[i][0][2]); + tri.b = Eigen::Vector3f(verts_acc[i][1][0], verts_acc[i][1][1], verts_acc[i][1][2]); + tri.c = Eigen::Vector3f(verts_acc[i][2][0], verts_acc[i][2][1], verts_acc[i][2][2]); + tri.id = ids_acc[i]; + triangles[i] = tri; + } + + const int64_t n_nodes = node_mins.size(0); + auto mins_acc = node_mins.accessor(); + auto maxs_acc = node_maxs.accessor(); + auto child_acc = node_children.accessor(); + + std::vector nodes; + nodes.resize(n_nodes); + + for (int64_t i = 0; i < n_nodes; ++i) { + TriangleBvhNode node; + node.bb.min = Eigen::Vector3f(mins_acc[i][0], mins_acc[i][1], mins_acc[i][2]); + node.bb.max = Eigen::Vector3f(maxs_acc[i][0], maxs_acc[i][1], maxs_acc[i][2]); + node.left_idx = child_acc[i][0]; + node.right_idx = child_acc[i][1]; + node.escape_idx = child_acc[i][2]; + nodes[i] = node; + } + + return new cuBVHImpl{std::move(triangles), std::move(nodes)}; +} + +at::Tensor floodfill(at::Tensor grid) { + + // assert grid is uint8_t + assert(grid.dtype() == at::ScalarType::Bool); + + const int B = grid.size(0); + const int H = grid.size(1); + const int W = grid.size(2); + const int D = grid.size(3); + + // allocate mask + at::Tensor mask = at::zeros({B, H, W, D}, at::device(grid.device()).dtype(at::ScalarType::Int)); + + _floodfill_batch(grid.data_ptr(), B, H, W, D, mask.data_ptr()); + + return mask; +} + +std::tuple sparse_marching_cubes( + at::Tensor coords, // [N,3] int32, cuda + at::Tensor corners, // [N,8] float32, cuda + double iso_d, // (PyTorch passes double โ‡’ cast to float) + bool ensure_consistency) // whether to ensure corner consistency +{ + TORCH_CHECK(coords.is_cuda(), "coords must reside on CUDA"); + TORCH_CHECK(corners.is_cuda(), "corners must reside on CUDA"); + TORCH_CHECK(coords.dtype() == at::kInt, "coords must be int32"); + TORCH_CHECK(corners.dtype() == at::kFloat, "corners must be float32"); + TORCH_CHECK(coords.sizes().size() == 2 && coords.size(1) == 3, + "coords must be of shape [N,3]"); + TORCH_CHECK(corners.sizes().size() == 2 && corners.size(1) == 8, + "corners must be of shape [N,8]"); + TORCH_CHECK(coords.size(0) == corners.size(0), + "coords and corners must have the same first-dim (N)"); + + // Ensure contiguous memory - PyTorch extensions expect this. + coords = coords.contiguous(); + corners = corners.contiguous(); + const int N = static_cast(coords.size(0)); + const int *d_coords = coords.data_ptr(); + const float *d_corners = corners.data_ptr(); + const float iso = static_cast(iso_d); + + // Use the current PyTorch CUDA stream + cudaStream_t stream = at::cuda::getCurrentCUDAStream().stream(); + + // --- call the CUDA sparse MC core (header we wrote earlier) ------------------- + auto mesh = _sparse_marching_cubes(d_coords, d_corners, N, iso, ensure_consistency, stream); + thrust::device_vector &verts_vec = mesh.first; + thrust::device_vector &tris_vec = mesh.second; + const int64_t M = static_cast(verts_vec.size()); + const int64_t T = static_cast(tris_vec.size()); + + // --- create output tensors ---------------------------------------------------- + auto opts_f = torch::TensorOptions().dtype(torch::kFloat32).device(coords.device()); + auto opts_i = torch::TensorOptions().dtype(torch::kInt32).device(coords.device()); + + at::Tensor verts = at::empty({M, 3}, opts_f); + at::Tensor tris = at::empty({T, 3}, opts_i); + + // Copy GPUโ†’GPU (same stream โ‡’ async & cheap) + cudaMemcpyAsync(verts.data_ptr(), + thrust::raw_pointer_cast(verts_vec.data()), + M * 3 * sizeof(float), + cudaMemcpyDeviceToDevice, stream); + + cudaMemcpyAsync(tris.data_ptr(), + thrust::raw_pointer_cast(tris_vec.data()), + T * 3 * sizeof(int), + cudaMemcpyDeviceToDevice, stream); + + // Make sure copies finish before we free device_vectors + cudaStreamSynchronize(stream); + + return {verts, tris}; +} + +// ------------------------ GPU Hash Table bindings (virtual pattern) ---------- + +class cuHashTableImpl : public cuHashTable { +public: + cuHashTableImpl() {} + ~cuHashTableImpl() override {} + + void set_num_dims(int d) override { + ht.set_num_dims(d); + } + + int get_num_dims() const override { + return ht.num_dims; + } + + void resize(int capacity) override { + ht.resize(capacity); + } + + void prepare() override { + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + ht.prepare(stream); + } + + void insert(at::Tensor coords) override { + TORCH_CHECK(coords.is_cuda(), "coords must reside on CUDA"); + TORCH_CHECK(coords.dtype() == at::kInt, "coords must be int32"); + TORCH_CHECK(coords.dim() == 2, "coords must be 2D [N,D]"); + coords = coords.contiguous(); + const int N = (int)coords.size(0); + const int D = (int)coords.size(1); + ht.set_num_dims(D); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + ht.insert(coords.data_ptr(), N, stream); + } + + void build(at::Tensor coords) override { + TORCH_CHECK(coords.is_cuda(), "coords must reside on CUDA"); + TORCH_CHECK(coords.dtype() == at::kInt, "coords must be int32"); + TORCH_CHECK(coords.dim() == 2, "coords must be 2D [N,D]"); + coords = coords.contiguous(); + const int N = (int)coords.size(0); + const int D = (int)coords.size(1); + ht.set_num_dims(D); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + ht.build(coords.data_ptr(), N, stream); + } + + at::Tensor search(at::Tensor queries) const override { + TORCH_CHECK(queries.is_cuda(), "queries must reside on CUDA"); + TORCH_CHECK(queries.dtype() == at::kInt, "queries must be int32"); + TORCH_CHECK(queries.dim() == 2, "queries must be 2D [M,D]"); + TORCH_CHECK(ht.capacity > 0, "hash table is not built"); + at::Tensor q = queries.contiguous(); + const int M = (int)q.size(0); + auto opts_i = torch::TensorOptions().dtype(torch::kInt32).device(q.device()); + at::Tensor out = at::empty({M}, opts_i); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + ht.search(q.data_ptr(), M, out.data_ptr(), stream); + return out; + } + +private: + HashTableInt ht; +}; + +cuHashTable* create_cuHashTable() { + return new cuHashTableImpl{}; +} + +} // namespace cubvh \ No newline at end of file diff --git a/extensions/CUBVH/src/bindings.cpp b/extensions/CUBVH/src/bindings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4711a2743d86bf6784624ddf19938a9e2f1bedc6 --- /dev/null +++ b/extensions/CUBVH/src/bindings.cpp @@ -0,0 +1,88 @@ +// #include +#include + +#include +#include + +#include +#include + + +namespace py = pybind11; +using namespace cubvh; + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + +// CUDA API +py::class_(m, "cuBVH") + .def("ray_trace", &cuBVH::ray_trace) + .def("unsigned_distance", &cuBVH::unsigned_distance) + .def("signed_distance", &cuBVH::signed_distance) + .def("export_state", &cuBVH::export_state); + +m.def("create_cuBVH", &create_cuBVH); +m.def("create_cuBVH_from_state", &create_cuBVH_from_state); +m.def("build_cuBVH_state", &build_cuBVH_state); + +m.def("floodfill", &floodfill); + +m.def("sparse_marching_cubes", &sparse_marching_cubes, + py::arg("coords"), py::arg("corners"), + py::arg("iso"), + py::arg("ensure_consistency") = false +); + +// GPU Hash Table bindings +py::class_(m, "cuHashTable") + .def("set_num_dims", &cuHashTable::set_num_dims) + .def("get_num_dims", &cuHashTable::get_num_dims) + .def("resize", &cuHashTable::resize) + .def("prepare", &cuHashTable::prepare) + .def("insert", &cuHashTable::insert, py::arg("coords")) + .def("build", &cuHashTable::build, py::arg("coords")) + .def("search", &cuHashTable::search, py::arg("queries")); + +m.def("create_cuHashTable", &create_cuHashTable); + +// CPU API +m.def("fill_holes", &fill_holes, + py::arg("vertices"), py::arg("faces"), + py::arg("return_added") = false, + py::arg("check_containment") = true, + py::arg("eps") = 1e-6, + py::arg("verbose") = false +); + +m.def("merge_vertices", &merge_vertices, + py::arg("vertices"), py::arg("faces"), + py::arg("threshold") +); + +m.def("sparse_marching_cubes_cpu", &sparse_marching_cubes_cpu, + py::arg("coords"), py::arg("corners"), + py::arg("iso"), + py::arg("ensure_consistency") = false +); + +// CPU decimator +m.def("decimate", &decimate, + py::arg("vertices"), py::arg("faces"), + py::arg("target_vertices") +); + +m.def("parallel_decimate", ¶llel_decimate, + py::arg("vertices"), py::arg("faces"), + py::arg("target_vertices") +); + +// CPU Hash Table bindings +py::class_(m, "HashTable") + .def(py::init<>()) + .def("set_num_dims", &HashTable::set_num_dims) + .def("get_num_dims", &HashTable::get_num_dims) + .def("resize", &HashTable::resize) + .def("prepare", &HashTable::prepare) + .def("insert", &HashTable::insert, py::arg("coords")) + .def("build", &HashTable::build, py::arg("coords")) + .def("search", &HashTable::search, py::arg("queries")); +} \ No newline at end of file diff --git a/extensions/CUBVH/src/bvh.cu b/extensions/CUBVH/src/bvh.cu new file mode 100644 index 0000000000000000000000000000000000000000..0d340590bf27a8447a1b71b70549c92cf79dc6c5 --- /dev/null +++ b/extensions/CUBVH/src/bvh.cu @@ -0,0 +1,839 @@ +// #include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace Eigen; +using namespace cubvh; + + +namespace cubvh { + +constexpr float MAX_DIST = 1000.0f; +constexpr float MAX_DIST_SQ = MAX_DIST*MAX_DIST; + +__global__ void signed_distance_watertight_kernel(uint32_t n_elements, const Vector3f* __restrict__ positions, float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds); +__global__ void signed_distance_raystab_kernel(uint32_t n_elements, const Vector3f* __restrict__ positions, float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds); +__global__ void unsigned_distance_kernel(uint32_t n_elements, const Vector3f* __restrict__ positions, float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds); +__global__ void raytrace_kernel(uint32_t n_elements, const Vector3f* __restrict__ rays_o, const Vector3f* __restrict__ rays_d, Vector3f* __restrict__ positions, int64_t* __restrict__ face_id, float* __restrict__ depth, const TriangleBvhNode* __restrict__ nodes, const Triangle* __restrict__ triangles); + +struct DistAndIdx { + float dist; + uint32_t idx; + + // Sort in descending order! + __host__ __device__ bool operator<(const DistAndIdx& other) { + return dist < other.dist; + } +}; + +template +__host__ __device__ void inline compare_and_swap(T& t1, T& t2) { + if (t1 < t2) { + T tmp{t1}; t1 = t2; t2 = tmp; + } +} + +// Sorting networks from http://users.telenet.be/bertdobbelaere/SorterHunter/sorting_networks.html#N4L5D3 +template +__host__ __device__ void sorting_network(T values[N]) { + static_assert(N <= 8, "Sorting networks are only implemented up to N==8"); + if (N <= 1) { + return; + } else if (N == 2) { + compare_and_swap(values[0], values[1]); + } else if (N == 3) { + compare_and_swap(values[0], values[2]); + compare_and_swap(values[0], values[1]); + compare_and_swap(values[1], values[2]); + } else if (N == 4) { + compare_and_swap(values[0], values[2]); + compare_and_swap(values[1], values[3]); + compare_and_swap(values[0], values[1]); + compare_and_swap(values[2], values[3]); + compare_and_swap(values[1], values[2]); + } else if (N == 5) { + compare_and_swap(values[0], values[3]); + compare_and_swap(values[1], values[4]); + + compare_and_swap(values[0], values[2]); + compare_and_swap(values[1], values[3]); + + compare_and_swap(values[0], values[1]); + compare_and_swap(values[2], values[4]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[3], values[4]); + + compare_and_swap(values[2], values[3]); + } else if (N == 6) { + compare_and_swap(values[0], values[5]); + compare_and_swap(values[1], values[3]); + compare_and_swap(values[2], values[4]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[3], values[4]); + + compare_and_swap(values[0], values[3]); + compare_and_swap(values[2], values[5]); + + compare_and_swap(values[0], values[1]); + compare_and_swap(values[2], values[3]); + compare_and_swap(values[4], values[5]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[3], values[4]); + } else if (N == 7) { + compare_and_swap(values[0], values[6]); + compare_and_swap(values[2], values[3]); + compare_and_swap(values[4], values[5]); + + compare_and_swap(values[0], values[2]); + compare_and_swap(values[1], values[4]); + compare_and_swap(values[3], values[6]); + + compare_and_swap(values[0], values[1]); + compare_and_swap(values[2], values[5]); + compare_and_swap(values[3], values[4]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[4], values[6]); + + compare_and_swap(values[2], values[3]); + compare_and_swap(values[4], values[5]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[3], values[4]); + compare_and_swap(values[5], values[6]); + } else if (N == 8) { + compare_and_swap(values[0], values[2]); + compare_and_swap(values[1], values[3]); + compare_and_swap(values[4], values[6]); + compare_and_swap(values[5], values[7]); + + compare_and_swap(values[0], values[4]); + compare_and_swap(values[1], values[5]); + compare_and_swap(values[2], values[6]); + compare_and_swap(values[3], values[7]); + + compare_and_swap(values[0], values[1]); + compare_and_swap(values[2], values[3]); + compare_and_swap(values[4], values[5]); + compare_and_swap(values[6], values[7]); + + compare_and_swap(values[2], values[4]); + compare_and_swap(values[3], values[5]); + + compare_and_swap(values[1], values[4]); + compare_and_swap(values[3], values[6]); + + compare_and_swap(values[1], values[2]); + compare_and_swap(values[3], values[4]); + compare_and_swap(values[5], values[6]); + } +} + +template +class TriangleBvhWithBranchingFactor : public TriangleBvh { +public: + // Stackless traversal using threaded BVH (escape links). Assumes escape_idx is populated. + __host__ __device__ static std::pair ray_intersect_stackless(Ref ro, Ref rd, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles) { + float mint = MAX_DIST; + int shortest_idx = -1; + + int idx = 0; + while (idx != -1) { + const TriangleBvhNode& node = bvhnodes[idx]; + + float tbb = node.bb.ray_intersect(ro, rd).x(); + if (tbb >= mint) { + idx = node.escape_idx; + continue; + } + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + float t = triangles[i].ray_intersect(ro, rd); + if (t < mint) { + mint = t; + shortest_idx = i; + } + } + idx = node.escape_idx; + } else { + // descend first child; siblings are reached via escape links + idx = node.left_idx; + } + } + + return {shortest_idx, mint}; + } + + __host__ __device__ static std::pair closest_triangle_stackless(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, float max_distance_sq = MAX_DIST_SQ) { + float shortest_distance_sq = max_distance_sq; + int shortest_idx = -1; + + int idx = 0; + while (idx != -1) { + const TriangleBvhNode& node = bvhnodes[idx]; + + float dbb = node.bb.distance_sq(point); + if (dbb > shortest_distance_sq) { + idx = node.escape_idx; + continue; + } + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + float dist_sq = triangles[i].distance_sq(point); + if (dist_sq <= shortest_distance_sq) { + shortest_distance_sq = dist_sq; + shortest_idx = i; + } + } + idx = node.escape_idx; + } else { + idx = node.left_idx; + } + } + + if (shortest_idx == -1) { + shortest_idx = 0; + shortest_distance_sq = 0.0f; + } + + return {shortest_idx, std::sqrt(shortest_distance_sq)}; + } + + // For normal averaging around a point on the surface. Returns unnormalized normal. + __host__ __device__ static Vector3f avg_normal_around_point_stackless(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles) { + static constexpr float EPSILON = 1e-6f; + + float total_weight = 0; + Vector3f result = Vector3f::Zero(); + + int idx = 0; + while (idx != -1) { + const TriangleBvhNode& node = bvhnodes[idx]; + + float dbb = node.bb.distance_sq(point); + if (dbb >= EPSILON) { + idx = node.escape_idx; + continue; + } + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + if (triangles[i].distance_sq(point) < EPSILON) { + float weight = 1; // TODO: cot weight + result += triangles[i].normal(); + total_weight += weight; + } + } + idx = node.escape_idx; + } else { + idx = node.left_idx; + } + } + + return result / total_weight; + } + + __host__ __device__ static std::pair ray_intersect(Ref ro, Ref rd, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles) { + FixedIntStack query_stack; + query_stack.push(0); + + float mint = MAX_DIST; + int shortest_idx = -1; + + while (!query_stack.empty()) { + int idx = query_stack.pop(); + + const TriangleBvhNode& node = bvhnodes[idx]; + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + float t = triangles[i].ray_intersect(ro, rd); + if (t < mint) { + mint = t; + shortest_idx = i; + } + } + } else { + DistAndIdx children[BRANCHING_FACTOR]; + + int first_child = node.left_idx; + int end_child = node.right_idx; + int child_count = end_child - first_child; + + if (child_count <= 0 || child_count > static_cast(BRANCHING_FACTOR)) { + return ray_intersect_stackless(ro, rd, bvhnodes, triangles); + } + + #pragma unroll + for (uint32_t i = 0; i < BRANCHING_FACTOR; ++i) { + int child_idx = first_child + static_cast(i); + if (child_idx < end_child) { + children[i] = {bvhnodes[child_idx].bb.ray_intersect(ro, rd).x(), static_cast(child_idx)}; + } else { + children[i] = {std::numeric_limits::infinity(), UINT32_MAX}; + } + } + + sorting_network(children); + + #pragma unroll + for (int i = (int)BRANCHING_FACTOR - 1; i >= 0; --i) { + uint32_t child_idx = children[i].idx; + if (child_idx == UINT32_MAX) { + continue; + } + if (children[i].dist < mint) { + query_stack.push(static_cast(child_idx)); + } + } + } + + if (query_stack.overflowed()) { + // Fallback to stackless traversal to guarantee correctness + return ray_intersect_stackless(ro, rd, bvhnodes, triangles); + } + } + + return {shortest_idx, mint}; + } + + __host__ __device__ static std::pair closest_triangle(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, float max_distance_sq = MAX_DIST_SQ) { + FixedIntStack query_stack; + query_stack.push(0); + + float shortest_distance_sq = max_distance_sq; + int shortest_idx = -1; + + while (!query_stack.empty()) { + int idx = query_stack.pop(); + + const TriangleBvhNode& node = bvhnodes[idx]; + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + float dist_sq = triangles[i].distance_sq(point); + if (dist_sq <= shortest_distance_sq) { + shortest_distance_sq = dist_sq; + shortest_idx = i; + } + } + } else { + DistAndIdx children[BRANCHING_FACTOR]; + + int first_child = node.left_idx; + int end_child = node.right_idx; + int child_count = end_child - first_child; + + if (child_count <= 0 || child_count > static_cast(BRANCHING_FACTOR)) { + return closest_triangle_stackless(point, bvhnodes, triangles, shortest_distance_sq); + } + + #pragma unroll + for (uint32_t i = 0; i < BRANCHING_FACTOR; ++i) { + int child_idx = first_child + static_cast(i); + if (child_idx < end_child) { + children[i] = {bvhnodes[child_idx].bb.distance_sq(point), static_cast(child_idx)}; + } else { + children[i] = {std::numeric_limits::infinity(), UINT32_MAX}; + } + } + + sorting_network(children); + + #pragma unroll + for (int i = (int)BRANCHING_FACTOR - 1; i >= 0; --i) { + uint32_t child_idx = children[i].idx; + if (child_idx == UINT32_MAX) { + continue; + } + if (children[i].dist <= shortest_distance_sq) { + query_stack.push(static_cast(child_idx)); + } + } + } + + if (query_stack.overflowed()) { + return closest_triangle_stackless(point, bvhnodes, triangles, shortest_distance_sq); + } + } + + if (shortest_idx == -1) { + // printf("No closest triangle found. This must be a bug! %d\n", BRANCHING_FACTOR); + shortest_idx = 0; + shortest_distance_sq = 0.0f; + } + + return {shortest_idx, std::sqrt(shortest_distance_sq)}; + } + + // Assumes that "point" is a location on a triangle + __host__ __device__ static Vector3f avg_normal_around_point(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles) { + FixedIntStack query_stack; + query_stack.push(0); + + static constexpr float EPSILON = 1e-6f; + + float total_weight = 0; + Vector3f result = Vector3f::Zero(); + + while (!query_stack.empty()) { + int idx = query_stack.pop(); + + const TriangleBvhNode& node = bvhnodes[idx]; + + if (node.left_idx < 0) { + int end = -node.right_idx-1; + for (int i = -node.left_idx-1; i < end; ++i) { + if (triangles[i].distance_sq(point) < EPSILON) { + float weight = 1; // TODO: cot weight + result += triangles[i].normal(); + total_weight += weight; + } + } + } else { + int first_child = node.left_idx; + int end_child = node.right_idx; + + for (int child_idx = first_child; child_idx < end_child; ++child_idx) { + if (bvhnodes[child_idx].bb.distance_sq(point) < EPSILON) { + query_stack.push(child_idx); + } + } + } + } + + if (query_stack.overflowed()) { + return avg_normal_around_point_stackless(point, bvhnodes, triangles); + } + + return result / total_weight; + } + + __host__ __device__ static std::pair signed_distance_watertight(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, float max_distance_sq = MAX_DIST_SQ) { + auto res = closest_triangle(point, bvhnodes, triangles, max_distance_sq); + + const Triangle& tri = triangles[res.first]; + Vector3f closest_point = tri.closest_point(point); + Vector3f avg_normal = avg_normal_around_point(closest_point, bvhnodes, triangles); + + return {res.first, std::copysignf(res.second, avg_normal.dot(point - closest_point))}; + } + + __host__ __device__ static std::pair signed_distance_raystab(const Vector3f& point, const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, float max_distance_sq = MAX_DIST_SQ, pcg32 rng={}) { + auto res = closest_triangle(point, bvhnodes, triangles, max_distance_sq); + + Vector2f offset = {rng.next_float(), rng.next_float()}; + + static constexpr uint32_t N_STAB_RAYS = 32; + for (uint32_t i = 0; i < N_STAB_RAYS; ++i) { + // Use a Fibonacci lattice (with random offset) to regularly + // distribute the stab rays over the sphere. + // ref: http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/ + Vector3f d = fibonacci_dir(i, offset); + + // If any of the stab rays goes outside the mesh, the SDF is positive. + if (ray_intersect(point, -d, bvhnodes, triangles).first < 0 || ray_intersect(point, d, bvhnodes, triangles).first < 0) { + return {res.first, res.second}; + } + } + + return {res.first, -res.second}; + } + + + void signed_distance_gpu(uint32_t n_elements, uint32_t mode, const float* positions, float* distances, int64_t* face_id, float* uvw, const Triangle* gpu_triangles, uint32_t n_triangles, cudaStream_t stream) override { + + const Vector3f* positions_vec = (const Vector3f*)positions; + Vector3f* uvw_vec = (Vector3f*)uvw; + + if (mode == 0) { + // watertight + linear_kernel(signed_distance_watertight_kernel, 0u, stream, + n_elements, + positions_vec, + distances, + face_id, + uvw_vec, + m_nodes_gpu.data(), + gpu_triangles, + n_triangles, + false + ); + + } else { + // raystab + linear_kernel(signed_distance_raystab_kernel, 0u, stream, + n_elements, + positions_vec, + distances, + face_id, + uvw_vec, + m_nodes_gpu.data(), + gpu_triangles, + n_triangles, + false + ); + } + } + + void unsigned_distance_gpu(uint32_t n_elements, const float* positions, float* distances, int64_t* face_id, float* uvw, const Triangle* gpu_triangles, uint32_t n_triangles, cudaStream_t stream) override { + + const Vector3f* positions_vec = (const Vector3f*)positions; + Vector3f* uvw_vec = (Vector3f*)uvw; + + linear_kernel(unsigned_distance_kernel, 0u, stream, + n_elements, + positions_vec, + distances, + face_id, + uvw_vec, + m_nodes_gpu.data(), + gpu_triangles, + n_triangles, + false + ); + } + + void ray_trace_gpu(uint32_t n_elements, const float* rays_o, const float* rays_d, float* positions, int64_t* face_id, float* depth, const Triangle* gpu_triangles, cudaStream_t stream) override { + + // cast float* to Vector3f* + const Vector3f* rays_o_vec = (const Vector3f*)rays_o; + const Vector3f* rays_d_vec = (const Vector3f*)rays_d; + Vector3f* positions_vec = (Vector3f*)positions; + + linear_kernel(raytrace_kernel, 0u, stream, + n_elements, + rays_o_vec, + rays_d_vec, + positions_vec, + face_id, + depth, + m_nodes_gpu.data(), + gpu_triangles + ); + + } + + void build(std::vector& triangles, uint32_t n_primitives_per_leaf) override { + m_nodes.clear(); + + // Root + m_nodes.emplace_back(); + m_nodes.front().bb = BoundingBox(std::begin(triangles), std::end(triangles)); + + struct BuildNode { + int node_idx; + std::vector::iterator begin; + std::vector::iterator end; + }; + + std::stack build_stack; + build_stack.push({0, std::begin(triangles), std::end(triangles)}); + + while (!build_stack.empty()) { + const BuildNode& curr = build_stack.top(); + size_t node_idx = curr.node_idx; + + std::array children; + children[0].begin = curr.begin; + children[0].end = curr.end; + + build_stack.pop(); + + // Partition the triangles into the children + int n_children = 1; + while (n_children < BRANCHING_FACTOR) { + for (int i = n_children - 1; i >= 0; --i) { + auto& child = children[i]; + + // Choose axis with maximum standard deviation + Vector3f mean = Vector3f::Zero(); + for (auto it = child.begin; it != child.end; ++it) { + mean += it->centroid(); + } + mean /= (float)std::distance(child.begin, child.end); + + Vector3f var = Vector3f::Zero(); + for (auto it = child.begin; it != child.end; ++it) { + Vector3f diff = it->centroid() - mean; + var += diff.cwiseProduct(diff); + } + var /= (float)std::distance(child.begin, child.end); + + Vector3f::Index axis; + var.maxCoeff(&axis); + + auto m = child.begin + std::distance(child.begin, child.end)/2; + std::nth_element(child.begin, m, child.end, [&](const Triangle& tri1, const Triangle& tri2) { return tri1.centroid(axis) < tri2.centroid(axis); }); + + children[i*2].begin = children[i].begin; + children[i*2+1].end = children[i].end; + children[i*2].end = children[i*2+1].begin = m; + } + + n_children *= 2; + } + + // Create next build nodes + m_nodes[node_idx].left_idx = (int)m_nodes.size(); + for (uint32_t i = 0; i < BRANCHING_FACTOR; ++i) { + auto& child = children[i]; + assert(child.begin != child.end); + child.node_idx = (int)m_nodes.size(); + + m_nodes.emplace_back(); + m_nodes.back().bb = BoundingBox(child.begin, child.end); + + if (std::distance(child.begin, child.end) <= n_primitives_per_leaf) { + m_nodes.back().left_idx = -(int)std::distance(std::begin(triangles), child.begin)-1; + m_nodes.back().right_idx = -(int)std::distance(std::begin(triangles), child.end)-1; + } else { + build_stack.push(child); + } + } + m_nodes[node_idx].right_idx = (int)m_nodes.size(); + } + + // Thread the BVH with escape links for stackless traversal. + // Initialize all escape indices to -1. + for (auto& n : m_nodes) n.escape_idx = -1; + + // Recursive lambda to assign escape links in pre-order (child order 0..BRANCHING_FACTOR-1) + std::function thread_bvh = [&](int node_idx, int escape_idx) { + TriangleBvhNode& node = m_nodes[node_idx]; + node.escape_idx = escape_idx; + if (node.left_idx < 0) return; // leaf + int first_child = node.left_idx; + int end_child = node.right_idx; // exclusive + for (int c = first_child; c < end_child; ++c) { + int next_escape = (c+1 < end_child) ? (c+1) : escape_idx; + thread_bvh(c, next_escape); + } + }; + + if (!m_nodes.empty()) { + thread_bvh(0, -1); + } + + m_nodes_gpu.resize_and_copy_from_host(m_nodes); + + // std::cout << "[INFO] Built TriangleBvh: nodes=" << m_nodes.size() << std::endl; + } + + TriangleBvhWithBranchingFactor() {} +}; + +using TriangleBvh4 = TriangleBvhWithBranchingFactor<4>; + +std::unique_ptr TriangleBvh::make() { + return std::unique_ptr(new TriangleBvh4()); +} + +const std::vector& TriangleBvh::host_nodes() const { + return m_nodes; +} + +void TriangleBvh::set_nodes(const std::vector& nodes) { + m_nodes = nodes; + + if (!m_nodes.empty()) { + for (auto& node : m_nodes) { + node.escape_idx = -1; + } + + std::function thread_bvh = [&](int node_idx, int escape_idx) { + if (node_idx < 0 || node_idx >= static_cast(m_nodes.size())) { + return; + } + + TriangleBvhNode& node = m_nodes[node_idx]; + node.escape_idx = escape_idx; + + if (node.left_idx < 0) { + return; + } + + int first_child = node.left_idx; + int end_child = node.right_idx; + + if (first_child < 0 || first_child >= static_cast(m_nodes.size())) { + return; + } + + if (end_child <= first_child) { + return; + } + + if (end_child > static_cast(m_nodes.size())) { + end_child = static_cast(m_nodes.size()); + } + + for (int c = first_child; c < end_child; ++c) { + int next_escape = (c + 1 < end_child) ? (c + 1) : escape_idx; + thread_bvh(c, next_escape); + } + }; + + thread_bvh(0, -1); + } + + m_nodes_gpu.resize_and_copy_from_host(m_nodes); +} + +__global__ void signed_distance_watertight_kernel( + uint32_t n_elements, const Vector3f* __restrict__ positions, + float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, + const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds +) { + uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= n_elements) return; + + float max_distance = use_existing_distances_as_upper_bounds ? distances[i] : MAX_DIST; + + Vector3f point = positions[i]; + + auto res = TriangleBvh4::signed_distance_watertight(point, bvhnodes, triangles, max_distance*max_distance); + + // write + distances[i] = res.second; + int tri_idx = res.first; + if (tri_idx < 0 || tri_idx >= static_cast(n_triangles)) { + face_id[i] = -1; + if (uvw) { + uvw[i] = Vector3f::Zero(); + } + return; + } + + face_id[i] = triangles[tri_idx].id; + + // optional output + if (uvw) { + // get closest point + Vector3f cpoint = triangles[res.first].closest_point(point); + // query uvw + uvw[i] = triangles[tri_idx].barycentric(cpoint); + } +} + +__global__ void signed_distance_raystab_kernel( + uint32_t n_elements, const Vector3f* __restrict__ positions, + float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, + const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds +) { + uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= n_elements) return; + + float max_distance = use_existing_distances_as_upper_bounds ? distances[i] : MAX_DIST; + pcg32 rng; + rng.advance(i * 2); + + Vector3f point = positions[i]; + + auto res = TriangleBvh4::signed_distance_raystab(point, bvhnodes, triangles, max_distance*max_distance, rng); + + // write + distances[i] = res.second; + int tri_idx = res.first; + if (tri_idx < 0 || tri_idx >= static_cast(n_triangles)) { + face_id[i] = -1; + if (uvw) { + uvw[i] = Vector3f::Zero(); + } + return; + } + + face_id[i] = triangles[tri_idx].id; + + // optional output + if (uvw) { + // get closest point + Vector3f cpoint = triangles[res.first].closest_point(point); + // query uvw + uvw[i] = triangles[tri_idx].barycentric(cpoint); + } +} + +__global__ void unsigned_distance_kernel( + uint32_t n_elements, const Vector3f* __restrict__ positions, + float* __restrict__ distances, int64_t* __restrict__ face_id, Vector3f* __restrict__ uvw, + const TriangleBvhNode* __restrict__ bvhnodes, const Triangle* __restrict__ triangles, uint32_t n_triangles, bool use_existing_distances_as_upper_bounds +) { + uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= n_elements) return; + + float max_distance = use_existing_distances_as_upper_bounds ? distances[i] : MAX_DIST; + + Vector3f point = positions[i]; + + auto res = TriangleBvh4::closest_triangle(point, bvhnodes, triangles, max_distance*max_distance); + + // write + distances[i] = res.second; + int tri_idx = res.first; + if (tri_idx < 0 || tri_idx >= static_cast(n_triangles)) { + face_id[i] = -1; + if (uvw) { + uvw[i] = Vector3f::Zero(); + } + return; + } + + face_id[i] = triangles[tri_idx].id; + + // optional output + if (uvw) { + // get closest point + Vector3f cpoint = triangles[tri_idx].closest_point(point); + // query uvw + uvw[i] = triangles[tri_idx].barycentric(cpoint); + } +} + +__global__ void raytrace_kernel( + uint32_t n_elements, const Vector3f* __restrict__ rays_o, const Vector3f* __restrict__ rays_d, + Vector3f* __restrict__ positions, int64_t* __restrict__ face_id, float* __restrict__ depth, + const TriangleBvhNode* __restrict__ nodes, const Triangle* __restrict__ triangles +) { + uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= n_elements) return; + + Vector3f ro = rays_o[i]; + Vector3f rd = rays_d[i]; + + auto res = TriangleBvh4::ray_intersect(ro, rd, nodes, triangles); + + // write depth + depth[i] = res.second; + + // intersection point is written back to positions. + // non-intersect point reaches at most 10 depth + positions[i] = ro + res.second * rd; + + // write face_id + if (res.first >= 0) { + face_id[i] = triangles[res.first].id; + } else { + face_id[i] = -1; + } +} + +} \ No newline at end of file diff --git a/extensions/vox2seq/benchmark.py b/extensions/vox2seq/benchmark.py new file mode 100644 index 0000000000000000000000000000000000000000..30351e0251cfed4db82d286af1b53654f8cdce8b --- /dev/null +++ b/extensions/vox2seq/benchmark.py @@ -0,0 +1,45 @@ +import time +import torch +import vox2seq + + +if __name__ == "__main__": + stats = { + 'z_order_cuda': [], + 'z_order_pytorch': [], + 'hilbert_cuda': [], + 'hilbert_pytorch': [], + } + RES = [16, 32, 64, 128, 256] + for res in RES: + coords = torch.meshgrid(torch.arange(res), torch.arange(res), torch.arange(res)) + coords = torch.stack(coords, dim=-1).reshape(-1, 3).int().cuda() + + start = time.time() + for _ in range(100): + code_z_cuda = vox2seq.encode(coords, mode='z_order').cuda() + torch.cuda.synchronize() + stats['z_order_cuda'].append((time.time() - start) / 100) + + start = time.time() + for _ in range(100): + code_z_pytorch = vox2seq.pytorch.encode(coords, mode='z_order').cuda() + torch.cuda.synchronize() + stats['z_order_pytorch'].append((time.time() - start) / 100) + + start = time.time() + for _ in range(100): + code_h_cuda = vox2seq.encode(coords, mode='hilbert').cuda() + torch.cuda.synchronize() + stats['hilbert_cuda'].append((time.time() - start) / 100) + + start = time.time() + for _ in range(100): + code_h_pytorch = vox2seq.pytorch.encode(coords, mode='hilbert').cuda() + torch.cuda.synchronize() + stats['hilbert_pytorch'].append((time.time() - start) / 100) + + print(f"{'Resolution':<12}{'Z-Order (CUDA)':<24}{'Z-Order (PyTorch)':<24}{'Hilbert (CUDA)':<24}{'Hilbert (PyTorch)':<24}") + for res, z_order_cuda, z_order_pytorch, hilbert_cuda, hilbert_pytorch in zip(RES, stats['z_order_cuda'], stats['z_order_pytorch'], stats['hilbert_cuda'], stats['hilbert_pytorch']): + print(f"{res:<12}{z_order_cuda:<24.6f}{z_order_pytorch:<24.6f}{hilbert_cuda:<24.6f}{hilbert_pytorch:<24.6f}") + diff --git a/extensions/vox2seq/setup.py b/extensions/vox2seq/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..500d97b7c2c69e2ced48a9286b1b030976f2fb47 --- /dev/null +++ b/extensions/vox2seq/setup.py @@ -0,0 +1,34 @@ +# +# Copyright (C) 2023, Inria +# GRAPHDECO research group, https://team.inria.fr/graphdeco +# All rights reserved. +# +# This software is free for non-commercial, research and evaluation use +# under the terms of the LICENSE.md file. +# +# For inquiries contact george.drettakis@inria.fr +# + +from setuptools import setup +from torch.utils.cpp_extension import CUDAExtension, BuildExtension +import os +os.path.dirname(os.path.abspath(__file__)) + +setup( + name="vox2seq", + packages=['vox2seq', 'vox2seq.pytorch'], + ext_modules=[ + CUDAExtension( + name="vox2seq._C", + sources=[ + "src/api.cu", + "src/z_order.cu", + "src/hilbert.cu", + "src/ext.cpp", + ], + ) + ], + cmdclass={ + 'build_ext': BuildExtension + } +) diff --git a/extensions/vox2seq/src/api.cu b/extensions/vox2seq/src/api.cu new file mode 100644 index 0000000000000000000000000000000000000000..072e930f90278f2f407b45750220d7d98c37b91e --- /dev/null +++ b/extensions/vox2seq/src/api.cu @@ -0,0 +1,92 @@ +#include +#include "api.h" +#include "z_order.h" +#include "hilbert.h" + + +torch::Tensor +z_order_encode( + const torch::Tensor& x, + const torch::Tensor& y, + const torch::Tensor& z +) { + // Allocate output tensor + torch::Tensor codes = torch::empty_like(x); + + // Call CUDA kernel + z_order_encode_cuda<<<(x.size(0) + BLOCK_SIZE - 1) / BLOCK_SIZE, BLOCK_SIZE>>>( + x.size(0), + reinterpret_cast(x.contiguous().data_ptr()), + reinterpret_cast(y.contiguous().data_ptr()), + reinterpret_cast(z.contiguous().data_ptr()), + reinterpret_cast(codes.data_ptr()) + ); + + return codes; +} + + +std::tuple +z_order_decode( + const torch::Tensor& codes +) { + // Allocate output tensors + torch::Tensor x = torch::empty_like(codes); + torch::Tensor y = torch::empty_like(codes); + torch::Tensor z = torch::empty_like(codes); + + // Call CUDA kernel + z_order_decode_cuda<<<(codes.size(0) + BLOCK_SIZE - 1) / BLOCK_SIZE, BLOCK_SIZE>>>( + codes.size(0), + reinterpret_cast(codes.contiguous().data_ptr()), + reinterpret_cast(x.data_ptr()), + reinterpret_cast(y.data_ptr()), + reinterpret_cast(z.data_ptr()) + ); + + return std::make_tuple(x, y, z); +} + + +torch::Tensor +hilbert_encode( + const torch::Tensor& x, + const torch::Tensor& y, + const torch::Tensor& z +) { + // Allocate output tensor + torch::Tensor codes = torch::empty_like(x); + + // Call CUDA kernel + hilbert_encode_cuda<<<(x.size(0) + BLOCK_SIZE - 1) / BLOCK_SIZE, BLOCK_SIZE>>>( + x.size(0), + reinterpret_cast(x.contiguous().data_ptr()), + reinterpret_cast(y.contiguous().data_ptr()), + reinterpret_cast(z.contiguous().data_ptr()), + reinterpret_cast(codes.data_ptr()) + ); + + return codes; +} + + +std::tuple +hilbert_decode( + const torch::Tensor& codes +) { + // Allocate output tensors + torch::Tensor x = torch::empty_like(codes); + torch::Tensor y = torch::empty_like(codes); + torch::Tensor z = torch::empty_like(codes); + + // Call CUDA kernel + hilbert_decode_cuda<<<(codes.size(0) + BLOCK_SIZE - 1) / BLOCK_SIZE, BLOCK_SIZE>>>( + codes.size(0), + reinterpret_cast(codes.contiguous().data_ptr()), + reinterpret_cast(x.data_ptr()), + reinterpret_cast(y.data_ptr()), + reinterpret_cast(z.data_ptr()) + ); + + return std::make_tuple(x, y, z); +} diff --git a/extensions/vox2seq/src/api.h b/extensions/vox2seq/src/api.h new file mode 100644 index 0000000000000000000000000000000000000000..26a68348d56585d0e9e1dfb4900a0d23587df9a6 --- /dev/null +++ b/extensions/vox2seq/src/api.h @@ -0,0 +1,76 @@ +/* + * Serialize a voxel grid + * + * Copyright (C) 2024, Jianfeng XIANG + * All rights reserved. + * + * Licensed under The MIT License [see LICENSE for details] + * + * Written by Jianfeng XIANG + */ + +#pragma once +#include + + +#define BLOCK_SIZE 256 + + +/** + * Z-order encode 3D points + * + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + * + * @return [N] tensor containing the z-order encoded values + */ +torch::Tensor +z_order_encode( + const torch::Tensor& x, + const torch::Tensor& y, + const torch::Tensor& z +); + + +/** + * Z-order decode 3D points + * + * @param codes [N] tensor containing the z-order encoded values + * + * @return 3 tensors [N] containing the x, y, z coordinates + */ +std::tuple +z_order_decode( + const torch::Tensor& codes +); + + +/** + * Hilbert encode 3D points + * + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + * + * @return [N] tensor containing the Hilbert encoded values + */ +torch::Tensor +hilbert_encode( + const torch::Tensor& x, + const torch::Tensor& y, + const torch::Tensor& z +); + + +/** + * Hilbert decode 3D points + * + * @param codes [N] tensor containing the Hilbert encoded values + * + * @return 3 tensors [N] containing the x, y, z coordinates + */ +std::tuple +hilbert_decode( + const torch::Tensor& codes +); diff --git a/extensions/vox2seq/src/ext.cpp b/extensions/vox2seq/src/ext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72e76d3b361eb8f355760f067f71005d4e37902c --- /dev/null +++ b/extensions/vox2seq/src/ext.cpp @@ -0,0 +1,10 @@ +#include +#include "api.h" + + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def("z_order_encode", &z_order_encode); + m.def("z_order_decode", &z_order_decode); + m.def("hilbert_encode", &hilbert_encode); + m.def("hilbert_decode", &hilbert_decode); +} \ No newline at end of file diff --git a/extensions/vox2seq/src/hilbert.cu b/extensions/vox2seq/src/hilbert.cu new file mode 100644 index 0000000000000000000000000000000000000000..b3c5bb19474a528cf6f3102e728fa7550588ca61 --- /dev/null +++ b/extensions/vox2seq/src/hilbert.cu @@ -0,0 +1,133 @@ +#include +#include +#include + +#include +#include +namespace cg = cooperative_groups; + +#include "hilbert.h" + + +// Expands a 10-bit integer into 30 bits by inserting 2 zeros after each bit. +static __device__ uint32_t expandBits(uint32_t v) +{ + v = (v * 0x00010001u) & 0xFF0000FFu; + v = (v * 0x00000101u) & 0x0F00F00Fu; + v = (v * 0x00000011u) & 0xC30C30C3u; + v = (v * 0x00000005u) & 0x49249249u; + return v; +} + + +// Removes 2 zeros after each bit in a 30-bit integer. +static __device__ uint32_t extractBits(uint32_t v) +{ + v = v & 0x49249249; + v = (v ^ (v >> 2)) & 0x030C30C3u; + v = (v ^ (v >> 4)) & 0x0300F00Fu; + v = (v ^ (v >> 8)) & 0x030000FFu; + v = (v ^ (v >> 16)) & 0x000003FFu; + return v; +} + + +__global__ void hilbert_encode_cuda( + size_t N, + const uint32_t* x, + const uint32_t* y, + const uint32_t* z, + uint32_t* codes +) { + size_t thread_id = cg::this_grid().thread_rank(); + if (thread_id >= N) return; + + uint32_t point[3] = {x[thread_id], y[thread_id], z[thread_id]}; + + uint32_t m = 1 << 9, q, p, t; + + // Inverse undo excess work + q = m; + while (q > 1) { + p = q - 1; + for (int i = 0; i < 3; i++) { + if (point[i] & q) { + point[0] ^= p; // invert + } else { + t = (point[0] ^ point[i]) & p; + point[0] ^= t; + point[i] ^= t; + } + } + q >>= 1; + } + + // Gray encode + for (int i = 1; i < 3; i++) { + point[i] ^= point[i - 1]; + } + t = 0; + q = m; + while (q > 1) { + if (point[2] & q) { + t ^= q - 1; + } + q >>= 1; + } + for (int i = 0; i < 3; i++) { + point[i] ^= t; + } + + // Convert to 3D Hilbert code + uint32_t xx = expandBits(point[0]); + uint32_t yy = expandBits(point[1]); + uint32_t zz = expandBits(point[2]); + + codes[thread_id] = xx * 4 + yy * 2 + zz; +} + + +__global__ void hilbert_decode_cuda( + size_t N, + const uint32_t* codes, + uint32_t* x, + uint32_t* y, + uint32_t* z +) { + size_t thread_id = cg::this_grid().thread_rank(); + if (thread_id >= N) return; + + uint32_t point[3]; + point[0] = extractBits(codes[thread_id] >> 2); + point[1] = extractBits(codes[thread_id] >> 1); + point[2] = extractBits(codes[thread_id]); + + uint32_t m = 2 << 9, q, p, t; + + // Gray decode by H ^ (H/2) + t = point[2] >> 1; + for (int i = 2; i > 0; i--) { + point[i] ^= point[i - 1]; + } + point[0] ^= t; + + // Undo excess work + q = 2; + while (q != m) { + p = q - 1; + for (int i = 2; i >= 0; i--) { + if (point[i] & q) { + point[0] ^= p; + } else { + t = (point[0] ^ point[i]) & p; + point[0] ^= t; + point[i] ^= t; + } + } + q <<= 1; + } + + x[thread_id] = point[0]; + y[thread_id] = point[1]; + z[thread_id] = point[2]; +} diff --git a/extensions/vox2seq/src/hilbert.h b/extensions/vox2seq/src/hilbert.h new file mode 100644 index 0000000000000000000000000000000000000000..4896bf6006f43e5e527d8bde691ce7a54b38c4d7 --- /dev/null +++ b/extensions/vox2seq/src/hilbert.h @@ -0,0 +1,35 @@ +#pragma once + +/** + * Hilbert encode 3D points + * + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + * + * @return [N] tensor containing the z-order encoded values + */ +__global__ void hilbert_encode_cuda( + size_t N, + const uint32_t* x, + const uint32_t* y, + const uint32_t* z, + uint32_t* codes +); + + +/** + * Hilbert decode 3D points + * + * @param codes [N] tensor containing the z-order encoded values + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + */ +__global__ void hilbert_decode_cuda( + size_t N, + const uint32_t* codes, + uint32_t* x, + uint32_t* y, + uint32_t* z +); diff --git a/extensions/vox2seq/src/z_order.cu b/extensions/vox2seq/src/z_order.cu new file mode 100644 index 0000000000000000000000000000000000000000..ba6f5a91e55588d1ca4bea7cb45e6936330a694b --- /dev/null +++ b/extensions/vox2seq/src/z_order.cu @@ -0,0 +1,66 @@ +#include +#include +#include + +#include +#include +namespace cg = cooperative_groups; + +#include "z_order.h" + + +// Expands a 10-bit integer into 30 bits by inserting 2 zeros after each bit. +static __device__ uint32_t expandBits(uint32_t v) +{ + v = (v * 0x00010001u) & 0xFF0000FFu; + v = (v * 0x00000101u) & 0x0F00F00Fu; + v = (v * 0x00000011u) & 0xC30C30C3u; + v = (v * 0x00000005u) & 0x49249249u; + return v; +} + + +// Removes 2 zeros after each bit in a 30-bit integer. +static __device__ uint32_t extractBits(uint32_t v) +{ + v = v & 0x49249249; + v = (v ^ (v >> 2)) & 0x030C30C3u; + v = (v ^ (v >> 4)) & 0x0300F00Fu; + v = (v ^ (v >> 8)) & 0x030000FFu; + v = (v ^ (v >> 16)) & 0x000003FFu; + return v; +} + + +__global__ void z_order_encode_cuda( + size_t N, + const uint32_t* x, + const uint32_t* y, + const uint32_t* z, + uint32_t* codes +) { + size_t thread_id = cg::this_grid().thread_rank(); + if (thread_id >= N) return; + + uint32_t xx = expandBits(x[thread_id]); + uint32_t yy = expandBits(y[thread_id]); + uint32_t zz = expandBits(z[thread_id]); + + codes[thread_id] = xx * 4 + yy * 2 + zz; +} + + +__global__ void z_order_decode_cuda( + size_t N, + const uint32_t* codes, + uint32_t* x, + uint32_t* y, + uint32_t* z +) { + size_t thread_id = cg::this_grid().thread_rank(); + if (thread_id >= N) return; + + x[thread_id] = extractBits(codes[thread_id] >> 2); + y[thread_id] = extractBits(codes[thread_id] >> 1); + z[thread_id] = extractBits(codes[thread_id]); +} diff --git a/extensions/vox2seq/src/z_order.h b/extensions/vox2seq/src/z_order.h new file mode 100644 index 0000000000000000000000000000000000000000..a4aa857d064e375c8f2eb023abd9ac4af5a2d8f5 --- /dev/null +++ b/extensions/vox2seq/src/z_order.h @@ -0,0 +1,35 @@ +#pragma once + +/** + * Z-order encode 3D points + * + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + * + * @return [N] tensor containing the z-order encoded values + */ +__global__ void z_order_encode_cuda( + size_t N, + const uint32_t* x, + const uint32_t* y, + const uint32_t* z, + uint32_t* codes +); + + +/** + * Z-order decode 3D points + * + * @param codes [N] tensor containing the z-order encoded values + * @param x [N] tensor containing the x coordinates + * @param y [N] tensor containing the y coordinates + * @param z [N] tensor containing the z coordinates + */ +__global__ void z_order_decode_cuda( + size_t N, + const uint32_t* codes, + uint32_t* x, + uint32_t* y, + uint32_t* z +); diff --git a/extensions/vox2seq/test.py b/extensions/vox2seq/test.py new file mode 100644 index 0000000000000000000000000000000000000000..60f4fc0ae1aa0ff55744455e66b0854706908506 --- /dev/null +++ b/extensions/vox2seq/test.py @@ -0,0 +1,25 @@ +import torch +import vox2seq + + +if __name__ == "__main__": + RES = 256 + coords = torch.meshgrid(torch.arange(RES), torch.arange(RES), torch.arange(RES)) + coords = torch.stack(coords, dim=-1).reshape(-1, 3).int().cuda() + code_z_cuda = vox2seq.encode(coords, mode='z_order') + code_z_pytorch = vox2seq.pytorch.encode(coords, mode='z_order') + code_h_cuda = vox2seq.encode(coords, mode='hilbert') + code_h_pytorch = vox2seq.pytorch.encode(coords, mode='hilbert') + assert torch.equal(code_z_cuda, code_z_pytorch) + assert torch.equal(code_h_cuda, code_h_pytorch) + + code = torch.arange(RES**3).int().cuda() + coords_z_cuda = vox2seq.decode(code, mode='z_order') + coords_z_pytorch = vox2seq.pytorch.decode(code, mode='z_order') + coords_h_cuda = vox2seq.decode(code, mode='hilbert') + coords_h_pytorch = vox2seq.pytorch.decode(code, mode='hilbert') + assert torch.equal(coords_z_cuda, coords_z_pytorch) + assert torch.equal(coords_h_cuda, coords_h_pytorch) + + print("All tests passed.") + diff --git a/extensions/vox2seq/vox2seq/__init__.py b/extensions/vox2seq/vox2seq/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ba13bb5f46b2ba90c7882f23b7d97c3b6fe960ac --- /dev/null +++ b/extensions/vox2seq/vox2seq/__init__.py @@ -0,0 +1,50 @@ + +from typing import * +import torch +from . import _C +from . import pytorch + + +@torch.no_grad() +def encode(coords: torch.Tensor, permute: List[int] = [0, 1, 2], mode: Literal['z_order', 'hilbert'] = 'z_order') -> torch.Tensor: + """ + Encodes 3D coordinates into a 30-bit code. + + Args: + coords: a tensor of shape [N, 3] containing the 3D coordinates. + permute: the permutation of the coordinates. + mode: the encoding mode to use. + """ + assert coords.shape[-1] == 3 and coords.ndim == 2, "Input coordinates must be of shape [N, 3]" + x = coords[:, permute[0]].int() + y = coords[:, permute[1]].int() + z = coords[:, permute[2]].int() + if mode == 'z_order': + return _C.z_order_encode(x, y, z) + elif mode == 'hilbert': + return _C.hilbert_encode(x, y, z) + else: + raise ValueError(f"Unknown encoding mode: {mode}") + + +@torch.no_grad() +def decode(code: torch.Tensor, permute: List[int] = [0, 1, 2], mode: Literal['z_order', 'hilbert'] = 'z_order') -> torch.Tensor: + """ + Decodes a 30-bit code into 3D coordinates. + + Args: + code: a tensor of shape [N] containing the 30-bit code. + permute: the permutation of the coordinates. + mode: the decoding mode to use. + """ + assert code.ndim == 1, "Input code must be of shape [N]" + if mode == 'z_order': + coords = _C.z_order_decode(code) + elif mode == 'hilbert': + coords = _C.hilbert_decode(code) + else: + raise ValueError(f"Unknown decoding mode: {mode}") + x = coords[permute.index(0)] + y = coords[permute.index(1)] + z = coords[permute.index(2)] + return torch.stack([x, y, z], dim=-1) diff --git a/extensions/vox2seq/vox2seq/pytorch/__init__.py b/extensions/vox2seq/vox2seq/pytorch/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..25c74c42feb802b24eee9a1bc8744040468c927d --- /dev/null +++ b/extensions/vox2seq/vox2seq/pytorch/__init__.py @@ -0,0 +1,48 @@ +import torch +from typing import * + +from .default import ( + encode, + decode, + z_order_encode, + z_order_decode, + hilbert_encode, + hilbert_decode, +) + + +@torch.no_grad() +def encode(coords: torch.Tensor, permute: List[int] = [0, 1, 2], mode: Literal['z_order', 'hilbert'] = 'z_order') -> torch.Tensor: + """ + Encodes 3D coordinates into a 30-bit code. + + Args: + coords: a tensor of shape [N, 3] containing the 3D coordinates. + permute: the permutation of the coordinates. + mode: the encoding mode to use. + """ + if mode == 'z_order': + return z_order_encode(coords[:, permute], depth=10).int() + elif mode == 'hilbert': + return hilbert_encode(coords[:, permute], depth=10).int() + else: + raise ValueError(f"Unknown encoding mode: {mode}") + + +@torch.no_grad() +def decode(code: torch.Tensor, permute: List[int] = [0, 1, 2], mode: Literal['z_order', 'hilbert'] = 'z_order') -> torch.Tensor: + """ + Decodes a 30-bit code into 3D coordinates. + + Args: + code: a tensor of shape [N] containing the 30-bit code. + permute: the permutation of the coordinates. + mode: the decoding mode to use. + """ + if mode == 'z_order': + return z_order_decode(code, depth=10)[:, permute].float() + elif mode == 'hilbert': + return hilbert_decode(code, depth=10)[:, permute].float() + else: + raise ValueError(f"Unknown decoding mode: {mode}") + \ No newline at end of file diff --git a/extensions/vox2seq/vox2seq/pytorch/default.py b/extensions/vox2seq/vox2seq/pytorch/default.py new file mode 100644 index 0000000000000000000000000000000000000000..906f9bfbe80fcf71977ca774b6491ff63a1ee43b --- /dev/null +++ b/extensions/vox2seq/vox2seq/pytorch/default.py @@ -0,0 +1,59 @@ +import torch +from .z_order import xyz2key as z_order_encode_ +from .z_order import key2xyz as z_order_decode_ +from .hilbert import encode as hilbert_encode_ +from .hilbert import decode as hilbert_decode_ + + +@torch.inference_mode() +def encode(grid_coord, batch=None, depth=16, order="z"): + assert order in {"z", "z-trans", "hilbert", "hilbert-trans"} + if order == "z": + code = z_order_encode(grid_coord, depth=depth) + elif order == "z-trans": + code = z_order_encode(grid_coord[:, [1, 0, 2]], depth=depth) + elif order == "hilbert": + code = hilbert_encode(grid_coord, depth=depth) + elif order == "hilbert-trans": + code = hilbert_encode(grid_coord[:, [1, 0, 2]], depth=depth) + else: + raise NotImplementedError + if batch is not None: + batch = batch.long() + code = batch << depth * 3 | code + return code + + +@torch.inference_mode() +def decode(code, depth=16, order="z"): + assert order in {"z", "hilbert"} + batch = code >> depth * 3 + code = code & ((1 << depth * 3) - 1) + if order == "z": + grid_coord = z_order_decode(code, depth=depth) + elif order == "hilbert": + grid_coord = hilbert_decode(code, depth=depth) + else: + raise NotImplementedError + return grid_coord, batch + + +def z_order_encode(grid_coord: torch.Tensor, depth: int = 16): + x, y, z = grid_coord[:, 0].long(), grid_coord[:, 1].long(), grid_coord[:, 2].long() + # we block the support to batch, maintain batched code in Point class + code = z_order_encode_(x, y, z, b=None, depth=depth) + return code + + +def z_order_decode(code: torch.Tensor, depth): + x, y, z, _ = z_order_decode_(code, depth=depth) + grid_coord = torch.stack([x, y, z], dim=-1) # (N, 3) + return grid_coord + + +def hilbert_encode(grid_coord: torch.Tensor, depth: int = 16): + return hilbert_encode_(grid_coord, num_dims=3, num_bits=depth) + + +def hilbert_decode(code: torch.Tensor, depth: int = 16): + return hilbert_decode_(code, num_dims=3, num_bits=depth) \ No newline at end of file diff --git a/extensions/vox2seq/vox2seq/pytorch/hilbert.py b/extensions/vox2seq/vox2seq/pytorch/hilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..c3fb6565ff855c50553d6215eb74407f88b43a01 --- /dev/null +++ b/extensions/vox2seq/vox2seq/pytorch/hilbert.py @@ -0,0 +1,303 @@ +""" +Hilbert Order +Modified from https://github.com/PrincetonLIPS/numpy-hilbert-curve + +Author: Xiaoyang Wu (xiaoyang.wu.cs@gmail.com), Kaixin Xu +Please cite our work if the code is helpful to you. +""" + +import torch + + +def right_shift(binary, k=1, axis=-1): + """Right shift an array of binary values. + + Parameters: + ----------- + binary: An ndarray of binary values. + + k: The number of bits to shift. Default 1. + + axis: The axis along which to shift. Default -1. + + Returns: + -------- + Returns an ndarray with zero prepended and the ends truncated, along + whatever axis was specified.""" + + # If we're shifting the whole thing, just return zeros. + if binary.shape[axis] <= k: + return torch.zeros_like(binary) + + # Determine the padding pattern. + # padding = [(0,0)] * len(binary.shape) + # padding[axis] = (k,0) + + # Determine the slicing pattern to eliminate just the last one. + slicing = [slice(None)] * len(binary.shape) + slicing[axis] = slice(None, -k) + shifted = torch.nn.functional.pad( + binary[tuple(slicing)], (k, 0), mode="constant", value=0 + ) + + return shifted + + +def binary2gray(binary, axis=-1): + """Convert an array of binary values into Gray codes. + + This uses the classic X ^ (X >> 1) trick to compute the Gray code. + + Parameters: + ----------- + binary: An ndarray of binary values. + + axis: The axis along which to compute the gray code. Default=-1. + + Returns: + -------- + Returns an ndarray of Gray codes. + """ + shifted = right_shift(binary, axis=axis) + + # Do the X ^ (X >> 1) trick. + gray = torch.logical_xor(binary, shifted) + + return gray + + +def gray2binary(gray, axis=-1): + """Convert an array of Gray codes back into binary values. + + Parameters: + ----------- + gray: An ndarray of gray codes. + + axis: The axis along which to perform Gray decoding. Default=-1. + + Returns: + -------- + Returns an ndarray of binary values. + """ + + # Loop the log2(bits) number of times necessary, with shift and xor. + shift = 2 ** (torch.Tensor([gray.shape[axis]]).log2().ceil().int() - 1) + while shift > 0: + gray = torch.logical_xor(gray, right_shift(gray, shift)) + shift = torch.div(shift, 2, rounding_mode="floor") + return gray + + +def encode(locs, num_dims, num_bits): + """Decode an array of locations in a hypercube into a Hilbert integer. + + This is a vectorized-ish version of the Hilbert curve implementation by John + Skilling as described in: + + Skilling, J. (2004, April). Programming the Hilbert curve. In AIP Conference + Proceedings (Vol. 707, No. 1, pp. 381-387). American Institute of Physics. + + Params: + ------- + locs - An ndarray of locations in a hypercube of num_dims dimensions, in + which each dimension runs from 0 to 2**num_bits-1. The shape can + be arbitrary, as long as the last dimension of the same has size + num_dims. + + num_dims - The dimensionality of the hypercube. Integer. + + num_bits - The number of bits for each dimension. Integer. + + Returns: + -------- + The output is an ndarray of uint64 integers with the same shape as the + input, excluding the last dimension, which needs to be num_dims. + """ + + # Keep around the original shape for later. + orig_shape = locs.shape + bitpack_mask = 1 << torch.arange(0, 8).to(locs.device) + bitpack_mask_rev = bitpack_mask.flip(-1) + + if orig_shape[-1] != num_dims: + raise ValueError( + """ + The shape of locs was surprising in that the last dimension was of size + %d, but num_dims=%d. These need to be equal. + """ + % (orig_shape[-1], num_dims) + ) + + if num_dims * num_bits > 63: + raise ValueError( + """ + num_dims=%d and num_bits=%d for %d bits total, which can't be encoded + into a int64. Are you sure you need that many points on your Hilbert + curve? + """ + % (num_dims, num_bits, num_dims * num_bits) + ) + + # Treat the location integers as 64-bit unsigned and then split them up into + # a sequence of uint8s. Preserve the association by dimension. + locs_uint8 = locs.long().view(torch.uint8).reshape((-1, num_dims, 8)).flip(-1) + + # Now turn these into bits and truncate to num_bits. + gray = ( + locs_uint8.unsqueeze(-1) + .bitwise_and(bitpack_mask_rev) + .ne(0) + .byte() + .flatten(-2, -1)[..., -num_bits:] + ) + + # Run the decoding process the other way. + # Iterate forwards through the bits. + for bit in range(0, num_bits): + # Iterate forwards through the dimensions. + for dim in range(0, num_dims): + # Identify which ones have this bit active. + mask = gray[:, dim, bit] + + # Where this bit is on, invert the 0 dimension for lower bits. + gray[:, 0, bit + 1 :] = torch.logical_xor( + gray[:, 0, bit + 1 :], mask[:, None] + ) + + # Where the bit is off, exchange the lower bits with the 0 dimension. + to_flip = torch.logical_and( + torch.logical_not(mask[:, None]).repeat(1, gray.shape[2] - bit - 1), + torch.logical_xor(gray[:, 0, bit + 1 :], gray[:, dim, bit + 1 :]), + ) + gray[:, dim, bit + 1 :] = torch.logical_xor( + gray[:, dim, bit + 1 :], to_flip + ) + gray[:, 0, bit + 1 :] = torch.logical_xor(gray[:, 0, bit + 1 :], to_flip) + + # Now flatten out. + gray = gray.swapaxes(1, 2).reshape((-1, num_bits * num_dims)) + + # Convert Gray back to binary. + hh_bin = gray2binary(gray) + + # Pad back out to 64 bits. + extra_dims = 64 - num_bits * num_dims + padded = torch.nn.functional.pad(hh_bin, (extra_dims, 0), "constant", 0) + + # Convert binary values into uint8s. + hh_uint8 = ( + (padded.flip(-1).reshape((-1, 8, 8)) * bitpack_mask) + .sum(2) + .squeeze() + .type(torch.uint8) + ) + + # Convert uint8s into uint64s. + hh_uint64 = hh_uint8.view(torch.int64).squeeze() + + return hh_uint64 + + +def decode(hilberts, num_dims, num_bits): + """Decode an array of Hilbert integers into locations in a hypercube. + + This is a vectorized-ish version of the Hilbert curve implementation by John + Skilling as described in: + + Skilling, J. (2004, April). Programming the Hilbert curve. In AIP Conference + Proceedings (Vol. 707, No. 1, pp. 381-387). American Institute of Physics. + + Params: + ------- + hilberts - An ndarray of Hilbert integers. Must be an integer dtype and + cannot have fewer bits than num_dims * num_bits. + + num_dims - The dimensionality of the hypercube. Integer. + + num_bits - The number of bits for each dimension. Integer. + + Returns: + -------- + The output is an ndarray of unsigned integers with the same shape as hilberts + but with an additional dimension of size num_dims. + """ + + if num_dims * num_bits > 64: + raise ValueError( + """ + num_dims=%d and num_bits=%d for %d bits total, which can't be encoded + into a uint64. Are you sure you need that many points on your Hilbert + curve? + """ + % (num_dims, num_bits) + ) + + # Handle the case where we got handed a naked integer. + hilberts = torch.atleast_1d(hilberts) + + # Keep around the shape for later. + orig_shape = hilberts.shape + bitpack_mask = 2 ** torch.arange(0, 8).to(hilberts.device) + bitpack_mask_rev = bitpack_mask.flip(-1) + + # Treat each of the hilberts as a s equence of eight uint8. + # This treats all of the inputs as uint64 and makes things uniform. + hh_uint8 = ( + hilberts.ravel().type(torch.int64).view(torch.uint8).reshape((-1, 8)).flip(-1) + ) + + # Turn these lists of uints into lists of bits and then truncate to the size + # we actually need for using Skilling's procedure. + hh_bits = ( + hh_uint8.unsqueeze(-1) + .bitwise_and(bitpack_mask_rev) + .ne(0) + .byte() + .flatten(-2, -1)[:, -num_dims * num_bits :] + ) + + # Take the sequence of bits and Gray-code it. + gray = binary2gray(hh_bits) + + # There has got to be a better way to do this. + # I could index them differently, but the eventual packbits likes it this way. + gray = gray.reshape((-1, num_bits, num_dims)).swapaxes(1, 2) + + # Iterate backwards through the bits. + for bit in range(num_bits - 1, -1, -1): + # Iterate backwards through the dimensions. + for dim in range(num_dims - 1, -1, -1): + # Identify which ones have this bit active. + mask = gray[:, dim, bit] + + # Where this bit is on, invert the 0 dimension for lower bits. + gray[:, 0, bit + 1 :] = torch.logical_xor( + gray[:, 0, bit + 1 :], mask[:, None] + ) + + # Where the bit is off, exchange the lower bits with the 0 dimension. + to_flip = torch.logical_and( + torch.logical_not(mask[:, None]), + torch.logical_xor(gray[:, 0, bit + 1 :], gray[:, dim, bit + 1 :]), + ) + gray[:, dim, bit + 1 :] = torch.logical_xor( + gray[:, dim, bit + 1 :], to_flip + ) + gray[:, 0, bit + 1 :] = torch.logical_xor(gray[:, 0, bit + 1 :], to_flip) + + # Pad back out to 64 bits. + extra_dims = 64 - num_bits + padded = torch.nn.functional.pad(gray, (extra_dims, 0), "constant", 0) + + # Now chop these up into blocks of 8. + locs_chopped = padded.flip(-1).reshape((-1, num_dims, 8, 8)) + + # Take those blocks and turn them unto uint8s. + # from IPython import embed; embed() + locs_uint8 = (locs_chopped * bitpack_mask).sum(3).squeeze().type(torch.uint8) + + # Finally, treat these as uint64s. + flat_locs = locs_uint8.view(torch.int64) + + # Return them in the expected shape. + return flat_locs.reshape((*orig_shape, num_dims)) \ No newline at end of file diff --git a/extensions/vox2seq/vox2seq/pytorch/z_order.py b/extensions/vox2seq/vox2seq/pytorch/z_order.py new file mode 100644 index 0000000000000000000000000000000000000000..b33963de44ddfcbecdf2e403ea70166f2d0e4eb0 --- /dev/null +++ b/extensions/vox2seq/vox2seq/pytorch/z_order.py @@ -0,0 +1,126 @@ +# -------------------------------------------------------- +# Octree-based Sparse Convolutional Neural Networks +# Copyright (c) 2022 Peng-Shuai Wang +# Licensed under The MIT License [see LICENSE for details] +# Written by Peng-Shuai Wang +# -------------------------------------------------------- + +import torch +from typing import Optional, Union + + +class KeyLUT: + def __init__(self): + r256 = torch.arange(256, dtype=torch.int64) + r512 = torch.arange(512, dtype=torch.int64) + zero = torch.zeros(256, dtype=torch.int64) + device = torch.device("cpu") + + self._encode = { + device: ( + self.xyz2key(r256, zero, zero, 8), + self.xyz2key(zero, r256, zero, 8), + self.xyz2key(zero, zero, r256, 8), + ) + } + self._decode = {device: self.key2xyz(r512, 9)} + + def encode_lut(self, device=torch.device("cpu")): + if device not in self._encode: + cpu = torch.device("cpu") + self._encode[device] = tuple(e.to(device) for e in self._encode[cpu]) + return self._encode[device] + + def decode_lut(self, device=torch.device("cpu")): + if device not in self._decode: + cpu = torch.device("cpu") + self._decode[device] = tuple(e.to(device) for e in self._decode[cpu]) + return self._decode[device] + + def xyz2key(self, x, y, z, depth): + key = torch.zeros_like(x) + for i in range(depth): + mask = 1 << i + key = ( + key + | ((x & mask) << (2 * i + 2)) + | ((y & mask) << (2 * i + 1)) + | ((z & mask) << (2 * i + 0)) + ) + return key + + def key2xyz(self, key, depth): + x = torch.zeros_like(key) + y = torch.zeros_like(key) + z = torch.zeros_like(key) + for i in range(depth): + x = x | ((key & (1 << (3 * i + 2))) >> (2 * i + 2)) + y = y | ((key & (1 << (3 * i + 1))) >> (2 * i + 1)) + z = z | ((key & (1 << (3 * i + 0))) >> (2 * i + 0)) + return x, y, z + + +_key_lut = KeyLUT() + + +def xyz2key( + x: torch.Tensor, + y: torch.Tensor, + z: torch.Tensor, + b: Optional[Union[torch.Tensor, int]] = None, + depth: int = 16, +): + r"""Encodes :attr:`x`, :attr:`y`, :attr:`z` coordinates to the shuffled keys + based on pre-computed look up tables. The speed of this function is much + faster than the method based on for-loop. + + Args: + x (torch.Tensor): The x coordinate. + y (torch.Tensor): The y coordinate. + z (torch.Tensor): The z coordinate. + b (torch.Tensor or int): The batch index of the coordinates, and should be + smaller than 32768. If :attr:`b` is :obj:`torch.Tensor`, the size of + :attr:`b` must be the same as :attr:`x`, :attr:`y`, and :attr:`z`. + depth (int): The depth of the shuffled key, and must be smaller than 17 (< 17). + """ + + EX, EY, EZ = _key_lut.encode_lut(x.device) + x, y, z = x.long(), y.long(), z.long() + + mask = 255 if depth > 8 else (1 << depth) - 1 + key = EX[x & mask] | EY[y & mask] | EZ[z & mask] + if depth > 8: + mask = (1 << (depth - 8)) - 1 + key16 = EX[(x >> 8) & mask] | EY[(y >> 8) & mask] | EZ[(z >> 8) & mask] + key = key16 << 24 | key + + if b is not None: + b = b.long() + key = b << 48 | key + + return key + + +def key2xyz(key: torch.Tensor, depth: int = 16): + r"""Decodes the shuffled key to :attr:`x`, :attr:`y`, :attr:`z` coordinates + and the batch index based on pre-computed look up tables. + + Args: + key (torch.Tensor): The shuffled key. + depth (int): The depth of the shuffled key, and must be smaller than 17 (< 17). + """ + + DX, DY, DZ = _key_lut.decode_lut(key.device) + x, y, z = torch.zeros_like(key), torch.zeros_like(key), torch.zeros_like(key) + + b = key >> 48 + key = key & ((1 << 48) - 1) + + n = (depth + 2) // 3 + for i in range(n): + k = key >> (i * 9) & 511 + x = x | (DX[k] << (i * 3)) + y = y | (DY[k] << (i * 3)) + z = z | (DZ[k] << (i * 3)) + + return x, y, z, b \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..e7e262e37d6fabb088313a5fe010a6b07f091ae9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,45 @@ +--extra-index-url https://download.pytorch.org/whl/cu121 + +torch==2.4.0 +torchvision==0.19.0 +pillow==10.4.0 +imageio==2.36.1 +imageio-ffmpeg==0.5.1 +tqdm==4.67.1 +easydict==1.13 +opencv-python-headless==4.10.0.84 +scipy==1.14.1 +rembg==2.0.60 +onnxruntime==1.20.1 +trimesh==4.5.3 +rtree>=1.0 +xatlas==0.0.9 +pyvista==0.44.2 +pymeshfix==0.17.0 +igraph==0.11.8 +pygltflib==1.16.3 +numpy==1.26.4 +psutil>=5.9,<6 +safetensors==0.5.2 +scikit-learn==1.6.1 +geffnet==1.0.2 +transformers==4.46.3 +git+https://github.com/EasternJournalist/utils3d.git@9a4eb15e4021b67b12c460c7057d642626897ec8 + +--find-links https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu121_pyt240/download.html +pytorch3d==0.7.8 + +xformers==0.0.27.post2 +spconv-cu120==2.3.6 + +--find-links https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.4.0_cu121.html +kaolin + +gradio_litmodel3d==0.0.1 +pydantic==2.10.6 +fastapi==0.112.2 +starlette==0.38.6 +jinja2==3.1.5 + +https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post2/flash_attn-2.7.0.post2+cu12torch2.4cxx11abiFALSE-cp310-cp310-linux_x86_64.whl +https://huggingface.co/spaces/JeffreyXiang/TRELLIS/resolve/main/wheels/nvdiffrast-0.3.3-cp310-cp310-linux_x86_64.whl?download=true diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000000000000000000000000000000000000..d6c2d73f27490c1f034eba01275d687dfb19006e --- /dev/null +++ b/setup.sh @@ -0,0 +1,339 @@ +# Read Arguments +TEMP=`getopt -o h --long help,new-env,torch,basic,train,all,xformers,flash-attn,diffoctreerast,vox2seq,spconv,mipgaussian,kaolin,nvdiffrast,demo -n 'setup.sh' -- "$@"` + +eval set -- "$TEMP" + +HELP=false +NEW_ENV=false +TORCH=false +BASIC=false +TRAIN=false +ALL=false +XFORMERS=false +FLASHATTN=false +DIFFOCTREERAST=false +VOX2SEQ=false +LINEAR_ASSIGNMENT=false +SPCONV=false +ERROR=false +MIPGAUSSIAN=false +KAOLIN=false +NVDIFFRAST=false +DEMO=false + +if [ "$#" -eq 1 ] ; then + HELP=true +fi + +while true ; do + case "$1" in + -h|--help) HELP=true ; shift ;; + --new-env) NEW_ENV=true ; shift ;; + --torch) TORCH=true ; shift ;; + --basic) BASIC=true ; shift ;; + --train) TRAIN=true ; shift ;; + --all) ALL=true ; shift ;; + --xformers) XFORMERS=true ; shift ;; + --flash-attn) FLASHATTN=true ; shift ;; + --diffoctreerast) DIFFOCTREERAST=true ; shift ;; + --vox2seq) VOX2SEQ=true ; shift ;; + --spconv) SPCONV=true ; shift ;; + --mipgaussian) MIPGAUSSIAN=true ; shift ;; + --kaolin) KAOLIN=true ; shift ;; + --nvdiffrast) NVDIFFRAST=true ; shift ;; + --demo) DEMO=true ; shift ;; + --) shift ; break ;; + *) ERROR=true ; break ;; + esac +done + +if [ "$ERROR" = true ] ; then + echo "Error: Invalid argument" + HELP=true +fi + +if [ "$ALL" = true ] ; then + BASIC=true + XFORMERS=true + FLASHATTN=true + DIFFOCTREERAST=true + SPCONV=true + MIPGAUSSIAN=true + KAOLIN=true + NVDIFFRAST=true +fi + +if [ "$HELP" = true ] ; then + echo "Usage: . ./setup.sh [OPTIONS]" + echo "Options:" + echo " -h, --help Display this help message" + echo " --new-env Create a new conda environment (if available) and install PyTorch" + echo " --torch Install PyTorch into the current environment (via pip)" + echo " --basic Install basic pip dependencies" + echo " --train Install training dependencies" + echo " --all Install all dependencies (basic, xformers, flash-attn," + echo " diffoctreerast, spconv, mipgaussian, kaolin, nvdiffrast)" + echo " --xformers Install xformers" + echo " --flash-attn Install flash-attn" + echo " --diffoctreerast Install diffoctreerast" + echo " --vox2seq Install vox2seq" + echo " --spconv Install spconv" + echo " --mipgaussian Install mip-splatting" + echo " --kaolin Install kaolin" + echo " --nvdiffrast Install nvdiffrast" + echo " --demo Install all dependencies for demo" + return +fi + +if [ "$NEW_ENV" = true ] ; then + if command -v conda &>/dev/null ; then + conda create -n anigen python=3.10 -y + conda activate anigen + else + echo "[WARN] conda not found, skipping environment creation. Using current Python environment." + fi + TORCH=true +fi + +if [ "$TORCH" = true ] ; then + pip install torch==2.4.0 torchvision==0.19.0 --index-url https://download.pytorch.org/whl/cu118 +fi + +# Check which flags require PyTorch +NEEDS_TORCH=false +for flag in "$XFORMERS" "$FLASHATTN" "$DIFFOCTREERAST" "$VOX2SEQ" "$SPCONV" "$MIPGAUSSIAN" "$KAOLIN" "$NVDIFFRAST" "$TRAIN" ; do + if [ "$flag" = true ] ; then + NEEDS_TORCH=true + break + fi +done + +# Get system information +WORKDIR=$(pwd) +if python -c "import torch" 2>/dev/null ; then + PYTORCH_VERSION_RAW=$(python -c "import torch; print(torch.__version__)") + PYTORCH_VERSION=$(echo $PYTORCH_VERSION_RAW | sed 's/+.*//') + PLATFORM=$(python -c "import torch; print(('cuda' if torch.version.cuda else ('hip' if torch.version.hip else 'unknown')) if torch.cuda.is_available() else 'cpu')") +elif [ "$NEEDS_TORCH" = true ] ; then + echo "[ERROR] PyTorch is not installed. Please either:" + echo " - Use --new-env to create a new conda environment with PyTorch, or" + echo " - Use --torch to install PyTorch into the current environment, or" + echo " - Install PyTorch manually before running this script." + return 1 +else + PYTORCH_VERSION="" + PLATFORM="" +fi +case $PLATFORM in + cuda) + CUDA_VERSION=$(python -c "import torch; print(torch.version.cuda)") + CUDA_MAJOR_VERSION=$(echo $CUDA_VERSION | cut -d'.' -f1) + CUDA_MINOR_VERSION=$(echo $CUDA_VERSION | cut -d'.' -f2) + echo "[SYSTEM] PyTorch Version: $PYTORCH_VERSION, CUDA Version: $CUDA_VERSION" + ;; + hip) + HIP_VERSION=$(python -c "import torch; print(torch.version.hip)") + HIP_MAJOR_VERSION=$(echo $HIP_VERSION | cut -d'.' -f1) + HIP_MINOR_VERSION=$(echo $HIP_VERSION | cut -d'.' -f2) + # Install pytorch 2.4.1 for hip + if [ "$PYTORCH_VERSION" != "2.4.1+rocm6.1" ] ; then + echo "[SYSTEM] Installing PyTorch 2.4.1 for HIP ($PYTORCH_VERSION -> 2.4.1+rocm6.1)" + pip install torch==2.4.1 torchvision==0.19.1 --index-url https://download.pytorch.org/whl/rocm6.1 --user + mkdir -p /tmp/extensions + sudo cp /opt/rocm/share/amd_smi /tmp/extensions/amd_smi -r + cd /tmp/extensions/amd_smi + sudo chmod -R 777 . + pip install . + cd $WORKDIR + PYTORCH_VERSION=$(python -c "import torch; print(torch.__version__)") + fi + echo "[SYSTEM] PyTorch Version: $PYTORCH_VERSION, HIP Version: $HIP_VERSION" + ;; + *) + ;; +esac + +if [ "$BASIC" = true ] ; then + pip install pillow imageio imageio-ffmpeg tqdm easydict opencv-python-headless scipy ninja rembg onnxruntime trimesh rtree open3d xatlas pyvista pymeshfix igraph transformers pygltflib psutil + pip install git+https://github.com/EasternJournalist/utils3d.git@9a4eb15e4021b67b12c460c7057d642626897ec8 + pip install "git+https://github.com/facebookresearch/pytorch3d.git" --no-build-isolation + pip install geffnet + pip install extensions/CUBVH --no-build-isolation + pip install gradio==4.44.1 gradio_litmodel3d==0.0.1 +fi + +if [ "$TRAIN" = true ] ; then + pip install tensorboard pandas lpips + pip uninstall -y pillow + sudo apt install -y libjpeg-dev + pip install pillow-simd +fi + +if [ "$XFORMERS" = true ] ; then + # install xformers + if [ "$PLATFORM" = "cuda" ] ; then + if [ "$CUDA_VERSION" = "11.8" ] ; then + case $PYTORCH_VERSION in + 2.0.1) pip install https://files.pythonhosted.org/packages/52/ca/82aeee5dcc24a3429ff5de65cc58ae9695f90f49fbba71755e7fab69a706/xformers-0.0.22-cp310-cp310-manylinux2014_x86_64.whl ;; + 2.1.0) pip install xformers==0.0.22.post7 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.1.1) pip install xformers==0.0.23 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.1.2) pip install xformers==0.0.23.post1 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.2.0) pip install xformers==0.0.24 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.2.1) pip install xformers==0.0.25 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.2.2) pip install xformers==0.0.25.post1 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.3.0) pip install xformers==0.0.26.post1 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.4.0) pip install xformers==0.0.27.post2 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.4.1) pip install xformers==0.0.28 --index-url https://download.pytorch.org/whl/cu118 ;; + 2.5.0) pip install xformers==0.0.28.post2 --index-url https://download.pytorch.org/whl/cu118 ;; + *) echo "[XFORMERS] Unsupported PyTorch & CUDA version: $PYTORCH_VERSION & $CUDA_VERSION" ;; + esac + elif [ "$CUDA_VERSION" = "12.1" ] ; then + case $PYTORCH_VERSION in + 2.1.0) pip install xformers==0.0.22.post7 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.1.1) pip install xformers==0.0.23 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.1.2) pip install xformers==0.0.23.post1 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.2.0) pip install xformers==0.0.24 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.2.1) pip install xformers==0.0.25 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.2.2) pip install xformers==0.0.25.post1 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.3.0) pip install xformers==0.0.26.post1 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.4.0) pip install xformers==0.0.27.post2 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.4.1) pip install xformers==0.0.28 --index-url https://download.pytorch.org/whl/cu121 ;; + 2.5.0) pip install xformers==0.0.28.post2 --index-url https://download.pytorch.org/whl/cu121 ;; + *) echo "[XFORMERS] Unsupported PyTorch & CUDA version: $PYTORCH_VERSION & $CUDA_VERSION" ;; + esac + elif [ "$CUDA_VERSION" = "12.4" ] ; then + case $PYTORCH_VERSION in + 2.5.0) pip install xformers==0.0.28.post2 --index-url https://download.pytorch.org/whl/cu124 ;; + *) echo "[XFORMERS] Unsupported PyTorch & CUDA version: $PYTORCH_VERSION & $CUDA_VERSION" ;; + esac + else + echo "[XFORMERS] Unsupported CUDA version: $CUDA_MAJOR_VERSION" + fi + elif [ "$PLATFORM" = "hip" ] ; then + case $PYTORCH_VERSION in + 2.4.1\+rocm6.1) pip install xformers==0.0.28 --index-url https://download.pytorch.org/whl/rocm6.1 ;; + *) echo "[XFORMERS] Unsupported PyTorch version: $PYTORCH_VERSION" ;; + esac + else + echo "[XFORMERS] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$FLASHATTN" = true ] ; then + if [ "$PLATFORM" = "cuda" ] ; then + pip install flash-attn --no-build-isolation + elif [ "$PLATFORM" = "hip" ] ; then + echo "[FLASHATTN] Prebuilt binaries not found. Building from source..." + mkdir -p /tmp/extensions + if [ ! -d /tmp/extensions/flash-attention ] ; then + git clone --recursive https://github.com/ROCm/flash-attention.git /tmp/extensions/flash-attention + fi + cd /tmp/extensions/flash-attention + git checkout tags/v2.6.3-cktile + GPU_ARCHS=gfx942 python setup.py install #MI300 series + cd $WORKDIR + else + echo "[FLASHATTN] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$KAOLIN" = true ] ; then + # install kaolin + if [ "$PLATFORM" = "cuda" ] ; then + case $PYTORCH_VERSION in + 2.0.1) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.0.1_cu118.html;; + 2.1.0) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.1.0_cu118.html;; + 2.1.1) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.1.1_cu118.html;; + 2.2.0) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.2.0_cu118.html;; + 2.2.1) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.2.1_cu118.html;; + 2.2.2) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.2.2_cu118.html;; + 2.4.0) pip install kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.4.0_cu121.html;; + *) echo "[KAOLIN] Unsupported PyTorch version: $PYTORCH_VERSION" ;; + esac + else + echo "[KAOLIN] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$NVDIFFRAST" = true ] ; then + if [ "$PLATFORM" = "cuda" ] ; then + mkdir -p /tmp/extensions + if [ ! -d /tmp/extensions/nvdiffrast ] ; then + git clone https://github.com/NVlabs/nvdiffrast.git /tmp/extensions/nvdiffrast + fi + pip install /tmp/extensions/nvdiffrast --no-build-isolation + else + echo "[NVDIFFRAST] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$DIFFOCTREERAST" = true ] ; then + if [ "$PLATFORM" = "cuda" ] ; then + mkdir -p /tmp/extensions + if [ ! -d /tmp/extensions/diffoctreerast ] ; then + git clone --recurse-submodules https://github.com/JeffreyXiang/diffoctreerast.git /tmp/extensions/diffoctreerast + fi + pip install /tmp/extensions/diffoctreerast --no-build-isolation + else + echo "[DIFFOCTREERAST] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$MIPGAUSSIAN" = true ] ; then + if [ "$PLATFORM" = "cuda" ] ; then + mkdir -p /tmp/extensions + if [ ! -d /tmp/extensions/mip-splatting ] ; then + git clone https://github.com/autonomousvision/mip-splatting.git /tmp/extensions/mip-splatting + fi + pip install /tmp/extensions/mip-splatting/submodules/diff-gaussian-rasterization/ --no-build-isolation + else + echo "[MIPGAUSSIAN] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$VOX2SEQ" = true ] ; then + if [ "$PLATFORM" = "cuda" ] ; then + mkdir -p /tmp/extensions + if [ ! -d /tmp/extensions/vox2seq ] ; then + cp -r extensions/vox2seq /tmp/extensions/vox2seq + fi + pip install /tmp/extensions/vox2seq --no-build-isolation + else + echo "[VOX2SEQ] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$SPCONV" = true ] ; then + # install spconv + if [ "$PLATFORM" = "cuda" ] ; then + case $CUDA_MAJOR_VERSION in + 11) pip install spconv-cu118 ;; + 12) pip install spconv-cu120 ;; + *) echo "[SPCONV] Unsupported PyTorch CUDA version: $CUDA_MAJOR_VERSION" ;; + esac + else + echo "[SPCONV] Unsupported platform: $PLATFORM" + fi +fi + +if [ "$DEMO" = true ] ; then + pip install gradio==4.44.1 gradio_litmodel3d==0.0.1 "huggingface_hub<0.25" + # Patch gradio_client bug: get_type() crashes on boolean schemas (github.com/gradio-app/gradio/issues/11084) + python << 'PATCH_EOF' +import re +from pathlib import Path +import gradio_client.utils as m +p = Path(m.__file__) +t = p.read_text() +if 'isinstance(schema, bool)' not in t: + t = re.sub( + r'(def get_type\(schema[^)]*\):)\n(\s+)(if "const" in schema:)', + r'\1\n\2if isinstance(schema, bool):\n\2 return "boolean"\n\2\3', + t, count=1 + ) + p.write_text(t) + print('[DEMO] Patched gradio_client for bool schema compatibility') +else: + print('[DEMO] gradio_client already patched') +PATCH_EOF +fi diff --git a/third_parties/dsine/README.md b/third_parties/dsine/README.md new file mode 100644 index 0000000000000000000000000000000000000000..58d84b70f9ad287ddcd9c0157b002ee646944458 --- /dev/null +++ b/third_parties/dsine/README.md @@ -0,0 +1,269 @@ + +# Rethinking Inductive Biases for Surface Normal Estimation + +

+ +

+ +Official implementation of the paper + +> **Rethinking Inductive Biases for Surface Normal Estimation** \ +> CVPR 2024 [oral] \ +> Gwangbin Bae and Andrew J. Davison \ +> [paper.pdf] +[arXiv] +[youtube] +[project page] + +## Abstract + +Despite the growing demand for accurate surface normal estimation models, existing methods use general-purpose dense prediction models, adopting the same inductive biases as other tasks. In this paper, we discuss the **inductive biases** needed for surface normal estimation and propose to **(1) utilize the per-pixel ray direction** and **(2) encode the relationship between neighboring surface normals by learning their relative rotation**. The proposed method can generate **crisp โ€” yet, piecewise smooth โ€” predictions** for challenging in-the-wild images of arbitrary resolution and aspect ratio. Compared to a recent ViT-based state-of-the-art model, our method shows a stronger generalization ability, despite being trained on an orders of magnitude smaller dataset. + +

+ +

+ +## Getting started + +We provide the instructions in **four steps** (click "โ–ธ" to expand). For example, if you just want to test DSINE on some images, you can stop after **Step 1**. This would minimize the amount of installation/downloading. + +
+Step 1. Test DSINE on some images (requires minimal dependencies) + +Start by installing dependencies. + +``` +conda create --name DSINE python=3.10 +conda activate DSINE + +conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia +python -m pip install geffnet +``` + +Then, download the model weights from this link and save it under `projects/dsine/checkpoints/`. Note that it should maintain the same folder structure as the google drive. For example, `checkpoints/exp001_cvpr2024/dsine.pt` (in google drive) is our best model. It should be saved as `projects/dsine/checkpoints/exp001_cvpr2024/dsine.pt`. The corresponding config file is `projects/dsine/experiments/exp001_cvpr2024/dsine.txt`. + +The models under `checkpoints/exp002_kappa/` (in google drive) are the ones that can also estimate uncertainty. + +Then, move to the folder `projects/dsine/`, and run + +``` +python test_minimal.py ./experiments/exp001_cvpr2024/dsine.txt +``` + +This will generate predictions for the images under `projects/dsine/samples/img/`. The result will be saved under `projects/dsine/samples/output/`. + +Our model assumes known camera intrinsics, but providing approximate intrinsics still gives good results. For some images in `projects/dsine/samples/img/`, the corresponding camera intrinsics (fx, fy, cx, cy - assuming perspective camera with no distortion) is provided as a `.txt` file. If such a file does not exist, the intrinsics will be approximated, by assuming $60^\circ$ field-of-view. +
+ + +
+Step 2. Test DSINE on benchmark datasets & run a real-time demo + +Install additional dependencies. + +``` +python -m pip install tensorboard +python -m pip install opencv-python +python -m pip install matplotlib + +python -m pip install pyrealsense2 # needed only for demo using a realsense camera +python -m pip install vidgear # needed only for demo on YouTube videos +python -m pip install yt_dlp # needed only for demo on YouTube videos +python -m pip install mss # needed only for demo on screen capture +``` + +Download the evaluation datasets (`dsine_eval.zip`) from this link. + +**NOTE:** By downloading the dataset, you are agreeing to the respective LICENSE of each dataset. The link to the dataset can be found in the respective `readme.txt`. + +If you go to `projects/__init__.py`, there is a variable called `DATASET_DIR` and `EXPERIMENT_DIR`: + +* `DATASET_DIR` is where your dataset should be stored. For example, the `dsine_eval` dataset (downloaded from the link above) should be saved under `DATASET_DIR/dsine_eval`. Update this variable. +* `EXPERIMENT_DIR` is where the experiments (e.g. model weights, log, etc) will be saved. Update this variable. + +Then, move to the folder `projects/dsine/`, and run: + +```python +# getting benchmark performance on the six evaluation datasets +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode benchmark + +# getting benchmark performance on the six evaluation datasets (with visualization) +# it will be saved under EXPERIMENT_DIR/dsine/exp001_cvpr2024/dsine/test/ +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode benchmark --visualize + +# generate predictions for the images in `projects/dsine/samples/img/ +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode samples + +# measure the throughput (inference speed) on your device +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode throughput +``` + +You can also run a real-time demo by running: + +```python +# captures your screen and makes prediction +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode screen + +# demo using webcam +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode webcam + +# demo using a realsense camera +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode rs + +# demo on a Youtube video (replace with a different link) +python test.py ./experiments/exp001_cvpr2024/dsine.txt --mode https://www.youtube.com/watch?v=X-iEq8hWd6k +``` + +For each input option, there are some additional parameters. See `projects/dsine/test.py` for more information. + +You can also try building your own real-time demo. Please see [this notebook](https://github.com/baegwangbin/DSINE/blob/main/notes/real_time_demo.ipynb) for more information. +
+ + +
+Step 3. Train DSINE + +In `projects/dsine/`, run: + +```python +python train.py ./experiments/exp000_test/test.txt +``` + +And do `tensorboard --logdir EXPERIMENT_DIR/dsine/exp000_test/test/log` to open the tensorboard. + +This will train the model on the train split of the NYUv2 dataset, which should be under `DATASET_DIR/dsine_eval/nyuv2/train/`. There are only 795 images here, and the performance will not be good. To get better results you need to: + +**(1) Create a custom dataloader** + +>We are checking if we can release the entire training dataset (~400GB). Before the release, you can try building your custom dataloader. You need to define a `get_sample(args, sample_path, info)` function and provide a data split in `data/datasets`. Check how they are defined/provided for other datasets. You also need to update `projects/baseline_normal/dataloader.py` so the newly defined `get_sample` function can be used. + +**(2) Generate GT surface normals** (optional) + +>In case your dataset does not come with ground truth surface normal maps, you can try generating them from the ground truth depth maps. Please see [this notebook](https://github.com/baegwangbin/DSINE/blob/main/notes/depth_to_normal.ipynb) for more information. + +**(3) Customize data augmentation** + +>In case you are using synthetic images, you need the right set of data augmentation functions to minimize the synthetic-to-real domain gap. We provide a wide range of augmentation functions, but the hyperparameters are not finetuned and you can potentially get better results by finetuning them. Please see [this notebook](https://github.com/baegwangbin/DSINE/blob/main/notes/visualize_augmentation.ipynb) for more information. + +
+ + +
+Step 4. Start your own surface normal estimation project + +If you want to start your own surface normal estimation project, you can do so very easily. + +First of all, have a look at `projects/baseline_normal`. This is a place where you can try different CNN architectures without worrying about the camera intrinsics and rotation estimation. You can try popular architectures like U-Net, and try different backbones. In this folder, you can run: + +```python +python train.py ./experiments/exp000_test/test.txt +``` + +The project-specific `config` is defined in `projects/baseline_normal/config.py`. Default config, which is shared across all projects are in `projects/__init__.py`. + +The dataloaders are in `projects/baseline_normal/dataloader.py`. We use the same dataloaders in `dsine` project, so we don't have `projects/dsine/dataloader.py`. + +The losses are defined in `projects/baseline_normal/losses.py`. These are building blocks for your custom loss functions in your own project. For example, in the DSINE project, we produce a list of predictions and the loss is the weighted sum of the losses computed for each prediction. You can see how this is done in `projects/dsine/losses.py`. + +You can start a new project by copying the folder `projects/dsine` to create `projects/NEW_PROJECT_NAME`. Then, update the `config.py` and `losses.py`. + +Lastly, you can should `train.py` and `test.py`. For things that should be different in different projects, we made a note like following: + +```python +#โ†“โ†“โ†“โ†“ +#NOTE: forward pass +img = data_dict['img'].to(device) +intrins = data_dict['intrins'].to(device) +... +pred_list = model(img, intrins=intrins, mode='test') +norm_out = pred_list[-1] +#โ†‘โ†‘โ†‘โ†‘ +``` + +Search for the arrows (โ†“โ†“โ†“โ†“/โ†‘โ†‘โ†‘โ†‘) to see where things should be modified in different projects. + +The test commands above (e.g. for getting the benchmark performance & running real-time demo) should apply the same for all projects. +
+ +## Additional instructions + +If you want to make contributions to this repo, please make a pull request and add instructions in the following format. + +
+Using torch hub to predict normal (contribution by hugoycj) + +NOTE: the code below is deprecated and should be modified (as the folder structure has changed). + +``` +import torch +import cv2 +import numpy as np + +# Load the normal predictor model from torch hub +normal_predictor = torch.hub.load("hugoycj/DSINE-hub", "DSINE", trust_repo=True) + +# Load the input image using OpenCV +image = cv2.imread(args.input, cv2.IMREAD_COLOR) +h, w = image.shape[:2] + +# Use the model to infer the normal map from the input image +with torch.inference_mode(): + normal = normal_predictor.infer_cv2(image)[0] # Output shape: (H, W, 3) + normal = (normal + 1) / 2 # Convert values to the range [0, 1] + +# Convert the normal map to a displayable format +normal = (normal * 255).cpu().numpy().astype(np.uint8).transpose(1, 2, 0) +normal = cv2.cvtColor(normal, cv2.COLOR_RGB2BGR) + +# Save the output normal map to a file +cv2.imwrite(args.output, normal) +``` + +If the network is unavailable to retrieve weights, you can use local weights for torch hub as shown below: + +``` +normal_predictor = torch.hub.load("hugoycj/DSINE-hub", "DSINE", local_file_path='./checkpoints/dsine.pt', trust_repo=True) +``` +
+ + +
+Generating ground truth surface normals +We provide the code used to generate the ground truth surface normals from ground truth depth maps. See this notebook for more information. +
+ + +
+About the coordinate system +We use the right-handed coordinate system with (X, Y, Z) = (right, down, front). An important thing to note is that both the ground truth normals and our prediction are the outward normals. For example, in the case of a fronto-parallel wall facing the camera, the normals would be (0, 0, 1), not (0, 0, -1). If you instead need to use the inward normals, please do normals = -normals. +
+ + +
+Sharing your model weights +If you wish to share your model weights, please make a pull request by providing the corresponding config file and the link to the weights. +
+ +## Citation + +If you find our work useful in your research please consider citing our paper: + +``` +@inproceedings{bae2024dsine, + title = {Rethinking Inductive Biases for Surface Normal Estimation}, + author = {Gwangbin Bae and Andrew J. Davison}, + booktitle = {IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)}, + year = {2024} +} +``` + +If you use the models that also estimate the uncertainty, please also cite the following paper, where we introduced the loss function: + +``` +@InProceedings{bae2021eesnu, + title = {Estimating and Exploiting the Aleatoric Uncertainty in Surface Normal Estimation} + author = {Gwangbin Bae and Ignas Budvytis and Roberto Cipolla}, + booktitle = {International Conference on Computer Vision (ICCV)}, + year = {2021} +} +``` diff --git a/third_parties/dsine/__init__.py b/third_parties/dsine/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/third_parties/dsine/config.py b/third_parties/dsine/config.py new file mode 100644 index 0000000000000000000000000000000000000000..4a9a37509ffbe8d883ecd1d146d2126f54bfe835 --- /dev/null +++ b/third_parties/dsine/config.py @@ -0,0 +1,85 @@ +import os +import sys +import glob +from datetime import datetime + +from projects import DATASET_DIR, EXPERIMENT_DIR, get_default_parser +import utils.utils as utils + +import logging +logger = logging.getLogger('root') + + +def get_args(test=False): + parser = get_default_parser() + + #โ†“โ†“โ†“โ†“ + #NOTE: project-specific args + parser.add_argument('--NNET_architecture', type=str, default='v02') + parser.add_argument('--NNET_output_dim', type=int, default=3, help='{3, 4}') + parser.add_argument('--NNET_output_type', type=str, default='R', help='{R, G}') + parser.add_argument('--NNET_feature_dim', type=int, default=64) + parser.add_argument('--NNET_hidden_dim', type=int, default=64) + + parser.add_argument('--NNET_encoder_B', type=int, default=5) + + parser.add_argument('--NNET_decoder_NF', type=int, default=2048) + parser.add_argument('--NNET_decoder_BN', default=False, action="store_true") + parser.add_argument('--NNET_decoder_down', type=int, default=8) + parser.add_argument('--NNET_learned_upsampling', default=False, action="store_true") + + parser.add_argument('--NRN_prop_ps', type=int, default=5) + parser.add_argument('--NRN_num_iter_train', type=int, default=5) + parser.add_argument('--NRN_num_iter_test', type=int, default=5) + parser.add_argument('--NRN_ray_relu', default=False, action="store_true") + + parser.add_argument('--loss_fn', type=str, default='AL') + parser.add_argument('--loss_gamma', type=float, default=0.8) + #โ†‘โ†‘โ†‘โ†‘ + + # read arguments from txt file + assert '.txt' in sys.argv[1] + arg_filename_with_prefix = '@' + sys.argv[1] + args = parser.parse_args([arg_filename_with_prefix] + sys.argv[2:]) + + #โ†“โ†“โ†“โ†“ + #NOTE: update args + args.exp_root = os.path.join(EXPERIMENT_DIR, 'dsine') + args.load_normal = True + args.load_intrins = True + #โ†‘โ†‘โ†‘โ†‘ + + # set working dir + exp_dir = os.path.join(args.exp_root, args.exp_name) + os.makedirs(exp_dir, exist_ok=True) + + args.output_dir = os.path.join(exp_dir, args.exp_id) + os.makedirs(args.output_dir, exist_ok=True) + os.makedirs(os.path.join(args.output_dir, 'log'), exist_ok=True) # save log + os.makedirs(os.path.join(args.output_dir, 'models'), exist_ok=True) # save models + os.makedirs(os.path.join(args.output_dir, 'test'), exist_ok=True) # save test images + + if not test and \ + not args.overwrite_models and \ + len(glob.glob(os.path.join(args.output_dir, 'models', '*.pt'))) > 0: + print('checkpoints exist!') + exit() + + # training + if not test: + global logger + utils.change_logger_dest(logger, os.path.join(args.output_dir, 'log', '%s.log' % datetime.now())) + from torch.utils.tensorboard.writer import SummaryWriter + args.writer = SummaryWriter(log_dir=os.path.join(args.output_dir, 'log')) + + # save args + args_path = os.path.join(args.output_dir, 'log', 'params.txt') + utils.save_args(args, args_path) + logger.info('config saved in %s' % args_path) + + # log + logger.info('DATASET_DIR: %s' % DATASET_DIR) + logger.info('EXPERIMENT_DIR: %s' % args.output_dir) + + return args + diff --git a/third_parties/dsine/experiments/exp000_test/test.txt b/third_parties/dsine/experiments/exp000_test/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..783cc4892636e14685bae539dacc37f3858ec5c0 --- /dev/null +++ b/third_parties/dsine/experiments/exp000_test/test.txt @@ -0,0 +1,37 @@ +--exp_name exp000_test +--exp_id test + +--NNET_architecture v02 +--NNET_encoder_B 5 +--NNET_decoder_NF 2048 +--NNET_decoder_down 8 +--NNET_learned_upsampling + +--NRN_prop_ps 5 +--NRN_num_iter_train 5 +--NRN_num_iter_test 5 +--NRN_ray_relu + +--data_augmentation_intrins +--input_height 0 +--input_width 0 +--data_augmentation_hflip +--data_augmentation_appear 2 + +--diff_lr +--loss_fn AL + +--num_epochs 5 +--batch_size 4 +--workers 32 +--accumulate_grad_batches 4 + +--gpus 0 + +--dataset_name_train nyuv2 +--dataset_name_val nyuv2 +--train_split train +--val_split test + +--validate_every 1000 +--visualize_every 1000 diff --git a/third_parties/dsine/experiments/exp001_cvpr2024/dsine.txt b/third_parties/dsine/experiments/exp001_cvpr2024/dsine.txt new file mode 100644 index 0000000000000000000000000000000000000000..93554fc547658079529df8c855331e1f40afe50e --- /dev/null +++ b/third_parties/dsine/experiments/exp001_cvpr2024/dsine.txt @@ -0,0 +1,34 @@ +--exp_name exp001_cvpr2024 +--exp_id dsine + +--NNET_architecture v02 +--NNET_encoder_B 5 +--NNET_decoder_NF 2048 +--NNET_decoder_down 8 +--NNET_learned_upsampling + +--NRN_prop_ps 5 +--NRN_num_iter_train 5 +--NRN_num_iter_test 5 +--NRN_ray_relu + +--data_augmentation_intrins +--input_height 0 +--input_width 0 +--data_augmentation_hflip +--data_augmentation_appear 2 + +--diff_lr +--loss_fn AL + +--num_epochs 5 +--batch_size 4 +--workers 32 +--accumulate_grad_batches 4 + +--gpus 0 + +--validate_every 20000 +--visualize_every 10000 + +--ckpt_path ./checkpoints/exp001_cvpr2024/dsine.pt \ No newline at end of file diff --git a/third_parties/dsine/experiments/exp002_kappa/dsine.txt b/third_parties/dsine/experiments/exp002_kappa/dsine.txt new file mode 100644 index 0000000000000000000000000000000000000000..89b08b962916306b5b406ca76a16f71240b15d19 --- /dev/null +++ b/third_parties/dsine/experiments/exp002_kappa/dsine.txt @@ -0,0 +1,37 @@ +--exp_name exp002_kappa +--exp_id dsine + +--NNET_architecture v02_kappa +--NNET_encoder_B 5 +--NNET_decoder_NF 2048 +--NNET_decoder_down 8 +--NNET_learned_upsampling + +--NNET_output_dim 4 +--NNET_output_type G + +--NRN_prop_ps 5 +--NRN_num_iter_train 5 +--NRN_num_iter_test 5 +--NRN_ray_relu + +--data_augmentation_intrins +--input_height 0 +--input_width 0 +--data_augmentation_hflip +--data_augmentation_appear 2 + +--diff_lr +--loss_fn NLL_angmf + +--num_epochs 5 +--batch_size 4 +--workers 32 +--accumulate_grad_batches 4 + +--gpus 0 + +--validate_every 20000 +--visualize_every 10000 + +--ckpt_path ./checkpoints/exp002_kappa/dsine.pt \ No newline at end of file diff --git a/third_parties/dsine/experiments/exp002_kappa/dsine_plus_scannet.txt b/third_parties/dsine/experiments/exp002_kappa/dsine_plus_scannet.txt new file mode 100644 index 0000000000000000000000000000000000000000..fb513ebddf55277852e8e65782f80676d3e9dcdc --- /dev/null +++ b/third_parties/dsine/experiments/exp002_kappa/dsine_plus_scannet.txt @@ -0,0 +1,37 @@ +--exp_name exp002_kappa +--exp_id dsine_plus_scannet + +--NNET_architecture v02_kappa +--NNET_encoder_B 5 +--NNET_decoder_NF 2048 +--NNET_decoder_down 8 +--NNET_learned_upsampling + +--NNET_output_dim 4 +--NNET_output_type G + +--NRN_prop_ps 5 +--NRN_num_iter_train 5 +--NRN_num_iter_test 5 +--NRN_ray_relu + +--data_augmentation_intrins +--input_height 0 +--input_width 0 +--data_augmentation_hflip +--data_augmentation_appear 2 + +--diff_lr +--loss_fn NLL_angmf + +--num_epochs 5 +--batch_size 4 +--workers 32 +--accumulate_grad_batches 4 + +--gpus 0 + +--validate_every 20000 +--visualize_every 10000 + +--ckpt_path ./checkpoints/exp002_kappa/dsine_plus_scannet.pt \ No newline at end of file diff --git a/third_parties/dsine/experiments/exp002_kappa/scannet.txt b/third_parties/dsine/experiments/exp002_kappa/scannet.txt new file mode 100644 index 0000000000000000000000000000000000000000..93e94f185ad3d2462d60b68dcfc2212cfa6a9905 --- /dev/null +++ b/third_parties/dsine/experiments/exp002_kappa/scannet.txt @@ -0,0 +1,37 @@ +--exp_name exp002_kappa +--exp_id scannet + +--NNET_architecture v02_kappa +--NNET_encoder_B 5 +--NNET_decoder_NF 2048 +--NNET_decoder_down 8 +--NNET_learned_upsampling + +--NNET_output_dim 4 +--NNET_output_type G + +--NRN_prop_ps 5 +--NRN_num_iter_train 5 +--NRN_num_iter_test 5 +--NRN_ray_relu + +--data_augmentation_intrins +--input_height 0 +--input_width 0 +--data_augmentation_hflip +--data_augmentation_appear 2 + +--diff_lr +--loss_fn NLL_angmf + +--num_epochs 5 +--batch_size 4 +--workers 32 +--accumulate_grad_batches 4 + +--gpus 0 + +--validate_every 20000 +--visualize_every 10000 + +--ckpt_path ./checkpoints/exp002_kappa/scannet.pt \ No newline at end of file diff --git a/third_parties/dsine/losses.py b/third_parties/dsine/losses.py new file mode 100644 index 0000000000000000000000000000000000000000..e8257cd9f4ce19b4b740416f507a6fa6d7d60865 --- /dev/null +++ b/third_parties/dsine/losses.py @@ -0,0 +1,36 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +import logging +logger = logging.getLogger('root') + +from projects.baseline_normal.losses import define_loss + + +# compute loss for DSINE experiments +class ComputeLoss(nn.Module): + def __init__(self, args): + """ args.loss_fn can be one of following: + - L1 - L1 loss (no uncertainty) + - L2 - L2 loss (no uncertainty) + - AL - Angular loss (no uncertainty) + - NLL_vonmf - NLL of vonMF distribution + - NLL_angmf - NLL of Angular vonMF distribution (from "Estimating and Exploiting the Aleatoric Uncertainty in Surface Normal Estimation", ICCV 2021) + """ + super(ComputeLoss, self).__init__() + logger.info('Loss: %s / gamma: %s' % (args.loss_fn, args.loss_gamma)) + + # define pixel-wise loss fn + self.loss_name = loss_name = args.loss_fn + self.loss_fn = define_loss(loss_name) + self.gamma = args.loss_gamma + + def forward(self, pred_list, gt_norm, gt_norm_mask): + n_predictions = len(pred_list) + loss = 0.0 + for i in range(n_predictions): + i_weight = self.gamma ** (n_predictions - i - 1) + norm_out = pred_list[i] + loss = loss + i_weight * self.loss_fn(norm_out, gt_norm, gt_norm_mask) + return loss diff --git a/third_parties/dsine/models/conv_encoder_decoder/__init__.py b/third_parties/dsine/models/conv_encoder_decoder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9cefc4eb4e36ad96dac5fd6aaf50c65a83029fc --- /dev/null +++ b/third_parties/dsine/models/conv_encoder_decoder/__init__.py @@ -0,0 +1,53 @@ +""" Set of convolutional encoder-decoder architectures + Activation should be defined in accordance with the task +""" +import torch +import torch.nn as nn +import torch.nn.functional as F + +import logging +logger = logging.getLogger('root') + + +class ConvEncoderDecoder(nn.Module): + def __init__(self, architecture, output_dim, **kwargs): + super(ConvEncoderDecoder, self).__init__() + logger.info('Model - defining a convolutional encoder decoder ...') + logger.info('Model - architecture: %s' % architecture) + logger.info('Model - output_dim: %s' % output_dim) + + if architecture == 'UNet': + from .unet import UNet + self.model = UNet(n_classes=output_dim) + + # models from segmentation_models_pytorch library + # for example, "smp__Unet__resnet50" uses Unet architecture with resnet50 backbone + elif architecture[:3] == 'smp': + from .seg_models import SegModel + _, architecture, encoder_name = architecture.split('__') + self.model = SegModel(architecture=architecture, + encoder_name=encoder_name, + classes=output_dim) + + # DenseDepth and its variants + # for example, "densedepth__B5__NF2048__down2__bilinear__BN" means: + # - "B5": uses EfficientNet B5 backbone (pretrained) + # - "NF2048": bottleneck num_feature = 2048 + # - "down2": make inference at H/2 X W/2 resolution, then upsample it + # - "bilinear": uses bilinear upsampling (replace with "learned" to use convex upsampling) + # - "BN": uses BatchNorm (replace with "GN" to use GroupNorm) + elif architecture[:10] == 'densedepth': + from .dense_depth import DenseDepth + _, B, NF, down, learned, BN = architecture.split('__') + self.model = DenseDepth(num_classes=output_dim, + B=int(B[1:2]), pretrained=True, + NF=int(NF[2:]), BN=BN=='BN', + down=int(down.split('down')[1]), learned_upsampling=learned=='learned', + **kwargs) + + else: + raise Exception('architecture not implemented') + + + def forward(self, img, **kwargs): + return self.model(img, **kwargs) diff --git a/third_parties/dsine/models/conv_encoder_decoder/dense_depth.py b/third_parties/dsine/models/conv_encoder_decoder/dense_depth.py new file mode 100644 index 0000000000000000000000000000000000000000..25966109fd697ee743bc663de8cbfda7eeabba94 --- /dev/null +++ b/third_parties/dsine/models/conv_encoder_decoder/dense_depth.py @@ -0,0 +1,37 @@ +""" The code below is an adaptation of DenseDepth (https://github.com/ialhashim/DenseDepth) + We replaced the BatchNorm with GroupNorm, + added weight standardization, + added convex upsampling layer, + and allowed the backbone and decoder depth to be changeable +""" +import torch +import torch.nn as nn +import torch.nn.functional as F + +from models.conv_encoder_decoder.submodules import Encoder, Decoder + + +class DenseDepth(nn.Module): + def __init__(self, num_classes, + B=5, pretrained=True, + NF=2048, BN=True, + down=2, learned_upsampling=True, + **kwargs): + super(DenseDepth, self).__init__() + self.encoder = Encoder(B=B, pretrained=pretrained) + self.decoder = Decoder(num_classes=num_classes, + B=B, NF=NF, BN=BN, + down=down, learned_upsampling=learned_upsampling, + **kwargs) + + def forward(self, x, **kwargs): + return self.decoder(self.encoder(x), **kwargs) + + def get_1x_lr_params(self): # lr/10 learning rate + return self.encoder.parameters() + + def get_10x_lr_params(self): # lr learning rate + modules = [self.decoder] + for m in modules: + yield from m.parameters() + diff --git a/third_parties/dsine/models/conv_encoder_decoder/seg_models.py b/third_parties/dsine/models/conv_encoder_decoder/seg_models.py new file mode 100644 index 0000000000000000000000000000000000000000..d4e3a7d2e94ca407654f0f63cea155ca47a7dc89 --- /dev/null +++ b/third_parties/dsine/models/conv_encoder_decoder/seg_models.py @@ -0,0 +1,52 @@ +""" models from the segmentation_models_pytorch library + install the library before using these models +""" +import torch +import torch.nn as nn +import segmentation_models_pytorch as smp + + +class SegModel(nn.Module): + def __init__(self, architecture='Unet', + encoder_name='mobilenet_v2', + encoder_weights='imagenet', + encoder_depth=4, + in_channels=3, + classes=4): + super().__init__() + + """ + architecture = { + Unet, UnetPlusPlus, EfficientUnetPlusPlus, DeepLabV3, DeepLabV3+ + } + encoder_name = { + resnet18 / 11M, resnet34 / 21M, resnet50 / 23M, resnet101 / 42M + densenet121 / 6M, densenet169 / 12M, densenet201 / 18M + efficientnet-b0 / 4M, -b1 / 6M, -b2 / 7M, -b3 / 10M, -b4 / 17M, -b5 / 28M + mobilenet_v2 / 2M + } + encoder_weights = { + "imagenet", None + } + in_channels = 3 + classes = 4 + """ + + if encoder_depth == 4: + decoder_channels = (256, 128, 64, 32) + + exec("""self.model = smp.%s( + encoder_name='%s', + encoder_weights='%s', + encoder_depth=%s, + decoder_channels=%s, + in_channels=%s, + classes=%s, + activation=None, + ) + """ % (architecture, encoder_name, encoder_weights, encoder_depth, decoder_channels, in_channels, classes)) + + + def forward(self, x): + return self.model(x) + diff --git a/third_parties/dsine/models/conv_encoder_decoder/submodules.py b/third_parties/dsine/models/conv_encoder_decoder/submodules.py new file mode 100644 index 0000000000000000000000000000000000000000..8306c4ee9ba82e0fd0817f330e0f93abf54ee806 --- /dev/null +++ b/third_parties/dsine/models/conv_encoder_decoder/submodules.py @@ -0,0 +1,219 @@ +""" submodules +""" +import torch +import torch.nn as nn +import torch.nn.functional as F +import geffnet +import os + +INPUT_CHANNELS_DICT = { + 0: [1280, 112, 40, 24, 16], + 1: [1280, 112, 40, 24, 16], + 2: [1408, 120, 48, 24, 16], + 3: [1536, 136, 48, 32, 24], + 4: [1792, 160, 56, 32, 24], + 5: [2048, 176, 64, 40, 24], + 6: [2304, 200, 72, 40, 32], + 7: [2560, 224, 80, 48, 32] +} + + +class Encoder(nn.Module): + def __init__(self, B=5, pretrained=True): + """ e.g. B=5 will return EfficientNet-B5 + """ + super(Encoder, self).__init__() + basemodel_name = 'tf_efficientnet_b%s_ap' % B + basemodel = geffnet.create_model(basemodel_name, pretrained=False) + if pretrained: + ckpt_path = 'ckpts/dsine/tf_efficientnet_b5_ap-9e82fae8.pth' + if os.path.exists(ckpt_path): + print(f'Loading geffnet from {ckpt_path}') + basemodel.load_state_dict(torch.load(ckpt_path, map_location='cpu')) + else: + print(f'Warning: {ckpt_path} not found. Initializing randomly.') + + # Remove last layer + basemodel.global_pool = nn.Identity() + basemodel.classifier = nn.Identity() + self.original_model = basemodel + + def forward(self, x): + features = [x] + for k, v in self.original_model._modules.items(): + if (k == 'blocks'): + for ki, vi in v._modules.items(): + features.append(vi(features[-1])) + else: + features.append(v(features[-1])) + return features + + +class UpSampleBN(nn.Module): + def __init__(self, skip_input, output_features, align_corners=True): + super(UpSampleBN, self).__init__() + self._net = nn.Sequential(nn.Conv2d(skip_input, output_features, kernel_size=3, stride=1, padding=1), + nn.BatchNorm2d(output_features), + nn.LeakyReLU(), + nn.Conv2d(output_features, output_features, kernel_size=3, stride=1, padding=1), + nn.BatchNorm2d(output_features), + nn.LeakyReLU()) + self.align_corners = align_corners + + def forward(self, x, concat_with): + up_x = F.interpolate(x, size=[concat_with.size(2), concat_with.size(3)], mode='bilinear', align_corners=self.align_corners) + f = torch.cat([up_x, concat_with], dim=1) + return self._net(f) + + +class Conv2d_WS(nn.Conv2d): + """ weight standardization + """ + def __init__(self, in_channels, out_channels, kernel_size, stride=1, + padding=0, dilation=1, groups=1, bias=True): + super(Conv2d_WS, self).__init__(in_channels, out_channels, kernel_size, stride, + padding, dilation, groups, bias) + + def forward(self, x): + weight = self.weight + weight_mean = weight.mean(dim=1, keepdim=True).mean(dim=2, + keepdim=True).mean(dim=3, keepdim=True) + weight = weight - weight_mean + std = weight.view(weight.size(0), -1).std(dim=1).view(-1, 1, 1, 1) + 1e-5 + weight = weight / std.expand_as(weight) + return F.conv2d(x, weight, self.bias, self.stride, self.padding, self.dilation, self.groups) + + +class UpSampleGN(nn.Module): + """ UpSample with GroupNorm + """ + def __init__(self, skip_input, output_features, align_corners=True): + super(UpSampleGN, self).__init__() + self._net = nn.Sequential(Conv2d_WS(skip_input, output_features, kernel_size=3, stride=1, padding=1), + nn.GroupNorm(8, output_features), + nn.LeakyReLU(), + Conv2d_WS(output_features, output_features, kernel_size=3, stride=1, padding=1), + nn.GroupNorm(8, output_features), + nn.LeakyReLU()) + self.align_corners = align_corners + + def forward(self, x, concat_with): + up_x = F.interpolate(x, size=[concat_with.size(2), concat_with.size(3)], mode='bilinear', align_corners=self.align_corners) + f = torch.cat([up_x, concat_with], dim=1) + return self._net(f) + + +def upsample_via_bilinear(out, up_mask, downsample_ratio): + """ bilinear upsampling (up_mask is a dummy variable) + """ + return F.interpolate(out, scale_factor=downsample_ratio, mode='bilinear', align_corners=False) + + +def upsample_via_mask(out, up_mask, downsample_ratio, padding='zero'): + """ convex upsampling + """ + # out: low-resolution output (B, o_dim, H, W) + # up_mask: (B, 9*k*k, H, W) + k = downsample_ratio + + B, C, H, W = out.shape + up_mask = up_mask.view(B, 1, 9, k, k, H, W) + up_mask = torch.softmax(up_mask, dim=2) # (B, 1, 9, k, k, H, W) + + if padding == 'zero': + # with zero padding + up_out = F.unfold(out, [3, 3], padding=1) # (B, 2, H, W) -> (B, 2 X 3*3, H*W) + elif padding == 'replicate': + # with replicate padding + out = F.pad(out, pad=(1,1,1,1), mode='replicate') + up_out = F.unfold(out, [3, 3], padding=0) # (B, C, H, W) -> (B, C X 3*3, H*W) + else: + raise Exception('invalid padding for convex upsampling') + + up_out = up_out.view(B, C, 9, 1, 1, H, W) # (B, C, 9, 1, 1, H, W) + + up_out = torch.sum(up_mask * up_out, dim=2) # (B, C, k, k, H, W) + up_out = up_out.permute(0, 1, 4, 2, 5, 3) # (B, C, H, k, W, k) + return up_out.reshape(B, C, k*H, k*W) # (B, C, kH, kW) + + +def dummy_activation(out): + return out + + +def get_prediction_head(input_dim, hidden_dim, output_dim): + return nn.Sequential( + nn.Conv2d(input_dim, hidden_dim, 3, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(hidden_dim, hidden_dim, 1), + nn.ReLU(inplace=True), + nn.Conv2d(hidden_dim, output_dim, 1), + ) + + +class Decoder(nn.Module): + def __init__(self, num_classes=2, + B=5, NF=2048, BN=True, + down=2, learned_upsampling=True, + activation_fn=dummy_activation): + super(Decoder, self).__init__() + input_channels = INPUT_CHANNELS_DICT[B] + + # use BN or GN + UpSample = UpSampleBN if BN else UpSampleGN + + features = NF + self.conv2 = nn.Conv2d(input_channels[0], features, kernel_size=1, stride=1, padding=0) + self.up1 = UpSample(skip_input=features // 1 + input_channels[1], output_features=features // 2) + self.up2 = UpSample(skip_input=features // 2 + input_channels[2], output_features=features // 4) + + if down == 8: + i_dim = features // 4 + elif down == 4: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3], output_features=features // 8) + i_dim = features // 8 + elif down == 2: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3], output_features=features // 8) + self.up4 = UpSample(skip_input=features // 8 + input_channels[4], output_features=features // 16) + i_dim = features // 16 + else: + raise Exception('invalid downsampling ratio') + + self.downsample_ratio = down + self.output_dim = num_classes + + h_dim = 128 + self.pred_head = get_prediction_head(i_dim, h_dim, num_classes) + + if learned_upsampling: + h_dim = 128 + self.mask_head = get_prediction_head(i_dim, h_dim, 9*self.downsample_ratio*self.downsample_ratio) + self.upsample_fn = upsample_via_mask + else: + self.mask_head = lambda a: None + self.upsample_fn = upsample_via_bilinear + + self.activation_fn = activation_fn + + + def forward(self, features): + x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + + x_d0 = self.conv2(x_block4) + x_d1 = self.up1(x_d0, x_block3) + + if self.downsample_ratio == 8: + x_feat = self.up2(x_d1, x_block2) + elif self.downsample_ratio == 4: + x_d2 = self.up2(x_d1, x_block2) + x_feat = self.up3(x_d2, x_block1) + elif self.downsample_ratio == 2: + x_d2 = self.up2(x_d1, x_block2) + x_d3 = self.up3(x_d2, x_block1) + x_feat = self.up4(x_d3, x_block0) + + out = self.activation_fn(self.pred_head(x_feat)) + mask = self.mask_head(x_feat) + up_out = self.upsample_fn(out, mask, self.downsample_ratio) + return up_out + diff --git a/third_parties/dsine/models/conv_encoder_decoder/unet.py b/third_parties/dsine/models/conv_encoder_decoder/unet.py new file mode 100644 index 0000000000000000000000000000000000000000..0a798c69c155ab9bbaf1ed58a7699eeee6052a91 --- /dev/null +++ b/third_parties/dsine/models/conv_encoder_decoder/unet.py @@ -0,0 +1,113 @@ +""" U-Net from https://github.com/milesial/Pytorch-UNet/blob/master/unet/unet_model.py + See license at https://github.com/milesial/Pytorch-UNet/blob/master/LICENSE +""" +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class DoubleConv(nn.Module): + """(convolution => [BN] => ReLU) * 2""" + + def __init__(self, in_channels, out_channels, mid_channels=None): + super().__init__() + if not mid_channels: + mid_channels = out_channels + self.double_conv = nn.Sequential( + nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(mid_channels), + nn.ReLU(inplace=True), + nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True) + ) + + def forward(self, x): + return self.double_conv(x) + + +class Down(nn.Module): + """Downscaling with maxpool then double conv""" + + def __init__(self, in_channels, out_channels): + super().__init__() + self.maxpool_conv = nn.Sequential( + nn.MaxPool2d(2), + DoubleConv(in_channels, out_channels) + ) + + def forward(self, x): + return self.maxpool_conv(x) + + +class Up(nn.Module): + """Upscaling then double conv""" + + def __init__(self, in_channels, out_channels, bilinear=True): + super().__init__() + + # if bilinear, use the normal convolutions to reduce the number of channels + if bilinear: + self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) + self.conv = DoubleConv(in_channels, out_channels, in_channels // 2) + else: + self.up = nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size=2, stride=2) + self.conv = DoubleConv(in_channels, out_channels) + + def forward(self, x1, x2): + x1 = self.up(x1) + # input is CHW + diffY = x2.size()[2] - x1.size()[2] + diffX = x2.size()[3] - x1.size()[3] + + x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, + diffY // 2, diffY - diffY // 2]) + # if you have padding issues, see + # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a + # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd + x = torch.cat([x2, x1], dim=1) + return self.conv(x) + + +class OutConv(nn.Module): + def __init__(self, in_channels, out_channels): + super(OutConv, self).__init__() + self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1) + + def forward(self, x): + return self.conv(x) + + +class UNet(nn.Module): + def __init__(self, n_classes): + super(UNet, self).__init__() + self.n_channels = 3 + self.n_classes = n_classes + self.bilinear = True + + self.inc = DoubleConv(self.n_channels, 64) + self.down1 = Down(64, 128) + self.down2 = Down(128, 256) + self.down3 = Down(256, 512) + factor = 2 if self.bilinear else 1 + self.down4 = Down(512, 1024 // factor) + self.up1 = Up(1024, 512 // factor, self.bilinear) + self.up2 = Up(512, 256 // factor, self.bilinear) + self.up3 = Up(256, 128 // factor, self.bilinear) + self.up4 = Up(128, 64, self.bilinear) + self.outc = OutConv(64, n_classes) + + def forward(self, x): + x1 = self.inc(x) + x2 = self.down1(x1) + x3 = self.down2(x2) + x4 = self.down3(x3) + x5 = self.down4(x4) + x = self.up1(x5, x4) + x = self.up2(x, x3) + x = self.up3(x, x2) + x = self.up4(x, x1) + out = self.outc(x) + + return out + diff --git a/third_parties/dsine/models/dsine/submodules.py b/third_parties/dsine/models/dsine/submodules.py new file mode 100644 index 0000000000000000000000000000000000000000..a271cfdd46f415b725957197be2e5db0e1901e5e --- /dev/null +++ b/third_parties/dsine/models/dsine/submodules.py @@ -0,0 +1,74 @@ +""" submodules for DSINE +""" +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + + +def get_pixel_coords(h, w): + # pixel array (1, 2, H, W) + pixel_coords = np.ones((3, h, w)).astype(np.float32) + x_range = np.concatenate([np.arange(w).reshape(1, w)] * h, axis=0) + y_range = np.concatenate([np.arange(h).reshape(h, 1)] * w, axis=1) + pixel_coords[0, :, :] = x_range + 0.5 + pixel_coords[1, :, :] = y_range + 0.5 + return torch.from_numpy(pixel_coords).unsqueeze(0) + + +class ConvGRU(nn.Module): + def __init__(self, hidden_dim, input_dim, ks=3): + super(ConvGRU, self).__init__() + p = (ks - 1) // 2 + self.convz = nn.Conv2d(hidden_dim+input_dim, hidden_dim, ks, padding=p) + self.convr = nn.Conv2d(hidden_dim+input_dim, hidden_dim, ks, padding=p) + self.convq = nn.Conv2d(hidden_dim+input_dim, hidden_dim, ks, padding=p) + + def forward(self, h, x): + hx = torch.cat([h, x], dim=1) + z = torch.sigmoid(self.convz(hx)) + r = torch.sigmoid(self.convr(hx)) + q = torch.tanh(self.convq(torch.cat([r*h, x], dim=1))) + h = (1-z) * h + z * q + return h + + +def get_unfold(pred_norm, ps, pad): + B, C, H, W = pred_norm.shape + pred_norm = F.pad(pred_norm, pad=(pad,pad,pad,pad), mode='replicate') # (B, C, h, w) + pred_norm_unfold = F.unfold(pred_norm, [ps, ps], padding=0) # (B, C X ps*ps, h*w) + pred_norm_unfold = pred_norm_unfold.view(B, C, ps*ps, H, W) # (B, C, ps*ps, h, w) + return pred_norm_unfold + + +def normal_activation(out, elu_kappa=True): + normal, kappa = out[:, :3, :, :], out[:, 3:, :, :] + normal = F.normalize(normal, p=2, dim=1) + if elu_kappa: + kappa = F.elu(kappa) + 1.0 + return torch.cat([normal, kappa], dim=1) + + +class RayReLU(nn.Module): + def __init__(self, eps=1e-2): + super(RayReLU, self).__init__() + self.eps = eps + + def forward(self, pred_norm, ray): + # angle between the predicted normal and ray direction + cos = torch.cosine_similarity(pred_norm, ray, dim=1).unsqueeze(1) # (B, 1, H, W) + + # component of pred_norm along view + norm_along_view = ray * cos + + # cos should be bigger than eps + norm_along_view_relu = ray * (torch.relu(cos - self.eps) + self.eps) + + # difference + diff = norm_along_view_relu - norm_along_view + + # updated pred_norm + new_pred_norm = pred_norm + diff + new_pred_norm = F.normalize(new_pred_norm, dim=1) + + return new_pred_norm \ No newline at end of file diff --git a/third_parties/dsine/models/dsine/v00.py b/third_parties/dsine/models/dsine/v00.py new file mode 100644 index 0000000000000000000000000000000000000000..5b1337b1cfbcba112f341c5d115faf5484082251 --- /dev/null +++ b/third_parties/dsine/models/dsine/v00.py @@ -0,0 +1,107 @@ +""" DSINE_v00 + - (X) ray direction encoding + - (X) rotation estimation +""" +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from models.conv_encoder_decoder.submodules import Encoder, UpSampleBN, UpSampleGN, \ + INPUT_CHANNELS_DICT, upsample_via_bilinear, upsample_via_mask, get_prediction_head +from models.dsine.submodules import normal_activation + +import logging +logger = logging.getLogger('root') + + +class DSINE_v00(nn.Module): + def __init__(self, args): + super(DSINE_v00, self).__init__() + B = args.NNET_encoder_B + NF = args.NNET_decoder_NF + BN = args.NNET_decoder_BN + down = args.NNET_decoder_down + learned_upsampling = args.NNET_learned_upsampling + + logger.info('Defining DSINE_v00 (baseline encoder-decoder, w/o ray encoding)') + logger.info('B: %s / NF: %s / BN: %s' % (B, NF, BN)) + logger.info('output_dim: %s / down: %s / learned upsampling: %s' % (args.NNET_output_dim, down, learned_upsampling)) + self.encoder = Encoder(B=B, pretrained=True) + self.decoder = Decoder(num_classes=args.NNET_output_dim, + B=B, NF=NF, BN=BN, + down=down, learned_upsampling=learned_upsampling) + + def forward(self, x, **kwargs): + return self.decoder(self.encoder(x), **kwargs) + + def get_1x_lr_params(self): # lr/10 learning rate + return self.encoder.parameters() + + def get_10x_lr_params(self): # lr learning rate + modules = [self.decoder] + for m in modules: + yield from m.parameters() + + +class Decoder(nn.Module): + def __init__(self, num_classes=3, B=5, NF=2048, BN=False, + down=8, learned_upsampling=True): + super(Decoder, self).__init__() + input_channels = INPUT_CHANNELS_DICT[B] + + # use BN or GN + UpSample = UpSampleBN if BN else UpSampleGN + + features = NF + self.conv2 = nn.Conv2d(input_channels[0], features, kernel_size=1, stride=1, padding=0) + self.up1 = UpSample(skip_input=features // 1 + input_channels[1], output_features=features // 2, align_corners=False) + self.up2 = UpSample(skip_input=features // 2 + input_channels[2], output_features=features // 4, align_corners=False) + + if down == 8: + i_dim = features // 4 + elif down == 4: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3], output_features=features // 8, align_corners=False) + i_dim = features // 8 + elif down == 2: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3], output_features=features // 8, align_corners=False) + self.up4 = UpSample(skip_input=features // 8 + input_channels[4], output_features=features // 16, align_corners=False) + i_dim = features // 16 + else: + raise Exception('invalid downsampling ratio') + + self.downsample_ratio = down + self.output_dim = num_classes + + self.pred_head = get_prediction_head(i_dim, 128, num_classes) + if learned_upsampling: + self.mask_head = get_prediction_head(i_dim, 128, 9 * self.downsample_ratio * self.downsample_ratio) + self.upsample_fn = upsample_via_mask + else: + self.mask_head = lambda a: None + self.upsample_fn = upsample_via_bilinear + + + def forward(self, features, intrins=None, mode=None): + x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + x_d0 = self.conv2(x_block4) + x_d1 = self.up1(x_d0, x_block3) + + if self.downsample_ratio == 8: + x_feat = self.up2(x_d1, x_block2) + elif self.downsample_ratio == 4: + x_d2 = self.up2(x_d1, x_block2) + x_feat = self.up3(x_d2, x_block1) + elif self.downsample_ratio == 2: + x_d2 = self.up2(x_d1, x_block2) + x_d3 = self.up3(x_d2, x_block1) + x_feat = self.up4(x_d3, x_block0) + + out = self.pred_head(x_feat) + out = normal_activation(out, elu_kappa=True) + + mask = self.mask_head(x_feat) + up_out = self.upsample_fn(out, mask, self.downsample_ratio) + up_out = normal_activation(up_out, elu_kappa=False) + return [up_out] + diff --git a/third_parties/dsine/models/dsine/v01.py b/third_parties/dsine/models/dsine/v01.py new file mode 100644 index 0000000000000000000000000000000000000000..d98376dbd3a159f5b8af88d7717f2ab971b7500a --- /dev/null +++ b/third_parties/dsine/models/dsine/v01.py @@ -0,0 +1,128 @@ +""" DSINE_v01 + - (O) ray direction encoding + - (X) rotation estimation +""" +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from models.conv_encoder_decoder.submodules import Encoder, UpSampleBN, UpSampleGN, \ + INPUT_CHANNELS_DICT, upsample_via_bilinear, upsample_via_mask, get_prediction_head +from models.dsine.submodules import normal_activation, get_pixel_coords + +import logging +logger = logging.getLogger('root') + + +class DSINE_v01(nn.Module): + def __init__(self, args): + super(DSINE_v01, self).__init__() + B = args.NNET_encoder_B + NF = args.NNET_decoder_NF + BN = args.NNET_decoder_BN + down = args.NNET_decoder_down + learned_upsampling = args.NNET_learned_upsampling + + logger.info('Defining DSINE_v01 (baseline encoder-decoder, w/ ray encoding)') + logger.info('B: %s / NF: %s / BN: %s' % (B, NF, BN)) + logger.info('output_dim: %s / down: %s / learned upsampling: %s' % (args.NNET_output_dim, down, learned_upsampling)) + self.encoder = Encoder(B=B, pretrained=True) + self.decoder = Decoder(num_classes=args.NNET_output_dim, + B=B, NF=NF, BN=BN, + down=down, learned_upsampling=learned_upsampling) + + def forward(self, x, **kwargs): + return self.decoder(self.encoder(x), **kwargs) + + def get_1x_lr_params(self): # lr/10 learning rate + return self.encoder.parameters() + + def get_10x_lr_params(self): # lr learning rate + modules = [self.decoder] + for m in modules: + yield from m.parameters() + + +class Decoder(nn.Module): + def __init__(self, num_classes=3, B=5, NF=2048, BN=False, + down=8, learned_upsampling=True): + super(Decoder, self).__init__() + input_channels = INPUT_CHANNELS_DICT[B] + + # use BN or GN + UpSample = UpSampleBN if BN else UpSampleGN + + features = NF + self.conv2 = nn.Conv2d(input_channels[0] + 2, features, kernel_size=1, stride=1, padding=0) + self.up1 = UpSample(skip_input=features // 1 + input_channels[1] + 2, output_features=features // 2, align_corners=False) + self.up2 = UpSample(skip_input=features // 2 + input_channels[2] + 2, output_features=features // 4, align_corners=False) + + if down == 8: + i_dim = features // 4 + elif down == 4: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3] + 2, output_features=features // 8, align_corners=False) + i_dim = features // 8 + elif down == 2: + self.up3 = UpSample(skip_input=features // 4 + input_channels[3] + 2, output_features=features // 8, align_corners=False) + self.up4 = UpSample(skip_input=features // 8 + input_channels[4] + 2, output_features=features // 16, align_corners=False) + i_dim = features // 16 + else: + raise Exception('invalid downsampling ratio') + + self.downsample_ratio = down + self.output_dim = num_classes + + self.pred_head = get_prediction_head(i_dim+2, 128, num_classes) + if learned_upsampling: + self.mask_head = get_prediction_head(i_dim+2, 128, 9 * self.downsample_ratio * self.downsample_ratio) + self.upsample_fn = upsample_via_mask + else: + self.mask_head = lambda a: None + self.upsample_fn = upsample_via_bilinear + + # pixel coordinates (1, 2, H, W) + self.pixel_coords = get_pixel_coords(h=2000, w=2000).to(0) + + def ray_embedding(self, x, intrins, orig_H, orig_W): + B, _, H, W = x.shape + fu = intrins[:, 0, 0].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + cu = intrins[:, 0, 2].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + fv = intrins[:, 1, 1].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + cv = intrins[:, 1, 2].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + + # (B, 2, H, W) + uv = self.pixel_coords[:, :2, :H, :W].repeat(B, 1, 1, 1) + uv[:, 0, :, :] = (uv[:, 0, :, :] - cu) / fu + uv[:, 1, :, :] = (uv[:, 1, :, :] - cv) / fv + return torch.cat([x, uv], dim=1) + + def forward(self, features, intrins, mode='train'): + x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + _, _, orig_H, orig_W = features[0].shape + + # STEP 1: make top-left pixel (0.5, 0.5) + intrins[:, 0, 2] += 0.5 + intrins[:, 1, 2] += 0.5 + + x_d0 = self.conv2(self.ray_embedding(x_block4, intrins, orig_H, orig_W)) + x_d1 = self.up1(x_d0, self.ray_embedding(x_block3, intrins, orig_H, orig_W)) + + if self.downsample_ratio == 8: + x_feat = self.up2(x_d1, self.ray_embedding(x_block2, intrins, orig_H, orig_W)) + elif self.downsample_ratio == 4: + x_d2 = self.up2(x_d1, self.ray_embedding(x_block2, intrins, orig_H, orig_W)) + x_feat = self.up3(x_d2, self.ray_embedding(x_block1, intrins, orig_H, orig_W)) + elif self.downsample_ratio == 2: + x_d2 = self.up2(x_d1, self.ray_embedding(x_block2, intrins, orig_H, orig_W)) + x_d3 = self.up3(x_d2, self.ray_embedding(x_block1, intrins, orig_H, orig_W)) + x_feat = self.up4(x_d3, self.ray_embedding(x_block0, intrins, orig_H, orig_W)) + + out = self.pred_head(self.ray_embedding(x_feat, intrins, orig_H, orig_W)) + out = normal_activation(out, elu_kappa=True) + + mask = self.mask_head(self.ray_embedding(x_feat, intrins, orig_H, orig_W)) + up_out = self.upsample_fn(out, mask, self.downsample_ratio) + up_out = normal_activation(up_out, elu_kappa=False) + return [up_out] + diff --git a/third_parties/dsine/models/dsine/v02.py b/third_parties/dsine/models/dsine/v02.py new file mode 100644 index 0000000000000000000000000000000000000000..8357305dfbbe7730844c0c8e96ffe633873c16eb --- /dev/null +++ b/third_parties/dsine/models/dsine/v02.py @@ -0,0 +1,259 @@ +""" DSINE_v02 + - (O) ray direction encoding + - (O) rotation estimation +""" +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from models.conv_encoder_decoder.submodules import Encoder, UpSampleBN, UpSampleGN, \ + INPUT_CHANNELS_DICT, upsample_via_bilinear, upsample_via_mask, get_prediction_head +from models.dsine.submodules import get_pixel_coords, ConvGRU, get_unfold, RayReLU +from utils.rotation import axis_angle_to_matrix + +import logging +logger = logging.getLogger('root') + + +class DSINE_v02(nn.Module): + def __init__(self, args): + super(DSINE_v02, self).__init__() + B = args.NNET_encoder_B + NF = args.NNET_decoder_NF + BN = args.NNET_decoder_BN + down = self.downsample_ratio = args.NNET_decoder_down + learned_upsampling = args.NNET_learned_upsampling + + self.ps = args.NRN_prop_ps + self.num_iter_train = args.NRN_num_iter_train + self.num_iter_test = args.NRN_num_iter_test + self.v_relu = args.NRN_ray_relu + + logger.info('Defining DSINE_v02 (full model)') + logger.info('B: %s / NF: %s / BN: %s / down: %s / learned_upsampling: %s' % (B, NF, BN, down, learned_upsampling)) + logger.info('ps: %s / iter train: %s / iter test: %s / v_relu: %s' % (self.ps, self.num_iter_train, self.num_iter_test, self.v_relu)) + + # define encoder + self.encoder = Encoder(B=B, pretrained=True) + + # define decoder + self.output_dim = output_dim = args.NNET_output_dim + self.feature_dim = feature_dim = args.NNET_feature_dim + self.hidden_dim = hidden_dim = args.NNET_hidden_dim + self.decoder = Decoder([output_dim, feature_dim, hidden_dim], B=B, NF=NF, BN=BN) + + # ray direction-based ReLU + if self.v_relu: + self.ray_relu = RayReLU(eps=1e-2) + + # pixel_coords (1, 3, H, W) + # NOTE: this is set to some arbitrarily high number, + # if your input is 2000+ pixels wide/tall, increase these values + self.pixel_coords = get_pixel_coords(h=2000, w=2000).to(0) + + # define ConvGRU cell + self.gru = ConvGRU(hidden_dim=hidden_dim, input_dim=feature_dim+2, ks=self.ps) + + # padding used during NRN + self.pad = (self.ps - 1) // 2 + + # prediction heads + self.prob_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps) # weights assigned for each nghbr pixel + self.xy_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps*2) # rotation axis for each nghbr pixel + self.angle_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps) # rotation angle for each nghbr pixel + + # prediction heads - weights used for upsampling the coarse resolution output + self.up_prob_head = get_prediction_head(self.hidden_dim+2, 64, 9 * self.downsample_ratio * self.downsample_ratio) + + def get_ray(self, intrins, H, W, orig_H, orig_W, return_uv=False): + B, _, _ = intrins.shape + fu = intrins[:, 0, 0].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + cu = intrins[:, 0, 2].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + fv = intrins[:, 1, 1].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + cv = intrins[:, 1, 2].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + + # (B, 2, H, W) + ray = self.pixel_coords[:, :, :H, :W].repeat(B, 1, 1, 1) + ray[:, 0, :, :] = (ray[:, 0, :, :] - cu) / fu + ray[:, 1, :, :] = (ray[:, 1, :, :] - cv) / fv + + if return_uv: + return ray[:, :2, :, :] + else: + return F.normalize(ray, dim=1) + + def upsample(self, h, pred_norm, uv_8): + up_mask = self.up_prob_head(torch.cat([h, uv_8], dim=1)) + up_pred_norm = upsample_via_mask(pred_norm, up_mask, self.downsample_ratio, padding='replicate') + up_pred_norm = F.normalize(up_pred_norm, dim=1) + return up_pred_norm + + def refine(self, h, feat_map, pred_norm, intrins, orig_H, orig_W, uv_8, ray_8): + B, C, H, W = pred_norm.shape + fu = intrins[:, 0, 0][:,None,None,None] * (W / orig_W) # (B, 1, 1, 1) + cu = intrins[:, 0, 2][:,None,None,None] * (W / orig_W) # (B, 1, 1, 1) + fv = intrins[:, 1, 1][:,None,None,None] * (H / orig_H) # (B, 1, 1, 1) + cv = intrins[:, 1, 2][:,None,None,None] * (H / orig_H) # (B, 1, 1, 1) + + h_new = self.gru(h, feat_map) + + # get nghbr prob (B, 1, ps*ps, h, w) + nghbr_prob = self.prob_head(torch.cat([h_new, uv_8], dim=1)).unsqueeze(1) + nghbr_prob = torch.sigmoid(nghbr_prob) + + # get nghbr normals (B, 3, ps*ps, h, w) + nghbr_normals = get_unfold(pred_norm, ps=self.ps, pad=self.pad) + + # get nghbr xy (B, 2, ps*ps, h, w) + nghbr_xys = self.xy_head(torch.cat([h_new, uv_8], dim=1)) + nghbr_xs, nghbr_ys = torch.split(nghbr_xys, [self.ps*self.ps, self.ps*self.ps], dim=1) + nghbr_xys = torch.cat([nghbr_xs.unsqueeze(1), nghbr_ys.unsqueeze(1)], dim=1) + nghbr_xys = F.normalize(nghbr_xys, dim=1) + + # get nghbr theta (B, 1, ps*ps, h, w) + nghbr_angle = self.angle_head(torch.cat([h_new, uv_8], dim=1)).unsqueeze(1) + nghbr_angle = torch.sigmoid(nghbr_angle) * np.pi + + # get nghbr pixel coord (1, 3, ps*ps, h, w) + nghbr_pixel_coord = get_unfold(self.pixel_coords[:, :, :H, :W], ps=self.ps, pad=self.pad) + + # nghbr axes (B, 3, ps*ps, h, w) + nghbr_axes = torch.zeros_like(nghbr_normals) + + du_over_fu = nghbr_xys[:, 0, ...] / fu # (B, ps*ps, h, w) + dv_over_fv = nghbr_xys[:, 1, ...] / fv # (B, ps*ps, h, w) + + term_u = (nghbr_pixel_coord[:, 0, ...] + nghbr_xys[:, 0, ...] - cu) / fu # (B, ps*ps, h, w) + term_v = (nghbr_pixel_coord[:, 1, ...] + nghbr_xys[:, 1, ...] - cv) / fv # (B, ps*ps, h, w) + + nx = nghbr_normals[:, 0, ...] # (B, ps*ps, h, w) + ny = nghbr_normals[:, 1, ...] # (B, ps*ps, h, w) + nz = nghbr_normals[:, 2, ...] # (B, ps*ps, h, w) + + nghbr_delta_z_num = - (du_over_fu * nx + dv_over_fv * ny) + nghbr_delta_z_denom = (term_u * nx + term_v * ny + nz) + nghbr_delta_z_denom[torch.abs(nghbr_delta_z_denom) < 1e-8] = 1e-8 * torch.sign(nghbr_delta_z_denom[torch.abs(nghbr_delta_z_denom) < 1e-8]) + nghbr_delta_z = nghbr_delta_z_num / nghbr_delta_z_denom + + nghbr_axes[:, 0, ...] = du_over_fu + nghbr_delta_z * term_u + nghbr_axes[:, 1, ...] = dv_over_fv + nghbr_delta_z * term_v + nghbr_axes[:, 2, ...] = nghbr_delta_z + nghbr_axes = F.normalize(nghbr_axes, dim=1) # (B, 3, ps*ps, h, w) + + # make sure axes are all valid + invalid = torch.sum(torch.logical_or(torch.isnan(nghbr_axes), torch.isinf(nghbr_axes)).float(), dim=1) > 0.5 # (B, ps*ps, h, w) + nghbr_axes[:, 0, ...][invalid] = 0.0 + nghbr_axes[:, 1, ...][invalid] = 0.0 + nghbr_axes[:, 2, ...][invalid] = 0.0 + + # nghbr_axes_angle (B, 3, ps*ps, h, w) + nghbr_axes_angle = nghbr_axes * nghbr_angle + nghbr_axes_angle = nghbr_axes_angle.permute(0, 2, 3, 4, 1) # (B, ps*ps, h, w, 3) + nghbr_R = axis_angle_to_matrix(nghbr_axes_angle) # (B, ps*ps, h, w, 3, 3) + + # (B, 3, ps*ps, h, w) + nghbr_normals_rot = torch.bmm( + nghbr_R.reshape(B * self.ps * self.ps * H * W, 3, 3), + nghbr_normals.permute(0, 2, 3, 4, 1).reshape(B * self.ps * self.ps * H * W, 3).unsqueeze(-1) + ).reshape(B, self.ps*self.ps, H, W, 3, 1).squeeze(-1).permute(0, 4, 1, 2, 3) # (B, 3, ps*ps, h, w) + nghbr_normals_rot = F.normalize(nghbr_normals_rot, dim=1) + + # ray ReLU + if self.v_relu: + nghbr_normals_rot = torch.cat([ + self.ray_relu(nghbr_normals_rot[:, :, i, :, :], ray_8).unsqueeze(2) + for i in range(nghbr_normals_rot.size(2)) + ], dim=2) + + # (B, 1, ps*ps, h, w) * (B, 3, ps*ps, h, w) + pred_norm = torch.sum(nghbr_prob * nghbr_normals_rot, dim=2) # (B, C, H, W) + pred_norm = F.normalize(pred_norm, dim=1) + + up_mask = self.up_prob_head(torch.cat([h_new, uv_8], dim=1)) + up_pred_norm = upsample_via_mask(pred_norm, up_mask, self.downsample_ratio, padding='replicate') + up_pred_norm = F.normalize(up_pred_norm, dim=1) + + return h_new, pred_norm, up_pred_norm + + def forward(self, img, intrins=None, mode='train'): + # Step 1. encoder + features = self.encoder(img) + + # Step 2. get uv encoding + B, _, orig_H, orig_W = img.shape + intrins[:, 0, 2] += 0.5 + intrins[:, 1, 2] += 0.5 + uv_32 = self.get_ray(intrins, orig_H//32, orig_W//32, orig_H, orig_W, return_uv=True) + uv_16 = self.get_ray(intrins, orig_H//16, orig_W//16, orig_H, orig_W, return_uv=True) + uv_8 = self.get_ray(intrins, orig_H//8, orig_W//8, orig_H, orig_W, return_uv=True) + ray_8 = self.get_ray(intrins, orig_H//8, orig_W//8, orig_H, orig_W) + + # Step 3. decoder - initial prediction + pred_norm, feat_map, h = self.decoder(features, uvs=(uv_32, uv_16, uv_8)) + + if self.v_relu: + pred_norm = self.ray_relu(pred_norm, ray_8) + + # Step 4. add ray direction encoding + feat_map = torch.cat([feat_map, uv_8], dim=1) + + # iterative refinement + up_pred_norm = self.upsample(h, pred_norm, uv_8) + pred_list = [up_pred_norm] + for i in range(self.num_iter_train) if mode == 'train' else range(self.num_iter_test): + h, pred_norm, up_pred_norm = self.refine(h, feat_map, + pred_norm.detach(), + intrins, orig_H, orig_W, uv_8, ray_8) + pred_list.append(up_pred_norm) + return pred_list + + def get_1x_lr_params(self): + modules = [self.encoder] + for m in modules: + yield from m.parameters() + + def get_10x_lr_params(self): + modules = [self.decoder, self.gru, self.prob_head, self.xy_head, self.angle_head, self.up_prob_head] + for m in modules: + yield from m.parameters() + + +class Decoder(nn.Module): + def __init__(self, output_dims, B=5, NF=2048, BN=False, downsample_ratio=8): + super(Decoder, self).__init__() + input_channels = INPUT_CHANNELS_DICT[B] + output_dim, feature_dim, hidden_dim = output_dims + features = NF + bottleneck_features = NF + self.downsample_ratio = downsample_ratio + + # use BN or GN + UpSample = UpSampleBN if BN else UpSampleGN + + i_dim = features // 4 + h_dim = 128 + self.conv2 = nn.Conv2d(bottleneck_features + 2, features, kernel_size=1, stride=1, padding=0) + self.up1 = UpSample(skip_input=features // 1 + input_channels[1] + 2, output_features=features // 2, align_corners=False) + self.up2 = UpSample(skip_input=features // 2 + input_channels[2] + 2, output_features=features // 4, align_corners=False) + + # prediction heads + self.normal_head = get_prediction_head(i_dim+2, h_dim, output_dim) + self.feature_head = get_prediction_head(i_dim+2, h_dim, feature_dim) + self.hidden_head = get_prediction_head(i_dim+2, h_dim, hidden_dim) + + def forward(self, features, uvs): + _, _, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + uv_32, uv_16, uv_8 = uvs + + x_d0 = self.conv2(torch.cat([x_block4, uv_32], dim=1)) + x_d1 = self.up1(x_d0, torch.cat([x_block3, uv_16], dim=1)) + x_feat = self.up2(x_d1, torch.cat([x_block2, uv_8], dim=1)) + x_feat = torch.cat([x_feat, uv_8], dim=1) + + normal = self.normal_head(x_feat) + normal = F.normalize(normal, dim=1) + f = self.feature_head(x_feat) + h = self.hidden_head(x_feat) + return normal, f, h + diff --git a/third_parties/dsine/models/dsine/v02_kappa.py b/third_parties/dsine/models/dsine/v02_kappa.py new file mode 100644 index 0000000000000000000000000000000000000000..b420d50b3e16b15fbcda0e0bfddbdd2cbb4782f4 --- /dev/null +++ b/third_parties/dsine/models/dsine/v02_kappa.py @@ -0,0 +1,280 @@ +""" DSINE_v02_kappa + - (O) ray direction encoding + - (O) rotation estimation + - (O) estimates uncertainty +""" +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from models.conv_encoder_decoder.submodules import Encoder, UpSampleBN, UpSampleGN, \ + INPUT_CHANNELS_DICT, upsample_via_bilinear, upsample_via_mask, get_prediction_head +from models.dsine.submodules import normal_activation, get_pixel_coords, ConvGRU, get_unfold, RayReLU +from utils.rotation import axis_angle_to_matrix + +import logging +logger = logging.getLogger('root') + + +class DSINE_v02_kappa(nn.Module): + def __init__(self, args): + super(DSINE_v02_kappa, self).__init__() + B = args.NNET_encoder_B + NF = args.NNET_decoder_NF + BN = args.NNET_decoder_BN + down = self.downsample_ratio = args.NNET_decoder_down + learned_upsampling = args.NNET_learned_upsampling + + self.ps = args.NRN_prop_ps + self.num_iter_train = args.NRN_num_iter_train + self.num_iter_test = args.NRN_num_iter_test + self.v_relu = args.NRN_ray_relu + + logger.info('Defining DSINE_v02_kappa (DSINE_v02 + also estimates uncertainty)') + logger.info('B: %s / NF: %s / BN: %s / down: %s / learned_upsampling: %s' % (B, NF, BN, down, learned_upsampling)) + logger.info('ps: %s / iter train: %s / iter test: %s / v_relu: %s' % (self.ps, self.num_iter_train, self.num_iter_test, self.v_relu)) + + # define encoder + self.encoder = Encoder(B=B, pretrained=True) + + # define decoder + self.output_dim = output_dim = args.NNET_output_dim + self.feature_dim = feature_dim = args.NNET_feature_dim + self.hidden_dim = hidden_dim = args.NNET_hidden_dim + self.decoder = Decoder([output_dim, feature_dim, hidden_dim], B=B, NF=NF, BN=BN) + + # ray direction-based ReLU + if self.v_relu: + self.ray_relu = RayReLU(eps=1e-2) + + # pixel_coords (1, 3, H, W) + # NOTE: this is set to some arbitrarily high number, + # if your input is 2000+ pixels wide/tall, increase these values + self.pixel_coords = get_pixel_coords(h=2000, w=2000).to(0) + + # define ConvGRU cell + self.gru = ConvGRU(hidden_dim=hidden_dim, input_dim=feature_dim+2, ks=self.ps) + + # Refinement + self.pad = (self.ps - 1) // 2 + + # prediction heads + self.prob_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps) # weights assigned for each nghbr pixel + self.xy_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps*2) # rotation axis for each nghbr pixel + self.angle_head = get_prediction_head(self.hidden_dim+2, 64, self.ps*self.ps) # rotation angle for each nghbr pixel + + # kappa head + self.kappa_head = get_prediction_head(self.hidden_dim+2, 64, 1) # kappa weights + + # prediction heads - weights used for upsampling the coarse resolution output + self.up_prob_head = get_prediction_head(self.hidden_dim+2, 64, 9 * self.downsample_ratio * self.downsample_ratio) + + def get_ray(self, intrins, H, W, orig_H, orig_W, return_uv=False): + B, _, _ = intrins.shape + fu = intrins[:, 0, 0].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + cu = intrins[:, 0, 2].unsqueeze(-1).unsqueeze(-1) * (W / orig_W) + fv = intrins[:, 1, 1].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + cv = intrins[:, 1, 2].unsqueeze(-1).unsqueeze(-1) * (H / orig_H) + + # (B, 2, H, W) + ray = self.pixel_coords[:, :, :H, :W].repeat(B, 1, 1, 1) + ray[:, 0, :, :] = (ray[:, 0, :, :] - cu) / fu + ray[:, 1, :, :] = (ray[:, 1, :, :] - cv) / fv + + if return_uv: + return ray[:, :2, :, :] + else: + ray = F.normalize(ray, dim=1) + return ray + + def upsample(self, h, pred_norm, pred_kappa, uv_8): + up_mask = self.up_prob_head(torch.cat([h, uv_8], dim=1)) + pred = torch.cat([pred_norm, pred_kappa], dim=1) + up_pred_norm = upsample_via_mask(pred, up_mask, self.downsample_ratio, padding='replicate') + up_pred_norm = normal_activation(up_pred_norm, elu_kappa=False) + return up_pred_norm + + def refine(self, h, feat_map, pred_norm, intrins, orig_H, orig_W, uv_8, ray_8): + B, C, H, W = pred_norm.shape + fu = intrins[:, 0, 0][:,None,None,None] * (W / orig_W) # (B, 1, 1, 1) + cu = intrins[:, 0, 2][:,None,None,None] * (W / orig_W) # (B, 1, 1, 1) + fv = intrins[:, 1, 1][:,None,None,None] * (H / orig_H) # (B, 1, 1, 1) + cv = intrins[:, 1, 2][:,None,None,None] * (H / orig_H) # (B, 1, 1, 1) + + h_new = self.gru(h, feat_map) + + # get nghbr prob (B, 1, ps*ps, h, w) + nghbr_prob = self.prob_head(torch.cat([h_new, uv_8], dim=1)).unsqueeze(1) + nghbr_prob = torch.sigmoid(nghbr_prob) + + # new kappa (B, 1, h, w) + new_kappa = self.kappa_head(torch.cat([h_new, uv_8], dim=1)) + new_kappa = F.elu(new_kappa) + 1.0 + + # get nghbr normals (B, 3, ps*ps, h, w) + nghbr_normals = get_unfold(pred_norm, ps=self.ps, pad=self.pad) + + # get nghbr xy (B, 2, ps*ps, h, w) + nghbr_xys = self.xy_head(torch.cat([h_new, uv_8], dim=1)) + nghbr_xs, nghbr_ys = torch.split(nghbr_xys, [self.ps*self.ps, self.ps*self.ps], dim=1) + nghbr_xys = torch.cat([nghbr_xs.unsqueeze(1), nghbr_ys.unsqueeze(1)], dim=1) + nghbr_xys = F.normalize(nghbr_xys, dim=1) + + # get nghbr theta (B, 1, ps*ps, h, w) + nghbr_angle = self.angle_head(torch.cat([h_new, uv_8], dim=1)).unsqueeze(1) + nghbr_angle = torch.sigmoid(nghbr_angle) * np.pi + + # get nghbr pixel coord (1, 3, ps*ps, h, w) + nghbr_pixel_coord = get_unfold(self.pixel_coords[:, :, :H, :W], ps=self.ps, pad=self.pad) + + # nghbr axes (B, 3, ps*ps, h, w) + nghbr_axes = torch.zeros_like(nghbr_normals) + + du_over_fu = nghbr_xys[:, 0, ...] / fu # (B, ps*ps, h, w) + dv_over_fv = nghbr_xys[:, 1, ...] / fv # (B, ps*ps, h, w) + + term_u = (nghbr_pixel_coord[:, 0, ...] + nghbr_xys[:, 0, ...] - cu) / fu # (B, ps*ps, h, w) + term_v = (nghbr_pixel_coord[:, 1, ...] + nghbr_xys[:, 1, ...] - cv) / fv # (B, ps*ps, h, w) + + nx = nghbr_normals[:, 0, ...] # (B, ps*ps, h, w) + ny = nghbr_normals[:, 1, ...] # (B, ps*ps, h, w) + nz = nghbr_normals[:, 2, ...] # (B, ps*ps, h, w) + + nghbr_delta_z_num = - (du_over_fu * nx + dv_over_fv * ny) + nghbr_delta_z_denom = (term_u * nx + term_v * ny + nz) + nghbr_delta_z_denom[torch.abs(nghbr_delta_z_denom) < 1e-8] = 1e-8 * torch.sign(nghbr_delta_z_denom[torch.abs(nghbr_delta_z_denom) < 1e-8]) + nghbr_delta_z = nghbr_delta_z_num / nghbr_delta_z_denom + + nghbr_axes[:, 0, ...] = du_over_fu + nghbr_delta_z * term_u + nghbr_axes[:, 1, ...] = dv_over_fv + nghbr_delta_z * term_v + nghbr_axes[:, 2, ...] = nghbr_delta_z + nghbr_axes = F.normalize(nghbr_axes, dim=1) # (B, 3, ps*ps, h, w) + + # make sure axes are all valid + invalid = torch.sum(torch.logical_or(torch.isnan(nghbr_axes), torch.isinf(nghbr_axes)).float(), dim=1) > 0.5 # (B, ps*ps, h, w) + nghbr_axes[:, 0, ...][invalid] = 0.0 + nghbr_axes[:, 1, ...][invalid] = 0.0 + nghbr_axes[:, 2, ...][invalid] = 0.0 + + # nghbr_axes_angle (B, 3, ps*ps, h, w) + nghbr_axes_angle = nghbr_axes * nghbr_angle + nghbr_axes_angle = nghbr_axes_angle.permute(0, 2, 3, 4, 1) # (B, ps*ps, h, w, 3) + nghbr_R = axis_angle_to_matrix(nghbr_axes_angle) # (B, ps*ps, h, w, 3, 3) + + # (B, 3, ps*ps, h, w) + nghbr_normals_rot = torch.bmm( + nghbr_R.reshape(B * self.ps * self.ps * H * W, 3, 3), + nghbr_normals.permute(0, 2, 3, 4, 1).reshape(B * self.ps * self.ps * H * W, 3).unsqueeze(-1) + ).reshape(B, self.ps*self.ps, H, W, 3, 1).squeeze(-1).permute(0, 4, 1, 2, 3) # (B, 3, ps*ps, h, w) + nghbr_normals_rot = F.normalize(nghbr_normals_rot, dim=1) + + # ray ReLU + if self.v_relu: + nghbr_normals_rot = torch.cat([ + self.ray_relu(nghbr_normals_rot[:, :, i, :, :], ray_8).unsqueeze(2) + for i in range(nghbr_normals_rot.size(2)) + ], dim=2) + + # (B, 1, ps*ps, h, w) * (B, 3, ps*ps, h, w) + pred_norm = torch.sum(nghbr_prob * nghbr_normals_rot, dim=2) # (B, C, H, W) + pred_norm = F.normalize(pred_norm, dim=1) + + # concat with kappa + pred = torch.cat([pred_norm, new_kappa], dim=1) + + up_mask = self.up_prob_head(torch.cat([h_new, uv_8], dim=1)) + up_pred_norm = upsample_via_mask(pred, up_mask, self.downsample_ratio, padding='replicate') + up_pred_norm = normal_activation(up_pred_norm, elu_kappa=False) + + return h_new, pred_norm, up_pred_norm + + def forward(self, img, intrins=None, mode='train'): + # Step 1. encoder + features = self.encoder(img) + + # Step 2. get uv encoding + B, _, orig_H, orig_W = img.shape + intrins[:, 0, 2] += 0.5 + intrins[:, 1, 2] += 0.5 + uv_32 = self.get_ray(intrins, orig_H//32, orig_W//32, orig_H, orig_W, return_uv=True) + uv_16 = self.get_ray(intrins, orig_H//16, orig_W//16, orig_H, orig_W, return_uv=True) + uv_8 = self.get_ray(intrins, orig_H//8, orig_W//8, orig_H, orig_W, return_uv=True) + ray_8 = self.get_ray(intrins, orig_H//8, orig_W//8, orig_H, orig_W) + + # Step 3. decoder - initial prediction + pred_norm, feat_map, h, pred_kappa = self.decoder(features, uvs=(uv_32, uv_16, uv_8)) + + if self.v_relu: + pred_norm = self.ray_relu(pred_norm, ray_8) + + # Step 4. add positional encoding + feat_map = torch.cat([feat_map, uv_8], dim=1) + + # iterative refinement + up_pred_norm = self.upsample(h, pred_norm, pred_kappa, uv_8) + pred_list = [up_pred_norm] + for i in range(self.num_iter_train) if mode == 'train' else range(self.num_iter_test): + h, pred_norm, up_pred_norm = self.refine(h, feat_map, + pred_norm.detach(), + intrins, orig_H, orig_W, uv_8, ray_8) + pred_list.append(up_pred_norm) + return pred_list + + def get_1x_lr_params(self): + modules = [self.encoder] + for m in modules: + yield from m.parameters() + + def get_10x_lr_params(self): + modules = [self.decoder, self.gru, self.prob_head, self.xy_head, self.angle_head, self.kappa_head, self.up_prob_head] + for m in modules: + yield from m.parameters() + + +class Decoder(nn.Module): + def __init__(self, output_dims, B=5, NF=2048, BN=False, downsample_ratio=8): + super(Decoder, self).__init__() + input_channels = INPUT_CHANNELS_DICT[B] + output_dim, feature_dim, hidden_dim = output_dims + features = NF + bottleneck_features = NF + self.downsample_ratio = downsample_ratio + + # use BN or GN + UpSample = UpSampleBN if BN else UpSampleGN + + i_dim = features // 4 + h_dim = 128 + self.conv2 = nn.Conv2d(bottleneck_features + 2, features, kernel_size=1, stride=1, padding=0) + self.up1 = UpSample(skip_input=features // 1 + input_channels[1] + 2, output_features=features // 2, align_corners=False) + self.up2 = UpSample(skip_input=features // 2 + input_channels[2] + 2, output_features=features // 4, align_corners=False) + + # prediction heads + self.normal_head = get_prediction_head(i_dim+2, h_dim, 3) + self.feature_head = get_prediction_head(i_dim+2, h_dim, feature_dim) + self.hidden_head = get_prediction_head(i_dim+2, h_dim, hidden_dim) + + # added + self.kappa_head = get_prediction_head(i_dim+2, h_dim, 1) + + def forward(self, features, uvs): + _, _, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + uv_32, uv_16, uv_8 = uvs + + x_d0 = self.conv2(torch.cat([x_block4, uv_32], dim=1)) + x_d1 = self.up1(x_d0, torch.cat([x_block3, uv_16], dim=1)) + x_feat = self.up2(x_d1, torch.cat([x_block2, uv_8], dim=1)) + x_feat = torch.cat([x_feat, uv_8], dim=1) + + normal = self.normal_head(x_feat) + normal = F.normalize(normal, dim=1) + f = self.feature_head(x_feat) + h = self.hidden_head(x_feat) + + # added + kappa = self.kappa_head(x_feat) + kappa = F.elu(kappa) + 1.0 + + return normal, f, h, kappa + diff --git a/third_parties/dsine/test.py b/third_parties/dsine/test.py new file mode 100644 index 0000000000000000000000000000000000000000..29140a8373e817b1fb98ba4e68b23c5aa854034a --- /dev/null +++ b/third_parties/dsine/test.py @@ -0,0 +1,318 @@ +import os +import sys +import numpy as np +from tqdm import tqdm +import glob + +import torch +import torch.nn.functional as F + +import time +from torchvision import transforms +import cv2 +from PIL import Image + +import sys +sys.path.append('../../') +import utils.utils as utils +import utils.visualize as vis_utils + +#โ†“โ†“โ†“โ†“ +#NOTE: project-specific imports (e.g. config) +import projects.dsine.config as config +from projects.baseline_normal.dataloader import * +from utils.projection import intrins_from_fov, intrins_from_txt +#โ†‘โ†‘โ†‘โ†‘ + + +def test(args, model, test_loader, device, results_dir=None): + with torch.no_grad(): + total_normal_errors = None + + for data_dict in tqdm(test_loader): + + #โ†“โ†“โ†“โ†“ + #NOTE: forward pass + img = data_dict['img'].to(device) + scene_names = data_dict['scene_name'] + img_names = data_dict['img_name'] + intrins = data_dict['intrins'].to(device) + + # pad input + _, _, orig_H, orig_W = img.shape + lrtb = utils.get_padding(orig_H, orig_W) + img, intrins = utils.pad_input(img, intrins, lrtb) + + # forward pass + pred_list = model(img, intrins=intrins, mode='test') + norm_out = pred_list[-1] + + # crop the padded part + norm_out = norm_out[:, :, lrtb[2]:lrtb[2]+orig_H, lrtb[0]:lrtb[0]+orig_W] + + pred_norm, pred_kappa = norm_out[:, :3, :, :], norm_out[:, 3:, :, :] + pred_kappa = None if pred_kappa.size(1) == 0 else pred_kappa + #โ†‘โ†‘โ†‘โ†‘ + + if 'normal' in data_dict.keys(): + gt_norm = data_dict['normal'].to(device) + gt_norm_mask = data_dict['normal_mask'].to(device) + + pred_error = utils.compute_normal_error(pred_norm, gt_norm) + if total_normal_errors is None: + total_normal_errors = pred_error[gt_norm_mask] + else: + total_normal_errors = torch.cat((total_normal_errors, pred_error[gt_norm_mask]), dim=0) + + if results_dir is not None: + prefixs = ['%s_%s' % (i,j) for (i,j) in zip(scene_names, img_names)] + vis_utils.visualize_normal(results_dir, prefixs, img, pred_norm, pred_kappa, + gt_norm, gt_norm_mask, pred_error) + + if total_normal_errors is not None: + metrics = utils.compute_normal_metrics(total_normal_errors) + print("mean median rmse 5 7.5 11.25 22.5 30") + print("%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f" % ( + metrics['mean'], metrics['median'], metrics['rmse'], + metrics['a1'], metrics['a2'], metrics['a3'], metrics['a4'], metrics['a5'])) + + +def test_samples(args, model, device): + img_paths = glob.glob('./samples/img/*.png') + glob.glob('./samples/img/*.jpg') + img_paths.sort() + os.makedirs('./samples/output/', exist_ok=True) + + # normalize + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + with torch.no_grad(): + for img_path in img_paths: + print(img_path) + ext = os.path.splitext(img_path)[1] + img = Image.open(img_path).convert('RGB') + img = np.array(img).astype(np.float32) / 255.0 + img = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0).to(device) + + #โ†“โ†“โ†“โ†“ + #NOTE: forward pass + + # pad input + _, _, orig_H, orig_W = img.shape + lrtb = utils.get_padding(orig_H, orig_W) + img = F.pad(img, lrtb, mode="constant", value=0.0) + img = normalize(img) + + # get intrinsics + intrins_path = img_path.replace(ext, '.txt') + if os.path.exists(intrins_path): + # camera intrinsics should be given as a txt file + # it should contain the values of fx, fy, cx, cy + intrins = intrins_from_txt(intrins_path, device=device).unsqueeze(0) + else: + # if intrins is not given, we just assume that the principal point is at the center + # and that the field-of-view is 60 degrees (feel free to modify this assumption) + intrins = intrins_from_fov(new_fov=60.0, H=orig_H, W=orig_W, device=device).unsqueeze(0) + intrins[:, 0, 2] += lrtb[0] + intrins[:, 1, 2] += lrtb[2] + + norm_out = model(img, intrins=intrins, mode='test')[-1] + norm_out = norm_out[:, :, lrtb[2]:lrtb[2]+orig_H, lrtb[0]:lrtb[0]+orig_W] + pred_norm = norm_out[:, :3, :, :] + #โ†‘โ†‘โ†‘โ†‘ + + # save to output folder + # by saving the prediction as uint8 png format, you lose a lot of precision + # if you want to use the predicted normals for downstream tasks, we recommend saving them as float32 NPY files + target_path = img_path.replace('/img/', '/output/').replace(ext, '.png') + im = Image.fromarray(vis_utils.normal_to_rgb(pred_norm)[0,...]) + im.save(target_path) + + +def measure_throughput(model, img, intrins, dtype='fp32', nwarmup=50, nruns=1000): + img = img.to("cuda") + intrins = intrins.to("cuda") + if dtype=='fp16': + img = img.half() + intrins = intrins.half() + + print("Warm up ...") + with torch.no_grad(): + for _ in range(nwarmup): + norm_outs = model(img, intrins, mode='test') + + torch.cuda.synchronize() + print("Start timing ...") + timings = [] + with torch.no_grad(): + for i in range(1, nruns+1): + start_time = time.time() + norm_outs = model(img, intrins, mode='test') + torch.cuda.synchronize() + end_time = time.time() + timings.append(end_time - start_time) + if i%10==0: + print('Iteration %d/%d, avg batch time %.2f ms'%(i, nruns, np.mean(timings)*1000)) + + print("Input shape:", img.size()) + print('Average throughput: %.2f images/second'%(img.shape[0]/np.mean(timings))) + + +def demo(args, model, InputStream, frame_name): + cv2.namedWindow(frame_name, cv2.WINDOW_NORMAL) + cv2.setWindowProperty(frame_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) + pause = False + + lrtb = InputStream.lrtb + H, W = InputStream.new_H, InputStream.new_W + + while True: + with torch.no_grad(): + if pause: + pass + else: + data_dict = InputStream.get_sample() + color_image = data_dict['color_image'] + + #โ†“โ†“โ†“โ†“ + #NOTE: forward pass + + img = data_dict['img'] + intrins = data_dict['intrins'] + + norm_out = model(img, intrins=intrins, mode='test')[-1] + + norm_out = norm_out[:, :, lrtb[2]:lrtb[2]+H, lrtb[0]:lrtb[0]+W] + pred_norm = norm_out[:, :3, :, :] + pred_kappa = norm_out[:, 3:, :, :] + #โ†‘โ†‘โ†‘โ†‘ + + # visualize + pred_norm_rgb = vis_utils.normal_to_rgb(pred_norm)[0,...][...,::-1] + if pred_kappa.size(1) == 0: + pred_uncertainty = [] + elif 'NLL_angmf' in args.loss_fn: + pred_uncertainty = [vis_utils.alpha_to_jet(vis_utils.kappa_to_alpha(pred_kappa))] # BGR + else: + pred_uncertainty = [vis_utils.depth_to_rgb(pred_kappa[0,...], None, 0.0, None, 'gray')[...,::-1]] + out = np.hstack([color_image, pred_norm_rgb]+pred_uncertainty) + + cv2.imshow(frame_name, out) + + # keyboard input + k = cv2.waitKey(1) + if k == ord(' '): + pause = not pause + elif k == ord('q'): + exit() + + +if __name__ == '__main__': + device = torch.device('cuda') + args = config.get_args(test=True) + + if args.ckpt_path is None: + ckpt_paths = glob.glob(os.path.join(args.output_dir, 'models', '*.pt')) + ckpt_paths.sort() + args.ckpt_path = ckpt_paths[-1] + assert os.path.exists(args.ckpt_path) + + #โ†“โ†“โ†“โ†“ + #NOTE: define and load model + if args.NNET_architecture == 'v00': + from models.dsine.v00 import DSINE_v00 as DSINE + elif args.NNET_architecture == 'v01': + from models.dsine.v01 import DSINE_v01 as DSINE + elif args.NNET_architecture == 'v02': + from models.dsine.v02 import DSINE_v02 as DSINE + elif args.NNET_architecture == 'v02_kappa': + from models.dsine.v02_kappa import DSINE_v02_kappa as DSINE + else: + raise Exception('invalid arch') + model = DSINE(args).to(device) + + model = utils.load_checkpoint(args.ckpt_path, model) + model.eval() + #โ†‘โ†‘โ†‘โ†‘ + + # test the model + if args.mode == 'benchmark': + # do not resize/crop the images when benchmarking + args.input_height = args.input_width = 0 + args.data_augmentation_same_fov = 0 + + for dataset_name, split in [('nyuv2', 'test'), + ('scannet', 'test'), + ('ibims', 'ibims'), + ('sintel', 'sintel'), + ('vkitti', 'vkitti'), + ('oasis', 'val') + ]: + + args.dataset_name_test = dataset_name + args.test_split = split + test_loader = TestLoader(args).data + + results_dir = None + if args.visualize: + results_dir = os.path.join(args.output_dir, 'test', dataset_name) + os.makedirs(results_dir, exist_ok=True) + + test(args, model, test_loader, device, results_dir) + + # test on samples + elif args.mode == 'samples': + test_samples(args, model, device) + + #โ†“โ†“โ†“โ†“ + #NOTE: measure throughput + elif args.mode == 'throughput': + H, W = 480, 640 + batch_size = 8 + dummy_img = torch.rand(batch_size, 3, H, W).float().to(device) + dummy_intrins = torch.cat([intrins_from_fov(60.0, H, W).unsqueeze(0)]*batch_size, dim=0).float().to(device) + measure_throughput(model, dummy_img, dummy_intrins, dtype='fp32') + #โ†‘โ†‘โ†‘โ†‘ + + # demo + else: + from utils.demo_data import define_input + if args.mode == 'screen': + input_name = 'screen' + kwargs = dict( + intrins = None, + top = (1080-480) // 2, + left = (1920-640) // 2, + height = 480, + width = 640, + ) + + elif args.mode == 'webcam': + input_name = 'webcam' + kwargs = dict( + intrins = None, + new_width = -1, + webcam_index = 1, + ) + + elif args.mode == 'rs': + input_name = 'rs' + kwargs = dict( + enable_auto_exposure = True, + enable_auto_white_balance = True, + ) + + elif 'youtube.com' in args.mode: + input_name = 'youtube' + kwargs = dict( + intrins = None, + new_width = 1024, + video_id = args.mode.split('watch?v=')[1], + ) + + else: + raise Exception('invalid input option for demo') + + InputStream = define_input(input=input_name, device=device, **kwargs) + demo(args, model, InputStream, frame_name=args.ckpt_path) + + diff --git a/third_parties/dsine/test_minimal.py b/third_parties/dsine/test_minimal.py new file mode 100644 index 0000000000000000000000000000000000000000..6bd1fd02642242063b9f5154577c517dc1e7f756 --- /dev/null +++ b/third_parties/dsine/test_minimal.py @@ -0,0 +1,80 @@ +import os +import sys +import glob +import numpy as np + +import torch +import torch.nn.functional as F +from torchvision import transforms +from PIL import Image + +import sys +sys.path.append('../../') +import utils.utils as utils +import projects.dsine.config as config +from utils.projection import intrins_from_fov, intrins_from_txt + +if __name__ == '__main__': + device = torch.device('cuda') + args = config.get_args(test=True) + assert os.path.exists(args.ckpt_path) + + if args.NNET_architecture == 'v00': + from models.dsine.v00 import DSINE_v00 as DSINE + elif args.NNET_architecture == 'v01': + from models.dsine.v01 import DSINE_v01 as DSINE + elif args.NNET_architecture == 'v02': + from models.dsine.v02 import DSINE_v02 as DSINE + elif args.NNET_architecture == 'v02_kappa': + from models.dsine.v02_kappa import DSINE_v02_kappa as DSINE + else: + raise Exception('invalid arch') + + model = DSINE(args).to(device) + model = utils.load_checkpoint(args.ckpt_path, model) + model.eval() + + img_paths = glob.glob('./samples/img/*.png') + glob.glob('./samples/img/*.jpg') + img_paths.sort() + os.makedirs('./samples/output/', exist_ok=True) + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + with torch.no_grad(): + for img_path in img_paths: + print(img_path) + ext = os.path.splitext(img_path)[1] + img = Image.open(img_path).convert('RGB') + img = np.array(img).astype(np.float32) / 255.0 + img = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0).to(device) + + # pad input + _, _, orig_H, orig_W = img.shape + lrtb = utils.get_padding(orig_H, orig_W) + img = F.pad(img, lrtb, mode="constant", value=0.0) + img = normalize(img) + + # get intrinsics + intrins_path = img_path.replace(ext, '.txt') + if os.path.exists(intrins_path): + # NOTE: camera intrinsics should be given as a txt file + # it should contain the values of fx, fy, cx, cy + intrins = intrins_from_txt(intrins_path, device=device).unsqueeze(0) + else: + # NOTE: if intrins is not given, we just assume that the principal point is at the center + # and that the field-of-view is 60 degrees (feel free to modify this assumption) + intrins = intrins_from_fov(new_fov=60.0, H=orig_H, W=orig_W, device=device).unsqueeze(0) + intrins[:, 0, 2] += lrtb[0] + intrins[:, 1, 2] += lrtb[2] + + pred_norm = model(img, intrins=intrins)[-1] + pred_norm = pred_norm[:, :, lrtb[2]:lrtb[2]+orig_H, lrtb[0]:lrtb[0]+orig_W] + + # save to output folder + # NOTE: by saving the prediction as uint8 png format, you lose a lot of precision + # if you want to use the predicted normals for downstream tasks, we recommend saving them as float32 NPY files + target_path = img_path.replace('/img/', '/output/').replace(ext, '.png') + + pred_norm = pred_norm.detach().cpu().permute(0, 2, 3, 1).numpy() + pred_norm = (((pred_norm + 1) * 0.5) * 255).astype(np.uint8) + im = Image.fromarray(pred_norm[0,...]) + im.save(target_path) diff --git a/third_parties/dsine/train.py b/third_parties/dsine/train.py new file mode 100644 index 0000000000000000000000000000000000000000..cb197c8182cde7deea2498c0481bb4d49bb359cd --- /dev/null +++ b/third_parties/dsine/train.py @@ -0,0 +1,274 @@ +import os +import numpy as np +from tqdm import tqdm + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.distributed as dist +import torch.multiprocessing as mp +import torch.optim as optim +import torch.utils.data.distributed + +import sys +sys.path.append('../../') +import utils.utils as utils +import utils.visualize as vis_utils + +# setup logging +logger = utils.setup_custom_logger('root') +import logging +logging.getLogger('PIL').setLevel(logging.INFO) + +#โ†“โ†“โ†“โ†“ +#NOTE: project-specific imports (e.g. config) +import projects.dsine.config as config +from projects.baseline_normal.dataloader import * +from projects.dsine.losses import ComputeLoss +#โ†‘โ†‘โ†‘โ†‘ + +BEST_KEY = 'mean' # metric to use when selecting the best model + + +def train(model, args, device): + if device is None: + device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu') + + should_write = ((not args.distributed) or args.rank == 0) + if should_write: + logger.info('Number of model parameters: %s' % sum([p.data.nelement() for p in model.parameters()])) + + # train & val dataloader + train_loader = TrainLoader(args, epoch=0).data + val_loader = ValLoader(args).data + + # define losses + loss_fn = ComputeLoss(args) + + # optimizer + if not args.diff_lr: + logger.info("Using same LR") + params = model.parameters() + else: + logger.info("Using diff LR") + m = model.module if args.multigpu else model + #โ†“โ†“โ†“โ†“ + #NOTE: For some parameters (e.g. those in encoder), we use 1/10 learning rate. This part may need to be updated depending on how you defined your model. + params = [{"params": m.get_1x_lr_params(), "lr": args.lr / 10}, + {"params": m.get_10x_lr_params(), "lr": args.lr}] + #โ†‘โ†‘โ†‘โ†‘ + optimizer = optim.AdamW(params, weight_decay=args.weight_decay, lr=args.lr) + + # learning rate scheduler + scheduler = optim.lr_scheduler.OneCycleLR(optimizer=optimizer, + max_lr=args.lr, + epochs=args.num_epochs, + steps_per_epoch=len(train_loader) // args.accumulate_grad_batches, + div_factor=25.0, + final_div_factor=10000.0) + + # cudnn setting + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + scaler = torch.cuda.amp.GradScaler() + + # best accuracy (lower the better) + best_acc = 1e4 + + # start training + total_iter = 0 + model.train() + for epoch in range(args.num_epochs): + train_loader = TrainLoader(args, epoch=epoch).data + + if args.rank == 0: + data_loader = tqdm(train_loader, desc=f"Epoch: {epoch + 1}/{args.num_epochs}. Loop: Train") + else: + data_loader = train_loader + + for batch_idx, data_dict in enumerate(data_loader): + total_iter += args.batch_size_orig + + #โ†“โ†“โ†“โ†“ + #NOTE: forward pass + img = data_dict['img'].to(device) + gt_norm = data_dict['normal'].to(device) + gt_norm_mask = data_dict['normal_mask'].to(device) + intrins = data_dict['intrins'].to(device) + + pred_list = model(img, intrins=intrins, mode='train') + loss = loss_fn(pred_list, gt_norm, gt_norm_mask) + #โ†‘โ†‘โ†‘โ†‘ + + # back-propagate + loss = loss / args.accumulate_grad_batches + scaler.scale(loss).backward() + + if ((batch_idx + 1) % args.accumulate_grad_batches == 0): + scaler.unscale_(optimizer) + nn.utils.clip_grad_norm_(model.parameters(), args.grad_clip) + scaler.step(optimizer) + scaler.update() + optimizer.zero_grad() + scheduler.step() + + # log loss + if should_write: + loss_ = float(loss.data.cpu().numpy()) + args.writer.add_scalar('loss', loss_, global_step=total_iter) + data_loader.set_description(f"Epoch: {epoch + 1}/{args.num_epochs}. Loop: Train. Loss: {'%.5f' % loss_}") + data_loader.refresh() + + #โ†“โ†“โ†“โ†“ + #NOTE: visualize (in tensorboard) + if should_write and ((total_iter % args.visualize_every) < args.batch_size_orig): + for pred_idx, norm_out in enumerate(pred_list): + vis_ = vis_utils.visualize_normal_tb(args, img, norm_out, gt_norm, gt_norm_mask) + args.writer.add_image('train vis (iter: %s)' % pred_idx, vis_, global_step=total_iter, dataformats='HWC') + #โ†‘โ†‘โ†‘โ†‘ + + # validation + if should_write and ((total_iter % args.validate_every) < args.batch_size_orig): + if args.save_all_models: + utils.save_model(model, os.path.join(args.output_dir, 'models', 'iter_%010d.pt' % total_iter), total_iter) + else: + model.eval() + metrics = validate(model, args, val_loader, device, total_iter) + if metrics[BEST_KEY] <= best_acc: + utils.save_model(model, os.path.join(args.output_dir, 'models', 'best.pt'), total_iter) + best_acc = metrics[BEST_KEY] + print('best acc: %s' % best_acc) + model.train() + + # validation after epoch + if should_write: + if args.save_all_models: + utils.save_model(model, os.path.join(args.output_dir, 'models', 'iter_%010d.pt' % total_iter), total_iter) + else: + model.eval() + metrics = validate(model, args, val_loader, device, total_iter) + if metrics[BEST_KEY] <= best_acc: + utils.save_model(model, os.path.join(args.output_dir, 'models', 'best.pt'), total_iter) + best_acc = metrics[BEST_KEY] + print('best acc: %s' % best_acc) + if epoch+1 == args.num_epochs: + utils.save_model(model, os.path.join(args.output_dir, 'models', 'last.pt'), total_iter) + model.train() + + del train_loader + return model + + +def validate(model, args, val_loader, device, total_iter): + with torch.no_grad(): + total_metrics = utils.RunningAverageDict() + for data_dict in tqdm(val_loader, desc="Loop: Validation"): + + #โ†“โ†“โ†“โ†“ + #NOTE: forward pass + img = data_dict['img'].to(device) + gt_norm = data_dict['normal'].to(device) + gt_norm_mask = data_dict['normal_mask'].to(device) + intrins = data_dict['intrins'].to(device) + + norm_out = model(img, intrins=intrins, mode='test')[-1] + pred_norm = norm_out[:, :3, :, :] + #โ†‘โ†‘โ†‘โ†‘ + + pred_error = utils.compute_normal_error(pred_norm, gt_norm) + metrics_, num_pixels = utils.compute_normal_metrics2(pred_error[gt_norm_mask]) + total_metrics.update(metrics_, num_pixels) + + metrics = total_metrics.get_value() + metrics['rmse'] = np.sqrt(metrics['mse']) + + # tb logging + for k, v in metrics.items(): + args.writer.add_scalar(k, v, global_step=total_iter) + return metrics + + +# main worker +def main_worker(gpu, ngpus_per_node, args): + args.gpu = gpu + + #โ†“โ†“โ†“โ†“ + #NOTE: define model + if args.NNET_architecture == 'v00': + from models.dsine.v00 import DSINE_v00 as DSINE + elif args.NNET_architecture == 'v01': + from models.dsine.v01 import DSINE_v01 as DSINE + elif args.NNET_architecture == 'v02': + from models.dsine.v02 import DSINE_v02 as DSINE + elif args.NNET_architecture == 'v02_kappa': + from models.dsine.v02_kappa import DSINE_v02_kappa as DSINE + else: + raise Exception('invalid model architecture') + model = DSINE(args) + #โ†‘โ†‘โ†‘โ†‘ + + # If a gpu is set by user: NO PARALLELISM + if args.gpu is not None: + torch.cuda.set_device(args.gpu) + model = model.cuda(args.gpu) + + args.multigpu = False + if args.distributed: + # Use DDP + args.multigpu = True + args.rank = args.rank * ngpus_per_node + gpu + dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, + world_size=args.world_size, rank=args.rank) + args.batch_size = int(args.batch_size / ngpus_per_node) + args.workers = int((args.num_workers + ngpus_per_node - 1) / ngpus_per_node) + + logger.info('GPU: %s / RANK: %s / Batch size: %s / Num workers: %s' % + (args.gpu, args.rank, args.batch_size, args.workers)) + + torch.cuda.set_device(args.gpu) + model = nn.SyncBatchNorm.convert_sync_batchnorm(model) + model = model.cuda(args.gpu) + model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], output_device=args.gpu, + find_unused_parameters=True) + + elif args.gpu is None: + # Use DP + args.multigpu = True + model = model.cuda() + model = torch.nn.DataParallel(model) + + train(model, args, device=args.gpu) + + +if __name__ == '__main__': + args = config.get_args() + + # set visible gpus + os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" + if args.gpus != '-1': + os.environ["CUDA_VISIBLE_DEVICES"] = ",".join(list(args.gpus)) + + args.world_size = 1 + args.rank = 0 + nodes = ["127.0.0.1"] + + if args.distributed: + mp.set_start_method('forkserver') + port = np.random.randint(15000, 15025) + args.dist_url = 'tcp://{}:{}'.format(nodes[0], port) + args.dist_backend = 'nccl' + args.gpu = None + + ngpus_per_node = torch.cuda.device_count() + args.num_workers = args.workers + args.ngpus_per_node = ngpus_per_node + + args.batch_size_orig = args.batch_size + + if args.distributed: + args.world_size = ngpus_per_node * args.world_size + mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args)) + else: + if ngpus_per_node == 1: + args.gpu = 0 + main_worker(args.gpu, ngpus_per_node, args) diff --git a/third_parties/dsine/utils/d2n/ReadMe.md b/third_parties/dsine/utils/d2n/ReadMe.md new file mode 100644 index 0000000000000000000000000000000000000000..cc36a97f7c230be711bebc3f7eaa7b9e234a34d1 --- /dev/null +++ b/third_parties/dsine/utils/d2n/ReadMe.md @@ -0,0 +1,7 @@ +# Depth-to-Normal + +We generated our meta-dataset by collecting RGB-D datasets and converting the depth maps into surface normal maps. + +We took [PlaneSVD from Klasing et al.](https://ieeexplore.ieee.org/document/5152493) and added a few modifications to handle depth discontinuties. We encourage you to try using other algorithms as it can potentially improve the quality of the ground truth and hence the performance of the model. + +Please see `notes/depth_to_normal.ipynb` for example usage. diff --git a/third_parties/dsine/utils/d2n/cross.py b/third_parties/dsine/utils/d2n/cross.py new file mode 100644 index 0000000000000000000000000000000000000000..d69067fed001b2c5113299f7b12d9a609913adb7 --- /dev/null +++ b/third_parties/dsine/utils/d2n/cross.py @@ -0,0 +1,40 @@ +import torch +import torch.nn.functional as F + + +def d2n_tblr(points: torch.Tensor, + k: int = 3, + d_min: float = 1e-3, + d_max: float = 10.0) -> torch.Tensor: + """ points: 3D points in camera coordinates, shape: (B, 3, H, W) + k: neighborhood size + e.g.) If k=3, 3x3 neighborhood is used. Two vectors are defined by doing (top-bottom) and (left-right) + Then the normals are computed via cross-product + d_min/max: Range of valid depth values + """ + k = (k - 1) // 2 + + B, _, H, W = points.size() + points_pad = F.pad(points, (k,k,k,k), mode='constant', value=0) # (B, 3, k+H+k, k+W+k) + valid_pad = (points_pad[:,2:,:,:] > d_min) & (points_pad[:,2:,:,:] < d_max) # (B, 1, k+H+k, k+W+k) + valid_pad = valid_pad.float() + + # vertical vector (top - bottom) + vec_vert = points_pad[:, :, :H, k:k+W] - points_pad[:, :, 2*k:2*k+H, k:k+W] # (B, 3, H, W) + + # horizontal vector (left - right) + vec_hori = points_pad[:, :, k:k+H, :W] - points_pad[:, :, k:k+H, 2*k:2*k+W] # (B, 3, H, W) + + # valid_mask (all five depth values - center/top/bottom/left/right should be valid) + valid_mask = valid_pad[:, :, k:k+H, k:k+W ] * \ + valid_pad[:, :, :H, k:k+W ] * \ + valid_pad[:, :, 2*k:2*k+H, k:k+W ] * \ + valid_pad[:, :, k:k+H, :W ] * \ + valid_pad[:, :, k:k+H, 2*k:2*k+W ] + valid_mask = valid_mask > 0.5 + + # get cross product (B, 3, H, W) + cross_product = - torch.linalg.cross(vec_vert, vec_hori, dim=1) + normal = F.normalize(cross_product, p=2.0, dim=1, eps=1e-12) + + return normal, valid_mask diff --git a/third_parties/dsine/utils/d2n/plane_svd.py b/third_parties/dsine/utils/d2n/plane_svd.py new file mode 100644 index 0000000000000000000000000000000000000000..049a13053ca6e46b36a6e07ebdcca325f9bb5203 --- /dev/null +++ b/third_parties/dsine/utils/d2n/plane_svd.py @@ -0,0 +1,139 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class Depth2normal(nn.Module): + def __init__(self, + d_min: float = 0.0, + d_max: float = 10.0, + k: int = 3, + d: int = 1, + min_nghbr: int = 4, + gamma: float = None, + gamma_exception: bool = False): + super(Depth2normal, self).__init__() + + # range of valid depth values + # if the depth is outside this range, it will be considered invalid + self.d_min = d_min + self.d_max = d_max + + # neighborhood size, k x k neighborhood around each pixel will be considered + self.k = k + + # spacing between the nghbrs (dilation) + self.d = d + + # if the difference between the center depth and nghbr depth is larger than this, it will be ignored + # e.g. gamma=0.05 means that a nghbr pixel is ignored if its depth is more than 5% different from the center pixel + self.gamma = gamma + + # minimum number of nghbr pixels + # if the number of valid nghbr pixels is below this value, the normals would be considered invalid + self.min_nghbr = min_nghbr + + # if the normal of a flat surface is near-vertical to the viewing direction, the depth gradient will be very high, + # and most nghbr pixels would not pass the above "gamma" test + # this can be a problem when using datasets like Virtual KITTI (i.e. the ones with large horizontal surfaces) + # if gamma_exception is set to True, + # the "gamma" test will be ignored when the number of valid nghbr pixels < self.min_nghbr + self.gamma_exception = gamma_exception + + # padding for depth map + self.pad = (k + (k - 1) * (d - 1)) // 2 + + # index of the center pixel + self.center_idx = (k*k - 1) // 2 + + # torch Unfold to unfold the depth map + self.unfold = torch.nn.Unfold(kernel_size=(k, k), padding=self.pad, dilation=d) + + def forward(self, points: torch.Tensor) -> torch.Tensor: + """ points: 3D points in camera coordinates, shape: (B, 3, H, W) + """ + b, _, h, w = points.shape + + # matrix_a (b, h, w, k*k, 3) + torch_patches = self.unfold(points) # (b, 3*k*k, h, w) + matrix_a = torch_patches.view(b, 3, self.k * self.k, h, w) # (b, 3, k*k, h, w) + matrix_a = matrix_a.permute(0, 3, 4, 2, 1) # (b, h, w, k*k, 3) + + # filter by depth + valid_condition = torch.logical_and(points[:,2:,:,:] > self.d_min, points[:,2:,:,:] < self.d_max) + valid_condition = valid_condition.float() # (B, 1, H, W) + valid_condition = self.unfold(valid_condition) # (b, 1*k*k, h, w) + valid_condition = valid_condition.view(b, 1, self.k * self.k, h, w) # (b, 1, k*k, h, w) + valid_condition = valid_condition.permute(0, 3, 4, 2, 1) # (b, h, w, k*k, 1) + + # valid_condition (b, h, w, k*k, 1) + if self.gamma is not None: + valid_depth_diff = torch.abs(matrix_a[:, :, :, :, 2:] - matrix_a[:, :, :, self.center_idx:self.center_idx+1, 2:]) \ + / matrix_a[:, :, :, self.center_idx:self.center_idx+1, 2:] + valid_depth_diff = (valid_depth_diff < self.gamma).float() # (b, h, w, k*k, 1) + + if self.gamma_exception: + valid_depth_diff_sum = torch.sum(valid_depth_diff, dim=3, keepdim=True) # (b, h, w, 1, 1) + valid_depth_diff_sum = (valid_depth_diff_sum < self.min_nghbr).float() # (b, h, w, 1, 1) + valid_depth_diff = valid_depth_diff + valid_depth_diff_sum + valid_depth_diff = (valid_depth_diff > 0.5).float() + + valid_condition = valid_condition * valid_depth_diff + + # matrix A (b, h, w, k*k, 4) + matrix_1 = torch.ones_like(matrix_a[:,:,:,:,0:1]) + matrix_A = torch.cat([matrix_a, matrix_1], dim=-1) + + # fill zero for invalid pixels + matrix_A_zero = torch.zeros_like(matrix_A) + matrix_A = torch.where(valid_condition.repeat([1, 1, 1, 1, 4]) > 0.5, matrix_A, matrix_A_zero) + + # transpose + matrix_At = torch.transpose(matrix_A, 3, 4) + + matrix_A = matrix_A.view(-1, self.k * self.k, 4) # (b*h*w, k*k, 4) + matrix_At = matrix_At.view(-1, 4, self.k * self.k) # (b*h*w, 4, k*k) + At_A = torch.bmm(matrix_At, matrix_A) # (b*h*w, 4, 4) + + # eig_val: (b*h*w, 4) / eig_vec: (b*h*w, 4, 4) + eig_val, eig_vec = torch.linalg.eig(At_A) + + # valid_mask (b*h*w) + valid_eig = torch.logical_and(torch.sum(eig_val.imag, dim=1) == 0, + torch.sum(eig_vec.imag, dim=(1, 2)) == 0) + + # find the smallest eigenvalue + eig_val = eig_val.real + eig_vec = eig_vec.real + + idx = torch.argmin(eig_val, dim=1, keepdim=True) # (b*h*w, 1) + idx_onehot = torch.zeros_like(eig_val).scatter_(1, idx, 1.) # (b*h*w, 4) + idx_onehot = idx_onehot.unsqueeze(1).repeat(1, 4, 1) + + # normal (b, 3, h, w) + normal = torch.sum(eig_vec * idx_onehot, dim=2) + normal = normal.view(b, h, w, 4).permute(0, 3, 1, 2).contiguous() + normal = F.normalize(normal[:,:3,:,:], p=2.0, dim=1, eps=1e-12) + + # flip if needed + flip = torch.sign(torch.sum(normal * points, dim=1, keepdim=True)) + normal = normal * flip + + # valid_mask1 (b, 1, h, w): center pixel valid depth + valid_mask1 = valid_condition[:,:,:,self.center_idx,0].unsqueeze(1) + + # valid_mask2 (b, 1, h, w): sufficient number of valid neighbors + valid_mask2 = torch.sum(valid_condition[..., 0], dim=3).unsqueeze(1) >= self.min_nghbr + + # valid_mask3 (b, 1, h, w): eigenvalue real + valid_mask3 = valid_eig.view(b, h, w).unsqueeze(1) + + # valid_mask4 (b, 1, h, w): + valid_mask4 = torch.norm(normal, p=2, dim=1, keepdim=True) > 0.5 + + # valid_mask + valid_mask = valid_mask1 * valid_mask2 * valid_mask3 * valid_mask4 + + return normal, valid_mask > 0.5 + + diff --git a/third_parties/dsine/utils/demo_data.py b/third_parties/dsine/utils/demo_data.py new file mode 100644 index 0000000000000000000000000000000000000000..ba20011329c92e3e040b509b4a1acabaa3477b19 --- /dev/null +++ b/third_parties/dsine/utils/demo_data.py @@ -0,0 +1,386 @@ +import os +import cv2 +import torch +import torch.nn.functional as F +import numpy as np +from torchvision import transforms + +from utils.projection import intrins_from_fov +from utils.utils import get_padding + + +def define_input(input, device='cpu', **kwargs): + if input == 'screen': + InputStream = InputScreen(device=device, **kwargs) + elif input == 'webcam': + InputStream = InputWebcam(device=device, **kwargs) + elif input == 'rs': + InputStream = InputRealsense(device=device, **kwargs) + elif input == 'youtube': + InputStream = InputYoutube(device=device, **kwargs) + elif input == 'video': + InputStream = InputVideo(device=device, **kwargs) + else: + raise Exception('input option %s is not valid' % input) + return InputStream + + +def img_to_tensor(color_image, lrtb=(0,0,0,0), device="cpu"): + """ color_image is a BGR numpy array of shape (H, W, 3) + this function returns an RGB torch tensor of shape (1, H, W, 3) + """ + # NOTE: THIS IS SLOW + # img = color_image.astype(np.float32) / 255.0 + # img = torch.from_numpy(img).to(device).permute(2, 0, 1).unsqueeze(0) + + # NOTE: THIS IS FASTER + img = color_image[:, :, ::-1].astype(np.uint8) + img = torch.from_numpy(img).to(device).permute(2, 0, 1).to(dtype=torch.float32) + img = (img / 255.0).unsqueeze(0).contiguous() + img = F.pad(img, lrtb, mode="constant", value=0.0) + return img + + +class InputScreen(): + def __init__(self, device=0, + intrins: torch.Tensor = None, + top: int = (1080-480) // 2, + left: int = (1920-640) // 2, + height: int = 480, + width: int = 640, + **kwargs + ): + from mss import mss + + self.device = device + self.bounding_box = {'top': top, 'left': left, 'width': width, 'height': height} + self.sct = mss() + + # input should be padded to ensure that both H and W are divisible by 32 + self.new_H, self.new_W = height, width + self.lrtb = get_padding(self.new_H, self.new_W) + + # intrins (if None, assume that FoV is 60) + # intrins should be updated after padding + if intrins is None: + self.intrins = intrins_from_fov(new_fov=60.0, H=self.new_H, W=self.new_W, device=device) + else: + self.intrins = intrins + + if self.intrins.ndim == 2: + self.intrins = self.intrins.unsqueeze(0) + self.intrins[:, 0, 2] += self.lrtb[0] + self.intrins[:, 1, 2] += self.lrtb[2] + + self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + def get_sample(self): + # color_image: numpy array, BGR, (H, W, 3) + color_image = np.array(self.sct.grab(self.bounding_box))[:,:,:3] + + # img: torch tensor, RGB, (1, 3, H, W) + img = img_to_tensor(color_image, lrtb=self.lrtb, device=self.device) + img = self.normalize(img) + + # intrins: torch tensor (3, 3) + intrins = self.intrins.clone() + + # sample + sample = { + 'color_image': color_image, + 'img': img, + 'intrins': intrins, + } + + return sample + + +class InputWebcam(): + def __init__(self, device=0, + intrins: torch.Tensor = None, + new_width: int = -1, + webcam_index: int = 1, + **kwargs + ): + self.device = device + self.cap = cv2.VideoCapture(webcam_index) + assert self.cap.isOpened() + + while(self.cap.isOpened()): + ret, frame = self.cap.read() + if ret == True: + first_frame = frame + break + + # input should be padded to ensure that both H and W are divisible by 32 + self.orig_H, self.orig_W, _ = first_frame.shape + if new_width == -1: + self.new_H, self.new_W = self.orig_H, self.orig_W + self.interp = None + else: + self.new_W = new_width + self.new_H = round(self.orig_H * (self.new_W / self.orig_W)) + if self.new_W < self.orig_W: + self.interp = cv2.INTER_AREA + else: + self.interp = cv2.INTER_LINEAR + self.lrtb = get_padding(self.new_H, self.new_W) + + # intrins (if None, assume that FoV is 60) + # intrins should be updated after padding + if intrins is None: + self.intrins = intrins_from_fov(new_fov=60.0, H=self.new_H, W=self.new_W, device=device) + else: + self.intrins = intrins + + if self.intrins.ndim == 2: + self.intrins = self.intrins.unsqueeze(0) + self.intrins[:, 0, 2] += self.lrtb[0] + self.intrins[:, 1, 2] += self.lrtb[2] + + self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + def get_sample(self): + # color_image: numpy array, BGR, (H, W, 3) + while(self.cap.isOpened()): + ret, frame = self.cap.read() + if ret == True: + color_image = frame + break + + if self.interp is not None: + color_image = cv2.resize(color_image, (self.new_W, self.new_H), interpolation=self.interp) + + # img: torch tensor, RGB, (1, 3, H, W) + img = img_to_tensor(color_image, lrtb=self.lrtb, device=self.device) + img = self.normalize(img) + + # intrins: torch tensor (3, 3) + intrins = self.intrins.clone() + + # sample + sample = { + 'color_image': color_image, + 'img': img, + 'intrins': intrins, + } + + return sample + + +class InputRealsense(): + def __init__(self, device=0, + enable_auto_exposure: bool = False, + enable_auto_white_balance: bool = False, + **kwargs + ): + import pyrealsense2 as rs + + self.device = device + # load camera + # Configure depth and color streams + self.rs_pipeline = rs.pipeline() + self.rs_config = rs.config() + # Get device product line for setting a supporting resolution + pipeline_wrapper = rs.pipeline_wrapper(self.rs_pipeline) + pipeline_profile = self.rs_config.resolve(pipeline_wrapper) + rs_device = pipeline_profile.get_device() + + found_rgb = False + for s in rs_device.sensors: + if s.get_info(rs.camera_info.name) == 'RGB Camera': + found_rgb = True + s.set_option(rs.option.enable_auto_exposure, enable_auto_exposure) + s.set_option(rs.option.enable_auto_white_balance, enable_auto_white_balance) + break + if not found_rgb: + print("The demo requires Depth camera with Color sensor") + exit(0) + + self.rs_config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) + self.rs_pipeline.start(self.rs_config) + profile = self.rs_pipeline.get_active_profile() + intr = profile.get_stream(rs.stream.color).as_video_stream_profile().get_intrinsics() + + # intrins - fixed for realsense + self.new_H, self.new_W = intr.height, intr.width + self.lrtb = get_padding(self.new_H, self.new_W) + + fx = intr.fx + cx = intr.ppx + fy = intr.fy + cy = intr.ppy + + self.intrins = torch.tensor([[fx, 0.0, cx ], + [0.0, fy, cy ], + [0.0, 0.0, 1.0]], dtype=torch.float32, device=device).unsqueeze(0) + self.intrins[:, 0, 2] += self.lrtb[0] + self.intrins[:, 1, 2] += self.lrtb[2] + + self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + def get_sample(self): + # color_image: numpy array, BGR, (H, W, 3) + frames = self.rs_pipeline.wait_for_frames() + color_frame = frames.get_color_frame() + color_image = np.asanyarray(color_frame.get_data()) + + # img: torch tensor, RGB, (1, 3, H, W) + img = img_to_tensor(color_image, lrtb=self.lrtb, device=self.device) + img = self.normalize(img) + + # intrins: torch tensor (3, 3) + intrins = self.intrins.clone() + + # sample + sample = { + 'color_image': color_image, + 'img': img, + 'intrins': intrins, + } + + return sample + + +class InputYoutube(): + def __init__(self, device=0, + intrins: torch.Tensor = None, + new_width: int = -1, + video_id: str = 'dQw4w9WgXcQ', + **kwargs): + self.device = device + self.video_id = video_id + + # read first image and set intrins + self.init_stream() + first_frame = self.stream.read() + + # input should be padded to ensure that both H and W are divisible by 32 + self.orig_H, self.orig_W, _ = first_frame.shape + if new_width == -1: + self.new_H, self.new_W = self.orig_H, self.orig_W + self.interp = None + else: + self.new_W = new_width + self.new_H = round(self.orig_H * (self.new_W / self.orig_W)) + if self.new_W < self.orig_W: + self.interp = cv2.INTER_AREA + else: + self.interp = cv2.INTER_LINEAR + self.lrtb = get_padding(self.new_H, self.new_W) + + # intrins (if None, assume that FoV is 60) + # intrins should be updated after padding + if intrins is None: + self.intrins = intrins_from_fov(new_fov=60.0, H=self.new_H, W=self.new_W, device=device) + else: + self.intrins = intrins + + if self.intrins.ndim == 2: + self.intrins = self.intrins.unsqueeze(0) + self.intrins[:, 0, 2] += self.lrtb[0] + self.intrins[:, 1, 2] += self.lrtb[2] + + self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + self.init_stream() + + def init_stream(self): + from vidgear.gears import CamGear + self.stream = CamGear(source='https://youtu.be/%s' % self.video_id, stream_mode=True, logging=True).start() + + def get_sample(self): + # color_image: numpy array, BGR, (H, W, 3) + color_image = self.stream.read() + if color_image is None: + self.init_stream() + color_image = self.stream.read() + + if self.interp is not None: + color_image = cv2.resize(color_image, (self.new_W, self.new_H), interpolation=self.interp) + + # img: torch tensor, RGB, (1, 3, H, W) + img = img_to_tensor(color_image, lrtb=self.lrtb, device=self.device) + img = self.normalize(img) + + # intrins: torch tensor (3, 3) + intrins = self.intrins.clone() + + # sample + sample = { + 'color_image': color_image, + 'img': img, + 'intrins': intrins, + } + + return sample + + +class InputVideo(): + def __init__(self, device=0, + intrins: torch.Tensor = None, + new_width: int = -1, + video_path: str = None, + **kwargs + ): + self.device = device + assert os.path.exists(video_path) + self.video_path = video_path + self.vidcap = cv2.VideoCapture(self.video_path) + _, first_frame = self.vidcap.read() + + # input should be padded to ensure that both H and W are divisible by 32 + self.orig_H, self.orig_W, _ = first_frame.shape + if new_width == -1: + self.new_H, self.new_W = self.orig_H, self.orig_W + self.interp = None + else: + self.new_W = new_width + self.new_H = round(self.orig_H * (self.new_W / self.orig_W)) + if self.new_W < self.orig_W: + self.interp = cv2.INTER_AREA + else: + self.interp = cv2.INTER_LINEAR + self.lrtb = get_padding(self.new_H, self.new_W) + + # intrins (if None, assume that FoV is 60) + # intrins should be updated after padding + if intrins is None: + self.intrins = intrins_from_fov(new_fov=60.0, H=self.new_H, W=self.new_W, device=device) + else: + self.intrins = intrins + + if self.intrins.ndim == 2: + self.intrins = self.intrins.unsqueeze(0) + self.intrins[:, 0, 2] += self.lrtb[0] + self.intrins[:, 1, 2] += self.lrtb[2] + + self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + def get_sample(self): + # color_image: numpy array, BGR, (H, W, 3) + success, color_image = self.vidcap.read() + if not success: + self.vidcap = cv2.VideoCapture(self.video_path) + success, color_image = self.vidcap.read() + assert success + + if self.interp is not None: + color_image = cv2.resize(color_image, (self.new_W, self.new_H), interpolation=self.interp) + + # img: torch tensor, RGB, (1, 3, H, W) + img = img_to_tensor(color_image, lrtb=self.lrtb, device=self.device) + img = self.normalize(img) + + # intrins: torch tensor (3, 3) + intrins = self.intrins.clone() + + # sample + sample = { + 'color_image': color_image, + 'img': img, + 'intrins': intrins, + } + + return sample + + diff --git a/third_parties/dsine/utils/projection.py b/third_parties/dsine/utils/projection.py new file mode 100644 index 0000000000000000000000000000000000000000..54078bfe5e871d314a1426fc89e25f9592d34ae9 --- /dev/null +++ b/third_parties/dsine/utils/projection.py @@ -0,0 +1,276 @@ +import numpy as np +import torch +import torch.nn.functional as F + + +def intrins_zero_to(intrins): + """ add 0.5 to ensure top-left pixel is (0.5, 0.5) + + NOTE: intrins should have the shape (..., 3, 3) + """ + intrins[..., 0, 2] += 0.5 + intrins[..., 1, 2] += 0.5 + return intrins + + +def intrins_to_zero(intrins): + """ subtract 0.5 to ensure top-left pixel is (0, 0) + + NOTE: intrins should have the shape (..., 3, 3) + """ + intrins[..., 0, 2] -= 0.5 + intrins[..., 1, 2] -= 0.5 + return intrins + + +def intrins_crop(intrins, + crop_top: int = 0, + crop_left: int = 0): + """ update intrins after crop + + NOTE: intrins should have the shape (..., 3, 3) + """ + intrins[..., 0, 2] -= crop_left + intrins[..., 1, 2] -= crop_top + return intrins + + +def intrins_resize(intrins, + ratio_H: float = 1.0, + ratio_W: float = 1.0): + """ update intrins after resize + + NOTE: intrins should have the shape (..., 3, 3) + NOTE: top-left is (0,0) + """ + intrins = intrins_zero_to(intrins) + intrins[..., 0, 0] *= ratio_W # fx + intrins[..., 0, 2] *= ratio_W # cx + intrins[..., 1, 1] *= ratio_H # fy + intrins[..., 1, 2] *= ratio_H # cy + intrins = intrins_to_zero(intrins) + return intrins + + +def get_intrins(fx, fy, cx, cy, dtype=torch.float32, device='cpu'): + """ intrins from fx, fy, cx, cy + + NOTE: top-left is (0,0) + """ + intrins = torch.tensor([[ fx, 0.0, cx], + [0.0, fy, cy], + [0.0, 0.0, 1.0]], dtype=dtype, device=device) + intrins_inv = torch.tensor([[1/fx, 0.0, -cx/fx], + [ 0.0, 1/fy, -cy/fy], + [ 0.0, 0.0, 1.0]], dtype=dtype, device=device) + return intrins, intrins_inv + + +def intrins_to_intrins_inv(intrins): + """ intrins to intrins_inv + + NOTE: top-left is (0,0) + """ + if torch.is_tensor(intrins): + intrins_inv = torch.zeros_like(intrins) + elif type(intrins) is np.ndarray: + intrins_inv = np.zeros_like(intrins) + else: + raise Exception('intrins should be torch tensor or numpy array') + + intrins_inv[0, 0] = 1 / intrins[0, 0] + intrins_inv[0, 2] = - intrins[0, 2] / intrins[0, 0] + intrins_inv[1, 1] = 1 / intrins[1, 1] + intrins_inv[1, 2] = - intrins[1, 2] / intrins[1, 1] + intrins_inv[2, 2] = 1.0 + return intrins_inv + + +def intrins_from_fov(new_fov, H, W, dtype=torch.float32, device='cpu'): + """ define intrins based on field-of-view + principal point is assumed to be at the center + + NOTE: new_fov should be in degrees + NOTE: top-left is (0,0) + """ + new_fx = new_fy = (max(H, W) / 2.0) / np.tan(np.deg2rad(new_fov / 2.0)) + new_cx = (W / 2.0) - 0.5 + new_cy = (H / 2.0) - 0.5 + + new_intrins = torch.tensor([ + [new_fx, 0, new_cx ], + [0, new_fy, new_cy ], + [0, 0, 1 ] + ], dtype=dtype, device=device) + + return new_intrins + + +def intrins_from_fov2(new_fov, H, W, cx, cy, dtype=torch.float32, device='cpu'): + """ define intrins based on field-of-view + principal point is assumed to be at (cx, cy) + + NOTE: new_fov should be in degrees + NOTE: top-left is (0,0) + """ + cx += 0.5 + cy += 0.5 + + if W >= H: + x1 = W - cx + x2 = cx + else: + x1 = H - cy + x2 = cy + + # use tan(x+y) = (tan(x) + tan(y)) / (1 โ€“ tan(x)tan(y)) + A = np.tan(np.deg2rad(new_fov)) + B = - (x1 + x2) + C = - np.tan(np.deg2rad(new_fov)) * x1 * x2 + new_f = (-B + np.sqrt(B**2.0 - (4 * A * C))) / (2*A) + + intrins = torch.tensor([[new_f, 0.0, cx-0.5], + [0.0, new_f, cy-0.5], + [0.0, 0.0, 1.0]], dtype=dtype, device=device) + return intrins + + +def intrins_from_txt(intrins_path, dtype=torch.float32, device='cpu'): + """ define intrins based on txt + it should contain fx,fy,cx,cy - separated by commas + + NOTE: top-left is (0,0) + """ + with open(intrins_path, 'r') as f: + intrins_ = f.readlines()[0].split()[0].split(',') + intrins_ = [float(i) for i in intrins_] + fx, fy, cx, cy = intrins_ + + intrins = torch.tensor([ + [fx, 0,cx], + [ 0,fy,cy], + [ 0, 0, 1] + ], dtype=dtype, device=device) + + return intrins + + +def get_fov(fx, fy, cx, cy, H, W): + """ compute horizontal and vertical field-of-view from intrins + + NOTE: top-left is (0,0) + """ + cx += 0.5 + cy += 0.5 + fov_x = np.rad2deg(np.arctan((W - cx) / fx) + np.arctan((cx) / fx)) + fov_y = np.rad2deg(np.arctan((H - cy) / fy) + np.arctan((cy) / fy)) + return fov_x, fov_y + + +def get_ray_array(H, W, intrins, flatten=True): + """ get ray array + multiplying the output by per-pixel depth would give you the camera-coordinates of each pixel + + NOTE: intrins should be a torch tensor of shape (B, 3, 3) + NOTE: top-left is (0,0) + """ + assert torch.is_tensor(intrins) and intrins.ndim == 3 + B, _, _ = intrins.shape + + fx = intrins[:, 0, 0].unsqueeze(-1).unsqueeze(-1) # (B, 1, 1) + fy = intrins[:, 1, 1].unsqueeze(-1).unsqueeze(-1) # (B, 1, 1) + cx = intrins[:, 0, 2].unsqueeze(-1).unsqueeze(-1) # (B, 1, 1) + cy = intrins[:, 1, 2].unsqueeze(-1).unsqueeze(-1) # (B, 1, 1) + + x_range = torch.cat([torch.arange(W, dtype=intrins.dtype, device=intrins.device).view(1, 1, W)] * H, axis=1).repeat(B,1,1) # (B, H, W) + y_range = torch.cat([torch.arange(H, dtype=intrins.dtype, device=intrins.device).view(1, H, 1)] * W, axis=2).repeat(B,1,1) # (B, H, W) + + # B, 3, H, W + ray_array = torch.ones((B, 3, H, W), dtype=intrins.dtype, device=intrins.device) + ray_array[:, 0, :, :] = (x_range - cx) / fx + ray_array[:, 1, :, :] = (y_range - cy) / fy + + if flatten: + ray_array = ray_array.view(B, 3, H*W) + + return ray_array + + +def get_cam_coords(intrins_inv, depth): + """ camera coordinates from intrins_inv and depth + + NOTE: intrins_inv should be a torch tensor of shape (B, 3, 3) + NOTE: depth should be a torch tensor of shape (B, 1, H, W) + NOTE: top-left is (0,0) + """ + assert torch.is_tensor(intrins_inv) and intrins_inv.ndim == 3 + assert torch.is_tensor(depth) and depth.ndim == 4 + assert intrins_inv.dtype == depth.dtype + assert intrins_inv.device == depth.device + B, _, H, W = depth.size() + + u_range = torch.arange(W, dtype=depth.dtype, device=depth.device).view(1, W).expand(H, W) # (H, W) + v_range = torch.arange(H, dtype=depth.dtype, device=depth.device).view(H, 1).expand(H, W) # (H, W) + ones = torch.ones(H, W, dtype=depth.dtype, device=depth.device) + pixel_coords = torch.stack((u_range, v_range, ones), dim=0).unsqueeze(0).repeat(B,1,1,1) # (B, 3, H, W) + pixel_coords = pixel_coords.view(B, 3, H*W) # (B, 3, H*W) + + cam_coords = intrins_inv.bmm(pixel_coords).view(B, 3, H, W) + cam_coords = cam_coords * depth + return cam_coords + + +def pix_to_src_coords(src_pix, new_H, new_W, orig_H, orig_W): + """ src_pix: homogeneous pixel coordinates + src_coords: used for F.grid_sample (align_corners=False) + """ + src_pix = src_pix[:2, :] / src_pix[2:, :] + + src_coords = torch.FloatTensor(1, new_H, new_W, 2).fill_(0) + src_coords[0, :, :, 0] = src_pix[0, :].reshape(new_H, new_W) + 0.5 + src_coords[0, :, :, 1] = src_pix[1, :].reshape(new_H, new_W) + 0.5 + v_center = orig_H / 2. + u_center = orig_W / 2. + src_coords[:, :, :, 0] = (src_coords[:, :, :, 0] - u_center) / u_center + src_coords[:, :, :, 1] = (src_coords[:, :, :, 1] - v_center) / v_center + + src_coords[src_coords > 2.0] = 2.0 + src_coords[src_coords < -2.0] = -2.0 + src_coords[torch.isinf(src_coords)] = 2.0 + src_coords[torch.isnan(src_coords)] = 2.0 + return src_coords + + +def zbuffer_to_radial(zbuffer, intrins, H, W): + """ convert zbuffer to radial + radial: Euclidean distance from the camera center + + NOTE: zbuffer should be a torch tensor of shape (B, 1, H, W) + NOTE: intrins should be a torch tensor of shape (B, 3, 3) + NOTE: top-left is (0,0) + """ + assert torch.is_tensor(zbuffer) and zbuffer.ndim == 4 + assert torch.is_tensor(intrins) and intrins.ndim == 3 + + ray_array = get_ray_array(H, W, intrins, flatten=False) # (B, 3, H, W) + cam_coord = ray_array * zbuffer + radial = torch.linalg.norm(cam_coord, dim=1, keepdim=True) + return radial + + +def radial_to_zbuffer(radial, intrins, H, W): + """ convert radial to zbuffer + radial: Euclidean distance from the camera center + + NOTE: radial should be a torch tensor of shape (B, 1, H, W) + NOTE: intrins should be a torch tensor of shape (B, 3, 3) + NOTE: top-left is (0,0) + """ + assert torch.is_tensor(radial) and radial.ndim == 4 + assert torch.is_tensor(intrins) and intrins.ndim == 3 + + ray_array = get_ray_array(H, W, intrins, flatten=False) # (B, 3, H, W) + ray_norm = torch.linalg.norm(ray_array, dim=1, keepdim=True) + zbuffer = radial / ray_norm + return zbuffer + diff --git a/third_parties/dsine/utils/rotation.py b/third_parties/dsine/utils/rotation.py new file mode 100644 index 0000000000000000000000000000000000000000..63970b7159850a63a4b2f1a1a6e47e37b2e3a56c --- /dev/null +++ b/third_parties/dsine/utils/rotation.py @@ -0,0 +1,207 @@ +import numpy as np +import torch +import torch.nn.functional as F + + +def get_r_yaw(yaw): + """ rotation around the y-axis + """ + return np.array([ + [np.cos(yaw), 0, np.sin(yaw) ], + [0, 1, 0 ], + [-np.sin(yaw), 0, np.cos(yaw) ], + ], dtype=np.float32 + ) + + +def get_r_pitch(pitch): + """ rotation around the x-axis + """ + return np.array([ + [1, 0, 0 ], + [0, np.cos(pitch), -np.sin(pitch) ], + [0, np.sin(pitch), np.cos(pitch) ] + ], dtype=np.float32 + ) + + +def get_r_roll(roll): + """ rotation around the z-axis + """ + return np.array([ + [np.cos(roll), -np.sin(roll), 0 ], + [np.sin(roll), np.cos(roll), 0 ], + [0, 0, 1 ] + ], dtype=np.float32 + ) + + +def get_R(yaw, pitch, roll): + """ rotation matrix from yaw, pitch, roll + """ + R_yaw = get_r_yaw(yaw) + R_pitch = get_r_pitch(pitch) + R_roll = get_r_roll(roll) + + R_yaw_inv = get_r_yaw(-yaw) + R_pitch_inv = get_r_pitch(-pitch) + R_roll_inv = get_r_roll(-roll) + + R = R_pitch @ R_roll @ R_yaw + R_inv = R_yaw_inv @ R_roll_inv @ R_pitch_inv + + return R, R_inv + + +# NOTE: the code below is copied from PyTorch3D +# (https://github.com/facebookresearch/pytorch3d/blob/main/pytorch3d/transforms/rotation_conversions.py) +# See the license at https://github.com/facebookresearch/pytorch3d/blob/main/LICENSE +def axis_angle_to_quaternion(axis_angle: torch.Tensor) -> torch.Tensor: + """ + Convert rotations given as axis/angle to quaternions. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + angles = torch.norm(axis_angle, p=2, dim=-1, keepdim=True) + half_angles = angles * 0.5 + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + quaternions = torch.cat( + [torch.cos(half_angles), axis_angle * sin_half_angles_over_angles], dim=-1 + ) + return quaternions + + +# NOTE: the code below is copied from PyTorch3D +# (https://github.com/facebookresearch/pytorch3d/blob/main/pytorch3d/transforms/rotation_conversions.py) +# See the license at https://github.com/facebookresearch/pytorch3d/blob/main/LICENSE +def quaternion_to_matrix(quaternions: torch.Tensor) -> torch.Tensor: + """ + Convert rotations given as quaternions to rotation matrices. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + # pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`. + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +# NOTE: the code below is copied from PyTorch3D +# (https://github.com/facebookresearch/pytorch3d/blob/main/pytorch3d/transforms/rotation_conversions.py) +# See the license at https://github.com/facebookresearch/pytorch3d/blob/main/LICENSE +def axis_angle_to_matrix(axis_angle: torch.Tensor) -> torch.Tensor: + """ + Convert rotations given as axis/angle to rotation matrices. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + return quaternion_to_matrix(axis_angle_to_quaternion(axis_angle)) + + +# NOTE: the code below is copied from PyTorch3D +# (https://github.com/facebookresearch/pytorch3d/blob/main/pytorch3d/transforms/rotation_conversions.py) +# See the license at https://github.com/facebookresearch/pytorch3d/blob/main/LICENSE +def _axis_angle_rotation(axis: str, angle: torch.Tensor) -> torch.Tensor: + """ + Return the rotation matrices for one of the rotations about an axis + of which Euler angles describe, for each value of the angle given. + + Args: + axis: Axis label "X" or "Y or "Z". + angle: any shape tensor of Euler angles in radians + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + cos = torch.cos(angle) + sin = torch.sin(angle) + one = torch.ones_like(angle) + zero = torch.zeros_like(angle) + + if axis == "X": + R_flat = (one, zero, zero, zero, cos, -sin, zero, sin, cos) + elif axis == "Y": + R_flat = (cos, zero, sin, zero, one, zero, -sin, zero, cos) + elif axis == "Z": + R_flat = (cos, -sin, zero, sin, cos, zero, zero, zero, one) + else: + raise ValueError("letter must be either X, Y or Z.") + + return torch.stack(R_flat, -1).reshape(angle.shape + (3, 3)) + + +# NOTE: the code below is copied from PyTorch3D +# (https://github.com/facebookresearch/pytorch3d/blob/main/pytorch3d/transforms/rotation_conversions.py) +# See the license at https://github.com/facebookresearch/pytorch3d/blob/main/LICENSE +def euler_angles_to_matrix(euler_angles: torch.Tensor, convention: str) -> torch.Tensor: + """ + Convert rotations given as Euler angles in radians to rotation matrices. + + Args: + euler_angles: Euler angles in radians as tensor of shape (..., 3). + convention: Convention string of three uppercase letters from + {"X", "Y", and "Z"}. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + if euler_angles.dim() == 0 or euler_angles.shape[-1] != 3: + raise ValueError("Invalid input euler angles.") + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + matrices = [ + _axis_angle_rotation(c, e) + for c, e in zip(convention, torch.unbind(euler_angles, -1)) + ] + # return functools.reduce(torch.matmul, matrices) + return torch.matmul(torch.matmul(matrices[0], matrices[1]), matrices[2]) + diff --git a/third_parties/dsine/utils/utils.py b/third_parties/dsine/utils/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..eb3f529fb5577b8bc0c32961d82d164a1e9268de --- /dev/null +++ b/third_parties/dsine/utils/utils.py @@ -0,0 +1,223 @@ +import os +import numpy as np +import torch +import torch.nn.functional as F +import torch.distributed as dist + +import logging +logger = logging.getLogger('root') + + +def load_checkpoint(fpath, model): + assert os.path.exists(fpath) + logger.info('loading checkpoint... %s' % fpath) + ckpt = torch.load(fpath, map_location='cpu')['model'] + + load_dict = {} + for k, v in ckpt.items(): + if k.startswith('module.'): + k_ = k.replace('module.', '') + load_dict[k_] = v + else: + load_dict[k] = v + + model.load_state_dict(load_dict) + logger.info('loading checkpoint... / done') + return model + + +def save_model(model, target_path, total_iter): + torch.save({"model": model.state_dict(), + # 'optimizer_state_dict': optimizer.state_dict(), + # 'lr_scheduler_state_dict': scheduler.state_dict(), + "iter": total_iter + }, target_path) + logger.info('model saved / path: {}'.format(target_path)) + + +class dotdict(dict): + __getattr__ = dict.get + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + + +def save_args(args, filename): + with open(filename, 'w') as f: + for arg in vars(args): + f.write('{}: {}\n'.format(arg, getattr(args, arg))) + + +def is_dist_avail_and_initialized(): + if not dist.is_available(): + return False + if not dist.is_initialized(): + return False + return True + + +def get_world_size(): + if not is_dist_avail_and_initialized(): + return 1 + return dist.get_world_size() + + +def get_local_rank(): + if not is_dist_avail_and_initialized(): + return 0 + return int(os.environ["LOCAL_RANK"]) + + +def txt_to_list(txt_path): + with open(txt_path, 'r') as f: + content = f.readlines() + content = [i.strip() for i in content] + return content + + +def setup_custom_logger(name, test=False): + formatter = logging.Formatter(fmt='[%(asctime)s]- %(levelname)s - %(module)s - %(message)s') + logger = logging.getLogger(name) + if test: + logger.setLevel(logging.INFO) + else: + logger.setLevel(logging.DEBUG) + + handler = logging.StreamHandler() + handler.setFormatter(formatter) + logger.addHandler(handler) + return logger + + +def change_logger_dest(logger, new_dest): + formatter = logging.Formatter(fmt='[%(asctime)s]- %(levelname)s - %(module)s - %(message)s') + handler = logging.FileHandler(new_dest, mode='a') + handler.setFormatter(formatter) + logger.addHandler(handler) + return logger + + +class RunningAverage: + def __init__(self): + self.avg = 0 + self.count = 0 + + def append(self, value, count_add=1): + self.avg = (count_add * value + self.count * self.avg) / (count_add + self.count) + self.count += count_add + + def get_value(self): + return self.avg + + +class RunningAverageDict: + def __init__(self): + self._dict = None + + def update(self, new_dict, count_add): + if self._dict is None: + self._dict = dict() + for key, value in new_dict.items(): + self._dict[key] = RunningAverage() + + for key, value in new_dict.items(): + self._dict[key].append(value, count_add) + + def get_value(self): + return {key: value.get_value() for key, value in self._dict.items()} + + +def compute_normal_error(pred_norm, gt_norm): + """ compute per-pixel surface normal error in degrees + NOTE: pred_norm and gt_norm should be torch tensors of shape (B, 3, ...) + """ + pred_error = torch.cosine_similarity(pred_norm, gt_norm, dim=1) + pred_error = torch.clamp(pred_error, min=-1.0, max=1.0) + pred_error = torch.acos(pred_error) * 180.0 / np.pi + pred_error = pred_error.unsqueeze(1) # (B, 1, ...) + return pred_error + + +def compute_normal_metrics(total_normal_errors): + """ compute surface normal metrics (used for benchmarking) + NOTE: total_normal_errors should be a 1D torch tensor of errors in degrees + """ + total_normal_errors = total_normal_errors.detach().cpu().numpy() + num_pixels = total_normal_errors.shape[0] + + metrics = { + 'mean': np.average(total_normal_errors), + 'median': np.median(total_normal_errors), + 'rmse': np.sqrt(np.sum(total_normal_errors * total_normal_errors) / num_pixels), + 'a1': 100.0 * (np.sum(total_normal_errors < 5) / num_pixels), + 'a2': 100.0 * (np.sum(total_normal_errors < 7.5) / num_pixels), + 'a3': 100.0 * (np.sum(total_normal_errors < 11.25) / num_pixels), + 'a4': 100.0 * (np.sum(total_normal_errors < 22.5) / num_pixels), + 'a5': 100.0 * (np.sum(total_normal_errors < 30) / num_pixels) + } + return metrics + + +def compute_normal_metrics2(total_normal_errors): + """ compute surface normal metrics (used for validation) + NOTE: total_normal_errors should be a 1D torch tensor of errors in degrees + """ + num_pixels = total_normal_errors.shape[0] + + metrics = { + 'mean': torch.mean(total_normal_errors).item(), + 'mse': torch.mean(total_normal_errors * total_normal_errors).item(), + 'a1': 100.0 * torch.mean((total_normal_errors < 5).float()).item(), + 'a2': 100.0 * torch.mean((total_normal_errors < 7.5).float()).item(), + 'a3': 100.0 * torch.mean((total_normal_errors < 11.25).float()).item(), + 'a4': 100.0 * torch.mean((total_normal_errors < 22.5).float()).item(), + 'a5': 100.0 * torch.mean((total_normal_errors < 30).float()).item(), + } + return metrics, num_pixels + + + +def get_padding(orig_H, orig_W): + """ returns how the input of shape (orig_H, orig_W) should be padded + this ensures that both H and W are divisible by 32 + """ + if orig_W % 32 == 0: + l = 0 + r = 0 + else: + new_W = 32 * ((orig_W // 32) + 1) + l = (new_W - orig_W) // 2 + r = (new_W - orig_W) - l + + if orig_H % 32 == 0: + t = 0 + b = 0 + else: + new_H = 32 * ((orig_H // 32) + 1) + t = (new_H - orig_H) // 2 + b = (new_H - orig_H) - t + return l, r, t, b + + +def pad_input(img, intrins, lrtb=(0,0,0,0)): + """ pad input image + img should be a torch tensor of shape (B, 3, H, W) + intrins should be a torch tensor of shape (B, 3, 3) + """ + l, r, t, b = lrtb + if l+r+t+b != 0: + pad_value_R = (0 - 0.485) / 0.229 + pad_value_G = (0 - 0.456) / 0.224 + pad_value_B = (0 - 0.406) / 0.225 + + img_R = F.pad(img[:,0:1,:,:], (l, r, t, b), mode="constant", value=pad_value_R) + img_G = F.pad(img[:,1:2,:,:], (l, r, t, b), mode="constant", value=pad_value_G) + img_B = F.pad(img[:,2:3,:,:], (l, r, t, b), mode="constant", value=pad_value_B) + + img = torch.cat([img_R, img_G, img_B], dim=1) + + if intrins is not None: + intrins[:, 0, 2] += l + intrins[:, 1, 2] += t + return img, intrins + + diff --git a/third_parties/dsine/utils/visualize.py b/third_parties/dsine/utils/visualize.py new file mode 100644 index 0000000000000000000000000000000000000000..5914672def71c7143c4f67e30600f078c810ee5a --- /dev/null +++ b/third_parties/dsine/utils/visualize.py @@ -0,0 +1,232 @@ +import cv2 +import numpy as np + +import torch + +from matplotlib import cm +import matplotlib.pyplot as plt + +import logging +logger = logging.getLogger('root') + +from utils.utils import compute_normal_error + + +def tensor_to_numpy(tensor_in): + """ torch tensor to numpy array + """ + if tensor_in is not None: + if tensor_in.ndim == 3: + # (C, H, W) -> (H, W, C) + tensor_in = tensor_in.detach().cpu().permute(1, 2, 0).numpy() + elif tensor_in.ndim == 4: + # (B, C, H, W) -> (B, H, W, C) + tensor_in = tensor_in.detach().cpu().permute(0, 2, 3, 1).numpy() + else: + raise Exception('invalid tensor size') + return tensor_in + + +def unnormalize(img_in, img_stats={'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225]}): + """ unnormalize input image + """ + if torch.is_tensor(img_in): + img_in = tensor_to_numpy(img_in) + + img_out = np.zeros_like(img_in) + for ich in range(3): + img_out[..., ich] = img_in[..., ich] * img_stats['std'][ich] + img_out[..., ich] += img_stats['mean'][ich] + img_out = (img_out * 255.0).astype(np.uint8) + return img_out + + +def normal_to_rgb(normal, normal_mask=None): + """ surface normal map to RGB + (used for visualization) + + NOTE: x, y, z are mapped to R, G, B + NOTE: [-1, 1] are mapped to [0, 255] + """ + if torch.is_tensor(normal): + normal = tensor_to_numpy(normal) + normal_mask = tensor_to_numpy(normal_mask) + + normal_norm = np.linalg.norm(normal, axis=-1, keepdims=True) + normal_norm[normal_norm < 1e-12] = 1e-12 + normal = normal / normal_norm + + normal_rgb = (((normal + 1) * 0.5) * 255).astype(np.uint8) + if normal_mask is not None: + normal_rgb = normal_rgb * normal_mask # (B, H, W, 3) + return normal_rgb + + +def normal_to_uint8(normal, valid_mask): + """ surface normal map to uint8 + (used to generate ground truth) + + NOTE: normal should be pre-normalized + """ + if torch.is_tensor(normal): + normal = tensor_to_numpy(normal) + valid_mask = tensor_to_numpy(valid_mask) + + norm_uint8 = ((normal + 1) * 0.5) * 255 + assert np.min(norm_uint8) >= 0 + assert np.max(norm_uint8) <= 255 + norm_uint8 = np.rint(norm_uint8).astype(np.uint8) + norm_uint8 = norm_uint8 * valid_mask + return norm_uint8 + + +def normal_to_uint16(normal, valid_mask): + """ surface normal map to uint16 + (used to generate ground truth) + + NOTE: normal should be pre-normalized + """ + if torch.is_tensor(normal): + normal = tensor_to_numpy(normal) + valid_mask = tensor_to_numpy(valid_mask) + + norm_uint16 = ((normal + 1) * 0.5) * 65535 + assert np.min(norm_uint16) >= 0 + assert np.max(norm_uint16) <= 65535 + norm_uint16 = np.rint(norm_uint16).astype(np.uint16) + norm_uint16 = norm_uint16 * valid_mask + return norm_uint16 + + +def kappa_to_alpha(pred_kappa, to_numpy=True): + """ Confidence kappa to uncertainty alpha + Assuming AngMF distribution (introduced in https://arxiv.org/abs/2109.09881) + """ + if torch.is_tensor(pred_kappa) and to_numpy: + pred_kappa = tensor_to_numpy(pred_kappa) + + if torch.is_tensor(pred_kappa): + alpha = ((2 * pred_kappa) / ((pred_kappa ** 2.0) + 1)) \ + + ((torch.exp(- pred_kappa * np.pi) * np.pi) / (1 + torch.exp(- pred_kappa * np.pi))) + alpha = torch.rad2deg(alpha) + else: + alpha = ((2 * pred_kappa) / ((pred_kappa ** 2.0) + 1)) \ + + ((np.exp(- pred_kappa * np.pi) * np.pi) / (1 + np.exp(- pred_kappa * np.pi))) + alpha = np.degrees(alpha) + + return alpha + + +def alpha_to_jet(pred_alpha, a_max=60.0): + """ Uncertainty alpha to JET + (used for visualization) + """ + pred_alpha = np.clip(pred_alpha, a_min=0.0, a_max=a_max) + pred_alpha = ((pred_alpha[0,:,:,:] / 60.0) * 255.0).astype(np.uint8) + pred_alpha = cv2.applyColorMap(pred_alpha, cv2.COLORMAP_JET) + return pred_alpha + + +def depth_to_rgb(depth, depth_mask=None, d_min=None, d_max=None, colormap='jet'): + """ Convert depth map, or any 1D map to RGB using colormap + """ + assert depth.ndim == 3 + if torch.is_tensor(depth): + depth = tensor_to_numpy(depth) + depth_mask = tensor_to_numpy(depth_mask) + + if d_min is not None: + depth[depth < d_min] = d_min + else: + d_min = np.min(depth) + + if d_max is not None: + depth[depth > d_max] = d_max + else: + d_max = np.max(depth) + + depth = (depth - d_min) / abs(d_max - d_min) + + if colormap == 'jet': + depth = (cm.jet(depth[:,:,0]) * 255).astype(np.uint8) + depth = depth[:,:,:3] + elif colormap == 'gray': + depth = (cm.gray(depth[:,:,0]) * 255).astype(np.uint8) + depth = depth[:,:,:3] + if depth_mask is not None: + depth = depth * depth_mask + + return depth + + +def visualize_normal(target_dir, prefixs, img, pred_norm, pred_kappa, + gt_norm, gt_norm_mask, pred_error, num_vis=-1): + """ visualize normal + """ + error_max = 60.0 + + img = tensor_to_numpy(img) # (B, H, W, 3) + pred_norm = tensor_to_numpy(pred_norm) # (B, H, W, 3) + pred_kappa = tensor_to_numpy(pred_kappa) # (B, H, W, 1) + gt_norm = tensor_to_numpy(gt_norm) # (B, H, W, 3) + gt_norm_mask = tensor_to_numpy(gt_norm_mask) # (B, H, W, 1) + pred_error = tensor_to_numpy(pred_error) # (B, H, W, 1) + + num_vis = len(prefixs) if num_vis == -1 else num_vis + for i in range(num_vis): + # img + img_ = unnormalize(img[i, ...]) + target_path = '%s/%s_img.png' % (target_dir, prefixs[i]) + plt.imsave(target_path, img_) + + # pred_norm + target_path = '%s/%s_norm.png' % (target_dir, prefixs[i]) + plt.imsave(target_path, normal_to_rgb(pred_norm[i, ...])) + + # pred_kappa + if pred_kappa is not None: + pred_alpha = kappa_to_alpha(pred_kappa[i, :, :, 0]) + target_path = '%s/%s_pred_alpha.png' % (target_dir, prefixs[i]) + plt.imsave(target_path, pred_alpha, vmin=0.0, vmax=error_max, cmap='jet') + + # gt_norm, pred_error + if gt_norm is not None: + target_path = '%s/%s_gt.png' % (target_dir, prefixs[i]) + plt.imsave(target_path, normal_to_rgb(gt_norm[i, ...], gt_norm_mask[i, ...])) + + E = pred_error[i, :, :, 0] * gt_norm_mask[i, :, :, 0] + target_path = '%s/%s_pred_error.png' % (target_dir, prefixs[i]) + plt.imsave(target_path, E, vmin=0, vmax=error_max, cmap='jet') + + +def visualize_normal_tb(args, img, norm_out, gt_norm, gt_norm_mask): + """ visualize normal (tensorboard logging) + """ + pred_norm = norm_out[:, :3, :, :] + pred_kappa = norm_out[:, 3:, :, :] if args.NNET_output_dim == 4 else None + pred_error = compute_normal_error(pred_norm, gt_norm) + error_max = 60.0 + + img = tensor_to_numpy(img) # (B, H, W, 3) + pred_norm = tensor_to_numpy(pred_norm) # (B, H, W, 3) + pred_kappa = tensor_to_numpy(pred_kappa) # (B, H, W, 1) + gt_norm = tensor_to_numpy(gt_norm) # (B, H, W, 3) + gt_norm_mask = tensor_to_numpy(gt_norm_mask) # (B, H, W, 1) + pred_error = tensor_to_numpy(pred_error) # (B, H, W, 1) + + # visualize + vis_list = [] + vis_list.append(unnormalize(img[0, ...])) + vis_list.append(normal_to_rgb(pred_norm[0, ...])) + if pred_kappa is not None: + if 'NLL_angmf' in args.loss_fn: + vis_list.append(depth_to_rgb(kappa_to_alpha(pred_kappa[0, ...]), None, d_min=0.0, d_max=error_max)) + else: + vis_list.append(depth_to_rgb(pred_kappa[0, ...], None, d_min=0.0, d_max=None, colormap='gray')) + if gt_norm is not None: + vis_list.append(normal_to_rgb(gt_norm[0, ...], gt_norm_mask[0, ...])) + vis_list.append(depth_to_rgb(pred_error[0, ...], gt_norm_mask[0, ...], d_min=0.0, d_max=error_max)) + + return np.hstack(vis_list).astype(np.uint8) + diff --git a/train.py b/train.py new file mode 100644 index 0000000000000000000000000000000000000000..6913cda7eb1b608250221e4049e77339742a841d --- /dev/null +++ b/train.py @@ -0,0 +1,200 @@ +import os +import sys +import json +import glob +import argparse +import traceback +from easydict import EasyDict as edict + +import torch +import torch.multiprocessing as mp +import numpy as np +import random + +from anigen import models, datasets, trainers +from anigen.utils.dist_utils import setup_dist +import torch.distributed as dist + +try: + from torch.distributed.elastic.multiprocessing.errors import record +except ImportError: # pragma: no cover - elastic may be unavailable in older Torch versions + def record(fn): # type: ignore + return fn + + +def find_ckpt(cfg): + # Load checkpoint + cfg['load_ckpt'] = None + if cfg.load_dir != '': + if cfg.ckpt == 'latest': + files = glob.glob(os.path.join(cfg.load_dir, 'ckpts', '*.pt')) + if len(files) != 0: + steps = [] + for f in files: + try: + steps.append(int(os.path.basename(f).split('step')[-1].split('.')[0])) + except (ValueError, IndexError): + pass + if len(steps) > 0: + cfg.load_ckpt = max(steps) + elif cfg.ckpt == 'none': + cfg.load_ckpt = None + else: + cfg.load_ckpt = int(cfg.ckpt) + return cfg + + +def setup_rng(rank): + torch.manual_seed(rank) + torch.cuda.manual_seed_all(rank) + np.random.seed(rank) + random.seed(rank) + + +def get_model_summary(model): + model_summary = 'Parameters:\n' + model_summary += '=' * 128 + '\n' + model_summary += f'{"Name":<{72}}{"Shape":<{32}}{"Type":<{16}}{"Grad"}\n' + num_params = 0 + num_trainable_params = 0 + for name, param in model.named_parameters(): + model_summary += f'{name:<{72}}{str(param.shape):<{32}}{str(param.dtype):<{16}}{param.requires_grad}\n' + num_params += param.numel() + if param.requires_grad: + num_trainable_params += param.numel() + model_summary += '\n' + model_summary += f'Number of parameters: {num_params}\n' + model_summary += f'Number of trainable parameters: {num_trainable_params}\n' + return model_summary + + +def main(local_rank, cfg): + # Set up distributed training + rank = cfg.node_rank * cfg.num_gpus + local_rank + world_size = cfg.num_nodes * cfg.num_gpus + # if world_size > 1: + setup_dist(rank, local_rank, world_size, cfg.master_addr, cfg.master_port) + + # Seed rngs + setup_rng(rank) + + # Load data + dataset = getattr(datasets, cfg.dataset.name)(cfg.data_dir, **cfg.dataset.args, local_rank=local_rank) + + # Build model + model_dict = { + name: getattr(models, model.name)(**model.args).cuda() + for name, model in cfg.models.items() + } + + # Model summary + if rank == 0: + for name, backbone in model_dict.items(): + model_summary = get_model_summary(backbone) + # print(f'\n\nBackbone: {name}\n' + model_summary) + with open(os.path.join(cfg.output_dir, f'{name}_model_summary.txt'), 'w') as fp: + print(model_summary, file=fp) + + # Build trainer + trainer = getattr(trainers, cfg.trainer.name)(model_dict, dataset, **cfg.trainer.args, output_dir=cfg.output_dir, load_dir=cfg.load_dir, step=cfg.load_ckpt, skip_init_snapshot=cfg.skip_init_snapshot) + + # Train + if not cfg.tryrun: + if cfg.profile: + trainer.profile() + else: + trainer.run() + + if dist.is_initialized(): + dist.destroy_process_group() + + +@record +def _spawn_worker(local_rank, cfg): + try: + main(local_rank, cfg) + except BaseException: + traceback.print_exc() + sys.stderr.flush() + sys.stdout.flush() + raise + finally: + if dist.is_initialized(): + try: + dist.destroy_process_group() + except Exception: + pass + + +if __name__ == '__main__': + # Arguments and config + parser = argparse.ArgumentParser() + ## config + parser.add_argument('--config', type=str, required=True, help='Experiment config file') + ## io and resume + parser.add_argument('--output_dir', type=str, required=True, help='Output directory') + parser.add_argument('--load_dir', type=str, default='', help='Load directory, default to output_dir') + parser.add_argument('--ckpt', type=str, default='latest', help='Checkpoint step to resume training, default to latest') + parser.add_argument('--data_dir', type=str, default='', help='Data directory') + parser.add_argument('--auto_retry', type=int, default=3, help='Number of retries on error') + ## dubug + parser.add_argument('--tryrun', action='store_true', help='Try run without training') + parser.add_argument('--profile', action='store_true', help='Profile training') + ## multi-node and multi-gpu + parser.add_argument('--num_nodes', type=int, default=1, help='Number of nodes') + parser.add_argument('--node_rank', type=int, default=0, help='Node rank') + parser.add_argument('--num_gpus', type=int, default=-1, help='Number of GPUs per node, default to all') + parser.add_argument('--master_addr', type=str, default='localhost', help='Master address for distributed training') + parser.add_argument('--master_port', type=str, default='12345', help='Port for distributed training') + parser.add_argument('--skip_init_snapshot', action='store_true', help='Skip initial snapshot of dataset') + opt = parser.parse_args() + opt.load_dir = opt.load_dir if opt.load_dir != '' else opt.output_dir + opt.num_gpus = torch.cuda.device_count() if opt.num_gpus == -1 else opt.num_gpus + ## Load config + config = json.load(open(opt.config, 'r')) + ## Combine arguments and config + cfg = edict() + cfg.update(opt.__dict__) + cfg.update(config) + + os.environ.setdefault('NCCL_ASYNC_ERROR_HANDLING', '1') + os.environ.setdefault('TORCH_NCCL_BLOCKING_WAIT', '1') + os.environ.setdefault('TORCH_DISABLE_ADDR2LINE', '1') + os.environ.setdefault('PYTHONFAULTHANDLER', '1') + try: + mp.set_start_method('spawn') + except RuntimeError: + pass + + # Prepare output directory + if cfg.node_rank == 0: + os.makedirs(cfg.output_dir, exist_ok=True) + ## Save command and config + with open(os.path.join(cfg.output_dir, 'command.txt'), 'w') as fp: + print(' '.join(['python'] + sys.argv), file=fp) + with open(os.path.join(cfg.output_dir, 'config.json'), 'w') as fp: + json.dump(config, fp, indent=4) + + # Run + if cfg.auto_retry == 0: + cfg = find_ckpt(cfg) + if cfg.num_gpus > 1: + mp.spawn(_spawn_worker, args=(cfg,), nprocs=cfg.num_gpus, join=True) + else: + _spawn_worker(0, cfg) + else: + for rty in range(cfg.auto_retry): + try: + cfg = find_ckpt(cfg) + if cfg.num_gpus > 1: + mp.spawn(_spawn_worker, args=(cfg,), nprocs=cfg.num_gpus, join=True) + else: + _spawn_worker(0, cfg) + break + except Exception as e: + traceback.print_exc() + print(f'Error: {e}', flush=True) + if rty + 1 == cfg.auto_retry: + raise + print(f'Retrying ({rty + 1}/{cfg.auto_retry})...', flush=True) + \ No newline at end of file