Last active
March 2, 2025 10:07
-
-
Save stwind/b416c7485825ee158f673a703adbc2ab to your computer and use it in GitHub Desktop.
dsdfr_amass.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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