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.

Files changed (259) hide show
  1. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/CMakeLists.txt +1 -1
  2. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/PKG-INFO +1 -1
  3. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/CMakeLists.txt +1 -1
  4. ernie_renderer-0.2.0.dev30/benchmarks/scene/extents.cpp +40 -0
  5. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.cpp +25 -9
  6. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.h +8 -0
  7. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/CMakeLists.txt +6 -0
  8. ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.cpp +89 -0
  9. ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.h +43 -0
  10. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.cpp +54 -8
  11. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.h +24 -3
  12. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.cpp +44 -4
  13. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.h +37 -1
  14. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.cpp +11 -0
  15. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.h +63 -0
  16. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.cpp +1 -1
  17. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.h +9 -0
  18. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.cpp +93 -0
  19. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.h +63 -0
  20. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.cpp +72 -0
  21. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.h +186 -0
  22. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.cpp +67 -0
  23. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.h +87 -0
  24. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/registry.cpp +57 -0
  25. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.cpp +126 -0
  26. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.h +95 -0
  27. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.cpp +11 -2
  28. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.h +3 -0
  29. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/tokens.h +9 -0
  30. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.h +22 -1
  31. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/bytes.h +26 -0
  32. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/CMakeLists.txt +5 -0
  33. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/common.h +21 -1
  34. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/nanovdb_test.cpp +9 -0
  35. ernie_renderer-0.2.0.dev30/tests/scene/extent_cache_test.cpp +81 -0
  36. ernie_renderer-0.2.0.dev30/tests/scene/instancer_test.cpp +69 -0
  37. ernie_renderer-0.2.0.dev30/tests/scene/lux_test.cpp +75 -0
  38. ernie_renderer-0.2.0.dev30/tests/scene/mesh_test.cpp +75 -0
  39. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/scene_test.cpp +19 -0
  40. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/schema_test.cpp +3 -4
  41. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/storage_test.cpp +20 -0
  42. ernie_renderer-0.2.0.dev30/tests/scene/vol_test.cpp +83 -0
  43. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/bytes_test.cpp +17 -0
  44. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/worker_pool_test.cpp +10 -1
  45. ernie_renderer-0.2.0.dev22/ernie/scene/schemas/registry.cpp +0 -23
  46. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.clang-format +0 -0
  47. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.clang-tidy +0 -0
  48. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.dockerignore +0 -0
  49. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gersemirc +0 -0
  50. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gitattributes +0 -0
  51. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/scripts/coverage_badge.py +0 -0
  52. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/scripts/install-lavapipe-windows.sh +0 -0
  53. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.github/workflows/ci.yml +0 -0
  54. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.gitignore +0 -0
  55. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/.pre-commit-config.yaml +0 -0
  56. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/CMakePresets.json +0 -0
  57. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/Dockerfile +0 -0
  58. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/LICENSE +0 -0
  59. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/README.md +0 -0
  60. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/bench.h +0 -0
  61. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/main.cpp +0 -0
  62. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/benchmarks/scene/storage.cpp +0 -0
  63. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieConfig.cmake.in +0 -0
  64. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieFetch.cmake +0 -0
  65. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieInstall.cmake +0 -0
  66. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErniePackaging.cmake +0 -0
  67. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ErnieTesting.cmake +0 -0
  68. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/ernie.pc.in +0 -0
  69. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/bc7enc.cmake +0 -0
  70. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/dlpack.cmake +0 -0
  71. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/glm.cmake +0 -0
  72. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/googletest.cmake +0 -0
  73. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/json.cmake +0 -0
  74. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/nanobind.cmake +0 -0
  75. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/openexr.cmake +0 -0
  76. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/stb.cmake +0 -0
  77. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/tracy.cmake +0 -0
  78. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/volk.cmake +0 -0
  79. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/cmake/third_party/vulkan_headers.cmake +0 -0
  80. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/README.md +0 -0
  81. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/index.md +0 -0
  82. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/docs/requirements.txt +0 -0
  83. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/CMakeLists.txt +0 -0
  84. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/app/CMakeLists.txt +0 -0
  85. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/app/main.cpp +0 -0
  86. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/CMakeLists.txt +0 -0
  87. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.cpp +0 -0
  88. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.h +0 -0
  89. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/geometry/CMakeLists.txt +0 -0
  90. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/geometry/bounds.h +0 -0
  91. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/graph/CMakeLists.txt +0 -0
  92. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/CMakeLists.txt +0 -0
  93. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.cpp +0 -0
  94. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.h +0 -0
  95. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/image.cpp +0 -0
  96. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/image.h +0 -0
  97. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.cpp +0 -0
  98. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.h +0 -0
  99. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.cpp +0 -0
  100. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.h +0 -0
  101. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/CMakeLists.txt +0 -0
  102. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.cpp +0 -0
  103. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.h +0 -0
  104. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.cpp +0 -0
  105. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.h +0 -0
  106. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.cpp +0 -0
  107. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.h +0 -0
  108. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/constants.h +0 -0
  109. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.cpp +0 -0
  110. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.h +0 -0
  111. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_table.h +0 -0
  112. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.cpp +0 -0
  113. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.h +0 -0
  114. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.cpp +0 -0
  115. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.h +0 -0
  116. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.cpp +0 -0
  117. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.h +0 -0
  118. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar_table.h +0 -0
  119. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.cpp +0 -0
  120. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.h +0 -0
  121. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/CMakeLists.txt +0 -0
  122. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/ernie/__init__.py +0 -0
  123. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/python/module.cpp +0 -0
  124. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/render/CMakeLists.txt +0 -0
  125. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/convert.h +0 -0
  126. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.cpp +0 -0
  127. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.h +0 -0
  128. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/collection.cpp +0 -0
  129. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/collection.h +0 -0
  130. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/shade.cpp +0 -0
  131. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/shade.h +0 -0
  132. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/value.h +0 -0
  133. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.cpp +0 -0
  134. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.cpp +0 -0
  135. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.h +0 -0
  136. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/CMakeLists.txt +0 -0
  137. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/algorithm.h +0 -0
  138. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.cpp +0 -0
  139. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.h +0 -0
  140. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/file.cpp +0 -0
  141. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/file.h +0 -0
  142. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/glm.h +0 -0
  143. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/hash_index.h +0 -0
  144. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/linear_algebra.h +0 -0
  145. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/log.cpp +0 -0
  146. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/log.h +0 -0
  147. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/math.h +0 -0
  148. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.cpp +0 -0
  149. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.h +0 -0
  150. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/numbers.h +0 -0
  151. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/parallel.h +0 -0
  152. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.cpp +0 -0
  153. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.h +0 -0
  154. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/random.h +0 -0
  155. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.cpp +0 -0
  156. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.h +0 -0
  157. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/text.h +0 -0
  158. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/version.cpp +0 -0
  159. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/version.h +0 -0
  160. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/ernie/util/worker_pool.h +0 -0
  161. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/mkdocs.yml +0 -0
  162. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/pyproject.toml +0 -0
  163. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/consumer/CMakeLists.txt +0 -0
  164. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/consumer/main.cpp +0 -0
  165. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/device/vulkan_devices_test.cpp +0 -0
  166. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/README.md +0 -0
  167. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/make_exr.py +0 -0
  168. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
  169. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgba_half_window.exr +0 -0
  170. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/y_half_zips.exr +0 -0
  171. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/README.md +0 -0
  172. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
  173. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
  174. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/lamp.tilt +0 -0
  175. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/images/grey16.png +0 -0
  176. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/README.md +0 -0
  177. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
  178. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
  179. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
  180. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
  181. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/README.md +0 -0
  182. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
  183. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_raw.tif +0 -0
  184. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
  185. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
  186. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
  187. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
  188. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
  189. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/cube.nvdb +0 -0
  190. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/make_nvdb.py +0 -0
  191. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/geometry/bounds_test.cpp +0 -0
  192. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/ies_test.cpp +0 -0
  193. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/image_test.cpp +0 -0
  194. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/raster_test.cpp +0 -0
  195. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/io/texture_test.cpp +0 -0
  196. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/astronomy_test.cpp +0 -0
  197. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/atmosphere_test.cpp +0 -0
  198. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/cloud_test.cpp +0 -0
  199. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/reflectance_library_test.cpp +0 -0
  200. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/regolith_test.cpp +0 -0
  201. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/scattering_test.cpp +0 -0
  202. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/solar_test.cpp +0 -0
  203. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/physics/spectrum_test.cpp +0 -0
  204. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/python/test_package.py +0 -0
  205. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/api_test.cpp +0 -0
  206. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/path_test.cpp +0 -0
  207. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/scene/xform_test.cpp +0 -0
  208. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/algorithm_test.cpp +0 -0
  209. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/disk_cache_test.cpp +0 -0
  210. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/file_test.cpp +0 -0
  211. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/hash_index_test.cpp +0 -0
  212. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/linear_algebra_test.cpp +0 -0
  213. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/log_test.cpp +0 -0
  214. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/math_test.cpp +0 -0
  215. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/noise_test.cpp +0 -0
  216. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/parallel_test.cpp +0 -0
  217. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/profiler_test.cpp +0 -0
  218. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/random_test.cpp +0 -0
  219. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/tensor_test.cpp +0 -0
  220. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/text_test.cpp +0 -0
  221. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/tests/util/version_test.cpp +0 -0
  222. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/CMakeLists.txt +0 -0
  223. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSE +0 -0
  224. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
  225. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
  226. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/MIT.txt +0 -0
  227. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/NOTICE +0 -0
  228. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/README.md +0 -0
  229. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu.h +0 -0
  230. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
  231. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
  232. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
  233. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers.h +0 -0
  234. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
  235. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
  236. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
  237. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
  238. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_idct.h +0 -0
  239. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
  240. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
  241. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
  242. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
  243. {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
  244. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
  245. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
  246. {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
  247. {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
  248. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
  249. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
  250. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
  251. {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
  252. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
  253. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
  254. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
  255. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/LICENSE +0 -0
  256. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd.h +0 -0
  257. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd_errors.h +0 -0
  258. {ernie_renderer-0.2.0.dev22 → ernie_renderer-0.2.0.dev30}/third_party/nanovdb/LICENSE +0 -0
  259. {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 ".dev22" CACHE STRING "Pre-release suffix of Ernie's version")
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.dev22
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
@@ -1,3 +1,3 @@
1
1
  # SPDX-License-Identifier: BSD-3-Clause
2
- add_executable(ernie_benchmarks main.cpp scene/storage.cpp)
2
+ add_executable(ernie_benchmarks main.cpp scene/extents.cpp scene/storage.cpp)
3
3
  target_link_libraries(ernie_benchmarks PRIVATE ernie_static ernie_build_options)
@@ -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
- // size.
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
- grids.push_back(ParseGrid(bytes.subspan(offset, size)));
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> ReadNanoVdb(const std::filesystem::path& path) {
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_, store_.PrimBucket(prim)}, {row, row + 1}, std::span(&extent, 1));
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(PrimId prim, AttributeId attribute) const {
342
- const auto& declared = buckets_[store_.PrimBucket(prim)].declared;
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(PrimId prim, AttributeId attribute) const;
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 the visible default-purpose extents of a subtree under `parent`'s world transform.
115
- void AddTo(Box& bounds, PathId path, const glm::dmat4& parent) const;
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
- if (const std::string problem = Problem(def, value); !problem.empty()) {
149
- throw std::invalid_argument("'" + path.String() + "': '" + std::string(attribute) + "' " +
150
- problem);
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
- /// @brief A bucket's prims as an extent function reads them: columns by attribute name.
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;