Skip to content

Instantly share code, notes, and snippets.

@stwind
Last active March 2, 2025 10:07
Show Gist options
  • Save stwind/b416c7485825ee158f673a703adbc2ab to your computer and use it in GitHub Desktop.
Save stwind/b416c7485825ee158f673a703adbc2ab to your computer and use it in GitHub Desktop.
dsdfr_amass.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"collapsed_sections": [
"rdd4k58h--OV",
"HcY5qOGVx0pe",
"p_ogqqtmx1sO",
"LtStOkIl_B7g",
"4rN0nR9N_FrB",
"R8lkDJfB_IcG",
"1kT-qQCN_K5t",
"8LpdeYz5_MCH",
"24rC-RS2_OBT",
"EWn7xWXh_Qix"
],
"machine_shape": "hm",
"gpuType": "L4",
"authorship_tag": "ABX9TyNpRCLtWVATwdaqlAOL2i9v",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/stwind/b416c7485825ee158f673a703adbc2ab/dsdfr_amass.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"source": [
"!nvidia-smi --query-gpu=name,memory.total --format=csv,noheader"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "vv2sYz00xiiw",
"outputId": "a1bebf9a-549d-4660-ffbb-04f85d2932ba"
},
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"NVIDIA L4, 23034 MiB\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"## Setup"
],
"metadata": {
"id": "7BFLyyJl-8_t"
}
},
{
"cell_type": "markdown",
"source": [
"### Dependencies"
],
"metadata": {
"id": "rdd4k58h--OV"
}
},
{
"cell_type": "markdown",
"source": [
"#### Common"
],
"metadata": {
"id": "HcY5qOGVx0pe"
}
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jHtu0f2h-3yQ",
"outputId": "7f2e8bac-e18c-4ffb-cf66-57bf1e718cab"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.7/57.7 MB\u001b[0m \u001b[31m9.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.3/4.3 MB\u001b[0m \u001b[31m9.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.9/66.9 kB\u001b[0m \u001b[31m261.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m708.6/708.6 kB\u001b[0m \u001b[31m337.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h"
]
}
],
"source": [
"!pip install --no-cache-dir -Uq einops ffmpeg-python mitsuba==3.6.0 fastsweep trimesh"
]
},
{
"cell_type": "markdown",
"source": [
"#### OpenVDB"
],
"metadata": {
"id": "p_ogqqtmx1sO"
}
},
{
"cell_type": "code",
"source": [
"!apt-get update -yqq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends libjemalloc-dev"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "3s6eSPh3xjge",
"outputId": "351caf7b-c7ff-4a8b-9e0d-37995a6cfc3f"
},
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"W: Skipping acquire of configured file 'main/source/Sources' as repository 'https://r2u.stat.illinois.edu/ubuntu jammy InRelease' does not seem to provide it (sources.list entry misspelt?)\n",
"Selecting previously unselected package libjemalloc2:amd64.\n",
"(Reading database ... 124947 files and directories currently installed.)\n",
"Preparing to unpack .../libjemalloc2_5.2.1-4ubuntu1_amd64.deb ...\n",
"Unpacking libjemalloc2:amd64 (5.2.1-4ubuntu1) ...\n",
"Selecting previously unselected package libjemalloc-dev.\n",
"Preparing to unpack .../libjemalloc-dev_5.2.1-4ubuntu1_amd64.deb ...\n",
"Unpacking libjemalloc-dev (5.2.1-4ubuntu1) ...\n",
"Setting up libjemalloc2:amd64 (5.2.1-4ubuntu1) ...\n",
"Setting up libjemalloc-dev (5.2.1-4ubuntu1) ...\n",
"Processing triggers for man-db (2.10.2-1) ...\n",
"Processing triggers for libc-bin (2.35-0ubuntu3.8) ...\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbb.so.12 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libhwloc.so.15 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libumf.so.0 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbbbind_2_0.so.3 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbbbind_2_5.so.3 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbbmalloc.so.2 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbbmalloc_proxy.so.2 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtcm.so.1 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libur_adapter_opencl.so.0 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtcm_debug.so.1 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libtbbbind.so.3 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libur_adapter_level_zero.so.0 is not a symbolic link\n",
"\n",
"/sbin/ldconfig.real: /usr/local/lib/libur_loader.so.0 is not a symbolic link\n",
"\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"!pip install -Uq conan nanobind"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "SgfEfe4GxnB8",
"outputId": "2b072c5f-3510-46de-bb50-787b8aeb017b"
},
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m485.7/485.7 kB\u001b[0m \u001b[31m922.7 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
" Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
" Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
" Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
" Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
" Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m236.9/236.9 kB\u001b[0m \u001b[31m26.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m124.2/124.2 kB\u001b[0m \u001b[31m15.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Building wheel for conan (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
" Building wheel for patch-ng (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"!wget -qc --show-progress https://github.com/AcademySoftwareFoundation/openvdb/archive/refs/tags/v12.0.0.tar.gz && tar -zxf v12.0.0.tar.gz"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ux6SjGXBxpZV",
"outputId": "1e2dd65b-5c1a-4cb7-a6f5-45b10bc4a421"
},
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"v12.0.0.tar.gz [ <=> ] 4.47M 7.74MB/s in 0.6s \n"
]
}
]
},
{
"cell_type": "code",
"source": [
"%%bash\n",
"\n",
"set -euxo pipefail\n",
"\n",
"cat << EOF > /content/conanfile.txt\n",
"[requires]\n",
"boost/1.86.0\n",
"\n",
"[generators]\n",
"CMakeDeps\n",
"CMakeToolchain\n",
"EOF\n",
"\n",
"conan profile detect --force -vquiet\n",
"conan install /content --output-folder=/content/build --build=missing -vquiet"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "uUn_z-MExpQo",
"outputId": "29cd0125-99a8-424e-e928-1d6dbd2531e8"
},
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"[settings]\n",
"arch=x86_64\n",
"build_type=Release\n",
"compiler=gcc\n",
"compiler.cppstd=gnu17\n",
"compiler.libcxx=libstdc++11\n",
"compiler.version=11\n",
"os=Linux\n",
"\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"+ cat\n",
"+ conan profile detect --force -vquiet\n",
"+ conan install /content --output-folder=/content/build --build=missing -vquiet\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"!cd openvdb-12.0.0 && \\\n",
" cmake -B build \\\n",
" -DCMAKE_TOOLCHAIN_FILE=/content/build/conan_toolchain.cmake \\\n",
" -Dnanobind_DIR=$(python -m nanobind --cmake_dir) \\\n",
" -DUSE_NUMPY=ON \\\n",
" -DOPENVDB_BUILD_PYTHON_MODULE=ON -DOPENVDB_BUILD_VDB_RENDER=ON . && \\\n",
" cmake --build build -- -j$(nproc) && \\\n",
" cmake --install build"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jvN9D0lNx3JX",
"outputId": "e2e4a3e1-18e9-481a-9183-92c6f1b25b94"
},
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"-- Using Conan toolchain: /content/build/conan_toolchain.cmake\n",
"-- Conan toolchain: Defining architecture flag: -m64\n",
"-- Conan toolchain: C++ Standard 17 with extensions ON\n",
"-- The CXX compiler identification is GNU 11.4.0\n",
"-- Detecting CXX compiler ABI info\n",
"-- Detecting CXX compiler ABI info - done\n",
"-- Check for working CXX compiler: /usr/bin/c++ - skipped\n",
"-- Detecting CXX compile features\n",
"-- Detecting CXX compile features - done\n",
"-- CMake Build Type: Release\n",
"-- Found PkgConfig: /usr/bin/pkg-config (found version \"1.8.0\")\n",
"-- Configuring for OpenVDB Version 12.0.0\n",
"-- Found Python: /usr/local/bin/python (found suitable version \"3.11.11\", minimum required is \"3.10\") found components: Development Interpreter Development.Module Development.Embed\n",
"-- Configuring for OpenVDB ABI Version 12\n",
"-- ----------------------------------------------------\n",
"-- ------------- Configuring OpenVDBCore --------------\n",
"-- ----------------------------------------------------\n",
"-- Conan: Component target declared 'Boost::diagnostic_definitions'\n",
"-- Conan: Component target declared 'Boost::disable_autolinking'\n",
"-- Conan: Component target declared 'Boost::dynamic_linking'\n",
"-- Conan: Component target declared 'Boost::headers'\n",
"-- Conan: Component target declared 'Boost::boost'\n",
"-- Conan: Component target declared 'boost::_libboost'\n",
"-- Conan: Component target declared 'Boost::atomic'\n",
"-- Conan: Component target declared 'Boost::charconv'\n",
"-- Conan: Component target declared 'Boost::container'\n",
"-- Conan: Component target declared 'Boost::context'\n",
"-- Conan: Component target declared 'Boost::date_time'\n",
"-- Conan: Component target declared 'Boost::exception'\n",
"-- Conan: Component target declared 'Boost::math'\n",
"-- Conan: Component target declared 'Boost::program_options'\n",
"-- Conan: Component target declared 'Boost::regex'\n",
"-- Conan: Component target declared 'Boost::serialization'\n",
"-- Conan: Component target declared 'Boost::stacktrace'\n",
"-- Conan: Component target declared 'Boost::system'\n",
"-- Conan: Component target declared 'Boost::timer'\n",
"-- Conan: Component target declared 'Boost::chrono'\n",
"-- Conan: Component target declared 'Boost::coroutine'\n",
"-- Conan: Component target declared 'Boost::filesystem'\n",
"-- Conan: Component target declared 'Boost::json'\n",
"-- Conan: Component target declared 'Boost::math_c99'\n",
"-- Conan: Component target declared 'Boost::math_c99f'\n",
"-- Conan: Component target declared 'Boost::math_c99l'\n",
"-- Conan: Component target declared 'Boost::math_tr1'\n",
"-- Conan: Component target declared 'Boost::math_tr1f'\n",
"-- Conan: Component target declared 'Boost::math_tr1l'\n",
"-- Conan: Component target declared 'Boost::random'\n",
"-- Conan: Component target declared 'Boost::stacktrace_addr2line'\n",
"-- Conan: Component target declared 'Boost::stacktrace_backtrace'\n",
"-- Conan: Component target declared 'Boost::stacktrace_basic'\n",
"-- Conan: Component target declared 'Boost::stacktrace_from_exception'\n",
"-- Conan: Component target declared 'Boost::stacktrace_noop'\n",
"-- Conan: Component target declared 'Boost::test'\n",
"-- Conan: Component target declared 'Boost::url'\n",
"-- Conan: Component target declared 'Boost::wserialization'\n",
"-- Conan: Component target declared 'Boost::fiber'\n",
"-- Conan: Component target declared 'Boost::graph'\n",
"-- Conan: Component target declared 'Boost::iostreams'\n",
"-- Conan: Component target declared 'Boost::nowide'\n",
"-- Conan: Component target declared 'Boost::prg_exec_monitor'\n",
"-- Conan: Component target declared 'Boost::process'\n",
"-- Conan: Component target declared 'Boost::test_exec_monitor'\n",
"-- Conan: Component target declared 'Boost::thread'\n",
"-- Conan: Component target declared 'Boost::wave'\n",
"-- Conan: Component target declared 'Boost::contract'\n",
"-- Conan: Component target declared 'Boost::fiber_numa'\n",
"-- Conan: Component target declared 'Boost::locale'\n",
"-- Conan: Component target declared 'Boost::log'\n",
"-- Conan: Component target declared 'Boost::type_erasure'\n",
"-- Conan: Component target declared 'Boost::unit_test_framework'\n",
"-- Conan: Component target declared 'Boost::log_setup'\n",
"-- Conan: Target declared 'boost::boost'\n",
"-- Conan: Target declared 'ZLIB::ZLIB'\n",
"-- Conan: Target declared 'BZip2::BZip2'\n",
"-- Conan: Including build module from '/root/.conan2/p/bzip23c098e896e3ea/p/lib/cmake/conan-official-bzip2-variables.cmake'\n",
"-- Conan: Target declared 'libbacktrace::libbacktrace'\n",
"\u001b[0mCMake Deprecation Warning at openvdb/openvdb/CMakeLists.txt:118 (message):\n",
" Support for Boost versions < 1.82 is deprecated and will be removed.\n",
"\n",
"\u001b[0m\n",
"-- Found Blosc: /usr/lib/x86_64-linux-gnu/libblosc.so (found suitable version \"1.21.1\", minimum required is \"1.17.0\")\n",
"-- Performing Test CMAKE_HAVE_LIBC_PTHREAD\n",
"-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success\n",
"-- Found Threads: TRUE\n",
"-- ----------------------------------------------------\n",
"-- ------------ Configuring OpenVDBPython -------------\n",
"-- ----------------------------------------------------\n",
"-- ----------------------------------------------------\n",
"-- ----------- Configuring OpenVDBBinaries ------------\n",
"-- ----------------------------------------------------\n",
"-- Found Jemalloc: /usr/lib/x86_64-linux-gnu/libjemalloc.so\n",
"-- Configuring done (1.3s)\n",
"-- Generating done (0.1s)\n",
"-- Build files have been written to: /content/openvdb-12.0.0/build\n",
"[ 0%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_internals.cpp.o\u001b[0m\n",
"[ 1%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_func.cpp.o\u001b[0m\n",
"[ 1%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_type.cpp.o\u001b[0m\n",
"[ 2%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_enum.cpp.o\u001b[0m\n",
"[ 2%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_ndarray.cpp.o\u001b[0m\n",
"[ 3%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_ft.cpp.o\u001b[0m\n",
"[ 3%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/nb_static_property.cpp.o\u001b[0m\n",
"[ 4%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/common.cpp.o\u001b[0m\n",
"[ 4%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/error.cpp.o\u001b[0m\n",
"[ 5%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/trampoline.cpp.o\u001b[0m\n",
"[ 6%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/VolumeToSpheres.cc.o\u001b[0m\n",
"[ 7%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/VolumeToSpheres.cc.o\u001b[0m\n",
"[ 7%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/VolumeToMesh.cc.o\u001b[0m\n",
"[ 8%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/VolumeAdvect.cc.o\u001b[0m\n",
"[ 8%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/VelocityFields.cc.o\u001b[0m\n",
"[ 10%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/VectorTransformer.cc.o\u001b[0m\n",
"[ 10%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/nanobind-static.dir/usr/local/lib/python3.11/dist-packages/nanobind/src/implicit.cpp.o\u001b[0m\n",
"[ 11%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/ValueTransformer.cc.o\u001b[0m\n",
"[ 11%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/TopologyToLevelSet.cc.o\u001b[0m\n",
"[ 12%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Statistics.cc.o\u001b[0m\n",
"[ 12%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/SignedFloodFill.cc.o\u001b[0m\n",
"[ 13%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/RayTracer.cc.o\u001b[0m\n",
"[ 13%] \u001b[32m\u001b[1mLinking CXX static library libnanobind-static.a\u001b[0m\n",
"[ 13%] Built target nanobind-static\n",
"[ 13%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/RayIntersector.cc.o\u001b[0m\n",
"[ 14%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Prune.cc.o\u001b[0m\n",
"[ 14%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PotentialFlow.cc.o\u001b[0m\n",
"[ 15%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PoissonSolver.cc.o\u001b[0m\n",
"[ 15%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PointsToMask.cc.o\u001b[0m\n",
"[ 16%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PointScatter.cc.o\u001b[0m\n",
"[ 17%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PointPartitioner.cc.o\u001b[0m\n",
"[ 17%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PointIndexGrid.cc.o\u001b[0m\n",
"[ 18%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/PointAdvect.cc.o\u001b[0m\n",
"[ 18%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/ParticlesToLevelSet.cc.o\u001b[0m\n",
"[ 19%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/ParticleAtlas.cc.o\u001b[0m\n",
"[ 19%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/NodeVisitor.cc.o\u001b[0m\n",
"[ 20%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/MultiResGrid.cc.o\u001b[0m\n",
"[ 20%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Morphology.cc.o\u001b[0m\n",
"[ 21%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/MeshToVolume.cc.o\u001b[0m\n",
"[ 22%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Merge.cc.o\u001b[0m\n",
"[ 22%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Mask.cc.o\u001b[0m\n",
"[ 23%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetUtil.cc.o\u001b[0m\n",
"[ 23%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetTracker.cc.o\u001b[0m\n",
"[ 24%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetSphere.cc.o\u001b[0m\n",
"[ 24%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/VolumeToMesh.cc.o\u001b[0m\n",
"[ 25%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/VolumeAdvect.cc.o\u001b[0m\n",
"[ 25%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/VelocityFields.cc.o\u001b[0m\n",
"[ 25%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetRebuild.cc.o\u001b[0m\n",
"[ 26%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/VectorTransformer.cc.o\u001b[0m\n",
"[ 26%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/ValueTransformer.cc.o\u001b[0m\n",
"[ 27%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/TopologyToLevelSet.cc.o\u001b[0m\n",
"[ 28%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetPlatonic.cc.o\u001b[0m\n",
"[ 28%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetMorph.cc.o\u001b[0m\n",
"[ 29%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Statistics.cc.o\u001b[0m\n",
"[ 30%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetMeasure.cc.o\u001b[0m\n",
"[ 31%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetFracture.cc.o\u001b[0m\n",
"[ 31%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetFilter.cc.o\u001b[0m\n",
"[ 32%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/LevelSetAdvect.cc.o\u001b[0m\n",
"[ 32%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Interpolation.cc.o\u001b[0m\n",
"[ 33%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/GridTransformer.cc.o\u001b[0m\n",
"[ 33%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/GridOperators.cc.o\u001b[0m\n",
"[ 34%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/FindActiveValues.cc.o\u001b[0m\n",
"[ 34%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/SignedFloodFill.cc.o\u001b[0m\n",
"[ 35%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/RayTracer.cc.o\u001b[0m\n",
"[ 35%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/RayIntersector.cc.o\u001b[0m\n",
"[ 36%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Prune.cc.o\u001b[0m\n",
"[ 36%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PotentialFlow.cc.o\u001b[0m\n",
"[ 36%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Filter.cc.o\u001b[0m\n",
"[ 37%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/FastSweeping.cc.o\u001b[0m\n",
"[ 38%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Diagnostics.cc.o\u001b[0m\n",
"[ 38%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/DenseSparseTools.cc.o\u001b[0m\n",
"[ 39%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Dense.cc.o\u001b[0m\n",
"[ 40%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PoissonSolver.cc.o\u001b[0m\n",
"[ 40%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Count.cc.o\u001b[0m\n",
"[ 41%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Composite.cc.o\u001b[0m\n",
"[ 41%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PointsToMask.cc.o\u001b[0m\n",
"[ 41%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Clip.cc.o\u001b[0m\n",
"[ 42%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/ChangeBackground.cc.o\u001b[0m\n",
"[ 43%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PointScatter.cc.o\u001b[0m\n",
"[ 43%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PointPartitioner.cc.o\u001b[0m\n",
"[ 44%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PointIndexGrid.cc.o\u001b[0m\n",
"[ 44%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/instantiations/Activate.cc.o\u001b[0m\n",
"[ 45%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/PointAdvect.cc.o\u001b[0m\n",
"[ 46%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/Grid.cc.o\u001b[0m\n",
"[ 46%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/Archive.cc.o\u001b[0m\n",
"[ 46%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/ParticlesToLevelSet.cc.o\u001b[0m\n",
"[ 47%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/ParticleAtlas.cc.o\u001b[0m\n",
"[ 48%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/Compression.cc.o\u001b[0m\n",
"[ 48%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/NodeVisitor.cc.o\u001b[0m\n",
"[ 49%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/DelayedLoadMetadata.cc.o\u001b[0m\n",
"[ 50%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/MultiResGrid.cc.o\u001b[0m\n",
"[ 50%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/File.cc.o\u001b[0m\n",
"[ 51%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/GridDescriptor.cc.o\u001b[0m\n",
"[ 51%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/Queue.cc.o\u001b[0m\n",
"[ 52%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/Stream.cc.o\u001b[0m\n",
"[ 52%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/io/TempFile.cc.o\u001b[0m\n",
"[ 53%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/math/Half.cc.o\u001b[0m\n",
"[ 53%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/math/Maps.cc.o\u001b[0m\n",
"[ 54%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/math/Proximity.cc.o\u001b[0m\n",
"[ 54%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Morphology.cc.o\u001b[0m\n",
"[ 55%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/MeshToVolume.cc.o\u001b[0m\n",
"[ 56%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/math/QuantizedUnitVec.cc.o\u001b[0m\n",
"[ 56%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/math/Transform.cc.o\u001b[0m\n",
"[ 57%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/Metadata.cc.o\u001b[0m\n",
"[ 57%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/MetaMap.cc.o\u001b[0m\n",
"[ 58%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/openvdb.cc.o\u001b[0m\n",
"[ 58%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/Platform.cc.o\u001b[0m\n",
"[ 59%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/AttributeArray.cc.o\u001b[0m\n",
"[ 59%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/AttributeArrayString.cc.o\u001b[0m\n",
"[ 60%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/AttributeGroup.cc.o\u001b[0m\n",
"[ 61%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/AttributeSet.cc.o\u001b[0m\n",
"[ 61%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/StreamCompression.cc.o\u001b[0m\n",
"[ 62%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/points/points.cc.o\u001b[0m\n",
"[ 62%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/util/Assert.cc.o\u001b[0m\n",
"[ 63%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_static.dir/util/Formats.cc.o\u001b[0m\n",
"[ 63%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Merge.cc.o\u001b[0m\n",
"[ 64%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Mask.cc.o\u001b[0m\n",
"[ 65%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetUtil.cc.o\u001b[0m\n",
"[ 65%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetTracker.cc.o\u001b[0m\n",
"[ 66%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetSphere.cc.o\u001b[0m\n",
"[ 66%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetRebuild.cc.o\u001b[0m\n",
"[ 67%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetPlatonic.cc.o\u001b[0m\n",
"[ 67%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetMorph.cc.o\u001b[0m\n",
"[ 68%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetMeasure.cc.o\u001b[0m\n",
"[ 68%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetFracture.cc.o\u001b[0m\n",
"[ 69%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetFilter.cc.o\u001b[0m\n",
"[ 70%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/LevelSetAdvect.cc.o\u001b[0m\n",
"[ 70%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Interpolation.cc.o\u001b[0m\n",
"[ 71%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/GridTransformer.cc.o\u001b[0m\n",
"[ 71%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/GridOperators.cc.o\u001b[0m\n",
"[ 72%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/FindActiveValues.cc.o\u001b[0m\n",
"[ 72%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Filter.cc.o\u001b[0m\n",
"[ 73%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/FastSweeping.cc.o\u001b[0m\n",
"[ 73%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Diagnostics.cc.o\u001b[0m\n",
"[ 74%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/DenseSparseTools.cc.o\u001b[0m\n",
"[ 75%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Dense.cc.o\u001b[0m\n",
"[ 75%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Count.cc.o\u001b[0m\n",
"[ 76%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Composite.cc.o\u001b[0m\n",
"[ 76%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Clip.cc.o\u001b[0m\n",
"[ 77%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/ChangeBackground.cc.o\u001b[0m\n",
"[ 77%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/instantiations/Activate.cc.o\u001b[0m\n",
"[ 78%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/Grid.cc.o\u001b[0m\n",
"[ 78%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/Archive.cc.o\u001b[0m\n",
"[ 79%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/Compression.cc.o\u001b[0m\n",
"[ 79%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/DelayedLoadMetadata.cc.o\u001b[0m\n",
"[ 80%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/File.cc.o\u001b[0m\n",
"[ 81%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/GridDescriptor.cc.o\u001b[0m\n",
"[ 81%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/Queue.cc.o\u001b[0m\n",
"[ 82%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/Stream.cc.o\u001b[0m\n",
"[ 82%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/io/TempFile.cc.o\u001b[0m\n",
"[ 83%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/math/Half.cc.o\u001b[0m\n",
"[ 83%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/math/Maps.cc.o\u001b[0m\n",
"[ 84%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/math/Proximity.cc.o\u001b[0m\n",
"[ 84%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/math/QuantizedUnitVec.cc.o\u001b[0m\n",
"[ 85%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/math/Transform.cc.o\u001b[0m\n",
"[ 86%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/Metadata.cc.o\u001b[0m\n",
"[ 86%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/MetaMap.cc.o\u001b[0m\n",
"[ 87%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/openvdb.cc.o\u001b[0m\n",
"[ 87%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/Platform.cc.o\u001b[0m\n",
"[ 88%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/AttributeArray.cc.o\u001b[0m\n",
"[ 88%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/AttributeArrayString.cc.o\u001b[0m\n",
"[ 89%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/AttributeGroup.cc.o\u001b[0m\n",
"[ 89%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/AttributeSet.cc.o\u001b[0m\n",
"[ 90%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/StreamCompression.cc.o\u001b[0m\n",
"[ 91%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/points/points.cc.o\u001b[0m\n",
"[ 91%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/util/Assert.cc.o\u001b[0m\n",
"[ 92%] \u001b[32mBuilding CXX object openvdb/openvdb/CMakeFiles/openvdb_shared.dir/util/Formats.cc.o\u001b[0m\n",
"[ 92%] \u001b[32m\u001b[1mLinking CXX static library libopenvdb.a\u001b[0m\n",
"[ 92%] Built target openvdb_static\n",
"[ 92%] \u001b[32m\u001b[1mLinking CXX shared library libopenvdb.so\u001b[0m\n",
"[ 92%] Built target openvdb_shared\n",
"[ 93%] \u001b[32mBuilding CXX object openvdb_cmd/vdb_print/CMakeFiles/vdb_print.dir/main.cc.o\u001b[0m\n",
"[ 95%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyGridBase.cc.o\u001b[0m\n",
"[ 95%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyFloatGrid.cc.o\u001b[0m\n",
"[ 95%] \u001b[32mBuilding CXX object openvdb_cmd/vdb_render/CMakeFiles/vdb_render.dir/main.cc.o\u001b[0m\n",
"[ 96%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyIntGrid.cc.o\u001b[0m\n",
"[ 96%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyMetadata.cc.o\u001b[0m\n",
"[ 97%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyOpenVDBModule.cc.o\u001b[0m\n",
"[ 97%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyPointGrid.cc.o\u001b[0m\n",
"[ 98%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyTransform.cc.o\u001b[0m\n",
"[ 99%] \u001b[32mBuilding CXX object openvdb/openvdb/python/CMakeFiles/openvdb_python.dir/pyVec3Grid.cc.o\u001b[0m\n",
"[100%] \u001b[32m\u001b[1mLinking CXX executable vdb_render\u001b[0m\n",
"[100%] Built target vdb_render\n",
"[100%] \u001b[32m\u001b[1mLinking CXX shared module openvdb.cpython-311-x86_64-linux-gnu.so\u001b[0m\n",
"[100%] Built target openvdb_python\n",
"[100%] \u001b[32m\u001b[1mLinking CXX executable vdb_print\u001b[0m\n",
"[100%] Built target vdb_print\n",
"-- Install configuration: \"Release\"\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindBlosc.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindJemalloc.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindLog4cplus.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindOpenEXR.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindOpenVDB.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/FindTBB.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/OpenVDBGLFW3Setup.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/OpenVDBHoudiniSetup.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/OpenVDBMayaSetup.cmake\n",
"-- Installing: /usr/local/lib/cmake/OpenVDB/OpenVDBUtils.cmake\n",
"-- Installing: /usr/local/lib/libopenvdb.a\n",
"-- Installing: /usr/local/lib/libopenvdb.so.12.0.0\n",
"-- Installing: /usr/local/lib/libopenvdb.so.12.0\n",
"-- Set non-toolchain portion of runtime path of \"/usr/local/lib/libopenvdb.so.12.0.0\" to \"/usr/local/lib:/root/.conan2/p/zlib9780dc2008618/p/lib:/root/.conan2/p/boost8d9c445f1bf77/p/lib:/root/.conan2/p/bzip23c098e896e3ea/p/lib\"\n",
"-- Installing: /usr/local/lib/libopenvdb.so\n",
"-- Installing: /usr/local/include/openvdb/Exceptions.h\n",
"-- Installing: /usr/local/include/openvdb/Grid.h\n",
"-- Installing: /usr/local/include/openvdb/Metadata.h\n",
"-- Installing: /usr/local/include/openvdb/MetaMap.h\n",
"-- Installing: /usr/local/include/openvdb/openvdb.h\n",
"-- Installing: /usr/local/include/openvdb/Platform.h\n",
"-- Installing: /usr/local/include/openvdb/PlatformConfig.h\n",
"-- Installing: /usr/local/include/openvdb/Types.h\n",
"-- Installing: /usr/local/include/openvdb/TypeList.h\n",
"-- Installing: /usr/local/include/openvdb/version.h\n",
"-- Installing: /usr/local/include/openvdb/io/Archive.h\n",
"-- Installing: /usr/local/include/openvdb/io/Compression.h\n",
"-- Installing: /usr/local/include/openvdb/io/DelayedLoadMetadata.h\n",
"-- Installing: /usr/local/include/openvdb/io/File.h\n",
"-- Installing: /usr/local/include/openvdb/io/GridDescriptor.h\n",
"-- Installing: /usr/local/include/openvdb/io/io.h\n",
"-- Installing: /usr/local/include/openvdb/io/Queue.h\n",
"-- Installing: /usr/local/include/openvdb/io/Stream.h\n",
"-- Installing: /usr/local/include/openvdb/io/TempFile.h\n",
"-- Installing: /usr/local/include/openvdb/math/BBox.h\n",
"-- Installing: /usr/local/include/openvdb/math/ConjGradient.h\n",
"-- Installing: /usr/local/include/openvdb/math/Coord.h\n",
"-- Installing: /usr/local/include/openvdb/math/DDA.h\n",
"-- Installing: /usr/local/include/openvdb/math/FiniteDifference.h\n",
"-- Installing: /usr/local/include/openvdb/math/Half.h\n",
"-- Installing: /usr/local/include/openvdb/math/LegacyFrustum.h\n",
"-- Installing: /usr/local/include/openvdb/math/Maps.h\n",
"-- Installing: /usr/local/include/openvdb/math/Mat.h\n",
"-- Installing: /usr/local/include/openvdb/math/Mat3.h\n",
"-- Installing: /usr/local/include/openvdb/math/Mat4.h\n",
"-- Installing: /usr/local/include/openvdb/math/Math.h\n",
"-- Installing: /usr/local/include/openvdb/math/Operators.h\n",
"-- Installing: /usr/local/include/openvdb/math/Proximity.h\n",
"-- Installing: /usr/local/include/openvdb/math/QuantizedUnitVec.h\n",
"-- Installing: /usr/local/include/openvdb/math/Quat.h\n",
"-- Installing: /usr/local/include/openvdb/math/Ray.h\n",
"-- Installing: /usr/local/include/openvdb/math/Stats.h\n",
"-- Installing: /usr/local/include/openvdb/math/Stencils.h\n",
"-- Installing: /usr/local/include/openvdb/math/Transform.h\n",
"-- Installing: /usr/local/include/openvdb/math/Tuple.h\n",
"-- Installing: /usr/local/include/openvdb/math/Vec2.h\n",
"-- Installing: /usr/local/include/openvdb/math/Vec3.h\n",
"-- Installing: /usr/local/include/openvdb/math/Vec4.h\n",
"-- Installing: /usr/local/include/openvdb/points/AttributeArray.h\n",
"-- Installing: /usr/local/include/openvdb/points/AttributeArrayString.h\n",
"-- Installing: /usr/local/include/openvdb/points/AttributeGroup.h\n",
"-- Installing: /usr/local/include/openvdb/points/AttributeSet.h\n",
"-- Installing: /usr/local/include/openvdb/points/IndexFilter.h\n",
"-- Installing: /usr/local/include/openvdb/points/IndexIterator.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointAdvect.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointAttribute.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointConversion.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointCount.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointDataGrid.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointDelete.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointGroup.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointMask.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointMove.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointRasterizeFrustum.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointRasterizeSDF.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointRasterizeTrilinear.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointSample.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointScatter.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointStatistics.h\n",
"-- Installing: /usr/local/include/openvdb/points/PointTransfer.h\n",
"-- Installing: /usr/local/include/openvdb/points/StreamCompression.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointAttributeImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointConversionImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointCountImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointDeleteImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointGroupImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointMaskImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointMoveImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointRasterizeFrustumImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointRasterizeSDFImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointRasterizeTrilinearImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointReplicateImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointSampleImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointScatterImpl.h\n",
"-- Installing: /usr/local/include/openvdb/points/impl/PointStatisticsImpl.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Activate.h\n",
"-- Installing: /usr/local/include/openvdb/tools/ChangeBackground.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Clip.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Composite.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Count.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Dense.h\n",
"-- Installing: /usr/local/include/openvdb/tools/DenseSparseTools.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Diagnostics.h\n",
"-- Installing: /usr/local/include/openvdb/tools/FastSweeping.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Filter.h\n",
"-- Installing: /usr/local/include/openvdb/tools/FindActiveValues.h\n",
"-- Installing: /usr/local/include/openvdb/tools/GridOperators.h\n",
"-- Installing: /usr/local/include/openvdb/tools/GridTransformer.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Interpolation.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetAdvect.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetFilter.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetFracture.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetMeasure.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetMorph.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetPlatonic.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetRebuild.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetSphere.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetTracker.h\n",
"-- Installing: /usr/local/include/openvdb/tools/LevelSetUtil.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Mask.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Merge.h\n",
"-- Installing: /usr/local/include/openvdb/tools/MeshToVolume.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Morphology.h\n",
"-- Installing: /usr/local/include/openvdb/tools/MultiResGrid.h\n",
"-- Installing: /usr/local/include/openvdb/tools/NodeVisitor.h\n",
"-- Installing: /usr/local/include/openvdb/tools/ParticleAtlas.h\n",
"-- Installing: /usr/local/include/openvdb/tools/ParticlesToLevelSet.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PointAdvect.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PointIndexGrid.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PointPartitioner.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PointScatter.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PointsToMask.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PoissonSolver.h\n",
"-- Installing: /usr/local/include/openvdb/tools/PotentialFlow.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Prune.h\n",
"-- Installing: /usr/local/include/openvdb/tools/RayIntersector.h\n",
"-- Installing: /usr/local/include/openvdb/tools/RayTracer.h\n",
"-- Installing: /usr/local/include/openvdb/tools/SignedFloodFill.h\n",
"-- Installing: /usr/local/include/openvdb/tools/Statistics.h\n",
"-- Installing: /usr/local/include/openvdb/tools/TopologyToLevelSet.h\n",
"-- Installing: /usr/local/include/openvdb/tools/ValueTransformer.h\n",
"-- Installing: /usr/local/include/openvdb/tools/VectorTransformer.h\n",
"-- Installing: /usr/local/include/openvdb/tools/VelocityFields.h\n",
"-- Installing: /usr/local/include/openvdb/tools/VolumeAdvect.h\n",
"-- Installing: /usr/local/include/openvdb/tools/VolumeToMesh.h\n",
"-- Installing: /usr/local/include/openvdb/tools/VolumeToSpheres.h\n",
"-- Installing: /usr/local/include/openvdb/tree/InternalNode.h\n",
"-- Installing: /usr/local/include/openvdb/tree/Iterator.h\n",
"-- Installing: /usr/local/include/openvdb/tree/LeafBuffer.h\n",
"-- Installing: /usr/local/include/openvdb/tree/LeafManager.h\n",
"-- Installing: /usr/local/include/openvdb/tree/LeafNode.h\n",
"-- Installing: /usr/local/include/openvdb/tree/LeafNodeBool.h\n",
"-- Installing: /usr/local/include/openvdb/tree/LeafNodeMask.h\n",
"-- Installing: /usr/local/include/openvdb/tree/NodeManager.h\n",
"-- Installing: /usr/local/include/openvdb/tree/NodeUnion.h\n",
"-- Installing: /usr/local/include/openvdb/tree/RootNode.h\n",
"-- Installing: /usr/local/include/openvdb/tree/Tree.h\n",
"-- Installing: /usr/local/include/openvdb/tree/TreeIterator.h\n",
"-- Installing: /usr/local/include/openvdb/tree/ValueAccessor.h\n",
"-- Installing: /usr/local/include/openvdb/util/Assert.h\n",
"-- Installing: /usr/local/include/openvdb/util/CpuTimer.h\n",
"-- Installing: /usr/local/include/openvdb/util/ExplicitInstantiation.h\n",
"-- Installing: /usr/local/include/openvdb/util/Formats.h\n",
"-- Installing: /usr/local/include/openvdb/util/logging.h\n",
"-- Installing: /usr/local/include/openvdb/util/MapsUtil.h\n",
"-- Installing: /usr/local/include/openvdb/util/Name.h\n",
"-- Installing: /usr/local/include/openvdb/util/NodeMasks.h\n",
"-- Installing: /usr/local/include/openvdb/util/NullInterrupter.h\n",
"-- Installing: /usr/local/include/openvdb/util/PagedArray.h\n",
"-- Installing: /usr/local/include/openvdb/util/Util.h\n",
"-- Installing: /usr/local/include/openvdb/thread/Threading.h\n",
"-- Installing: /usr/local/lib/python3.11/dist-packages/openvdb.cpython-311-x86_64-linux-gnu.so\n",
"-- Set non-toolchain portion of runtime path of \"/usr/local/lib/python3.11/dist-packages/openvdb.cpython-311-x86_64-linux-gnu.so\" to \"/usr/local/lib:/root/.conan2/p/zlib9780dc2008618/p/lib:/root/.conan2/p/boost8d9c445f1bf77/p/lib:/root/.conan2/p/bzip23c098e896e3ea/p/lib\"\n",
"-- Installing: /usr/local/bin/vdb_print\n",
"-- Set non-toolchain portion of runtime path of \"/usr/local/bin/vdb_print\" to \"/usr/local/lib:/root/.conan2/p/zlib9780dc2008618/p/lib:/root/.conan2/p/boost8d9c445f1bf77/p/lib:/root/.conan2/p/bzip23c098e896e3ea/p/lib\"\n",
"-- Installing: /usr/local/bin/vdb_render\n",
"-- Set non-toolchain portion of runtime path of \"/usr/local/bin/vdb_render\" to \"/usr/local/lib:/root/.conan2/p/zlib9780dc2008618/p/lib:/root/.conan2/p/boost8d9c445f1bf77/p/lib:/root/.conan2/p/bzip23c098e896e3ea/p/lib\"\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"!wget -qc --show-progress https://artifacts.aswf.io/io/aswf/openvdb/models/sphere.vdb/1.0.0/sphere.vdb-1.0.0.zip && unzip -nqq sphere.vdb-1.0.0.zip\n",
"!openvdb-12.0.0/build/openvdb_cmd/vdb_print/vdb_print -l -m sphere.vdb"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "7u1gsKeDx6SE",
"outputId": "34ed20bb-33da-4afe-a3a6-2c3f429714b0"
},
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\rsphere.vdb-1.0.0.zi 0%[ ] 0 --.-KB/s \rsphere.vdb-1.0.0.zi 100%[===================>] 347.43K --.-KB/s in 0.03s \n",
"VDB version: 1.1/222\n",
"creator: Houdini/SOP_OpenVDB_Write\n",
"\n",
"Name: ls_sphere\n",
"Information about Tree:\n",
" Type: Tree_float_5_4_3\n",
" Configuration:\n",
" Root(1 x 8), Internal(8 x 32^3), Internal(8 x 16^3), Leaf(1,451 x 8^3)\n",
" Background value: 0.150024\n",
" Min value: -0.149536\n",
" Max value: 0.149658\n",
" Number of active voxels: 270,638\n",
" Number of active tiles: 0\n",
" Bounding box of active voxels: [-62, -62, -62] -> [62, 62, 62]\n",
" Dimensions of active voxels: 125 x 125 x 125\n",
" Percentage of active voxels: 13.9%\n",
" Average leaf node fill ratio: 36.4%\n",
" Number of unallocated nodes: 0 (0%)\n",
"Memory footprint:\n",
" Actual: 5.289 MB\n",
" Active leaf voxels: 1.032 MB\n",
" Dense equivalent: 7.451 MB\n",
" Actual footprint is 71% of an equivalent dense volume\n",
" Leaf voxel footprint is 19.5% of actual footprint\n",
"Additional metadata:\n",
" class: level set\n",
" file_bbox_max: [62, 62, 62]\n",
" file_bbox_min: [-62, -62, -62]\n",
" file_mem_bytes: 5528004\n",
" file_voxel_count: 270638\n",
" is_local_space: false\n",
" is_saved_as_half_float: true\n",
" name: ls_sphere\n",
" value_type: float\n",
" vector_type: invariant\n",
"Transform:\n",
" voxel size: 0.05\n",
" index to world:\n",
" [0.05, 0, 0, 0] \n",
" [0, 0.05, 0, 0] \n",
" [0, 0, 0.05, 0] \n",
" [0, 0, 0, 1] \n",
"\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"### Commons"
],
"metadata": {
"id": "LtStOkIl_B7g"
}
},
{
"cell_type": "code",
"source": [
"%matplotlib inline\n",
"%config InlineBackend.figure_format = 'retina'\n",
"\n",
"import os\n",
"import math\n",
"import numpy as np\n",
"import matplotlib as mpl\n",
"import matplotlib.pyplot as plt\n",
"import cv2\n",
"import PIL\n",
"import matplotlib.font_manager as fm\n",
"import locale\n",
"from fastprogress import progress_bar\n",
"from einops import rearrange, reduce, repeat, einsum\n",
"\n",
"locale.getpreferredencoding = lambda: \"UTF-8\"\n",
"\n",
"COLORS = {\n",
" \"red\": np.array([0.79215686, 0.14901961, 0.14901961]),\n",
" \"blue\": np.array([0.08683021, 0.41940383, 0.71699529]),\n",
"}\n",
"COLORS.update({f\"gray{k:02d}\": np.array([k,k,k])*.01 for k in np.arange(5,100,5)})\n",
"\n",
"def mpl_theme(gray=COLORS['gray50'], stroke_width=.1, fontsize=7,\n",
" facecolor=COLORS['gray10']):\n",
" ## category20: https://github.com/d3/d3-3.x-api-reference/blob/master/Ordinal-Scales.md#category20\n",
" cat20 = mpl.cycler(color=[\"1f77b4\",\"ff7f0e\",\"2ca02c\",\"d62728\",\"9467bd\",\"8c564b\",\"e377c2\",\"7f7f7f\",\"bcbd22\",\"17becf\",\n",
" \"aec7e8\",\"ffbb78\",\"98df8a\",\"ff9896\",\"c5b0d5\",\"c49c94\",\"f7b6d2\",\"c7c7c7\", \"dbdb8d\", \"9edae5\"])\n",
" return {\n",
" \"font.size\": fontsize,\n",
" \"text.color\": gray,\n",
"\n",
" \"figure.dpi\": 100,\n",
" \"figure.facecolor\": facecolor,\n",
" \"figure.frameon\": False,\n",
" \"figure.figsize\": (5, 3),\n",
" \"figure.titlesize\": \"x-large\",\n",
" \"figure.titleweight\": \"bold\",\n",
" \"figure.constrained_layout.use\": True,\n",
" \"figure.constrained_layout.w_pad\": 0.05,\n",
" \"figure.constrained_layout.h_pad\": 0.05,\n",
" \"figure.constrained_layout.wspace\": 0.03,\n",
" \"figure.constrained_layout.hspace\": 0.03,\n",
"\n",
" \"axes.labelcolor\": gray,\n",
" \"axes.labelpad\": 8,\n",
" \"axes.labelsize\": \"large\",\n",
" \"axes.labelweight\": \"normal\",\n",
" \"axes.spines.left\": False,\n",
" \"axes.spines.bottom\": False,\n",
" \"axes.spines.top\": False,\n",
" \"axes.spines.right\": False,\n",
" \"axes.facecolor\": facecolor,\n",
" \"axes.edgecolor\": gray,\n",
" \"axes.linewidth\": stroke_width,\n",
" \"axes.axisbelow\": True,\n",
" \"axes.xmargin\": 0.02,\n",
" \"axes.ymargin\": 0.02,\n",
" \"axes.zmargin\": 0.02,\n",
" \"axes.prop_cycle\": cat20,\n",
" \"axes.titlepad\": 8,\n",
" \"axes.titlesize\": \"large\",\n",
" \"axes.titleweight\": 500,\n",
" \"axes.grid\": True,\n",
" \"axes.grid.axis\": \"both\",\n",
"\n",
" \"axes3d.grid\": False,\n",
"\n",
" \"ytick.right\": False,\n",
" \"ytick.color\": gray,\n",
" \"ytick.major.width\": stroke_width,\n",
" \"ytick.minor.left\": False,\n",
" \"xtick.minor.visible\": True,\n",
" \"xtick.minor.top\": False,\n",
" \"xtick.minor.bottom\": False,\n",
" \"xtick.color\": gray,\n",
" \"xtick.major.width\": stroke_width,\n",
"\n",
" \"grid.color\": gray,\n",
" \"grid.linewidth\": stroke_width,\n",
" \"grid.linestyle\": \"-\",\n",
" \"legend.fancybox\": False,\n",
" \"legend.edgecolor\": '0.3',\n",
" \"legend.framealpha\": 0.7,\n",
" \"legend.handletextpad\": 0.8,\n",
"\n",
" \"lines.linewidth\": 0.7\n",
" }\n",
"\n",
"def add_mpl_font(fname):\n",
" if fname not in [fe.fname for fe in fm.fontManager.ttflist]:\n",
" fm.fontManager.addfont(fname)\n",
"\n",
"def setup_overpass():\n",
" folder = \"fonts\"\n",
" os.makedirs(folder, exist_ok=True)\n",
" for style in [\"Regular\", \"Italic\", \"SemiBold\", \"SemiBoldItalic\", \"Bold\", \"BoldItalic\"]:\n",
" ttf = f\"Overpass-{style}.ttf\"\n",
" !wget -qc \"https://github.com/RedHatOfficial/Overpass/raw/master/fonts/ttf/{ttf}\" -O \"{folder}/{ttf}\"\n",
" add_mpl_font(f\"{folder}/{ttf}\")\n",
" mpl.rcParams['font.sans-serif'].insert(0, \"Overpass\")\n",
"\n",
"def setup_quicksand():\n",
" folder = \"fonts\"\n",
" os.makedirs(folder, exist_ok=True)\n",
" for style in [\"Bold\", \"Light\", \"Medium\", \"Regular\"]:\n",
" ttf = f\"Quicksand-{style}.ttf\"\n",
" !wget -qc \"https://github.com/andrew-paglinawan/QuicksandFamily/raw/refs/heads/master/fonts/statics/{ttf}\" -O \"{folder}/{ttf}\"\n",
" add_mpl_font(f\"{folder}/{ttf}\")\n",
" mpl.rcParams['font.sans-serif'].insert(0, \"Quicksand\")\n",
"\n",
"# setup_overpass()\n",
"setup_quicksand()\n",
"\n",
"plt.style.use([\"dark_background\", mpl_theme()])"
],
"metadata": {
"id": "LrIjlzxS_Bhk"
},
"execution_count": 1,
"outputs": []
},
{
"cell_type": "code",
"source": [
"import sys\n",
"import io\n",
"import bz2\n",
"import ffmpeg\n",
"import requests\n",
"import subprocess\n",
"import IPython.display as ipd\n",
"import ipywidgets as widgets\n",
"from scipy import linalg\n",
"from fastprogress import progress_bar\n",
"from einops import rearrange, reduce, repeat\n",
"from base64 import b64encode\n",
"from zipfile import ZipFile\n",
"from contextlib import contextmanager\n",
"\n",
"class Output(object):\n",
" def __init__(self):\n",
" self.out = widgets.Output()\n",
"\n",
" def display(self):\n",
" display(self.out)\n",
" return self\n",
"\n",
" def clear(self):\n",
" self.out.clear_output()\n",
" return self.out\n",
"\n",
" def close(self):\n",
" return self.out.close()\n",
"\n",
"def to_single_rgb(img):\n",
" img = np.asarray(img)\n",
" if len(img.shape) == 4: # take first frame from animations\n",
" return img[0,:,:,:]\n",
" if len(img.shape) == 2: # convert gray to rgb\n",
" return img[:,:,np.newaxis].repeat(3, 2)\n",
" if img.shape[-1] == 4: # drop alpha\n",
" return img[:,:,:3]\n",
" else:\n",
" return img\n",
"\n",
"def imread(url, size=None, mode=None):\n",
" if url.startswith(('http:', 'https:')):\n",
" resp = requests.get(url)\n",
" if resp.status_code != 200:\n",
" return None\n",
"\n",
" f = io.BytesIO(resp.content)\n",
" else:\n",
" f = url\n",
" img = PIL.Image.open(f)\n",
" if size is not None:\n",
" img.thumbnail((size, size), PIL.Image.Resampling.LANCZOS)\n",
" if mode is not None:\n",
" img = img.convert(mode)\n",
" return img\n",
"\n",
"def imshow(img, fmt='png', retina=True, zoom=None):\n",
" if isinstance(img, str):\n",
" display(ipd.Image(filename=img, retina=retina))\n",
" return\n",
"\n",
" if len(img.shape) == 3 and img.shape[-1] == 1:\n",
" img = img.squeeze()\n",
" if img.dtype == np.float32:\n",
" img = img * 255.0\n",
" img = np.uint8(img.clip(0, 255))\n",
" if fmt in ('jpeg', 'jpg'):\n",
" img = to_single_rgb(img)\n",
"\n",
" image = PIL.Image.fromarray(img)\n",
" height, width = img.shape[:2]\n",
" if zoom is not None:\n",
" width *= zoom\n",
" height *= zoom\n",
" retina = zoom == 1\n",
" if zoom < 1:\n",
" image.resize((int(width), int(height)))\n",
"\n",
" data = io.BytesIO()\n",
" image.save(data, fmt)\n",
" display(ipd.Image(data=data.getvalue(),width=width, height=height,retina=retina))\n",
"\n",
"def find_rectangle(n, ratio=1):\n",
" ny = int((n / ratio) ** .5)\n",
" return ny, math.ceil(n / ny)\n",
"\n",
"def make_mosaic(imgs, nx=None, ny=None, gap=0):\n",
" n, h, w = imgs.shape[:3]\n",
" has_channels = len(imgs.shape) > 3\n",
"\n",
" if nx is None and ny is None:\n",
" ny, nx = find_rectangle(n)\n",
" elif ny is None:\n",
" ny = math.ceil(n / nx)\n",
" elif nx is None:\n",
" nx = math.ceil(n / ny)\n",
"\n",
" sh, sw = h + gap, w + gap\n",
" shape = (ny * sh - gap, nx * sw - gap)\n",
" if has_channels:\n",
" shape += (imgs.shape[-1],)\n",
"\n",
" canvas = np.zeros(shape, dtype=imgs.dtype)\n",
" for i, x in enumerate(imgs):\n",
" iy, ix = divmod(i, nx)\n",
" canvas[iy * sh:iy * sh + h, ix * sw:ix * sw + w] = x\n",
" return canvas\n",
"\n",
"def ffprobe_video(path):\n",
" probe = ffmpeg.probe(path)\n",
" return next(s for s in probe['streams'] if s['codec_type'] == 'video')\n",
"\n",
"def read_frame(path, frame_no):\n",
" cap = cv2.VideoCapture(path)\n",
" cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no)\n",
" ret, frame = cap.read()\n",
" if not ret:\n",
" raise RuntimeError(f\"Faild reading frame {frame_no} from {path}\")\n",
" return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n",
"\n",
"def read_frames(path, start=0, num=None):\n",
" cap = cv2.VideoCapture(path)\n",
" n_frames = num or int(cap.get(cv2.CAP_PROP_FRAME_COUNT))\n",
" cap.set(cv2.CAP_PROP_POS_FRAMES, start)\n",
" for i in range(n_frames):\n",
" ret, frame = cap.read()\n",
" if not ret:\n",
" raise RuntimeError(f\"Faild reading frame {i} from {path}\")\n",
" yield cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n",
"\n",
"def read_video_frames(path):\n",
" info = ffprobe_video(path)\n",
" out, _ = ffmpeg.input(path).output('pipe:', format='rawvideo', pix_fmt='rgb24').run(capture_stdout=True)\n",
" return np.frombuffer(out, np.uint8).reshape([-1, info['height'], info['width'], 3])\n",
"\n",
"def show_video(path):\n",
" vcap = cv2.VideoCapture(path)\n",
" width = int(vcap.get(cv2.CAP_PROP_FRAME_WIDTH))\n",
" with open(path, \"r+b\") as f:\n",
" url = f\"data:video/mp4;base64,{b64encode(f.read()).decode()}\"\n",
" return ipd.HTML(f\"\"\"<video autoplay=\"autoplay\" width={width} controls loop><source src=\"{url}\"></video>\"\"\")\n",
"\n",
"def write_video(frames, size, path=\"__temp__.mp4\", fps=30,\n",
" preset=\"veryfast\", args=[]):\n",
" height, width = size\n",
" command = ['ffmpeg','-v','error','-f','rawvideo','-vcodec','rawvideo',\n",
" '-pix_fmt','rgb24','-s',f'{width}x{height}','-r', f'{fps}',\n",
" '-i', '-',\n",
" \"-movflags\", \"+faststart\", \"-preset\", preset,\n",
" \"-g\", \"30\", \"-bf\",\"2\",\"-c:v\", \"libx264\",\"-profile:v\", \"high\",\n",
" '-an', '-vcodec','h264','-pix_fmt','yuv420p', *args, '-y', path]\n",
" with subprocess.Popen(command, stdin=subprocess.PIPE, stderr=subprocess.PIPE) as proc:\n",
" with proc.stdin as stdin:\n",
" for image in frames:\n",
" data = image.tobytes()\n",
" if stdin.write(data) != len(data):\n",
" proc.wait()\n",
" stderr = proc.stderr\n",
" assert stderr is not None\n",
" s = stderr.read().decode()\n",
" raise RuntimeError(f\"Error writing '{path}': {s}\")\n",
" return path\n",
"\n",
"def read_video(path):\n",
" command = ['ffmpeg','-v','error','-nostdin','-i',path,'-vcodec','rawvideo',\n",
" '-f','image2pipe','-pix_fmt','rgb24','-vsync','vfr','-']\n",
"\n",
" info = ffprobe_video(path)\n",
" num_bytes = info['height'] * info['width'] * 3 * np.dtype(np.uint8).itemsize\n",
" with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:\n",
" stdout = proc.stdout\n",
" assert stdout is not None\n",
" data = stdout.read(num_bytes)\n",
" while data is not None and len(data) == num_bytes:\n",
" image = np.frombuffer(data, dtype=np.uint8)\n",
" yield image.reshape(info['height'], info['width'], 3)\n",
" data = stdout.read(num_bytes)\n",
"\n",
"def sdiv(a, b, nan=0, posinf=0, neginf=0):\n",
" return np.nan_to_num(a / b, nan=nan, posinf=posinf, neginf=neginf)\n",
"\n",
"def topk(x, n):\n",
" return np.argpartition(x, -n)[-n:]\n",
"\n",
"def norm(a, b, x, **kw):\n",
" return sdiv(x - a, b - a, **kw)\n",
"\n",
"def norm_v(x, **kw):\n",
" a, b = x.min(), x.max()\n",
" return sdiv(x - a, b - a, **kw)\n",
"\n",
"def normalize(x, keepdims=True, axis=-1, **kw):\n",
" return sdiv(x, np.linalg.norm(x, keepdims=keepdims, axis=axis), **kw)\n",
"\n",
"def nudge(x, v=0, eps=1e-12):\n",
" return np.where(np.isclose(np.abs(x), v, atol=eps), np.where(x - v >= 0, eps, -eps), x)\n",
"\n",
"def linspace_m(start, stop, n):\n",
" return np.linspace(start, stop, n, endpoint=False) + (stop - start) * .5 / n\n",
"\n",
"def indices_m(dims, shape, dtype=\"u4\"):\n",
" return tuple(np.meshgrid(*[np.round(linspace_m(0, d, s)).astype(dtype)\n",
" for d, s in zip(dims, shape)],\n",
" indexing='ij'))\n",
"\n",
"def saturate(x):\n",
" return np.clip(x, 0, 1)\n",
"\n",
"def lerp(a, b, t):\n",
" return a * (1.0 - t) + b * t\n",
"\n",
"def step(v, x):\n",
" return np.where(x < v, 0, 1)\n",
"\n",
"def window(x, a, b):\n",
" return step(a, x) * step(x, b)\n",
"\n",
"def satnorm(x, a, b):\n",
" return saturate(norm(x, a, b))\n",
"\n",
"def smoothstep(x):\n",
" return x * x * (3 - 2 * x)\n",
"\n",
"def smootherstep(x):\n",
" return x * x * x * (x * (x * 6 - 15) + 10)\n",
"\n",
"def cubic(a, b, c, d, t):\n",
" \"\"\"https://www.desmos.com/calculator/waof4r6avv\"\"\"\n",
" s = 1. - t\n",
" return s * s * (s * a + 3 * t * b) + t * t * (3 * s * c + t * d)\n",
"\n",
"def plt_show(pin=mpl.rcParams['savefig.pad_inches']):\n",
" with plt.rc_context({'savefig.pad_inches': pin}):\n",
" plt.show()\n",
"\n",
"def fig_image(fig=None, transparent=False, bbox_inches=None,\n",
" dpi=mpl.rcParams[\"figure.dpi\"]*2):\n",
" fig = fig or plt.gcf()\n",
"\n",
" buf = io.BytesIO()\n",
" fig.savefig(buf, format=\"png\", pad_inches=0, bbox_inches=bbox_inches,\n",
" facecolor=fig.get_facecolor(), dpi=dpi,transparent=transparent)\n",
" buf.seek(0)\n",
" data = np.frombuffer(buf.getvalue(), dtype=np.uint8)\n",
" buf.close()\n",
" plt.close(fig)\n",
"\n",
" code = cv2.COLOR_BGRA2RGBA if transparent else cv2.COLOR_BGR2RGB\n",
" return cv2.cvtColor(cv2.imdecode(data, cv2.IMREAD_UNCHANGED), code)\n",
"\n",
"def plt_savefig(name, pad_inches=mpl.rcParams['savefig.pad_inches'],\n",
" bbox_inches=0,facecolor='auto',\n",
" dpi=mpl.rcParams[\"figure.dpi\"]*2,close=True,**kw):\n",
" plt.savefig(name,\n",
" pad_inches=pad_inches,\n",
" bbox_inches=bbox_inches,\n",
" facecolor=facecolor,\n",
" dpi=dpi,**kw)\n",
" if close:\n",
" plt.close()\n",
"\n",
"class Flex(object):\n",
" def __init__(self, ratios, gap, size=None):\n",
" n, s = len(ratios), sum(ratios)\n",
" self.ratios = ratios\n",
" self.gap = gap\n",
" space = gap * n / s if size is None else gap * n / (size - gap * (n - 1))\n",
" self.h = dict(nrows=1, ncols=n, width_ratios=ratios, wspace=space)\n",
" self.v = dict(nrows=n, ncols=1, height_ratios=ratios, hspace=space)\n",
" self.size = s + gap * (n - 1) if size is None else size\n",
"\n",
"def ax_frame(ax):\n",
" ax.spines[[\"left\",\"right\",\"bottom\",\"top\"]].set_visible(True)\n",
" ax.grid(False)\n",
" ax.set(xticks=[],yticks=[])\n",
"\n",
"def ax_frames(axs):\n",
" for ax in axs.flat: ax_frame(ax)\n",
"\n",
"def ax_lim(mn, mx, ax=None, margin=.1):\n",
" ax = ax or plt.gca()\n",
" ax.set_xlim(mn[0], mx[0])\n",
" ax.set_ylim(mn[1], mx[1])\n",
" if len(mn) > 2:\n",
" ax.set_zlim(mn[2], mx[2])\n",
"\n",
"def ax_spines(sides=[\"left\",\"right\",\"bottom\",\"top\"], ax=None, **kw):\n",
" ax = ax or plt.gca()\n",
" ax.spines[sides].set(**kw)\n",
"\n",
"def lowess(x, y, f=2. / 3., iter=3):\n",
" \"\"\"https://gist.github.com/agramfort/850437\n",
" lowess(x, y, f=2./3., iter=3) -> yest\n",
" Lowess smoother: Robust locally weighted regression.\n",
" The lowess function fits a nonparametric regression curve to a scatterplot.\n",
" The arrays x and y contain an equal number of elements; each pair\n",
" (x[i], y[i]) defines a data point in the scatterplot. The function returns\n",
" the estimated (smooth) values of y.\n",
" The smoothing span is given by f. A larger value for f will result in a\n",
" smoother curve. The number of robustifying iterations is given by iter. The\n",
" function will run faster with a smaller number of iterations.\n",
" \"\"\"\n",
" n = len(x)\n",
" r = int(math.ceil(f * n))\n",
" h = [np.sort(np.abs(x - x[i]))[r] for i in range(n)]\n",
" w = np.clip(np.abs((x[:, None] - x[None, :]) / h), 0.0, 1.0)\n",
" w = (1 - w ** 3) ** 3\n",
" yest = np.zeros(n)\n",
" delta = np.ones(n)\n",
" for iteration in range(iter):\n",
" for i in range(n):\n",
" weights = delta * w[:, i]\n",
" b = np.array([np.sum(weights * y), np.sum(weights * y * x)])\n",
" A = np.array([[np.sum(weights), np.sum(weights * x)],\n",
" [np.sum(weights * x), np.sum(weights * x * x)]])\n",
" beta = linalg.solve(A, b)\n",
" yest[i] = beta[0] + beta[1] * x[i]\n",
"\n",
" residuals = y - yest\n",
" s = np.median(np.abs(residuals))\n",
" delta = np.clip(residuals / (6.0 * s), -1, 1)\n",
" delta = (1 - delta ** 2) ** 2\n",
"\n",
" return yest\n",
"\n",
"def plot_metrics(metrics, groups=None, title=\"Metrics\", lowess=False):\n",
" groups = groups or [list(metrics.keys())]\n",
" n = len(groups)\n",
" ny = math.ceil(n / 2)\n",
" fig = plt.figure(figsize=(8 if n > 1 else 4, 2 * ny))\n",
"\n",
" for i, group in enumerate(groups, 1):\n",
" ax = fig.add_subplot(ny, 2 if n > 1 else 1, i)\n",
" for k in group:\n",
" x, y = np.arange(len(metrics[k])), metrics[k]\n",
" alpha = max(0.3, min(1, (1000 - len(x)) / 1000))\n",
" ax.plot(x, y, alpha=alpha, label=k, marker='.', markeredgewidth=0,lw=.5,ms=5)\n",
" if np.any(np.min(y) - y[0] > (np.max(y) - np.min(y)) * 0.01):\n",
" ax.set_ylim(np.min(y), y[0])\n",
" if lowess and len(y) >= 9:\n",
" ax.plot(x, lowess(x, y, f=0.25, iter=3), linestyle='-', alpha=0.8, label=k + \".lowess\", lw=2)\n",
" ax.legend(loc='lower left')\n",
" ax.grid(axis='x')\n",
"\n",
" fig.suptitle(title)\n",
" plt.show()\n",
"\n",
"def plot_tfevents_vals(vals, groups=None, **kwargs):\n",
" groups = groups or [vals.keys()]\n",
" keys = {k for g in groups for k in g}\n",
" metrics = {k: np.array([v.value for v in vs]) for k, vs in vals.items() if k in keys}\n",
" keys1 = set(metrics.keys())\n",
" groups1 = list(filter(None, [[k for k in g if k in keys1] for g in groups]))\n",
" plot_metrics(metrics, groups=groups1, **kwargs)\n",
"\n",
"\n",
"def sph2cart(sph):\n",
" az, el, r = rearrange(sph, \"... d -> d ...\")\n",
" c = np.cos(el)\n",
" return rearrange(np.stack((c * np.cos(az), c * np.sin(az), np.sin(el)) * r), \"d ... -> ... d\")\n",
"\n",
"def cart2sph(cart):\n",
" x, y, z = cart[...,0], cart[...,1], cart[...,2]\n",
" az, el = np.arctan2(y, x), np.arctan2(z, np.hypot(x, y))\n",
" r = np.sqrt(x ** 2 + y ** 2 + z ** 2)\n",
" return np.column_stack((az, el, r))\n",
"\n",
"def iter_batch(xs, bs, drop_last=True):\n",
" n = len(xs) // bs\n",
" for i in range(n):\n",
" yield xs[i*bs:(i+1)*bs]\n",
" if not drop_last:\n",
" yield xs[n*bs:]\n",
"\n",
"@contextmanager\n",
"def stdout_redirected(to=os.devnull):\n",
" '''\n",
" https://blender.stackexchange.com/a/270199\n",
" '''\n",
" fd = sys.stdout.fileno()\n",
"\n",
" ##### assert that Python and C stdio write using the same file descriptor\n",
" ####assert libc.fileno(ctypes.c_void_p.in_dll(libc, \"stdout\")) == fd == 1\n",
"\n",
" def _redirect_stdout(to):\n",
" sys.stdout.close() # + implicit flush()\n",
" os.dup2(to.fileno(), fd) # fd writes to 'to' file\n",
" sys.stdout = os.fdopen(fd, 'w') # Python writes to fd\n",
"\n",
" with os.fdopen(os.dup(fd), 'w') as old:\n",
" with open(to, 'w') as f:\n",
" _redirect_stdout(to=f)\n",
" try:\n",
" yield # allow code to be run with the redirected stdout\n",
" finally:\n",
" _redirect_stdout(to=old) # restore stdout. buffering and flags such as CLOEXEC may be different\n",
"\n",
"def unpack_bz2(src_path):\n",
" data = bz2.BZ2File(src_path).read()\n",
" dst_path = src_path[:-4]\n",
" with open(dst_path, 'wb') as fp:\n",
" fp.write(data)\n",
" return dst_path\n",
"\n",
"def make_zip(files, target, filename=os.path.basename):\n",
" with ZipFile(target, 'w') as f:\n",
" for p in files:\n",
" f.write(p, filename(p))\n",
" return target"
],
"metadata": {
"id": "1lMrs3sh_EfA"
},
"execution_count": 2,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Mistuba"
],
"metadata": {
"id": "4rN0nR9N_FrB"
}
},
{
"cell_type": "markdown",
"source": [
"### Data"
],
"metadata": {
"id": "R8lkDJfB_IcG"
}
},
{
"cell_type": "code",
"source": [
"!wget -qc --show-progress https://rgl.s3.eu-central-1.amazonaws.com/media/papers/Vicini2022SDF_1.zip\n",
"!unzip -nqq Vicini2022SDF_1.zip -d Vicini2022SDF_1\n",
"!wget -qc --show-progress https://rgl.s3.eu-central-1.amazonaws.com/media/papers/Nicolet2021Large.zip\n",
"!unzip -nqq Nicolet2021Large.zip -d Nicolet2021Large"
],
"metadata": {
"id": "dKKgrK-d_G0i",
"outputId": "7a7044c6-acff-4431-89ac-2504add06fd3",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Vicini2022SDF_1.zip 100%[===================>] 382.87M 18.6MB/s in 21s \n",
"Nicolet2021Large.zi 100%[===================>] 234.95M 21.6MB/s in 12s \n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"### Utils"
],
"metadata": {
"id": "1kT-qQCN_K5t"
}
},
{
"cell_type": "code",
"source": [
"def dot(a, b, axis=-1, keepdims=False):\n",
" return (a * b).sum(axis=axis, keepdims=keepdims)\n",
"\n",
"def quat_axis_angle(a, r):\n",
" r = (np.asarray(r) * .5)[...,None]\n",
" return np.concatenate((a * np.sin(r), np.cos(r)),-1)\n",
"\n",
"def quat_mul(a, b):\n",
" ax, ay, az, aw = rearrange(a, \"... d -> d ...\")\n",
" bx, by, bz, bw = rearrange(b, \"... d -> d ...\")\n",
" res = np.stack((\n",
" ax * bw + aw * bx + ay * bz - az * by,\n",
" ay * bw + aw * by + az * bx - ax * bz,\n",
" az * bw + aw * bz + ax * by - ay * bx,\n",
" aw * bw - ax * bx - ay * by - az * bz))\n",
" return rearrange(res, \"d ... -> ... d\")\n",
"\n",
"def quat_mul_v(q, v):\n",
" x, y, z = rearrange(v, \"... d -> d ...\")\n",
" qx, qy, qz, qw = rearrange(q, \"... d -> d ...\")\n",
" ix = qw * x + qy * z - qz * y\n",
" iy = qw * y + qz * x - qx * z\n",
" iz = qw * z + qx * y - qy * x\n",
" iw = qx * x + qy * y + qz * z\n",
" res = np.stack((ix * qw + iw * qx - iy * qz + iz * qy,\n",
" iy * qw + iw * qy - iz * qx + ix * qz,\n",
" iz * qw + iw * qz - ix * qy + iy * qx))\n",
" return rearrange(res, \"d ... -> ... d\")\n",
"\n",
"def orthogonal(v, m=.5, n=.5):\n",
" x, y, z = rearrange(v, \"... d -> d ...\")\n",
" res = np.stack((m * -y + n * -z, m * x, n * x))\n",
" return normalize(rearrange(res, \"d ... -> ... d\"))\n",
"\n",
"def quat_between(a, b):\n",
" w, q = dot(a, b), np.cross(a, b)\n",
" qw = w + np.sqrt(q[...,0] ** 2 + q[...,1] ** 2 + q[...,2] ** 2 + w ** 2)\n",
" qa = normalize(np.concatenate((q, qw[...,None]),-1))\n",
" qb = quat_axis_angle(orthogonal(a), np.full(a.shape[:-1],np.pi))\n",
" return np.where(w[...,None] != -1, qa, qb)\n",
"\n",
"def quat_lookat(vdir, rad=None):\n",
" rad = rad or np.full(vdir.shape[0], 0, dtype=\"f4\")\n",
" YZ = np.array([[0,1,0],[0,0,1]], dtype=vdir.dtype)\n",
" w = dot(vdir, YZ[1:],keepdims=True)\n",
" q = np.where(w == 1, np.array([[0,0,0,1]],dtype=vdir.dtype),\n",
" np.where(w == -1, quat_axis_angle(YZ[:1], [np.pi]), quat_between(YZ[1:], vdir)))\n",
" return quat_mul(quat_axis_angle(vdir, rad), q)\n",
"\n",
"def m44_rotation_axis(idx, theta, dtype=\"f4\"):\n",
" c, s = np.cos(theta), np.sin(theta)\n",
" a, b = (idx + 1) % 3, (idx + 2) % 3\n",
"\n",
" mat = np.eye(4, dtype=dtype)\n",
" mat[a, a], mat[b, b] = c, c\n",
" mat[a, b], mat[b, a] = -s, s\n",
" return mat\n",
"\n",
"def regular_points_sphere(steps=[1,4,8,4,1]):\n",
" pts = np.concatenate([sph2cart(np.c_[np.linspace(0, np.pi*2, n, endpoint=False), np.full(n, a), np.ones(n)])\n",
" for n, a in zip(steps,np.linspace(-np.pi/2,np.pi/2,len(steps)))])\n",
" return pts @ m44_rotation_axis(0, np.pi/2)[:3,:3].T\n",
"\n",
"def m33_rotation_axis(idx, theta, dtype=\"f4\"):\n",
" c, s = np.cos(theta), np.sin(theta)\n",
" a, b = (idx + 1) % 3, (idx + 2) % 3\n",
"\n",
" mat = np.eye(3, dtype=dtype)\n",
" mat[a, a], mat[b, b] = c, c\n",
" mat[a, b], mat[b, a] = -s, s\n",
" return mat"
],
"metadata": {
"id": "vske6WnF_JdF"
},
"execution_count": 4,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### Shape"
],
"metadata": {
"id": "8LpdeYz5_MCH"
}
},
{
"cell_type": "code",
"source": [
"import drjit as dr\n",
"import mitsuba as mi\n",
"\n",
"mi.set_variant('cuda_ad_rgb')\n",
"# mi.set_variant('llvm_ad_rgb')\n",
"\n",
"class Mesh(mi.Mesh):\n",
" def __init__(self, props=mi.Properties()):\n",
" verts = props.get(\"vertices\")\n",
" faces = props.get(\"faces\")\n",
" super().__init__(props.get(\"name\"), verts.shape[0] // 3, faces.shape[0] // 3, props, True, False)\n",
" params = mi.traverse(self)\n",
" params['vertex_positions'] = verts.array\n",
" params['faces'] = faces.array\n",
" params.update()\n",
" self.recompute_vertex_normals()\n",
"\n",
" def to_string(self):\n",
" return \"mesh\"\n",
"\n",
"mi.register_mesh(\"mesh\", lambda props: Mesh(props))\n",
"\n",
"class Grid3d(mi.Object):\n",
" def __init__(self, shape):\n",
" super().__init__()\n",
" self.texture = mi.Texture3f(shape, 1, use_accel=False)\n",
" self.to_world = mi.Transform4f().translate([-.5,-.5,-.5])\n",
" self.to_local = self.to_world.inverse()\n",
" self.aabb = mi.ScalarBoundingBox3f(mi.ScalarPoint3f(-.5,-.5,-.5),\n",
" mi.ScalarPoint3f(.5,.5,.5))\n",
"\n",
" def bbox(self, delta=.05):\n",
" return mi.BoundingBox3f(self.aabb.min - delta, self.aabb.max + delta)\n",
"\n",
" def eval(self, x):\n",
" return self.texture.eval_cubic(self.to_local @ x)[0]\n",
"\n",
" def eval_grad(self, x):\n",
" g = mi.Vector3f(self.texture.eval_cubic_grad(self.to_local @ x)[1][0])\n",
" return self.to_world @ mi.Normal3f(g.x, g.y, g.z)\n",
"\n",
" def eval_and_grad(self, x):\n",
" v, g = self.texture.eval_cubic_grad(self.to_local @ x)\n",
" g = mi.Vector3f(g[0])\n",
" g = self.to_world @ mi.Normal3f(g.x, g.y, g.z)\n",
" return mi.Float(v[0]), g\n",
"\n",
" def eval_all(self, x):\n",
" v, g, h = self.texture.eval_cubic_hessian(self.to_local @ x)\n",
" v, g, h = mi.Float(v[0]), mi.Vector3f(g[0]), mi.Matrix3f(h[0])\n",
"\n",
" mat = self.to_local.matrix\n",
" to_local3 = mi.Matrix3f([\n",
" [mat[0, 0], mat[0, 1], mat[0, 2]],\n",
" [mat[1, 0], mat[1, 1], mat[1, 2]],\n",
" [mat[2, 0], mat[2, 1], mat[2, 2]]\n",
" ])\n",
" g = mi.Vector3f(to_local3.T @ g)\n",
" h = to_local3.T @ h @ to_local3\n",
"\n",
" return v, dr.detach(v, True), g, dr.detach(g, True), h\n",
"\n",
" def traverse(self, callback):\n",
" callback.put_parameter(\"data\", self.texture.tensor(), mi.ParamFlags.Differentiable)\n",
"\n",
" def parameters_changed(self, keys):\n",
" self.texture.set_tensor(self.texture.tensor())"
],
"metadata": {
"id": "_N251QDU_Ltg"
},
"execution_count": 5,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### Warp"
],
"metadata": {
"id": "24rC-RS2_OBT"
}
},
{
"cell_type": "code",
"source": [
"def bbox_distance_d(min_dist):\n",
" n = mi.Vector3f(0.0)\n",
" n[(min_dist.x < min_dist.y) & (min_dist.x < min_dist.z)] = mi.Vector3f(1, 0, 0)\n",
" n[(min_dist.y < min_dist.z) & (min_dist.y < min_dist.x)] = mi.Vector3f(0, 1, 0)\n",
" n[(min_dist.z < min_dist.x) & (min_dist.z < min_dist.y)] = mi.Vector3f(0, 0, 1)\n",
" return n\n",
"\n",
"def bbox_distance_inside_d(x, bbox):\n",
" bbox_max_dist, bbox_min_dist = dr.abs(bbox.max - x), dr.abs(bbox.min - x)\n",
" n = bbox_distance_d(dr.minimum(bbox_min_dist, bbox_max_dist))\n",
"\n",
" dist = dr.maximum(0.0, dr.minimum(dr.min(x - bbox.min), dr.min(bbox.max - x)))\n",
" dist_d = dr.select(dist > 0.0, n * dr.sign(bbox_max_dist - bbox_min_dist), 0.0)\n",
" return dist, dist_d\n",
"\n",
"def eval_trace_weight(ray, i, bbox, x, sdf_value, sdf_grad, hessian,\n",
" sil_weight_epsilon, sil_weight_offset, weight_power):\n",
" n_dot_d, n_dot_n = dr.dot(sdf_grad, ray.d), dr.dot(sdf_grad, sdf_grad)\n",
" dot_ratio = n_dot_d / n_dot_n\n",
" denom = sil_weight_epsilon + dr.abs(sdf_value) + sil_weight_offset * n_dot_d * dot_ratio\n",
" dist_weight = 1 / denom ** weight_power\n",
"\n",
" bbox_dist, bbox_dist_d = bbox_distance_inside_d(x, bbox)\n",
"\n",
" bbox_eps = 0.01\n",
" bbox_weight = dr.select(i > 0, dr.minimum(bbox_dist, bbox_eps) / bbox_eps, 1.0)\n",
" weight = dist_weight * bbox_weight\n",
"\n",
" bbox_weight_d = dr.select((i > 0) & (bbox_dist < bbox_eps), bbox_dist_d / bbox_eps, 0.0)\n",
" gradient = 2 * dot_ratio * (ray.d - dot_ratio * sdf_grad)\n",
" denom_d = dr.sign(sdf_value) * sdf_grad + sil_weight_offset * gradient @ hessian\n",
" dist_weight_d = -weight_power * dist_weight / denom * denom_d\n",
" weight_d = dist_weight * bbox_weight_d + bbox_weight * dist_weight_d\n",
"\n",
" return weight, weight_d\n",
"\n",
"@dr.syntax\n",
"def sphere_trace(sdf, ray, active,\n",
" trace_eps=1e-6,\n",
" sil_weight_epsilon=1e-6,\n",
" sil_weight_offset=.05,\n",
" weight_power=3,\n",
" extra_thresh=.05):\n",
" loop_record_state = dr.flag(dr.JitFlag.LoopRecord)\n",
" dr.set_flag(dr.JitFlag.LoopRecord, True)\n",
"\n",
" ray = mi.Ray3f(ray)\n",
" ray.d = dr.normalize(ray.d)\n",
"\n",
" bbox = sdf.bbox()\n",
" intersects_bbox, mint, maxt = bbox.ray_intersect(ray)\n",
" inside_bbox = bbox.contains(ray.o)\n",
" intersects_bbox &= (mint > 0) | inside_bbox\n",
" active = active & intersects_bbox\n",
"\n",
" ray.maxt = dr.minimum(maxt, ray.maxt)\n",
" trace_eps = trace_eps * dr.maximum(ray.maxt, 1)\n",
"\n",
" its_t = mi.Float(dr.inf)\n",
" t = dr.select(inside_bbox, 0.0, mint + 1e-5)\n",
" warp_t = mi.Float(0.0)\n",
" prev_surf_dist = mi.Float(0.0)\n",
" prev_sdf_grad_c = mi.Vector3f(0.0)\n",
" weight_sum = mi.Float(0.0)\n",
" mixed_sum_d = mi.Vector3f(0.0)\n",
" weight_d_sum = mi.Vector3f(0.0)\n",
" i = mi.Int32(0)\n",
" extra_weight_sum = mi.Float(0.0)\n",
" extra_weight_sum_d = mi.Vector3f(0.0)\n",
"\n",
" bbox_its_p = ray(t)\n",
" n = bbox_distance_d(dr.minimum(dr.abs(bbox.min - bbox_its_p), dr.abs(bbox.max - bbox_its_p)))\n",
" d_dot_n = dr.dot(ray.d, n)\n",
" t_d = mi.Vector3f(0.0)\n",
" t_d[~inside_bbox & (dr.abs(d_dot_n) > 0)] = -n / d_dot_n * t\n",
"\n",
" while active:\n",
" x = ray(t)\n",
" with dr.suspend_grad():\n",
" sdf_value, _, sdf_grad, _, hessian = sdf.eval_all(x)\n",
"\n",
" intersected = sdf_value < trace_eps\n",
" its_t[intersected] = t\n",
" surf_dist = dr.abs(sdf_value)\n",
" weight, weight_d = eval_trace_weight(ray, i, bbox, x, sdf_value, sdf_grad, hessian,\n",
" sil_weight_epsilon, sil_weight_offset, weight_power)\n",
"\n",
" inv_extra_w_den = 1 / dr.minimum(extra_thresh, surf_dist)\n",
" dist_difference = prev_surf_dist - surf_dist\n",
" extra_weight_sum += dr.select(dist_difference >= 0, dist_difference * inv_extra_w_den, 0.0)\n",
" extra_weight_sum = dr.minimum(extra_weight_sum, 1.0)\n",
"\n",
" curr_segment_value = dr.select(intersected, 0.0, surf_dist)\n",
" segment_length = 0.5 * (curr_segment_value + prev_surf_dist)\n",
" weight_increment = segment_length * weight * extra_weight_sum\n",
"\n",
" weight_sum = weight_sum + weight_increment\n",
" warp_t = warp_t + weight_increment * t\n",
"\n",
" weight_d = dr.fma(t, weight_d, dr.dot(ray.d, weight_d) * t_d)\n",
" sdf_grad_c = dr.fma(t, sdf_grad, dr.dot(ray.d, sdf_grad) * t_d)\n",
" segment_d = 0.5 * (sdf_grad_c + prev_sdf_grad_c)\n",
"\n",
" surf_dist_d = dr.sign(sdf_value) * sdf_grad_c\n",
" extra_w_d = (prev_sdf_grad_c - surf_dist_d) * inv_extra_w_den\n",
" extra_w_d = extra_w_d - dist_difference * dr.square(inv_extra_w_den) * dr.select(sdf_value < extra_thresh, surf_dist_d, 0.0)\n",
" extra_weight_sum_d += dr.select(dist_difference > 0.0, extra_w_d, 0.0)\n",
" extra_weight_sum_d[(extra_weight_sum >= 1.0) | (extra_weight_sum <= 0.0)] = 0.0\n",
" weight_d = weight * extra_weight_sum_d + weight_d * extra_weight_sum\n",
" weight *= extra_weight_sum\n",
"\n",
" weight_increment_d = dr.fma(weight, segment_d, weight_d * segment_length)\n",
" mixed_sum_d += dr.fma(weight_increment_d, t, weight * segment_length * t_d)\n",
" t_d = t_d + sdf_grad_c\n",
" weight_d_sum += weight_increment_d\n",
" i += 1\n",
" t += curr_segment_value\n",
" prev_surf_dist = surf_dist\n",
" prev_sdf_grad_c = sdf_grad_c\n",
" active &= (t <= ray.maxt) & (~intersected)\n",
"\n",
" refining = mi.Mask(dr.isfinite(its_t))\n",
" i = mi.Int32(0)\n",
" while refining:\n",
" min_dist = dr.detach(sdf.eval(ray(its_t)))\n",
" its_t[refining] += min_dist * (mi.Float(10) / mi.Float(10 + i))\n",
" refining &= (min_dist <= 0) | (min_dist > trace_eps)\n",
" i += 1\n",
" refining &= i < 10\n",
"\n",
" inv_weight_sum = 1 / weight_sum\n",
" warp_t = warp_t * inv_weight_sum\n",
" warp_t_d = (-warp_t * weight_d_sum + mixed_sum_d) * inv_weight_sum\n",
"\n",
" warp_weight = dr.clip(weight_sum, 0.0, 1.0)\n",
" warp_weight_d = dr.select((weight_sum > 0.0) & (weight_sum < 1.0), weight_d_sum, 0.0)\n",
"\n",
" invalid = (weight_sum < 1e-7) | ~intersects_bbox\n",
" warp_t[invalid] = dr.inf\n",
" warp_t_d[invalid] = 0.0\n",
" warp_weight[invalid] = 0.0\n",
" warp_weight_d[invalid] = 0.0\n",
"\n",
" dr.set_flag(dr.JitFlag.LoopRecord, loop_record_state)\n",
"\n",
" return its_t, warp_t, warp_t_d, warp_weight, warp_weight_d\n",
"\n",
"def compute_surface_interaction(sdf, ray, t):\n",
" si = dr.zeros(mi.SurfaceInteraction3f)\n",
" p = ray(t)\n",
"\n",
" sdf_value, sdf_grad = sdf.eval_and_grad(p)\n",
" t_diff = sdf_value / dr.detach(dr.dot(sdf_grad, -ray.d))\n",
" t = dr.replace_grad(mi.Float(t), t_diff)\n",
"\n",
" si.t = t\n",
" si.p = ray(t)\n",
" si.sh_frame.n = dr.normalize(sdf.eval_grad(si.p))\n",
" si.initialize_sh_frame()\n",
" si.n = si.sh_frame.n\n",
" si.wi = dr.select(si.is_valid(), si.to_local(-ray.d), -ray.d)\n",
" si.wavelengths = ray.wavelengths\n",
" si.dp_du = si.sh_frame.s\n",
" si.dp_dv = si.sh_frame.t\n",
" return si\n",
"\n",
"def outer_product(v, w):\n",
" return mi.Matrix3f(v.x * w.x, v.x * w.y, v.x * w.z,\n",
" v.y * w.x, v.y * w.y, v.y * w.z,\n",
" v.z * w.x, v.z * w.y, v.z * w.z)\n",
"\n",
"def normalize_sqr(x):\n",
" x2 = dr.squared_norm(x)\n",
" jac = mi.Matrix3f(1.0) / x2 - (2 / dr.square(x2)) * outer_product(x, x)\n",
" return x / x2, jac\n",
"\n",
"def warp_field_weight(sdf, x, d, sdf_value, sdf_grad, edge_eps):\n",
" bbox_dist, bbox_dist_d = bbox_distance_inside_d(x, sdf.bbox())\n",
" use_edge_eps = edge_eps <= bbox_dist\n",
" edge_eps_d = dr.select(use_edge_eps, mi.Vector3f(0.0), bbox_dist_d)\n",
" inv_edge_eps = 1 / dr.minimum(edge_eps, bbox_dist)\n",
" surf_dist = dr.abs(sdf_value)\n",
" fac = 1 - surf_dist * inv_edge_eps\n",
" w = dr.maximum(fac, 0.0)\n",
" w_d = -dr.sign(sdf_value) * sdf_grad * inv_edge_eps + surf_dist * dr.square(inv_edge_eps) * edge_eps_d\n",
" w_d = dr.select(fac >= 0.0, w_d, 0.0)\n",
" edge_eps_d = dr.select(use_edge_eps & (fac >= 0), surf_dist * dr.square(inv_edge_eps), 0.0)\n",
" return w, w_d, edge_eps_d\n",
"\n",
"class WarpField2D(mi.Object):\n",
" def __init__(self, sdf, edge_eps=0.05):\n",
" super().__init__()\n",
" self.sdf = sdf\n",
" self.max_reparam_depth = -1\n",
" self.edge_eps = dr.opaque(mi.Float, edge_eps)\n",
" self.clamping_thresh = 0.05\n",
"\n",
" def traverse(self, cb):\n",
" self.sdf.traverse(cb)\n",
"\n",
" def parameters_changed(self, keys):\n",
" self.sdf.parameters_changed(keys)\n",
"\n",
" def eval(self, x, ray_d, t, dt_dx, active, warp_weight=None, warp_weight_d=None):\n",
" active = active & dr.isfinite(t)\n",
"\n",
" sdf_value, _, sdf_normal, sdf_normal_d, h_mat = self.sdf.eval_all(x)\n",
"\n",
" sdf_normal_d_n, norm_jac = normalize_sqr(sdf_normal_d)\n",
" warp = -sdf_normal_d_n * sdf_value\n",
" jac = -norm_jac @ dr.detach(h_mat, True) * sdf_value - outer_product(sdf_normal_d_n, sdf_normal)\n",
"\n",
" weight, weight_grad, edge_eps_grad = warp_field_weight(self.sdf, dr.detach(x, True), dr.detach(ray_d, True),\n",
" dr.detach(sdf_value), dr.detach(sdf_normal),\n",
" self.edge_eps * dr.detach(t))\n",
" weight_grad += edge_eps_grad * ray_d * self.edge_eps\n",
"\n",
" weight_grad = weight_grad * warp_weight + weight * warp_weight_d\n",
" weight *= warp_weight\n",
"\n",
" weight = dr.detach(weight, True)\n",
" jac = outer_product(warp, weight_grad) + weight * jac\n",
" warp = warp * weight\n",
"\n",
" warp = dr.replace_grad(mi.Vector3f(0.0), warp)\n",
" warp = ray_d * dr.maximum(self.clamping_thresh, t) + warp\n",
" warp = dr.normalize(warp)\n",
"\n",
" proj_jac = (mi.Matrix3f(1.0) - outer_product(ray_d, ray_d)) @ jac\n",
" jac = proj_jac + proj_jac @ outer_product(ray_d, dt_dx / t)\n",
" div = jac[0, 0] + jac[1, 1] + jac[2, 2]\n",
"\n",
" active &= weight > 0\n",
" div = dr.select(active, div, 0.0)\n",
" warp = dr.replace_grad(ray_d, dr.select(active, warp, ray_d))\n",
" return warp, div\n",
"\n",
" def ray_test(self, ray, reparam=True, active=True):\n",
" with dr.suspend_grad():\n",
" its_t, warp_t, warp_t_d, warp_weight, warp_weight_d = sphere_trace(self.sdf, dr.detach(ray), active=active)\n",
"\n",
" div = mi.Float(1.0)\n",
" if reparam:\n",
" warp, div = self.eval(ray(warp_t), ray.d, t=warp_t, dt_dx=warp_t_d,\n",
" active=active, warp_weight=warp_weight, warp_weight_d=warp_weight_d)\n",
" ray.d = dr.replace_grad(ray.d, warp)\n",
" div = dr.replace_grad(mi.Float(1.0), div)\n",
"\n",
" return dr.isfinite(its_t), div\n",
"\n",
" def ray_intersect(self, ray, reparam=True, active=True):\n",
" with dr.suspend_grad():\n",
" its_t, warp_t, warp_t_d, warp_weight, warp_weight_d = sphere_trace(self.sdf, dr.detach(ray), active=active)\n",
"\n",
" div = mi.Float(1.0)\n",
" if reparam:\n",
" warp, div = self.eval(ray(warp_t), ray.d, t=warp_t, dt_dx=warp_t_d,\n",
" active=active, warp_weight=warp_weight, warp_weight_d=warp_weight_d)\n",
" ray.d = dr.replace_grad(ray.d, warp)\n",
" div = dr.replace_grad(mi.Float(1.0), div)\n",
"\n",
" si = compute_surface_interaction(self.sdf, ray, its_t)\n",
" return si, div"
],
"metadata": {
"id": "1p490ieC_PBw"
},
"execution_count": 6,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### Integrator"
],
"metadata": {
"id": "EWn7xWXh_Qix"
}
},
{
"cell_type": "code",
"source": [
"class ReparamIntegrator(mi.SamplingIntegrator):\n",
" def __init__(self, props=mi.Properties()):\n",
" super().__init__(props)\n",
" self.antithetic_sampling = props.get('antithetic_sampling', False)\n",
" self.warp = props.get(\"warp\")\n",
" self.bsdf = props.get(\"bsdf\")\n",
"\n",
" def prepare(self, sensor, film_size, seed, spp):\n",
" sampler = sensor.sampler().clone()\n",
" if spp != 0:\n",
" sampler.set_sample_count(spp)\n",
" spp = sampler.sample_count()\n",
" sampler.set_samples_per_wavefront(spp)\n",
"\n",
" wavefront_size = dr.prod(film_size) * spp\n",
" wavefront_size_limit = 0x40000000 if mi.Float == dr.cuda.ad.Float else 0xffffffff\n",
" if wavefront_size > wavefront_size_limit:\n",
" raise Exception(f\"Wavefront {wavefront_size} exceeds {wavefront_size_limit}\")\n",
" sampler.seed(seed, wavefront_size)\n",
" return sampler, spp\n",
"\n",
" def render(self, scene, sensor=0, seed=0,\n",
" spp=0, develop=True, evaluate=True, mode=dr.ADMode.Primal):\n",
" if isinstance(sensor, int):\n",
" sensor = scene.sensors()[sensor]\n",
"\n",
" film = sensor.film()\n",
" film_size = film.crop_size()\n",
" border_size = film.rfilter().border_size()\n",
" if film.sample_border():\n",
" film_size += 2 * border_size\n",
" film.prepare([])\n",
"\n",
" sampler, spp = self.prepare(sensor, film_size, seed, spp)\n",
"\n",
" spp = sampler.sample_count()\n",
" idx = dr.arange(mi.UInt32, dr.prod(film_size) * spp)\n",
"\n",
" log_spp = dr.log2i(spp)\n",
" if 1 << log_spp == spp:\n",
" idx >>= dr.opaque(mi.UInt32, log_spp)\n",
" else:\n",
" idx //= dr.opaque(mi.UInt32, spp)\n",
"\n",
" pos = mi.Vector2i()\n",
" pos.y = idx // film_size[0]\n",
" pos.x = dr.fma(type(pos.y)(-film_size[0]), pos.y, idx)\n",
" if film.sample_border():\n",
" pos -= border_size\n",
" pos += mi.Vector2i(film.crop_offset())\n",
"\n",
" block = film.create_block()\n",
"\n",
" diff_scale_factor = dr.rsqrt(mi.ScalarFloat(spp))\n",
" active = mi.Bool(True)\n",
" r = sampler.next_2d(active)\n",
" if self.antithetic_sampling:\n",
" sampler2 = sampler.clone()\n",
" self.eval_sample(mode, scene, sensor, sampler, block, pos + r, diff_scale_factor, active)\n",
" if self.antithetic_sampling:\n",
" self.eval_sample(mode, scene, sensor, sampler2, block, pos - r + 1.0, diff_scale_factor, active)\n",
"\n",
" film.put_block(block)\n",
" return film.develop()\n",
"\n",
" def eval_sample(self, mode, scene, sensor, sampler, block, position_sample, diff_scale_factor, active):\n",
" aperture_sample = mi.Point2f(0.5)\n",
" if sensor.needs_aperture_sample():\n",
" aperture_sample = sampler.next_2d(active)\n",
" time = sensor.shutter_open()\n",
" if sensor.shutter_open_time() > 0:\n",
" time += sampler.next_1d(active) * sensor.shutter_open_time()\n",
"\n",
" wavelength_sample = sampler.next_1d(active)\n",
" adjusted_position = (position_sample - sensor.film().crop_offset()) / mi.Vector2f(sensor.film().crop_size())\n",
" ray, ray_weight = sensor.sample_ray_differential(time, wavelength_sample, adjusted_position, aperture_sample)\n",
" ray.scale_differential(diff_scale_factor)\n",
"\n",
" rgb, valid_ray, det = self.sample(mode, scene, sampler, ray, mi.Mask(active))\n",
"\n",
" it = dr.zeros(mi.Interaction3f)\n",
" it.p = ray.o + ray.d\n",
" ds, ray_weight = sensor.sample_direction(it, aperture_sample)\n",
" ray_weight = dr.select(ray_weight > 0.0, ray_weight / dr.detach(ray_weight), 1.0)\n",
" ray_weight = dr.replace_grad(type(ray_weight)(1.0), ray_weight)\n",
"\n",
" rgb = ray_weight * rgb\n",
" aovs = [rgb.x, rgb.y, rgb.z]\n",
" if block.channel_count() == 5:\n",
" aovs.append(dr.select(valid_ray, mi.Float(1.0), mi.Float(0.0)))\n",
" aovs.append(dr.replace_grad(mi.Float(1.0), det * ray_weight[0]))\n",
"\n",
" block.put(ds.uv, aovs, active)\n",
"\n",
" def render_backward(self, scene, params, grad_in, sensor=0, seed=0, spp=0):\n",
" image = self.render(scene=scene, sensor=sensor, seed=seed,\n",
" spp=spp, develop=True, evaluate=False, mode=dr.ADMode.Backward)\n",
" dr.backward_from(image * grad_in)\n",
"\n",
" def render_forward(self, scene, params, sensor=0, seed=0, spp=0):\n",
" image = self.render(scene=scene, sensor=sensor, seed=seed, spp=spp,\n",
" develop=True, evaluate=False, mode=dr.ADMode.Forward)\n",
" dr.forward_to(image)\n",
" return dr.grad(image)\n",
"\n",
" def traverse(self, cb):\n",
" self.warp.traverse(cb)\n",
" super().traverse(cb)\n",
"\n",
" def parameters_changed(self, keys):\n",
" self.warp.parameters_changed(keys)\n",
" super().parameters_changed(keys)\n",
"\n",
" def sample(self, mode, scene, sampler, ray, active):\n",
" reparametrize = mode != dr.ADMode.Primal\n",
"\n",
" si, det = self.warp.ray_intersect(ray, reparam=reparametrize, active=active)\n",
" valid_ray = (not self.hide_emitters) and scene.environment() is not None\n",
" valid_ray |= si.is_valid()\n",
"\n",
" throughput = mi.Spectrum(1.0) * det\n",
" result = throughput * dr.select(active, si.emitter(scene, active).eval(si, active), 0.0)\n",
"\n",
" active_e = active & si.is_valid() & mi.has_flag(self.bsdf.flags(), mi.BSDFFlags.Smooth)\n",
" with dr.suspend_grad():\n",
" ds, _ = scene.sample_emitter_direction(si, sampler.next_2d(active_e), False, active_e)\n",
"\n",
" active_e &= ds.pdf != 0.0\n",
"\n",
" shadow_ray = si.spawn_ray_to(ds.p)\n",
" shadow_ray.d = dr.detach(shadow_ray.d)\n",
" occluded, det_e = self.warp.ray_test(shadow_ray, reparam=reparametrize, active=active_e)\n",
"\n",
" si_e = dr.zeros(mi.SurfaceInteraction3f)\n",
" si_e.sh_frame.n = ds.n\n",
" si_e.initialize_sh_frame()\n",
" si_e.n = si_e.sh_frame.n\n",
" si_e.wi = -shadow_ray.d\n",
" si_e.wavelengths = ray.wavelengths\n",
"\n",
" emitter_val = dr.select(active_e, ds.emitter.eval(si_e, active_e) / ds.pdf, 0.)\n",
" bsdf_val = self.bsdf.eval(mi.BSDFContext(), si, si.to_local(shadow_ray.d), active_e)\n",
" nee_contrib = dr.select(~occluded, bsdf_val * emitter_val * det_e, 0.)\n",
"\n",
" result[active_e] += throughput * nee_contrib\n",
"\n",
" return dr.select(valid_ray, mi.Spectrum(result), 0.0), valid_ray, det\n",
"\n",
" def to_string(self):\n",
" return \"integrator\"\n",
"\n",
"mi.register_integrator(\"sdf_reparam_direct\", lambda props: ReparamIntegrator(props))"
],
"metadata": {
"id": "sXsA2xib_QLm"
},
"execution_count": 7,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Train"
],
"metadata": {
"id": "1ZM5G3dQ_VoM"
}
},
{
"cell_type": "code",
"source": [
"import trimesh\n",
"import openvdb as vdb\n",
"from fastsweep import redistance\n",
"from bisect import bisect_left\n",
"\n",
"def array_to_vdb_grid(data, size=256, grid_class=vdb.GridClass.LEVEL_SET, name=\"distance\"):\n",
" grid = vdb.FloatGrid()\n",
" grid.copyFromArray(data)\n",
" grid.gridClass = grid_class\n",
" grid.name = name\n",
" grid.transform = vdb.createLinearTransform(voxelSize=1/size)\n",
" return grid\n",
"\n",
"def vdb_grid_to_array(grid):\n",
" mn, mx = grid.evalLeafBoundingBox()\n",
" shape = (mx[0] - mn[0] + 1, mx[1] - mn[2] + 1, mx[2] - mn[2] + 1)\n",
" arr = np.empty(shape, dtype=\"f4\")\n",
" grid.copyToArray(arr)\n",
" return arr\n",
"\n",
"def read_ply(path, scale=.3):\n",
" with open(path, \"rb\") as f:\n",
" mesh = trimesh.exchange.ply.load_ply(f)\n",
" verts = mesh['vertices'].astype(\"f4\")\n",
" verts = verts - verts.mean(0)\n",
" verts = verts / np.linalg.norm(verts,axis=-1).max() * scale\n",
" return verts, mesh[\"faces\"]\n",
"\n",
"def read_obj(fn, scale=.3):\n",
" with open(fn, \"rb\") as f:\n",
" mesh = trimesh.exchange.obj.load_obj(f)['geometry'][fn]\n",
"\n",
" verts = mesh['vertices'].astype(\"f4\")\n",
" verts = verts - verts.mean(0)\n",
" verts = verts / np.linalg.norm(verts,axis=-1).max() * scale\n",
" return verts, mesh['faces']\n",
"\n",
"def pick(i, ts, vs):\n",
" return vs[bisect_left(ts, i)]\n",
"\n",
"def to_image(img):\n",
" return np.rint((img ** (1/2.2)).clip(0,1) * 255).astype(\"u1\")\n",
"\n",
"def make_film(size):\n",
" return mi.load_dict({'type': 'hdrfilm', 'width': size[0], 'height': size[1],\n",
" 'pixel_format': 'rgb', 'pixel_filter': {'type': 'gaussian'},\n",
" 'sample_border': True})\n",
"\n",
"def set_film_size(film, size):\n",
" params = mi.traverse(film)\n",
" params['size'] = size\n",
" params.update()\n",
" film.parameters_changed()\n",
"\n",
"def render_direct(verts, faces, envmap, sensors, seed=41):\n",
" scene = mi.load_dict({\n",
" 'type': 'scene',\n",
" 'integrator': {'type': 'direct'},\n",
" 'mesh': {\n",
" 'type': 'mesh',\n",
" \"name\": \"mesh\",\n",
" \"vertices\": mi.Float(verts.ravel()),\n",
" \"faces\": mi.UInt(faces.ravel()),\n",
" 'bsdf': {'type': 'twosided',\n",
" 'material': {'type': 'diffuse',\n",
" 'reflectance': {'type': 'rgb','value': (.8, .8, .8)}}}},\n",
" 'emitter': {'type': 'envmap','filename': envmap}})\n",
" return [mi.Bitmap(mi.render(scene, sensor=sensor, seed=i + seed, spp=1024))\n",
" for i, sensor in enumerate(sensors)]\n",
"\n",
"def make_sphere_sdf(shape, center=[0.5, 0.5, 0.5], radius=0.3):\n",
" z, y, x = np.meshgrid(np.linspace(0, 1, shape[0]),\n",
" np.linspace(0, 1, shape[1]),\n",
" np.linspace(0, 1, shape[2]), indexing='ij')\n",
" pts = np.stack([x.ravel(), y.ravel(), z.ravel()], axis=1)\n",
" dist = np.linalg.norm(pts - center, axis=-1) - radius\n",
" sdf = dist.reshape(shape).astype(np.float32)\n",
" return redistance(mi.TensorXf(sdf))\n",
"\n",
"def clip_gradient(val, r=1e-1):\n",
" grad = dr.grad(val)\n",
" dr.set_grad(val, dr.select(dr.isnan(grad), 0.0, dr.clip(grad, -r, r)))\n",
"\n",
"def upsample_sdf(sdf):\n",
" shape = 2 * mi.ScalarVector3i(sdf.texture.shape[:3])\n",
" with dr.suspend_grad():\n",
" z, y, x = dr.meshgrid(*[dr.linspace(mi.Float, -.5 + .5 / shape[i], .5 - .5 / shape[i], shape[i])\n",
" for i in range(3)],\n",
" indexing='ij')\n",
" out = sdf.eval(mi.Point3f(x, y, z))\n",
" return mi.TensorXf(out, (*shape, *sdf.texture.shape[3:]))\n",
"\n",
"def eval_box_sdf(x, p, extents, smoothing):\n",
" q = dr.abs(x - p) - extents\n",
" return dr.norm(dr.maximum(q, 0.0)) + dr.minimum(dr.maximum(q.x, dr.maximum(q.y, q.z)), 0.0) - smoothing\n",
"\n",
"def make_box_sdf(shape):\n",
" z, y, x = dr.meshgrid(dr.linspace(mi.Float, -0.5, 0.5, shape[0]),\n",
" dr.linspace(mi.Float, -0.5, 0.5, shape[1]),\n",
" dr.linspace(mi.Float, -0.5, 0.5, shape[2]), indexing='ij')\n",
" dist = eval_box_sdf(mi.Point3f(x, y, z), mi.Point3f(0), mi.Vector3f(0.49), 0.01)\n",
" return mi.TensorXf(dist, shape)\n",
"\n",
"def discrete_laplacian(data):\n",
" shape = data.shape\n",
"\n",
" def val(x, y, z):\n",
" a = dr.clip(z, 0, shape[2] - 1) * shape[1] * shape[0]\n",
" b = dr.clip(y, 0, shape[1] - 1) * shape[0]\n",
" c = dr.clip(x, 0, shape[0] - 1)\n",
"\n",
" return dr.gather(mi.Float, data.array, a + b + c)\n",
"\n",
" z, y, x = dr.meshgrid(*[dr.arange(mi.UInt, shape[i]) for i in range(3)], indexing='ij')\n",
" c = val(x, y, z)\n",
" v = val(x - 1, y, z) + val(x + 1, y, z) + val(x, y - 1, z) + val(x, y + 1, z) + val(x, y, z - 1) + val(x, y, z + 1)\n",
" return dr.sum(dr.square(c - v / 6.))\n",
"\n",
"def box_filter3(data):\n",
" shape = data.shape\n",
"\n",
" def val(x, y, z):\n",
" a = dr.clip(z, 0, shape[2] - 1) * shape[1] * shape[0]\n",
" b = dr.clip(y, 0, shape[1] - 1) * shape[0]\n",
" c = dr.clip(x, 0, shape[0] - 1)\n",
" return dr.gather(mi.Float, data.array, a + b + c)\n",
"\n",
" z, y, x = dr.meshgrid(*[dr.arange(mi.UInt, shape[i]) for i in range(3)], indexing='ij')\n",
" v = val(x-1,y-1,z-1) + val(x-1,y-1,z) + val(x-1,y-1,z+1)\n",
" v = v + val(x-1,y,z-1) + val(x-1,y,z) + val(x-1,y,z+1)\n",
" v = v + val(x-1,y+1,z-1) + val(x-1,y+1,z) + val(x-1,y+1,z+1)\n",
" v = v + val(x,y-1,z-1) + val(x,y-1,z) + val(x,y-1,z+1)\n",
" v = v + val(x,y,z-1) + val(x,y,z) + val(x,y,z+1)\n",
" v = v + val(x,y+1,z-1) + val(x,y+1,z) + val(x,y+1,z+1)\n",
" v = v + val(x+1,y-1,z-1) + val(x+1,y-1,z) + val(x+1,y-1,z+1)\n",
" v = v + val(x+1,y,z-1) + val(x+1,y,z) + val(x+1,y,z+1)\n",
" v = v + val(x+1,y+1,z-1) + val(x+1,y+1,z) + val(x+1,y+1,z+1)\n",
" return v / 27.\n",
"\n",
"def box_filter5(data):\n",
" shape = data.shape\n",
"\n",
" def val(x, y, z):\n",
" a = dr.clip(z, 0, shape[2] - 1) * shape[1] * shape[0]\n",
" b = dr.clip(y, 0, shape[1] - 1) * shape[0]\n",
" c = dr.clip(x, 0, shape[0] - 1)\n",
" return dr.gather(mi.Float, data.array, a + b + c)\n",
"\n",
" z, y, x = dr.meshgrid(*[dr.arange(mi.UInt, shape[i]) for i in range(3)], indexing='ij')\n",
" v = val(x-2,y-2,z-2)+val(x-2,y-2,z-1)+val(x-2,y-2,z)+val(x-2,y-2,z+1)+val(x-2,y-2,z+2)\n",
" v = v + val(x-2,y-1,z-2)+val(x-2,y-1,z-1)+val(x-2,y-1,z)+val(x-2,y-1,z+1)+val(x-2,y-1,z+2)\n",
" v = v + val(x-2,y,z-2)+val(x-2,y,z-1)+val(x-2,y,z)+val(x-2,y,z+1)+val(x-2,y,z+2)\n",
" v = v + val(x-2,y+1,z-2)+val(x-2,y+1,z-1)+val(x-2,y+1,z)+val(x-2,y+1,z+1)+val(x-2,y+1,z+2)\n",
" v = v + val(x-2,y+2,z-2)+val(x-2,y+2,z-1)+val(x-2,y+2,z)+val(x-2,y+2,z+1)+val(x-2,y+2,z+2)\n",
"\n",
" v = v + val(x-1,y-2,z-2)+val(x-1,y-2,z-1)+val(x-1,y-2,z)+val(x-1,y-2,z+1)+val(x-1,y-2,z+2)\n",
" v = v + val(x-1,y-1,z-2)+val(x-1,y-1,z-1)+val(x-1,y-1,z)+val(x-1,y-1,z+1)+val(x-1,y-1,z+2)\n",
" v = v + val(x-1,y,z-2)+val(x-1,y,z-1)+val(x-1,y,z)+val(x-1,y,z+1)+val(x-1,y,z+2)\n",
" v = v + val(x-1,y+1,z-2)+val(x-1,y+1,z-1)+val(x-1,y+1,z)+val(x-1,y+1,z+1)+val(x-1,y+1,z+2)\n",
" v = v + val(x-1,y+2,z-2)+val(x-1,y+2,z-1)+val(x-1,y+2,z)+val(x-1,y+2,z+1)+val(x-1,y+2,z+2)\n",
"\n",
" v = v + val(x,y-2,z-2)+val(x,y-2,z-1)+val(x,y-2,z)+val(x,y-2,z+1)+val(x,y-2,z+2)\n",
" v = v + val(x,y-1,z-2)+val(x,y-1,z-1)+val(x,y-1,z)+val(x,y-1,z+1)+val(x,y-1,z+2)\n",
" v = v + val(x,y,z-2)+val(x,y,z-1)+val(x,y,z)+val(x,y,z+1)+val(x,y,z+2)\n",
" v = v + val(x,y+1,z-2)+val(x,y+1,z-1)+val(x,y+1,z)+val(x,y+1,z+1)+val(x,y+1,z+2)\n",
" v = v + val(x,y+2,z-2)+val(x,y+2,z-1)+val(x,y+2,z)+val(x,y+2,z+1)+val(x,y+2,z+2)\n",
"\n",
" v = v + val(x+1,y-2,z-2)+val(x+1,y-2,z-1)+val(x+1,y-2,z)+val(x+1,y-2,z+1)+val(x+1,y-2,z+2)\n",
" v = v + val(x+1,y-1,z-2)+val(x+1,y-1,z-1)+val(x+1,y-1,z)+val(x+1,y-1,z+1)+val(x+1,y-1,z+2)\n",
" v = v + val(x+1,y,z-2)+val(x+1,y,z-1)+val(x+1,y,z)+val(x+1,y,z+1)+val(x+1,y,z+2)\n",
" v = v + val(x+1,y+1,z-2)+val(x+1,y+1,z-1)+val(x+1,y+1,z)+val(x+1,y+1,z+1)+val(x+1,y+1,z+2)\n",
" v = v + val(x+1,y+2,z-2)+val(x+1,y+2,z-1)+val(x+1,y+2,z)+val(x+1,y+2,z+1)+val(x+1,y+2,z+2)\n",
"\n",
" v = v + val(x+2,y-2,z-2)+val(x+2,y-2,z-1)+val(x+2,y-2,z)+val(x+2,y-2,z+1)+val(x+2,y-2,z+2)\n",
" v = v + val(x+2,y-1,z-2)+val(x+2,y-1,z-1)+val(x+2,y-1,z)+val(x+2,y-1,z+1)+val(x+2,y-1,z+2)\n",
" v = v + val(x+2,y,z-2)+val(x+2,y,z-1)+val(x+2,y,z)+val(x+2,y,z+1)+val(x+2,y,z+2)\n",
" v = v + val(x+2,y+1,z-2)+val(x+2,y+1,z-1)+val(x+2,y+1,z)+val(x+2,y+1,z+1)+val(x+2,y+1,z+2)\n",
" v = v + val(x+2,y+2,z-2)+val(x+2,y+2,z-1)+val(x+2,y+2,z)+val(x+2,y+2,z+1)+val(x+2,y+2,z+2)\n",
" return v / 125.\n",
"\n",
"def soft_grad3(val):\n",
" dr.set_grad(val, box_filter3(dr.grad(val)))\n",
"\n",
"def soft_grad5(val):\n",
" dr.set_grad(val, box_filter5(dr.grad(val)))\n",
"\n",
"def render_sdf(data, pos=(0,1,-2)):\n",
" scene = mi.load_dict({\n",
" \"type\": \"scene\",\n",
" 'integrator': {'type': 'direct'},\n",
" 'sensor': {\n",
" 'type': 'perspective',\n",
" 'to_world': mi.ScalarTransform4f().look_at(pos,(0, 0, 0),(0, 1, 0)),\n",
" 'film': {\n",
" 'type': 'hdrfilm',\n",
" 'width': 256, 'height': 256,\n",
" 'rfilter': { 'type': 'box' },\n",
" },\n",
" \"sampler\": {\n",
" \"type\": \"independent\",\n",
" \"sample_count\": 512\n",
" }\n",
" },\n",
" \"emitter\": {\n",
" \"type\": \"envmap\",\n",
" \"filename\": \"Nicolet2021Large/scenes/suzanne/textures/kloppenheim_06_2k.hdr\"\n",
" },\n",
" 'sdf': {\n",
" \"type\" : \"sdfgrid\",\n",
" 'to_world': mi.ScalarTransform4f().translate((-.5,-.5,-.5)),\n",
" \"normals\" : \"smooth\",\n",
" \"grid\": data,\n",
" 'bsdf': {'type': 'diffuse'}\n",
" }\n",
" })\n",
" return mi.util.convert_to_bitmap(mi.render(scene, seed=0))\n",
"\n",
"@dr.syntax\n",
"def mesh2sdf(verts, faces, res=256):\n",
" scene = mi.load_dict({\n",
" 'type': 'scene',\n",
" 'integrator': {'type': 'path'},\n",
" 'sensor': {'type': 'perspective'},\n",
" 'shape': {\n",
" 'type': 'mesh',\n",
" \"name\": \"mesh\",\n",
" \"vertices\": mi.Float(verts.ravel()),\n",
" \"faces\": mi.UInt(faces.ravel())}})\n",
" z, y, x = dr.meshgrid(*[dr.linspace(mi.Float, -.5 + .5 / res, .5 - .5 / res, res) for i in range(3)], indexing='ij')\n",
" ray = mi.Ray3f(mi.Point3f(x, y, z), dr.normalize(mi.Vector3f(0, 1, 0)))\n",
" si = scene.ray_intersect(ray)\n",
"\n",
" values = .5 - dr.select(si.is_valid() & (dr.dot(si.n, ray.d) > 0), 1.0, 0.0)\n",
" grid = redistance(mi.TensorXf(values, (res, res, res)))\n",
"\n",
" # Gather voxels close to surface\n",
" indices = dr.arange(mi.UInt, res ** 3)\n",
" near_surface_indices = mi.UInt(np.array(indices)[dr.abs(grid.array) < 1.0 / res])\n",
"\n",
" # For each index, get the world space ray origin\n",
" ray_o = dr.gather(mi.Point3f, ray.o, near_surface_indices)\n",
" angular_res = 16\n",
" n_angle_samples = angular_res ** 2\n",
" r = dr.arange(mi.Float, angular_res)\n",
" u, v = dr.meshgrid((r + 0.5) / angular_res, (r + 0.5) / angular_res)\n",
" uv = dr.tile(mi.Vector2f(u, v), dr.width(ray_o))\n",
" ray = mi.Ray3f(dr.repeat(ray_o, n_angle_samples), mi.warp.square_to_uniform_sphere(uv))\n",
"\n",
" # Trace these rays and find the minimum distance and modulate by sign\n",
" si = scene.ray_intersect(ray)\n",
" min_dist = dr.full(mi.Float, 100.0, dr.width(near_surface_indices))\n",
" j = dr.arange(mi.UInt32, dr.width(near_surface_indices))\n",
" i = mi.UInt32(0)\n",
" while i < n_angle_samples:\n",
" min_dist = dr.minimum(min_dist, dr.gather(mi.Float, si.t, j * n_angle_samples + i))\n",
" i += 1\n",
" min_dist = min_dist * dr.sign(dr.gather(type(grid.array), grid.array, near_surface_indices))\n",
" dr.scatter(grid.array, min_dist, near_surface_indices)\n",
" return redistance(grid)"
],
"metadata": {
"id": "fOdZ6oWu_WKT"
},
"execution_count": 8,
"outputs": []
},
{
"cell_type": "code",
"source": [
"from argparse import Namespace\n",
"from tqdm import tqdm\n",
"from collections import defaultdict\n",
"\n",
"def make_refs(imgs):\n",
" rfilter = mi.scalar_rgb.load_dict({'type': 'gaussian'})\n",
" size = imgs[0].size().x\n",
" refs = {size: [mi.TensorXf(x) for x in imgs]}\n",
" while size > 4:\n",
" size //= 2\n",
" refs[size] = [mi.TensorXf(x.resample((size, size), rfilter)) for x in imgs]\n",
" return refs\n",
"\n",
"def train(args, data, film, sensors, ref_imgs, fine_iter=420,\n",
" lr=1e-2, lr_decay=1e-2,\n",
" reg=([128, 256], [1e-3, 1e-4, 1e-5])):\n",
" set_film_size(film, args.resolution // 2 ** len(args.render_upsample_iter))\n",
" for s in sensors: s.parameters_changed()\n",
"\n",
" folder = f\"data/{args.name}\"\n",
" os.makedirs(folder, exist_ok=True)\n",
"\n",
" scene = mi.load_dict({\n",
" 'type': 'scene',\n",
" 'integrator': {\n",
" 'type': 'sdf_reparam_direct',\n",
" 'warp': WarpField2D(Grid3d((args.size, args.size, args.size)), edge_eps=.01),\n",
" 'bsdf': {'type': 'twosided',\n",
" 'material': {'type': 'diffuse',\n",
" 'reflectance': {'type': 'rgb','value': (.8, .8, .8)}}}},\n",
" 'emitter': {'type': 'envmap','filename': args.envmap}})\n",
"\n",
" params = mi.traverse(scene)\n",
" sdf_key = 'integrator.data'\n",
" params.keep([sdf_key])\n",
"\n",
" opt = mi.ad.Adam(lr=lr, mask_updates=True)\n",
"\n",
" opt[sdf_key] = data\n",
" params.update(opt)\n",
"\n",
" bbox_sdf = make_box_sdf(opt[sdf_key].shape)\n",
" refs = make_refs(ref_imgs)\n",
"\n",
" vdb.write(f\"{folder}/0000.vdb\", array_to_vdb_grid(data=opt[sdf_key].numpy().squeeze()))\n",
"\n",
" seed = 0\n",
" metrics = defaultdict(list)\n",
" pbar = tqdm(range(args.n_iter))\n",
" n_sensors = len(sensors)\n",
" for i in pbar:\n",
" loss = mi.Float(0)\n",
" targets = refs[film.crop_size().x]\n",
" for j in range(n_sensors):\n",
" img = mi.render(scene, params=params, sensor=sensors[j],\n",
" seed=seed, spp=256,\n",
" seed_grad=seed + 1 + n_sensors, spp_grad=64)\n",
" seed += 1 + n_sensors\n",
"\n",
" view_loss = dr.mean(dr.abs(img - targets[j])) / n_sensors\n",
" dr.backward(view_loss)\n",
" loss += dr.detach(view_loss)\n",
"\n",
" reg_loss = discrete_laplacian(opt[sdf_key]) * pick(i, reg[0], reg[1])\n",
" dr.backward(reg_loss)\n",
" loss += dr.detach(reg_loss)\n",
"\n",
" clip_gradient(opt[sdf_key])\n",
" if i < fine_iter:\n",
" soft_grad5(opt[sdf_key])\n",
" soft_grad3(opt[sdf_key])\n",
" opt.step()\n",
"\n",
" opt.set_learning_rate({sdf_key: lr / (1. + lr_decay * i)})\n",
" opt[sdf_key] = mi.TensorXf(redistance(dr.maximum(opt[sdf_key], bbox_sdf)))[...,None]\n",
" dr.enable_grad(opt[sdf_key])\n",
"\n",
" vdb.write(f\"{folder}/{i+1:04d}.vdb\", array_to_vdb_grid(data=opt[sdf_key].numpy().squeeze()))\n",
"\n",
" if i in args.render_upsample_iter:\n",
" set_film_size(film, film.crop_size().x * 2)\n",
" for s in sensors: s.parameters_changed()\n",
"\n",
" params.update(opt)\n",
"\n",
" metric = {\"loss\": loss.numpy().item()}\n",
" pbar.set_postfix(metric)\n",
" for k, v in metric.items(): metrics[k].append(v)\n",
"\n",
" return scene, metrics"
],
"metadata": {
"id": "zmHv2L49w6NK"
},
"execution_count": 9,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Training"
],
"metadata": {
"id": "KxWvCa9bwzPb"
}
},
{
"cell_type": "code",
"source": [
"args = Namespace(\n",
" name=\"amass\",\n",
" size=256,resolution=512,\n",
"\n",
" n_iter=144,\n",
" render_upsample_iter=[64, 92, 128],\n",
" fine_iter=64,\n",
" lr=3e-3,\n",
"\n",
" envmap=\"Nicolet2021Large/scenes/suzanne/textures/kloppenheim_06_2k.hdr\")\n",
"\n",
"film = make_film((args.resolution, args.resolution))\n",
"pts = regular_points_sphere()\n",
"sensors = [mi.load_dict({'type': 'perspective','fov': 39.0,\n",
" 'to_world': mi.ScalarTransform4f().look_at(mi.ScalarPoint3f(p[0], p[1], p[2]) * 1.1,\n",
" mi.ScalarPoint3f(0, 0, 0),\n",
" mi.ScalarPoint3f(u[0],u[1],u[2])),\n",
" 'sampler': {'type': 'independent'},\n",
" 'film': film})\n",
" for p, u in zip(pts, quat_mul_v(quat_lookat(-pts),np.array([[0,1,0]])))]\n",
"\n",
"verts, faces = read_ply(\"15162.ply\")\n",
"verts = einsum(m33_rotation_axis(0, -np.pi/2), verts, \"r c,n c->n r\")\n",
"\n",
"ref_imgs = render_direct(verts, faces, args.envmap, sensors)"
],
"metadata": {
"id": "DT0w5IvBDH4u"
},
"execution_count": 33,
"outputs": []
},
{
"cell_type": "code",
"source": [
"imshow(cv2.resize(to_image(make_mosaic(np.asarray(ref_imgs),nx=6)),\n",
" None, fx=.5, fy=.5, interpolation=cv2.INTER_LANCZOS4))"
],
"metadata": {
"id": "QsgVsjj4P-yV",
"outputId": "4b4eae06-8e3e-495f-aafc-210201e14dd0",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 401
}
},
"execution_count": 23,
"outputs": [
{
"output_type": "display_data",
"data": {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment