ernie-renderer 0.2.0.dev22__tar.gz → 0.2.0.dev30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ernie-renderer might be problematic. Click here for more details.
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/CMakeLists.txt +1 -1
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/PKG-INFO +1 -1
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/CMakeLists.txt +1 -1
- ernie_renderer-0.2.0.dev30/benchmarks/scene/extents.cpp +40 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.cpp +25 -9
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.h +8 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/CMakeLists.txt +6 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.cpp +89 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.h +43 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.cpp +54 -8
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.h +24 -3
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.cpp +44 -4
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.h +37 -1
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.cpp +11 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.h +63 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.cpp +1 -1
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.h +9 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.cpp +93 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.h +63 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.cpp +72 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.h +186 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.cpp +67 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.h +87 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/registry.cpp +57 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.cpp +126 -0
- ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.h +95 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.cpp +11 -2
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.h +3 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/tokens.h +9 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.h +22 -1
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/bytes.h +26 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/CMakeLists.txt +5 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/common.h +21 -1
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/nanovdb_test.cpp +9 -0
- ernie_renderer-0.2.0.dev30/tests/scene/extent_cache_test.cpp +81 -0
- ernie_renderer-0.2.0.dev30/tests/scene/instancer_test.cpp +69 -0
- ernie_renderer-0.2.0.dev30/tests/scene/lux_test.cpp +75 -0
- ernie_renderer-0.2.0.dev30/tests/scene/mesh_test.cpp +75 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/scene_test.cpp +19 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/schema_test.cpp +3 -4
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/storage_test.cpp +20 -0
- ernie_renderer-0.2.0.dev30/tests/scene/vol_test.cpp +83 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/bytes_test.cpp +17 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/worker_pool_test.cpp +10 -1
- ernie_renderer-0.2.0.dev22/ernie/scene/schemas/registry.cpp +0 -23
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/workflows/ci.yml +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/CMakePresets.json +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/bench.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieTesting.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/geometry/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/geometry/bounds.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/convert.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/collection.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/collection.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/shade.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/shade.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/value.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/algorithm.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/hash_index.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/random.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/text.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/consumer/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/geometry/bounds_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/ies_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/image_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/raster_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/texture_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/api_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/path_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/xform_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/algorithm_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/disk_cache_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/file_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/hash_index_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/text_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/nanovdb/PNanoVDB.h +0 -0
|
@@ -15,7 +15,7 @@ project(
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
# Pre-release suffix such as .dev12, written by CI.
|
|
18
|
-
set(ERNIE_VERSION_SUFFIX ".
|
|
18
|
+
set(ERNIE_VERSION_SUFFIX ".dev30" CACHE STRING "Pre-release suffix of Ernie's version")
|
|
19
19
|
set(ERNIE_VERSION "${PROJECT_VERSION}${ERNIE_VERSION_SUFFIX}")
|
|
20
20
|
|
|
21
21
|
option(ERNIE_BUILD_TESTS "Build Ernie's tests" OFF)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ernie-renderer
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev30
|
|
4
4
|
Summary: Efficient Renderer for Natural and Interplanetary Environments: a physically based, spectral Vulkan ray tracer
|
|
5
5
|
Author: Alex Maietta
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file extents.cpp
|
|
3
|
+
/// @brief Cached extents at 100,000 prims: the first update, and one edit's.
|
|
4
|
+
#include "benchmarks/bench.h"
|
|
5
|
+
#include "ernie/scene/schemas/geom.h"
|
|
6
|
+
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <vector>
|
|
10
|
+
|
|
11
|
+
namespace ernie::bench {
|
|
12
|
+
namespace {
|
|
13
|
+
|
|
14
|
+
constexpr int kSpheres = 100'000;
|
|
15
|
+
|
|
16
|
+
std::unique_ptr<Scene> MakeSpheres() {
|
|
17
|
+
auto scene = std::make_unique<Scene>();
|
|
18
|
+
for (int i = 0; i < kSpheres; ++i) {
|
|
19
|
+
scene->Define("/World/Ball_" + std::to_string(i), "Sphere");
|
|
20
|
+
}
|
|
21
|
+
return scene;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const bool kFirstUpdate = Register("scene.extents.first_update_100k", [] {
|
|
25
|
+
std::unique_ptr<Scene> scene;
|
|
26
|
+
return Timing{Fastest([&] { scene = MakeSpheres(); }, [&] { scene->UpdateExtents(); }), 10.0};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const bool kOneEdit = Register("scene.extents.update_after_one_edit_of_100k", [] {
|
|
30
|
+
std::unique_ptr<Scene> scene = MakeSpheres();
|
|
31
|
+
scene->UpdateExtents();
|
|
32
|
+
const PrimId ball = *scene->Find("/World/Ball_54321");
|
|
33
|
+
double radius = 1.0;
|
|
34
|
+
const double ms = Fastest([&] { scene->Set(ball, Sphere::kRadius, radius += 1.0); },
|
|
35
|
+
[&] { scene->UpdateExtents(); });
|
|
36
|
+
return Timing{ms, 1.0};
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
} // namespace
|
|
40
|
+
} // namespace ernie::bench
|
|
@@ -173,9 +173,8 @@ NanoVdbGrid ParseGrid(std::span<const std::uint8_t> bytes) {
|
|
|
173
173
|
return grid;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
// The grids of a raw buffer: each GridData header gives its grid's
|
|
177
|
-
|
|
178
|
-
std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes) {
|
|
176
|
+
// The grids of a raw buffer, or only their headers: each GridData header gives its grid's size.
|
|
177
|
+
std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes, bool headsOnly = false) {
|
|
179
178
|
std::vector<NanoVdbGrid> grids;
|
|
180
179
|
std::size_t offset = 0;
|
|
181
180
|
while (offset + PNANOVDB_GRID_SIZE <= bytes.size()) {
|
|
@@ -189,7 +188,11 @@ std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes) {
|
|
|
189
188
|
if (size < PNANOVDB_GRID_SIZE || offset + size > bytes.size()) {
|
|
190
189
|
throw std::runtime_error("NanoVDB grid size runs past its data");
|
|
191
190
|
}
|
|
192
|
-
|
|
191
|
+
const std::span<const std::uint8_t> grid =
|
|
192
|
+
bytes.subspan(offset, static_cast<std::size_t>(size));
|
|
193
|
+
grids.push_back(headsOnly ? NanoVdbGridHead(grid.first(std::min(
|
|
194
|
+
static_cast<std::size_t>(size), kNanoVdbHeadBytes)))
|
|
195
|
+
: ParseGrid(grid));
|
|
193
196
|
offset += size;
|
|
194
197
|
}
|
|
195
198
|
if (grids.empty()) {
|
|
@@ -234,6 +237,10 @@ std::vector<NanoVdbGrid> ParseNanoVdbGrids(std::span<const std::uint8_t> bytes)
|
|
|
234
237
|
return RawGrids(bytes);
|
|
235
238
|
}
|
|
236
239
|
|
|
240
|
+
std::vector<NanoVdbGrid> ParseNanoVdbHeads(std::span<const std::uint8_t> bytes) {
|
|
241
|
+
return RawGrids(bytes, true);
|
|
242
|
+
}
|
|
243
|
+
|
|
237
244
|
NanoVdbGrid NanoVdbGridHead(std::span<const std::uint8_t> head) {
|
|
238
245
|
const auto magic = ReadLittleEndian<std::uint64_t>(head, 0);
|
|
239
246
|
if (magic != kMagicNumber && magic != kMagicGrid) {
|
|
@@ -247,8 +254,9 @@ NanoVdbGrid NanoVdbGridHead(std::span<const std::uint8_t> head) {
|
|
|
247
254
|
return grid;
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
std::vector<NanoVdbGrid>
|
|
251
|
-
// Grids are copied out of the mapping into buffers aligned for PNanoVDB
|
|
257
|
+
static std::vector<NanoVdbGrid> ReadGrids(const std::filesystem::path& path, bool headsOnly) {
|
|
258
|
+
// Grids are copied out of the mapping into buffers aligned for PNanoVDB; heads touch only the
|
|
259
|
+
// pages holding them.
|
|
252
260
|
const MappedFile file(path);
|
|
253
261
|
const std::span<const std::uint8_t> data(
|
|
254
262
|
reinterpret_cast<const std::uint8_t*>(file.Bytes().data()), file.Bytes().size());
|
|
@@ -256,7 +264,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
|
|
|
256
264
|
try {
|
|
257
265
|
const auto magic = ReadLittleEndian<std::uint64_t>(data, 0);
|
|
258
266
|
if (magic == kMagicGrid) {
|
|
259
|
-
return RawGrids(data);
|
|
267
|
+
return RawGrids(data, headsOnly);
|
|
260
268
|
}
|
|
261
269
|
if (magic != kMagicNumber && magic != kMagicFile) {
|
|
262
270
|
throw std::runtime_error("not a NanoVDB file");
|
|
@@ -267,7 +275,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
|
|
|
267
275
|
if (MajorVersion(ReadLittleEndian<std::uint32_t>(data, 8)) != kMajorVersion &&
|
|
268
276
|
MajorVersion(ReadLittleEndian<std::uint32_t>(data, PNANOVDB_GRID_OFF_VERSION)) ==
|
|
269
277
|
kMajorVersion) {
|
|
270
|
-
return RawGrids(data);
|
|
278
|
+
return RawGrids(data, headsOnly);
|
|
271
279
|
}
|
|
272
280
|
std::vector<NanoVdbGrid> grids;
|
|
273
281
|
std::size_t offset = 0;
|
|
@@ -296,7 +304,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
|
|
|
296
304
|
if (offset + size > data.size()) {
|
|
297
305
|
throw std::runtime_error("grid runs past the file's end");
|
|
298
306
|
}
|
|
299
|
-
std::vector<NanoVdbGrid> one = RawGrids(data.subspan(offset, size));
|
|
307
|
+
std::vector<NanoVdbGrid> one = RawGrids(data.subspan(offset, size), headsOnly);
|
|
300
308
|
grids.insert(grids.end(), std::make_move_iterator(one.begin()),
|
|
301
309
|
std::make_move_iterator(one.end()));
|
|
302
310
|
offset += size;
|
|
@@ -315,6 +323,14 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
|
|
|
315
323
|
}
|
|
316
324
|
}
|
|
317
325
|
|
|
326
|
+
std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
|
|
327
|
+
return ReadGrids(path, false);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
std::vector<NanoVdbGrid> ReadNanoVdbHeads(const std::filesystem::path& path) {
|
|
331
|
+
return ReadGrids(path, true);
|
|
332
|
+
}
|
|
333
|
+
|
|
318
334
|
const NanoVdbGrid* FindNanoVdbGrid(std::span<const NanoVdbGrid> grids, std::string_view name,
|
|
319
335
|
int index) {
|
|
320
336
|
// An index into the caller's grids, which cppcheck follows where
|
|
@@ -95,12 +95,20 @@ struct NanoVdbGrid {
|
|
|
95
95
|
/// `nanovdb_convert` without `-z`/`-b`).
|
|
96
96
|
std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path);
|
|
97
97
|
|
|
98
|
+
/// @brief Reads the headers of a NanoVDB file's grids (names, types, bounds and transforms)
|
|
99
|
+
/// without their voxels, as `NanoVdbGridHead` does for each grid.
|
|
100
|
+
/// @throws std::runtime_error As `ReadNanoVdb`.
|
|
101
|
+
std::vector<NanoVdbGrid> ReadNanoVdbHeads(const std::filesystem::path& path);
|
|
102
|
+
|
|
98
103
|
/// @brief Splits a raw in-memory NanoVDB buffer into its grids.
|
|
99
104
|
/// @param bytes Grids back to back, as Warp's `Volume.array()`.
|
|
100
105
|
/// @return The grids.
|
|
101
106
|
/// @throws std::runtime_error If it does not start with a version 32
|
|
102
107
|
/// NanoVDB grid.
|
|
103
108
|
std::vector<NanoVdbGrid> ParseNanoVdbGrids(std::span<const std::uint8_t> bytes);
|
|
109
|
+
/// @brief Reads the headers of a raw buffer's grids, without copying their voxels.
|
|
110
|
+
/// @throws std::runtime_error As `ParseNanoVdbGrids`.
|
|
111
|
+
std::vector<NanoVdbGrid> ParseNanoVdbHeads(std::span<const std::uint8_t> bytes);
|
|
104
112
|
|
|
105
113
|
/// Bytes at a grid's start holding its header, tree and root, root
|
|
106
114
|
/// statistics included.
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
add_library(
|
|
3
3
|
ernie_scene
|
|
4
4
|
OBJECT
|
|
5
|
+
extent_cache.cpp
|
|
5
6
|
path.cpp
|
|
6
7
|
schema.cpp
|
|
7
8
|
scene.cpp
|
|
8
9
|
storage.cpp
|
|
9
10
|
view.cpp
|
|
10
11
|
xform.cpp
|
|
12
|
+
schemas/camera.cpp
|
|
11
13
|
schemas/collection.cpp
|
|
12
14
|
schemas/geom.cpp
|
|
15
|
+
schemas/instancer.cpp
|
|
16
|
+
schemas/lux.cpp
|
|
17
|
+
schemas/mesh.cpp
|
|
13
18
|
schemas/registry.cpp
|
|
14
19
|
schemas/shade.cpp
|
|
20
|
+
schemas/vol.cpp
|
|
15
21
|
)
|
|
16
22
|
target_link_libraries(ernie_scene PUBLIC ernie_physics ernie_io PRIVATE ernie_build_options)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file extent_cache.cpp
|
|
3
|
+
/// @brief Replaying row changes into the extent boxes and recomputing stale runs.
|
|
4
|
+
#include "ernie/scene/extent_cache.h"
|
|
5
|
+
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
|
|
8
|
+
namespace ernie {
|
|
9
|
+
|
|
10
|
+
void ExtentCache::Track(BucketId bucket, ExtentFunction compute) {
|
|
11
|
+
buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
|
|
12
|
+
buckets_[bucket].compute = compute;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void ExtentCache::Update(const PrimStore& store) {
|
|
16
|
+
const ChangeSet changes = store.ChangesSince(cursor_);
|
|
17
|
+
const auto tracked = [&](BucketId bucket) {
|
|
18
|
+
return bucket < buckets_.size() && buckets_[bucket].compute != nullptr;
|
|
19
|
+
};
|
|
20
|
+
for (const BucketId bucket : changes.resets) {
|
|
21
|
+
if (tracked(bucket)) {
|
|
22
|
+
Resize(buckets_[bucket], 0);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for (const ChangeSet::Rows& rows : changes.rows) {
|
|
26
|
+
if (tracked(rows.bucket)) {
|
|
27
|
+
Replay(buckets_[rows.bucket], rows.change);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const ChangeSet::Values& values : changes.values) {
|
|
31
|
+
if (tracked(values.bucket)) {
|
|
32
|
+
for (const RowRange range : values.rows) {
|
|
33
|
+
buckets_[values.bucket].stale.SetRange(range.begin, range.end);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (BucketId bucket = 0; bucket < buckets_.size(); ++bucket) {
|
|
38
|
+
if (tracked(bucket) && store.GetBucket(bucket).version > cursor_) {
|
|
39
|
+
Refresh(buckets_[bucket], store, bucket);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
cursor_ = changes.version;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
std::optional<Box> ExtentCache::Find(const PrimStore& store, BucketId bucket,
|
|
46
|
+
std::uint32_t row) const {
|
|
47
|
+
if (bucket >= buckets_.size() || buckets_[bucket].compute == nullptr ||
|
|
48
|
+
store.GetBucket(bucket).version > cursor_ || row >= buckets_[bucket].boxes.size()) {
|
|
49
|
+
return std::nullopt;
|
|
50
|
+
}
|
|
51
|
+
return buckets_[bucket].boxes[row];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void ExtentCache::Replay(Entry& entry, const StructuralChange& change) {
|
|
55
|
+
using Kind = StructuralChange::Kind;
|
|
56
|
+
if (change.kind == Kind::Added) {
|
|
57
|
+
Resize(entry, change.row + change.count);
|
|
58
|
+
entry.stale.SetRange(change.row, change.row + change.count);
|
|
59
|
+
} else if (change.kind == Kind::Moved) {
|
|
60
|
+
// Recomputed, not copied: the moved row's own value edits are reported at its old place.
|
|
61
|
+
entry.stale.Set(change.row);
|
|
62
|
+
Resize(entry, change.from);
|
|
63
|
+
} else if (change.row + 1 == entry.boxes.size()) {
|
|
64
|
+
// Removing the last row moves nothing; otherwise the Moved that follows shrinks it.
|
|
65
|
+
Resize(entry, change.row);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void ExtentCache::Resize(Entry& entry, std::uint32_t rows) {
|
|
70
|
+
entry.boxes.resize(rows);
|
|
71
|
+
entry.stale.Resize(rows);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void ExtentCache::Refresh(Entry& entry, const PrimStore& store, BucketId bucket) {
|
|
75
|
+
const std::uint32_t rows = store.GetBucket(bucket).Rows();
|
|
76
|
+
if (entry.boxes.size() != rows) {
|
|
77
|
+
// Too far behind to replay (a reset): recompute the bucket whole.
|
|
78
|
+
Resize(entry, rows);
|
|
79
|
+
entry.stale.SetRange(0, rows);
|
|
80
|
+
}
|
|
81
|
+
const ExtentRows columns{store, bucket};
|
|
82
|
+
entry.stale.ForEachRun([&](std::size_t begin, std::size_t end) {
|
|
83
|
+
entry.compute(columns, {static_cast<std::uint32_t>(begin), static_cast<std::uint32_t>(end)},
|
|
84
|
+
std::span(entry.boxes).subspan(begin, end - begin));
|
|
85
|
+
});
|
|
86
|
+
entry.stale.Clear();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
} // namespace ernie
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file extent_cache.h
|
|
3
|
+
/// @brief Prims' extents kept per bucket and refreshed for the rows that changed.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "ernie/geometry/bounds.h"
|
|
7
|
+
#include "ernie/scene/schema.h"
|
|
8
|
+
#include "ernie/scene/storage.h"
|
|
9
|
+
#include "ernie/util/bytes.h"
|
|
10
|
+
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <optional>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
namespace ernie {
|
|
16
|
+
|
|
17
|
+
/// @brief The extents of every bucket with an extent function, a box per row. `Update` replays
|
|
18
|
+
/// the buckets' row changes and recomputes only the rows whose values or places changed.
|
|
19
|
+
class ExtentCache {
|
|
20
|
+
public:
|
|
21
|
+
/// Tracks a bucket, computing its extents with `compute`; null for a bucket without them.
|
|
22
|
+
void Track(BucketId bucket, ExtentFunction compute);
|
|
23
|
+
/// Brings every tracked bucket up to the store's version.
|
|
24
|
+
void Update(const PrimStore& store);
|
|
25
|
+
/// @return A row's extent, or none when its bucket changed since `Update` or has none.
|
|
26
|
+
std::optional<Box> Find(const PrimStore& store, BucketId bucket, std::uint32_t row) const;
|
|
27
|
+
|
|
28
|
+
private:
|
|
29
|
+
struct Entry {
|
|
30
|
+
ExtentFunction compute = nullptr;
|
|
31
|
+
std::vector<Box> boxes;
|
|
32
|
+
BitSet stale;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
static void Replay(Entry& entry, const StructuralChange& change);
|
|
36
|
+
static void Resize(Entry& entry, std::uint32_t rows);
|
|
37
|
+
static void Refresh(Entry& entry, const PrimStore& store, BucketId bucket);
|
|
38
|
+
|
|
39
|
+
std::vector<Entry> buckets_;
|
|
40
|
+
std::uint64_t cursor_ = 0;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
} // namespace ernie
|
|
@@ -136,7 +136,7 @@ std::vector<Path> Scene::Prims(std::string_view type) const {
|
|
|
136
136
|
|
|
137
137
|
void Scene::Set(PrimId prim, std::string_view attribute, const Value& value) {
|
|
138
138
|
const AttributeId token = store_.Tokens().Intern(attribute);
|
|
139
|
-
const AttributeDef* def = Declared(prim, token);
|
|
139
|
+
const AttributeDef* def = Declared(store_.PrimBucket(prim), token);
|
|
140
140
|
if (def != nullptr) {
|
|
141
141
|
Validate(*def, attribute, value, PrimPath(prim));
|
|
142
142
|
}
|
|
@@ -155,6 +155,27 @@ void Scene::Set(const Path& path, std::string_view attribute, const Value& value
|
|
|
155
155
|
Set(Require(path), attribute, value);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
void Scene::Write(PrimId prim, std::string_view attribute, Tensor array) {
|
|
159
|
+
const AttributeId token = store_.Tokens().Intern(attribute);
|
|
160
|
+
const AttributeDef* def = Declared(store_.PrimBucket(prim), token);
|
|
161
|
+
if (def == nullptr && !TakesUndeclared(prim, attribute)) {
|
|
162
|
+
throw std::invalid_argument(Describe(*this, prim) + " has no attribute '" +
|
|
163
|
+
std::string(attribute) + "'");
|
|
164
|
+
}
|
|
165
|
+
if (def != nullptr) {
|
|
166
|
+
ValidateArray(*def, attribute, array, PrimPath(prim));
|
|
167
|
+
}
|
|
168
|
+
store_.Set(prim, token, std::move(array));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
|
|
172
|
+
const Column* column = AuthoredColumn(prim, attribute);
|
|
173
|
+
if (column == nullptr || column->values->Type() != ColumnType::Tensor) {
|
|
174
|
+
return nullptr;
|
|
175
|
+
}
|
|
176
|
+
return &store_.Read<Tensor>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
|
|
177
|
+
}
|
|
178
|
+
|
|
158
179
|
std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
|
|
159
180
|
const Column* column = AuthoredColumn(prim, attribute);
|
|
160
181
|
if (column == nullptr) {
|
|
@@ -216,9 +237,13 @@ std::optional<Box> Scene::Extent(PrimId prim) const {
|
|
|
216
237
|
if (rule.kind != ExtentRule::Kind::Computed) {
|
|
217
238
|
return std::nullopt;
|
|
218
239
|
}
|
|
240
|
+
const BucketId bucket = store_.PrimBucket(prim);
|
|
219
241
|
const std::uint32_t row = store_.PrimRow(prim);
|
|
242
|
+
if (const std::optional<Box> cached = extents_.Find(store_, bucket, row)) {
|
|
243
|
+
return cached;
|
|
244
|
+
}
|
|
220
245
|
Box extent;
|
|
221
|
-
rule.compute({store_,
|
|
246
|
+
rule.compute({store_, bucket, this}, {row, row + 1}, std::span(&extent, 1));
|
|
222
247
|
return extent;
|
|
223
248
|
}
|
|
224
249
|
|
|
@@ -229,23 +254,31 @@ Box Scene::WorldBounds(const Path& path) const {
|
|
|
229
254
|
const glm::dmat4 above =
|
|
230
255
|
parent == kRootPath ? glm::dmat4(1.0) : WorldTransform(*store_.Find(parent));
|
|
231
256
|
Box bounds;
|
|
232
|
-
AddTo(bounds, id, above);
|
|
257
|
+
AddTo(bounds, id, above, true);
|
|
258
|
+
return bounds;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
Box Scene::BoundsInParent(PrimId prim) const {
|
|
262
|
+
Box bounds;
|
|
263
|
+
AddTo(bounds, store_.PrimPath(prim), glm::dmat4(1.0), false);
|
|
233
264
|
return bounds;
|
|
234
265
|
}
|
|
235
266
|
|
|
236
|
-
void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent) const {
|
|
267
|
+
void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const {
|
|
237
268
|
const PrimId prim = *store_.Find(path);
|
|
238
|
-
if (LeavesOutOfBounds(prim)) {
|
|
269
|
+
if (visibleOnly && LeavesOutOfBounds(prim)) {
|
|
239
270
|
return;
|
|
240
271
|
}
|
|
241
272
|
const glm::dmat4 local = LocalTransform(prim);
|
|
242
273
|
const glm::dmat4 world = ResetsXformStack(*this, prim) ? local : parent * local;
|
|
274
|
+
// A prim with an extent bounds what it is made of, so its children aren't added again.
|
|
243
275
|
if (const std::optional<Box> extent = Extent(prim)) {
|
|
244
276
|
bounds.Extend(extent->Transformed(world));
|
|
277
|
+
return;
|
|
245
278
|
}
|
|
246
279
|
store_.Paths().ForEachChild(path, [&](PathId child) {
|
|
247
280
|
if (store_.Find(child)) {
|
|
248
|
-
AddTo(bounds, child, world);
|
|
281
|
+
AddTo(bounds, child, world, visibleOnly);
|
|
249
282
|
}
|
|
250
283
|
});
|
|
251
284
|
}
|
|
@@ -283,6 +316,9 @@ BucketId Scene::FindOrAddBucket(const SchemaDef* schema, std::vector<Token> apis
|
|
|
283
316
|
const BucketId bucket = store_.AddBucket(key, layout);
|
|
284
317
|
buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
|
|
285
318
|
buckets_[bucket] = std::move(entry);
|
|
319
|
+
const ExtentRule rule = schema != nullptr ? schema->Extent() : kNoExtent;
|
|
320
|
+
const bool cached = rule.kind == ExtentRule::Kind::Computed && !rule.readsOtherPrims;
|
|
321
|
+
extents_.Track(bucket, cached ? rule.compute : nullptr);
|
|
286
322
|
return bucket;
|
|
287
323
|
}
|
|
288
324
|
|
|
@@ -338,12 +374,22 @@ const Column* Scene::AuthoredColumn(PrimId prim, std::string_view attribute) con
|
|
|
338
374
|
return column != nullptr && column->authored.Test(store_.PrimRow(prim)) ? column : nullptr;
|
|
339
375
|
}
|
|
340
376
|
|
|
341
|
-
const AttributeDef* Scene::Declared(
|
|
342
|
-
const auto& declared = buckets_[
|
|
377
|
+
const AttributeDef* Scene::Declared(BucketId bucket, AttributeId attribute) const {
|
|
378
|
+
const auto& declared = buckets_[bucket].declared;
|
|
343
379
|
const auto found = declared.find(attribute);
|
|
344
380
|
return found != declared.end() ? found->second : nullptr;
|
|
345
381
|
}
|
|
346
382
|
|
|
383
|
+
Dirty Scene::Classify(const ChangeSet::Values& change) const {
|
|
384
|
+
if (const AttributeDef* def = Declared(change.bucket, change.attribute)) {
|
|
385
|
+
return def->meta.dirty;
|
|
386
|
+
}
|
|
387
|
+
const std::string_view name = store_.Tokens().Text(change.attribute);
|
|
388
|
+
return name.starts_with(tokens::kXformOpPrefix) ? Dirty::Transform
|
|
389
|
+
: name.starts_with(tokens::kPrimvarsPrefix) ? Dirty::Primvars
|
|
390
|
+
: Dirty::Params;
|
|
391
|
+
}
|
|
392
|
+
|
|
347
393
|
bool Scene::TakesUndeclared(PrimId prim, std::string_view attribute) const {
|
|
348
394
|
const SchemaDef* schema = Schema(prim);
|
|
349
395
|
return schema == nullptr || schema->IsOpen(attribute) ||
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
6
|
#include "ernie/geometry/bounds.h"
|
|
7
|
+
#include "ernie/scene/extent_cache.h"
|
|
7
8
|
#include "ernie/scene/schema.h"
|
|
8
9
|
#include "ernie/scene/storage.h"
|
|
9
10
|
#include "ernie/scene/value.h"
|
|
@@ -67,6 +68,12 @@ class Scene {
|
|
|
67
68
|
/// @return The authored value, or none.
|
|
68
69
|
std::optional<Value> Get(PrimId prim, std::string_view attribute) const;
|
|
69
70
|
std::optional<Value> Get(const Path& path, std::string_view attribute) const;
|
|
71
|
+
/// @brief Authors an array attribute with a tensor on the host or a device, shared, not copied.
|
|
72
|
+
/// @throws std::invalid_argument for a non-array attribute, or a tensor of the wrong type or
|
|
73
|
+
/// shape.
|
|
74
|
+
void Write(PrimId prim, std::string_view attribute, Tensor array);
|
|
75
|
+
/// @return The authored array, or null.
|
|
76
|
+
const Tensor* Read(PrimId prim, std::string_view attribute) const;
|
|
70
77
|
/// @return Whether the attribute was authored.
|
|
71
78
|
bool Clear(PrimId prim, std::string_view attribute);
|
|
72
79
|
bool IsAuthored(PrimId prim, std::string_view attribute) const;
|
|
@@ -77,9 +84,18 @@ class Scene {
|
|
|
77
84
|
glm::dmat4 LocalTransform(PrimId prim) const;
|
|
78
85
|
glm::dmat4 WorldTransform(PrimId prim) const;
|
|
79
86
|
/// @return The prim's extent in its own space; none when it isn't computed from attributes.
|
|
87
|
+
/// Cached since `UpdateExtents` when its bucket hasn't changed, computed otherwise.
|
|
80
88
|
std::optional<Box> Extent(PrimId prim) const;
|
|
89
|
+
/// @brief Recomputes the cached extents of the rows that changed since the last update.
|
|
90
|
+
void UpdateExtents() {
|
|
91
|
+
extents_.Update(store_);
|
|
92
|
+
}
|
|
81
93
|
/// @return The world box of the prim and its visible descendants of the default purpose.
|
|
94
|
+
/// Prims with extents bound their own subtrees, as UsdGeomBBoxCache prunes at Boundables.
|
|
82
95
|
Box WorldBounds(const Path& path) const;
|
|
96
|
+
/// @return The box of a prim's subtree in its parent's space, whatever its visibility: what a
|
|
97
|
+
/// point instancer places at each instance.
|
|
98
|
+
Box BoundsInParent(PrimId prim) const;
|
|
83
99
|
|
|
84
100
|
PrimStore& Store() {
|
|
85
101
|
return store_;
|
|
@@ -90,6 +106,9 @@ class Scene {
|
|
|
90
106
|
std::uint64_t Version() const {
|
|
91
107
|
return store_.Version();
|
|
92
108
|
}
|
|
109
|
+
/// @return What a column change means to renderers: the attribute's declared category, or for
|
|
110
|
+
/// undeclared ones Transform for xformOps, Primvars for primvars and Params for the rest.
|
|
111
|
+
Dirty Classify(const ChangeSet::Values& change) const;
|
|
93
112
|
|
|
94
113
|
private:
|
|
95
114
|
struct BucketSchema {
|
|
@@ -104,20 +123,22 @@ class Scene {
|
|
|
104
123
|
const std::vector<Token>& Apis(PrimId prim) const;
|
|
105
124
|
/// @return The attribute's column when the prim authors it, or null.
|
|
106
125
|
const Column* AuthoredColumn(PrimId prim, std::string_view attribute) const;
|
|
107
|
-
const AttributeDef* Declared(
|
|
126
|
+
const AttributeDef* Declared(BucketId bucket, AttributeId attribute) const;
|
|
108
127
|
/// @return Whether the prim's type or an applied API schema leaves the attribute's namespace
|
|
109
128
|
/// open; any attribute for a prim without a type.
|
|
110
129
|
bool TakesUndeclared(PrimId prim, std::string_view attribute) const;
|
|
111
130
|
ColumnType TypeForUndeclared(PrimId prim, std::string_view attribute, const Value& value) const;
|
|
112
131
|
/// @return Whether the prim and its subtree are invisible or of a purpose bounds leave out.
|
|
113
132
|
bool LeavesOutOfBounds(PrimId prim) const;
|
|
114
|
-
/// Adds
|
|
115
|
-
|
|
133
|
+
/// Adds a subtree's extents under `parent`'s transform; with `visibleOnly`, only its visible
|
|
134
|
+
/// default-purpose prims'.
|
|
135
|
+
void AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const;
|
|
116
136
|
|
|
117
137
|
PrimStore store_;
|
|
118
138
|
Token invisible_ = 0;
|
|
119
139
|
Token defaultPurpose_ = 0;
|
|
120
140
|
std::vector<BucketSchema> buckets_;
|
|
141
|
+
ExtentCache extents_;
|
|
121
142
|
};
|
|
122
143
|
|
|
123
144
|
} // namespace ernie
|
|
@@ -68,6 +68,44 @@ std::string Problem(const AttributeDef& def, const Value& value) {
|
|
|
68
68
|
return {};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/// @return Why `array` doesn't fit the tensor attribute, or empty when it does.
|
|
72
|
+
std::string ArrayProblem(const AttributeDef& def, const Tensor& array) {
|
|
73
|
+
if (def.type != ColumnType::Tensor) {
|
|
74
|
+
return "takes one value, not an array; set it";
|
|
75
|
+
}
|
|
76
|
+
if (def.meta.bytes) {
|
|
77
|
+
return {};
|
|
78
|
+
}
|
|
79
|
+
const DType type = array.Type();
|
|
80
|
+
const bool integer = type == DType::Int32 || type == DType::Int64 || type == DType::UInt32;
|
|
81
|
+
const bool floating = type == DType::Float32 || type == DType::Float64;
|
|
82
|
+
if (def.meta.integer ? !integer : !floating) {
|
|
83
|
+
return def.meta.integer ? "must hold integers" : "must hold float32 or float64 numbers";
|
|
84
|
+
}
|
|
85
|
+
if (def.meta.rank != 0) {
|
|
86
|
+
return array.Rank() == def.meta.rank
|
|
87
|
+
? std::string()
|
|
88
|
+
: "must have " + std::to_string(def.meta.rank) + " dimensions";
|
|
89
|
+
}
|
|
90
|
+
const std::int64_t components = def.meta.components;
|
|
91
|
+
const bool rows =
|
|
92
|
+
array.Rank() == 2 && array.Shape()[1] == std::max<std::int64_t>(components, 1);
|
|
93
|
+
const bool flat =
|
|
94
|
+
array.Rank() == 1 && array.Elements() % std::max<std::int64_t>(components, 1) == 0;
|
|
95
|
+
if (!rows && !flat) {
|
|
96
|
+
return components > 1 ? "must be (n, " + std::to_string(components) + ") or flat"
|
|
97
|
+
: "must be flat";
|
|
98
|
+
}
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void ThrowIf(const std::string& problem, std::string_view attribute, const Path& path) {
|
|
103
|
+
if (!problem.empty()) {
|
|
104
|
+
throw std::invalid_argument("'" + path.String() + "': '" + std::string(attribute) + "' " +
|
|
105
|
+
problem);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
71
109
|
} // namespace
|
|
72
110
|
|
|
73
111
|
bool SchemaDef::IsA(const SchemaDef& other) const {
|
|
@@ -145,10 +183,12 @@ std::string ApiName::ToString() const {
|
|
|
145
183
|
|
|
146
184
|
void Validate(const AttributeDef& def, std::string_view attribute, const Value& value,
|
|
147
185
|
const Path& path) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
186
|
+
ThrowIf(Problem(def, value), attribute, path);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void ValidateArray(const AttributeDef& def, std::string_view attribute, const Tensor& array,
|
|
190
|
+
const Path& path) {
|
|
191
|
+
ThrowIf(ArrayProblem(def, array), attribute, path);
|
|
152
192
|
}
|
|
153
193
|
|
|
154
194
|
} // namespace ernie
|
|
@@ -30,6 +30,20 @@ enum class Dirty : std::uint32_t {
|
|
|
30
30
|
Visibility = 1u << 8,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
constexpr Dirty operator|(Dirty a, Dirty b) {
|
|
34
|
+
return static_cast<Dirty>(static_cast<std::uint32_t>(a) | static_cast<std::uint32_t>(b));
|
|
35
|
+
}
|
|
36
|
+
constexpr Dirty operator&(Dirty a, Dirty b) {
|
|
37
|
+
return static_cast<Dirty>(static_cast<std::uint32_t>(a) & static_cast<std::uint32_t>(b));
|
|
38
|
+
}
|
|
39
|
+
constexpr Dirty& operator|=(Dirty& a, Dirty b) {
|
|
40
|
+
return a = a | b;
|
|
41
|
+
}
|
|
42
|
+
/// @return Whether `bits` has any of `flags`.
|
|
43
|
+
constexpr bool Any(Dirty bits, Dirty flags) {
|
|
44
|
+
return (bits & flags) != Dirty::None;
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
/// @brief A limit of an attribute's numbers, inclusive or not.
|
|
34
48
|
struct Bound {
|
|
35
49
|
double value = 0.0;
|
|
@@ -64,6 +78,14 @@ struct AttributeMeta {
|
|
|
64
78
|
std::vector<std::string_view> options{};
|
|
65
79
|
bool color = false;
|
|
66
80
|
bool asset = false;
|
|
81
|
+
/// A tensor of integers rather than floats.
|
|
82
|
+
bool integer = false;
|
|
83
|
+
/// A tensor of raw bytes, in elements of any type.
|
|
84
|
+
bool bytes = false;
|
|
85
|
+
/// A tensor's vector size: (n, components) or flat; 0 for a flat array.
|
|
86
|
+
std::uint8_t components = 0;
|
|
87
|
+
/// A tensor's fixed rank, as a dense grid's 3; 0 for flat or vector arrays.
|
|
88
|
+
std::uint8_t rank = 0;
|
|
67
89
|
Dirty dirty = Dirty::Params;
|
|
68
90
|
/// Resolved from the nearest authoring ancestor.
|
|
69
91
|
bool inherited = false;
|
|
@@ -88,10 +110,14 @@ enum class SchemaKind : std::uint8_t {
|
|
|
88
110
|
MultipleApply,
|
|
89
111
|
};
|
|
90
112
|
|
|
91
|
-
|
|
113
|
+
class Scene;
|
|
114
|
+
|
|
115
|
+
/// @brief A bucket's prims as an extent function reads them: columns by attribute name, and the
|
|
116
|
+
/// scene for rules that read other prims.
|
|
92
117
|
struct ExtentRows {
|
|
93
118
|
const PrimStore& store;
|
|
94
119
|
BucketId bucket = 0;
|
|
120
|
+
const Scene* scene = nullptr;
|
|
95
121
|
|
|
96
122
|
/// @return The column of a declared attribute.
|
|
97
123
|
template <typename T> std::span<const T> Column(std::string_view attribute) const {
|
|
@@ -123,7 +149,13 @@ struct ExtentRule {
|
|
|
123
149
|
};
|
|
124
150
|
Kind kind = Kind::Inherit;
|
|
125
151
|
ExtentFunction compute = nullptr;
|
|
152
|
+
/// Reads other prims (a volume its fields), so it is computed afresh rather than cached.
|
|
153
|
+
bool readsOtherPrims = false;
|
|
126
154
|
};
|
|
155
|
+
/// An extent from other prims' (a volume's from its fields).
|
|
156
|
+
constexpr ExtentRule ComputedFromOtherPrims(ExtentFunction compute) {
|
|
157
|
+
return {ExtentRule::Kind::Computed, compute, true};
|
|
158
|
+
}
|
|
127
159
|
constexpr ExtentRule ComputedExtent(ExtentFunction compute) {
|
|
128
160
|
return {ExtentRule::Kind::Computed, compute};
|
|
129
161
|
}
|
|
@@ -190,6 +222,10 @@ struct ApiName {
|
|
|
190
222
|
/// @throws std::invalid_argument naming the prim, the attribute and the reason.
|
|
191
223
|
void Validate(const AttributeDef& def, std::string_view attribute, const Value& value,
|
|
192
224
|
const Path& path);
|
|
225
|
+
/// @brief Checks an array for a declared tensor attribute: its element type and vector size.
|
|
226
|
+
/// @throws std::invalid_argument naming the prim, the attribute and the reason.
|
|
227
|
+
void ValidateArray(const AttributeDef& def, std::string_view attribute, const Tensor& array,
|
|
228
|
+
const Path& path);
|
|
193
229
|
|
|
194
230
|
/// @brief The tokens of an enum a token attribute takes, in enumerator order.
|
|
195
231
|
template <typename E> struct ChoiceTokens;
|