ernie-renderer 0.2.0.dev16__tar.gz → 0.2.0.dev19__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.dev16 → ernie_renderer-0.2.0.dev19}/.github/workflows/ci.yml +1 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/CMakeLists.txt +5 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/CMakePresets.json +1 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/PKG-INFO +1 -1
- ernie_renderer-0.2.0.dev19/benchmarks/CMakeLists.txt +3 -0
- ernie_renderer-0.2.0.dev19/benchmarks/bench.h +52 -0
- ernie_renderer-0.2.0.dev19/benchmarks/main.cpp +22 -0
- ernie_renderer-0.2.0.dev19/benchmarks/scene_storage.cpp +118 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ErnieTesting.cmake +1 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/CMakeLists.txt +0 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/cloud.cpp +1 -2
- ernie_renderer-0.2.0.dev19/ernie/scene/CMakeLists.txt +3 -0
- ernie_renderer-0.2.0.dev19/ernie/scene/path.cpp +193 -0
- ernie_renderer-0.2.0.dev19/ernie/scene/path.h +152 -0
- ernie_renderer-0.2.0.dev19/ernie/scene/storage.cpp +235 -0
- ernie_renderer-0.2.0.dev19/ernie/scene/storage.h +408 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/bytes.h +51 -1
- ernie_renderer-0.2.0.dev19/ernie/util/hash_index.h +103 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/random.h +18 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/text.h +15 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/CMakeLists.txt +6 -0
- ernie_renderer-0.2.0.dev19/tests/common.h +33 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/consumer/CMakeLists.txt +0 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/io/ies_test.cpp +6 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/io/image_test.cpp +4 -3
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/io/nanovdb_test.cpp +10 -11
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/io/raster_test.cpp +50 -55
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/io/texture_test.cpp +10 -10
- ernie_renderer-0.2.0.dev19/tests/scene/path_test.cpp +93 -0
- ernie_renderer-0.2.0.dev19/tests/scene/storage_test.cpp +157 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/bytes_test.cpp +16 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/disk_cache_test.cpp +3 -2
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/file_test.cpp +8 -13
- ernie_renderer-0.2.0.dev19/tests/util/hash_index_test.cpp +50 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/text_test.cpp +9 -0
- ernie_renderer-0.2.0.dev16/ernie/scene/CMakeLists.txt +0 -3
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/device/vulkan_devices.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/nanovdb.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/nanovdb.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/tests/util/worker_pool_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev19}/third_party/nanovdb/PNanoVDB.h +0 -0
|
@@ -96,7 +96,7 @@ jobs:
|
|
|
96
96
|
- name: Build
|
|
97
97
|
run: cmake --build --preset ci --parallel 4
|
|
98
98
|
# The installed library used as end users use it: its headers compile alone and a program
|
|
99
|
-
# links and runs against it
|
|
99
|
+
# links and runs against it. Windows finds ernie.dll on the PATH.
|
|
100
100
|
- name: Install and build a consumer
|
|
101
101
|
shell: bash
|
|
102
102
|
run: |
|
|
@@ -15,10 +15,11 @@ 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 ".dev19" 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)
|
|
22
|
+
option(ERNIE_BUILD_BENCHMARKS "Build Ernie's benchmarks" OFF)
|
|
22
23
|
option(ERNIE_BUILD_PYTHON "Build Ernie's Python module" OFF)
|
|
23
24
|
option(ERNIE_BUILD_APP "Build the ernie program" ON)
|
|
24
25
|
option(ERNIE_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
|
|
@@ -110,6 +111,9 @@ if(ERNIE_BUILD_TESTS)
|
|
|
110
111
|
enable_testing()
|
|
111
112
|
add_subdirectory(tests)
|
|
112
113
|
endif()
|
|
114
|
+
if(ERNIE_BUILD_BENCHMARKS)
|
|
115
|
+
add_subdirectory(benchmarks)
|
|
116
|
+
endif()
|
|
113
117
|
|
|
114
118
|
if(PROJECT_IS_TOP_LEVEL AND NOT SKBUILD)
|
|
115
119
|
include(cmake/ErniePackaging.cmake)
|
|
@@ -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.dev19
|
|
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,52 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file bench.h
|
|
3
|
+
/// @brief Registering and timing benchmarks, which report against a target and never fail on time.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include <chrono>
|
|
8
|
+
#include <functional>
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace ernie::bench {
|
|
13
|
+
|
|
14
|
+
/// What a benchmark measured: its fastest run and the time it aims for, in milliseconds.
|
|
15
|
+
struct Timing {
|
|
16
|
+
double ms = 0.0;
|
|
17
|
+
double targetMs = 0.0;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
struct Benchmark {
|
|
21
|
+
std::string name;
|
|
22
|
+
std::function<Timing()> run;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/// @return Every benchmark registered at static initialization.
|
|
26
|
+
inline std::vector<Benchmark>& Registry() {
|
|
27
|
+
static std::vector<Benchmark> benchmarks;
|
|
28
|
+
return benchmarks;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Registers a benchmark from a namespace-scope `const bool`.
|
|
32
|
+
inline bool Register(std::string name, std::function<Timing()> run) {
|
|
33
|
+
Registry().push_back({std::move(name), std::move(run)});
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// @brief Times `step` `runs` times, after `setup` before each, to see past a noisy machine.
|
|
38
|
+
/// @return The fastest run, in milliseconds.
|
|
39
|
+
template <typename Setup, typename Step>
|
|
40
|
+
double Fastest(const Setup& setup, const Step& step, int runs = 5) {
|
|
41
|
+
double best = 1e30;
|
|
42
|
+
for (int run = 0; run < runs; ++run) {
|
|
43
|
+
setup();
|
|
44
|
+
const auto start = std::chrono::steady_clock::now();
|
|
45
|
+
step();
|
|
46
|
+
const auto elapsed = std::chrono::steady_clock::now() - start;
|
|
47
|
+
best = std::min(best, std::chrono::duration<double, std::milli>(elapsed).count());
|
|
48
|
+
}
|
|
49
|
+
return best;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
} // namespace ernie::bench
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file main.cpp
|
|
3
|
+
/// @brief Runs the registered benchmarks whose names contain the first argument, and prints each
|
|
4
|
+
/// fastest time beside its target.
|
|
5
|
+
#include "benchmarks/bench.h"
|
|
6
|
+
|
|
7
|
+
#include <cstdio>
|
|
8
|
+
#include <string_view>
|
|
9
|
+
|
|
10
|
+
int main(int argc, char** argv) {
|
|
11
|
+
const std::string_view filter = argc > 1 ? argv[1] : "";
|
|
12
|
+
std::printf("%-48s %12s %12s\n", "benchmark", "ms", "target ms");
|
|
13
|
+
for (const ernie::bench::Benchmark& benchmark : ernie::bench::Registry()) {
|
|
14
|
+
if (benchmark.name.find(filter) == std::string::npos) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const ernie::bench::Timing timing = benchmark.run();
|
|
18
|
+
std::printf("%-48s %12.3f %12.3f%s\n", benchmark.name.c_str(), timing.ms, timing.targetMs,
|
|
19
|
+
timing.ms > timing.targetMs ? " over" : "");
|
|
20
|
+
}
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file scene_storage.cpp
|
|
3
|
+
/// @brief The prim store at 100,000 prims: create, first sync, one edit, edit all, add and remove.
|
|
4
|
+
#include "benchmarks/bench.h"
|
|
5
|
+
#include "ernie/scene/storage.h"
|
|
6
|
+
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <vector>
|
|
10
|
+
|
|
11
|
+
namespace ernie::bench {
|
|
12
|
+
namespace {
|
|
13
|
+
|
|
14
|
+
constexpr std::uint32_t kPrims = 100'000;
|
|
15
|
+
|
|
16
|
+
/// 100,000 instanced robots, one per environment, with transforms.
|
|
17
|
+
struct Robots {
|
|
18
|
+
std::unique_ptr<PrimStore> store;
|
|
19
|
+
AttributeId transform = 0;
|
|
20
|
+
BucketId bucket = 0;
|
|
21
|
+
std::vector<PrimId> prims;
|
|
22
|
+
|
|
23
|
+
void Reset() {
|
|
24
|
+
store = std::make_unique<PrimStore>();
|
|
25
|
+
transform = store->Tokens().Intern("xformOp:transform");
|
|
26
|
+
bucket = store->AddBucket(
|
|
27
|
+
{store->Tokens().Intern("Xform"), {}},
|
|
28
|
+
std::vector<ColumnLayout>{ColumnLayout::Of<glm::dmat4>(transform, glm::dmat4(1.0))});
|
|
29
|
+
prims.clear();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void Create() {
|
|
33
|
+
PathTable& paths = store->Paths();
|
|
34
|
+
const PathId world = paths.Child(kRootPath, "World");
|
|
35
|
+
const Token robot = store->Tokens().Intern("robot");
|
|
36
|
+
std::vector<PathId> robots(kPrims);
|
|
37
|
+
paths.Reserve(2 * kPrims);
|
|
38
|
+
for (std::uint32_t i = 0; i < kPrims; ++i) {
|
|
39
|
+
robots[i] = paths.Child(paths.Child(world, "env_" + std::to_string(i)), robot);
|
|
40
|
+
}
|
|
41
|
+
prims = store->DefineMany(robots, bucket);
|
|
42
|
+
const std::span<glm::dmat4> transforms = store->Write<glm::dmat4>(bucket, transform);
|
|
43
|
+
for (std::uint32_t i = 0; i < kPrims; ++i) {
|
|
44
|
+
transforms[i] = glm::dmat4(1.0);
|
|
45
|
+
transforms[i][3] = glm::dvec4(i, 0.0, 0.0, 1.0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
void Fresh() {
|
|
50
|
+
Reset();
|
|
51
|
+
Create();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const bool kCreate = Register("scene.storage.create_100k", [] {
|
|
56
|
+
Robots robots;
|
|
57
|
+
return Timing{Fastest([&] { robots.Reset(); }, [&] { robots.Create(); }), 50.0};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const bool kFirstSync = Register("scene.storage.first_sync_100k", [] {
|
|
61
|
+
Robots robots;
|
|
62
|
+
return Timing{Fastest([&] { robots.Fresh(); }, [&] { robots.store->ChangesSince(0); }), 50.0};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const bool kOneEdit = Register("scene.storage.one_edit_of_100k", [] {
|
|
66
|
+
Robots robots;
|
|
67
|
+
robots.Fresh();
|
|
68
|
+
std::uint64_t cursor = 0;
|
|
69
|
+
const double ms =
|
|
70
|
+
Fastest([&] { cursor = robots.store->Version(); },
|
|
71
|
+
[&] {
|
|
72
|
+
robots.store->Set(robots.prims[54'321], robots.transform, glm::dmat4(2.0));
|
|
73
|
+
robots.store->ChangesSince(cursor);
|
|
74
|
+
});
|
|
75
|
+
return Timing{ms, 1.0};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const bool kEditAll = Register("scene.storage.edit_all_100k", [] {
|
|
79
|
+
Robots robots;
|
|
80
|
+
robots.Fresh();
|
|
81
|
+
std::uint64_t cursor = 0;
|
|
82
|
+
const double ms = Fastest([&] { cursor = robots.store->Version(); },
|
|
83
|
+
[&] {
|
|
84
|
+
for (glm::dmat4& transform : robots.store->Write<glm::dmat4>(
|
|
85
|
+
robots.bucket, robots.transform)) {
|
|
86
|
+
transform[3].y += 1.0;
|
|
87
|
+
}
|
|
88
|
+
robots.store->ChangesSince(cursor);
|
|
89
|
+
});
|
|
90
|
+
return Timing{ms, 10.0};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const bool kAddRemove = Register("scene.storage.add_remove_1000_of_100k", [] {
|
|
94
|
+
Robots robots;
|
|
95
|
+
std::uint64_t cursor = 0;
|
|
96
|
+
const double ms = Fastest(
|
|
97
|
+
[&] {
|
|
98
|
+
robots.Fresh();
|
|
99
|
+
cursor = robots.store->Version();
|
|
100
|
+
},
|
|
101
|
+
[&] {
|
|
102
|
+
for (std::uint32_t i = 0; i < 1000; ++i) {
|
|
103
|
+
robots.store->Remove(robots.prims[i * 97]);
|
|
104
|
+
}
|
|
105
|
+
PathTable& paths = robots.store->Paths();
|
|
106
|
+
const PathId spawned = paths.Child(kRootPath, "Spawned");
|
|
107
|
+
std::vector<PathId> added(1000);
|
|
108
|
+
for (std::uint32_t i = 0; i < 1000; ++i) {
|
|
109
|
+
added[i] = paths.Child(spawned, "p" + std::to_string(i));
|
|
110
|
+
}
|
|
111
|
+
robots.store->DefineMany(added, robots.bucket);
|
|
112
|
+
robots.store->ChangesSince(cursor);
|
|
113
|
+
});
|
|
114
|
+
return Timing{ms, 5.0};
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
} // namespace
|
|
118
|
+
} // namespace ernie::bench
|
|
@@ -4,7 +4,7 @@ include_guard(GLOBAL)
|
|
|
4
4
|
include("${CMAKE_CURRENT_LIST_DIR}/third_party/googletest.cmake")
|
|
5
5
|
include(GoogleTest)
|
|
6
6
|
|
|
7
|
-
# Hard timeouts per label
|
|
7
|
+
# Hard timeouts per label, to catch hangs; timings are tracked by benchmarks/.
|
|
8
8
|
set(ERNIE_TEST_TIMEOUT_unit 10)
|
|
9
9
|
set(ERNIE_TEST_TIMEOUT_gpu 60)
|
|
10
10
|
set(ERNIE_TEST_TIMEOUT_accuracy 120)
|
|
@@ -54,12 +54,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
|
54
54
|
target_link_options(ernie PRIVATE "LINKER:--exclude-libs,ALL")
|
|
55
55
|
endif()
|
|
56
56
|
|
|
57
|
-
# The same objects as one static library, for in-tree programs and tests, which may also reach
|
|
58
|
-
# internal APIs, and for the Python module, which carries everything itself.
|
|
59
57
|
add_library(ernie_static STATIC)
|
|
60
58
|
target_link_libraries(ernie_static PUBLIC ${ernie_layers})
|
|
61
|
-
# Its objects export the API (ERNIE_API), so on Windows every program linking it would also write
|
|
62
|
-
# an import library; the ernie program's would collide with libernie's own ernie.lib and ernie.exp.
|
|
63
59
|
target_link_options(ernie_static INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/NOIMPLIB;/NOEXP>")
|
|
64
60
|
|
|
65
61
|
if(ERNIE_BUILD_APP)
|
|
@@ -491,8 +491,7 @@ CloudTransportTable SimulateCloudTransport(const DropletPhaseTable& phase,
|
|
|
491
491
|
ParallelFor(shape.lightCosines * shape.thicknesses, [&](std::size_t job) {
|
|
492
492
|
const std::size_t light = job % shape.lightCosines;
|
|
493
493
|
const std::size_t thickness = shape.thicknesses - 1 - job / shape.lightCosines;
|
|
494
|
-
const std::uint64_t seed =
|
|
495
|
-
options.seed * 0x100000001b3ull + static_cast<std::uint64_t>(job) * 0x9e3779b9ull;
|
|
494
|
+
const std::uint64_t seed = HashCombine(options.seed, job);
|
|
496
495
|
const SlabTallies tallies =
|
|
497
496
|
SimulateSlab(shape, sampler, light, thickness, options.photons, seed);
|
|
498
497
|
StoreSlab(tallies, light, thickness, options.photons, table);
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file path.cpp
|
|
3
|
+
/// @brief Path parsing, token interning and the path table.
|
|
4
|
+
#include "ernie/scene/path.h"
|
|
5
|
+
|
|
6
|
+
#include "ernie/util/random.h"
|
|
7
|
+
#include "ernie/util/text.h"
|
|
8
|
+
|
|
9
|
+
#include <algorithm>
|
|
10
|
+
#include <stdexcept>
|
|
11
|
+
|
|
12
|
+
namespace ernie {
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
|
|
16
|
+
/// Calls `visit(name)` for each name of an absolute path's text; "/a/" ends in an empty name.
|
|
17
|
+
template <typename Visit> void ForEachName(std::string_view text, const Visit& visit) {
|
|
18
|
+
if (text.size() <= 1) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (std::size_t start = 1; start <= text.size();) {
|
|
22
|
+
const std::size_t end = std::min(text.find('/', start), text.size());
|
|
23
|
+
visit(text.substr(start, end - start));
|
|
24
|
+
start = end + 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
bool Path::IsValidName(std::string_view name) {
|
|
31
|
+
return IsIdentifier(name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Path::Path(std::string_view text) {
|
|
35
|
+
if (text.empty() || text.front() != '/') {
|
|
36
|
+
throw std::invalid_argument("Prim path '" + std::string(text) + "' is not absolute");
|
|
37
|
+
}
|
|
38
|
+
ForEachName(text, [&](std::string_view name) {
|
|
39
|
+
if (!IsValidName(name)) {
|
|
40
|
+
throw std::invalid_argument("Prim path '" + std::string(text) +
|
|
41
|
+
"' has an invalid name");
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
text_ = text;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Path Path::Root() {
|
|
48
|
+
return Path("/");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
std::string_view Path::Name() const {
|
|
52
|
+
if (text_.size() <= 1) {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
return std::string_view(text_).substr(text_.rfind('/') + 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Path Path::Parent() const {
|
|
59
|
+
if (text_.size() <= 1) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
const std::size_t slash = text_.rfind('/');
|
|
63
|
+
return slash == 0 ? Root() : Path(std::string_view(text_).substr(0, slash));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Path Path::Child(std::string_view name) const {
|
|
67
|
+
if (IsEmpty() || !IsValidName(name)) {
|
|
68
|
+
throw std::invalid_argument("Cannot append '" + std::string(name) + "' to '" + text_ + "'");
|
|
69
|
+
}
|
|
70
|
+
Path child;
|
|
71
|
+
child.text_ = IsRoot() ? "/" + std::string(name) : text_ + "/" + std::string(name);
|
|
72
|
+
return child;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool Path::HasPrefix(const Path& ancestor) const {
|
|
76
|
+
if (ancestor.IsEmpty() || IsEmpty()) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (ancestor.IsRoot()) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return text_.starts_with(ancestor.text_) &&
|
|
83
|
+
(text_.size() == ancestor.text_.size() || text_[ancestor.text_.size()] == '/');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
TokenTable::TokenTable() {
|
|
87
|
+
Intern("");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Token TokenTable::Intern(std::string_view text) {
|
|
91
|
+
const auto next = static_cast<Token>(texts_.size());
|
|
92
|
+
const Token token = index_.Insert(std::hash<std::string_view>()(text), next,
|
|
93
|
+
[&](Token other) { return texts_[other] == text; });
|
|
94
|
+
if (token == next) {
|
|
95
|
+
texts_.emplace_back(text);
|
|
96
|
+
}
|
|
97
|
+
return token;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
std::optional<Token> TokenTable::Find(std::string_view text) const {
|
|
101
|
+
return index_.Find(std::hash<std::string_view>()(text),
|
|
102
|
+
[&](Token other) { return texts_[other] == text; });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
PathTable::PathTable() : nodes_(1) {}
|
|
106
|
+
|
|
107
|
+
std::uint64_t PathTable::Hash(PathId parent, Token name) {
|
|
108
|
+
return Mix64(std::uint64_t{parent} << 32 | name);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void PathTable::Reserve(std::size_t count) {
|
|
112
|
+
nodes_.reserve(nodes_.size() + count);
|
|
113
|
+
children_.Reserve(children_.Size() + count);
|
|
114
|
+
names_.Reserve(count);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
PathId PathTable::Child(PathId parent, Token name) {
|
|
118
|
+
const auto next = static_cast<PathId>(nodes_.size());
|
|
119
|
+
const PathId id = children_.Insert(Hash(parent, name), next, [&](PathId other) {
|
|
120
|
+
return nodes_[other].parent == parent && nodes_[other].name == name;
|
|
121
|
+
});
|
|
122
|
+
if (id != next) {
|
|
123
|
+
return id;
|
|
124
|
+
}
|
|
125
|
+
nodes_.push_back({parent, name});
|
|
126
|
+
Node& above = nodes_[parent];
|
|
127
|
+
if (above.firstChild == kNoPath) {
|
|
128
|
+
above.firstChild = id;
|
|
129
|
+
} else {
|
|
130
|
+
nodes_[above.lastChild].nextSibling = id;
|
|
131
|
+
}
|
|
132
|
+
above.lastChild = id;
|
|
133
|
+
return id;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
PathId PathTable::Intern(const Path& path) {
|
|
137
|
+
if (path.IsEmpty()) {
|
|
138
|
+
throw std::invalid_argument("An empty path names no prim");
|
|
139
|
+
}
|
|
140
|
+
PathId id = kRootPath;
|
|
141
|
+
ForEachName(path.String(), [&](std::string_view name) { id = Child(id, name); });
|
|
142
|
+
return id;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
std::optional<PathId> PathTable::Find(const Path& path) const {
|
|
146
|
+
if (path.IsEmpty()) {
|
|
147
|
+
return std::nullopt;
|
|
148
|
+
}
|
|
149
|
+
PathId id = kRootPath;
|
|
150
|
+
bool found = true;
|
|
151
|
+
ForEachName(path.String(), [&](std::string_view name) {
|
|
152
|
+
const std::optional<Token> token = found ? names_.Find(name) : std::nullopt;
|
|
153
|
+
const std::optional<PathId> child =
|
|
154
|
+
token ? children_.Find(Hash(id, *token),
|
|
155
|
+
[&](PathId other) {
|
|
156
|
+
return nodes_[other].parent == id &&
|
|
157
|
+
nodes_[other].name == *token;
|
|
158
|
+
})
|
|
159
|
+
: std::nullopt;
|
|
160
|
+
found = child.has_value();
|
|
161
|
+
if (found) {
|
|
162
|
+
id = *child;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return found ? std::optional(id) : std::nullopt;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Path PathTable::ToPath(PathId id) const {
|
|
169
|
+
if (id == kRootPath) {
|
|
170
|
+
return Path::Root();
|
|
171
|
+
}
|
|
172
|
+
std::vector<std::string_view> names;
|
|
173
|
+
for (; id != kRootPath; id = nodes_[id].parent) {
|
|
174
|
+
names.push_back(names_.Text(nodes_[id].name));
|
|
175
|
+
}
|
|
176
|
+
std::string text;
|
|
177
|
+
for (auto name = names.rbegin(); name != names.rend(); ++name) {
|
|
178
|
+
text += '/';
|
|
179
|
+
text += *name;
|
|
180
|
+
}
|
|
181
|
+
return Path(text);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
bool PathTable::HasPrefix(PathId id, PathId ancestor) const {
|
|
185
|
+
for (; id != kNoPath; id = nodes_[id].parent) {
|
|
186
|
+
if (id == ancestor) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
} // namespace ernie
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file path.h
|
|
3
|
+
/// @brief Prim paths, interned names, and the scene's table of paths as (parent, name) nodes.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "ernie/util/hash_index.h"
|
|
7
|
+
|
|
8
|
+
#include <compare>
|
|
9
|
+
#include <cstdint>
|
|
10
|
+
#include <deque>
|
|
11
|
+
#include <functional>
|
|
12
|
+
#include <limits>
|
|
13
|
+
#include <optional>
|
|
14
|
+
#include <string>
|
|
15
|
+
#include <string_view>
|
|
16
|
+
#include <vector>
|
|
17
|
+
|
|
18
|
+
namespace ernie {
|
|
19
|
+
|
|
20
|
+
/// @brief An absolute prim path such as `/World/Rover/Wheel_FL`, as text.
|
|
21
|
+
class Path {
|
|
22
|
+
public:
|
|
23
|
+
Path() = default;
|
|
24
|
+
/// @param text An absolute path of valid names.
|
|
25
|
+
/// @throws std::invalid_argument If it is not.
|
|
26
|
+
Path(std::string_view text);
|
|
27
|
+
Path(const char* text) : Path(std::string_view(text)) {}
|
|
28
|
+
Path(const std::string& text) : Path(std::string_view(text)) {}
|
|
29
|
+
|
|
30
|
+
static Path Root();
|
|
31
|
+
/// @return Whether `name` is a valid prim name: a letter or underscore, then letters, digits
|
|
32
|
+
/// and underscores.
|
|
33
|
+
static bool IsValidName(std::string_view name);
|
|
34
|
+
|
|
35
|
+
const std::string& String() const {
|
|
36
|
+
return text_;
|
|
37
|
+
}
|
|
38
|
+
bool IsEmpty() const {
|
|
39
|
+
return text_.empty();
|
|
40
|
+
}
|
|
41
|
+
bool IsRoot() const {
|
|
42
|
+
return text_ == "/";
|
|
43
|
+
}
|
|
44
|
+
/// @return The last name; empty for the root and the empty path.
|
|
45
|
+
std::string_view Name() const;
|
|
46
|
+
/// @return The parent; empty for the root and the empty path.
|
|
47
|
+
Path Parent() const;
|
|
48
|
+
/// @throws std::invalid_argument If this path is empty or `name` is invalid.
|
|
49
|
+
Path Child(std::string_view name) const;
|
|
50
|
+
/// @return Whether this path is `ancestor` or lies below it.
|
|
51
|
+
bool HasPrefix(const Path& ancestor) const;
|
|
52
|
+
|
|
53
|
+
auto operator<=>(const Path&) const = default;
|
|
54
|
+
|
|
55
|
+
private:
|
|
56
|
+
std::string text_;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/// An interned name; 0 is no name.
|
|
60
|
+
using Token = std::uint32_t;
|
|
61
|
+
|
|
62
|
+
/// @brief Interned strings: each distinct name is stored once and compared as a number.
|
|
63
|
+
class TokenTable {
|
|
64
|
+
public:
|
|
65
|
+
TokenTable();
|
|
66
|
+
/// @return The name's token, adding it if new.
|
|
67
|
+
Token Intern(std::string_view text);
|
|
68
|
+
/// @return The name's token, if interned.
|
|
69
|
+
std::optional<Token> Find(std::string_view text) const;
|
|
70
|
+
std::string_view Text(Token token) const {
|
|
71
|
+
return texts_[token];
|
|
72
|
+
}
|
|
73
|
+
void Reserve(std::size_t count) {
|
|
74
|
+
index_.Reserve(count);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private:
|
|
78
|
+
std::deque<std::string> texts_;
|
|
79
|
+
HashIndex index_;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/// An interned path, a node of a `PathTable`; 0 is the root.
|
|
83
|
+
using PathId = std::uint32_t;
|
|
84
|
+
inline constexpr PathId kRootPath = 0;
|
|
85
|
+
inline constexpr PathId kNoPath = std::numeric_limits<PathId>::max();
|
|
86
|
+
|
|
87
|
+
/// @brief Every path the scene has named, as (parent, name) nodes with their children in order.
|
|
88
|
+
/// Paths are never removed, so ids stay valid; prims come and go on them.
|
|
89
|
+
class PathTable {
|
|
90
|
+
public:
|
|
91
|
+
PathTable();
|
|
92
|
+
|
|
93
|
+
/// @return The path's id, adding it and its ancestors if new.
|
|
94
|
+
PathId Intern(const Path& path);
|
|
95
|
+
/// @return The child's id, adding it if new.
|
|
96
|
+
PathId Child(PathId parent, Token name);
|
|
97
|
+
PathId Child(PathId parent, std::string_view name) {
|
|
98
|
+
return Child(parent, names_.Intern(name));
|
|
99
|
+
}
|
|
100
|
+
/// @return The path's id, if interned.
|
|
101
|
+
std::optional<PathId> Find(const Path& path) const;
|
|
102
|
+
|
|
103
|
+
Path ToPath(PathId id) const;
|
|
104
|
+
PathId Parent(PathId id) const {
|
|
105
|
+
return nodes_[id].parent;
|
|
106
|
+
}
|
|
107
|
+
Token Name(PathId id) const {
|
|
108
|
+
return nodes_[id].name;
|
|
109
|
+
}
|
|
110
|
+
PathId FirstChild(PathId id) const {
|
|
111
|
+
return nodes_[id].firstChild;
|
|
112
|
+
}
|
|
113
|
+
PathId NextSibling(PathId id) const {
|
|
114
|
+
return nodes_[id].nextSibling;
|
|
115
|
+
}
|
|
116
|
+
/// @return Whether `id` is `ancestor` or lies below it.
|
|
117
|
+
bool HasPrefix(PathId id, PathId ancestor) const;
|
|
118
|
+
|
|
119
|
+
std::size_t Size() const {
|
|
120
|
+
return nodes_.size();
|
|
121
|
+
}
|
|
122
|
+
/// Makes room for `count` more paths and as many new names.
|
|
123
|
+
void Reserve(std::size_t count);
|
|
124
|
+
TokenTable& Names() {
|
|
125
|
+
return names_;
|
|
126
|
+
}
|
|
127
|
+
const TokenTable& Names() const {
|
|
128
|
+
return names_;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private:
|
|
132
|
+
struct Node {
|
|
133
|
+
PathId parent = kNoPath;
|
|
134
|
+
Token name = 0;
|
|
135
|
+
PathId firstChild = kNoPath;
|
|
136
|
+
PathId lastChild = kNoPath;
|
|
137
|
+
PathId nextSibling = kNoPath;
|
|
138
|
+
};
|
|
139
|
+
static std::uint64_t Hash(PathId parent, Token name);
|
|
140
|
+
|
|
141
|
+
TokenTable names_;
|
|
142
|
+
std::vector<Node> nodes_;
|
|
143
|
+
HashIndex children_;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
} // namespace ernie
|
|
147
|
+
|
|
148
|
+
template <> struct std::hash<ernie::Path> {
|
|
149
|
+
std::size_t operator()(const ernie::Path& path) const noexcept {
|
|
150
|
+
return std::hash<std::string>()(path.String());
|
|
151
|
+
}
|
|
152
|
+
};
|