ernie-renderer 0.2.0.dev37__tar.gz → 0.2.0.dev40__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 (267) hide show
  1. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/CMakeLists.txt +1 -1
  2. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/PKG-INFO +1 -1
  3. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/scene.cpp +30 -11
  4. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/scene.h +4 -0
  5. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/geom.cpp +2 -0
  6. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/geom.h +48 -1
  7. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/mesh.cpp +13 -6
  8. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/mesh.h +47 -5
  9. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/registry.cpp +6 -0
  10. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/mesh_test.cpp +21 -0
  11. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/schema_test.cpp +28 -0
  12. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.clang-format +0 -0
  13. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.clang-tidy +0 -0
  14. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.dockerignore +0 -0
  15. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.gersemirc +0 -0
  16. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.gitattributes +0 -0
  17. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.github/scripts/coverage_badge.py +0 -0
  18. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.github/scripts/install-lavapipe-windows.sh +0 -0
  19. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.github/workflows/ci.yml +0 -0
  20. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.gitignore +0 -0
  21. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/.pre-commit-config.yaml +0 -0
  22. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/CMakePresets.json +0 -0
  23. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/Dockerfile +0 -0
  24. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/LICENSE +0 -0
  25. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/README.md +0 -0
  26. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/benchmarks/CMakeLists.txt +0 -0
  27. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/benchmarks/bench.h +0 -0
  28. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/benchmarks/main.cpp +0 -0
  29. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/benchmarks/scene/extents.cpp +0 -0
  30. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/benchmarks/scene/storage.cpp +0 -0
  31. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ErnieConfig.cmake.in +0 -0
  32. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ErnieFetch.cmake +0 -0
  33. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ErnieInstall.cmake +0 -0
  34. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ErniePackaging.cmake +0 -0
  35. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ErnieTesting.cmake +0 -0
  36. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/ernie.pc.in +0 -0
  37. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/bc7enc.cmake +0 -0
  38. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/dlpack.cmake +0 -0
  39. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/glm.cmake +0 -0
  40. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/googletest.cmake +0 -0
  41. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/json.cmake +0 -0
  42. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/nanobind.cmake +0 -0
  43. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/openexr.cmake +0 -0
  44. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/stb.cmake +0 -0
  45. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/tracy.cmake +0 -0
  46. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/volk.cmake +0 -0
  47. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/cmake/third_party/vulkan_headers.cmake +0 -0
  48. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/docs/README.md +0 -0
  49. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/docs/index.md +0 -0
  50. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/docs/requirements.txt +0 -0
  51. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/CMakeLists.txt +0 -0
  52. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/app/CMakeLists.txt +0 -0
  53. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/app/main.cpp +0 -0
  54. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/device/CMakeLists.txt +0 -0
  55. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/device/vulkan_devices.cpp +0 -0
  56. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/device/vulkan_devices.h +0 -0
  57. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/geometry/CMakeLists.txt +0 -0
  58. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/geometry/bounds.h +0 -0
  59. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/graph/CMakeLists.txt +0 -0
  60. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/CMakeLists.txt +0 -0
  61. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/ies.cpp +0 -0
  62. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/ies.h +0 -0
  63. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/image.cpp +0 -0
  64. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/image.h +0 -0
  65. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/nanovdb.cpp +0 -0
  66. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/nanovdb.h +0 -0
  67. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/raster.cpp +0 -0
  68. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/raster.h +0 -0
  69. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/texture.cpp +0 -0
  70. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/io/texture.h +0 -0
  71. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/CMakeLists.txt +0 -0
  72. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/astronomy.cpp +0 -0
  73. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/astronomy.h +0 -0
  74. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/atmosphere.cpp +0 -0
  75. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/atmosphere.h +0 -0
  76. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/cloud.cpp +0 -0
  77. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/cloud.h +0 -0
  78. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/constants.h +0 -0
  79. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/reflectance_library.cpp +0 -0
  80. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/reflectance_library.h +0 -0
  81. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/reflectance_table.h +0 -0
  82. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/regolith.cpp +0 -0
  83. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/regolith.h +0 -0
  84. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/scattering.cpp +0 -0
  85. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/scattering.h +0 -0
  86. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/solar.cpp +0 -0
  87. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/solar.h +0 -0
  88. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/solar_table.h +0 -0
  89. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/spectrum.cpp +0 -0
  90. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/physics/spectrum.h +0 -0
  91. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/python/CMakeLists.txt +0 -0
  92. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/python/ernie/__init__.py +0 -0
  93. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/python/module.cpp +0 -0
  94. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/render/CMakeLists.txt +0 -0
  95. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/CMakeLists.txt +0 -0
  96. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/convert.h +0 -0
  97. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/extent_cache.cpp +0 -0
  98. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/extent_cache.h +0 -0
  99. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/path.cpp +0 -0
  100. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/path.h +0 -0
  101. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schema.cpp +0 -0
  102. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schema.h +0 -0
  103. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/camera.cpp +0 -0
  104. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/camera.h +0 -0
  105. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/collection.cpp +0 -0
  106. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/collection.h +0 -0
  107. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/instancer.cpp +0 -0
  108. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/instancer.h +0 -0
  109. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/laser.cpp +0 -0
  110. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/laser.h +0 -0
  111. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/lux.cpp +0 -0
  112. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/lux.h +0 -0
  113. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/planet.cpp +0 -0
  114. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/planet.h +0 -0
  115. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/render.cpp +0 -0
  116. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/render.h +0 -0
  117. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/shade.cpp +0 -0
  118. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/shade.h +0 -0
  119. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/vol.cpp +0 -0
  120. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/schemas/vol.h +0 -0
  121. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/storage.cpp +0 -0
  122. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/storage.h +0 -0
  123. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/tokens.h +0 -0
  124. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/value.h +0 -0
  125. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/view.cpp +0 -0
  126. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/view.h +0 -0
  127. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/xform.cpp +0 -0
  128. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/scene/xform.h +0 -0
  129. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/CMakeLists.txt +0 -0
  130. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/algorithm.h +0 -0
  131. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/bytes.h +0 -0
  132. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/disk_cache.cpp +0 -0
  133. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/disk_cache.h +0 -0
  134. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/file.cpp +0 -0
  135. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/file.h +0 -0
  136. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/glm.h +0 -0
  137. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/hash_index.h +0 -0
  138. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/linear_algebra.h +0 -0
  139. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/log.cpp +0 -0
  140. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/log.h +0 -0
  141. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/math.h +0 -0
  142. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/noise.cpp +0 -0
  143. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/noise.h +0 -0
  144. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/numbers.h +0 -0
  145. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/parallel.h +0 -0
  146. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/profiler.cpp +0 -0
  147. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/profiler.h +0 -0
  148. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/random.h +0 -0
  149. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/tensor.cpp +0 -0
  150. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/tensor.h +0 -0
  151. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/text.h +0 -0
  152. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/version.cpp +0 -0
  153. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/version.h +0 -0
  154. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/ernie/util/worker_pool.h +0 -0
  155. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/mkdocs.yml +0 -0
  156. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/pyproject.toml +0 -0
  157. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/CMakeLists.txt +0 -0
  158. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/common.h +0 -0
  159. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/consumer/CMakeLists.txt +0 -0
  160. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/consumer/main.cpp +0 -0
  161. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/device/vulkan_devices_test.cpp +0 -0
  162. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/exr/README.md +0 -0
  163. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/exr/make_exr.py +0 -0
  164. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
  165. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/exr/rgba_half_window.exr +0 -0
  166. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/exr/y_half_zips.exr +0 -0
  167. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ies/README.md +0 -0
  168. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
  169. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
  170. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ies/lamp.tilt +0 -0
  171. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/images/grey16.png +0 -0
  172. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ktx2/README.md +0 -0
  173. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
  174. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
  175. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
  176. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
  177. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/README.md +0 -0
  178. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
  179. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/float_raw.tif +0 -0
  180. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
  181. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
  182. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
  183. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
  184. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
  185. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/volumes/cube.nvdb +0 -0
  186. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/fixtures/volumes/make_nvdb.py +0 -0
  187. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/geometry/bounds_test.cpp +0 -0
  188. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/io/ies_test.cpp +0 -0
  189. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/io/image_test.cpp +0 -0
  190. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/io/nanovdb_test.cpp +0 -0
  191. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/io/raster_test.cpp +0 -0
  192. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/io/texture_test.cpp +0 -0
  193. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/astronomy_test.cpp +0 -0
  194. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/atmosphere_test.cpp +0 -0
  195. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/cloud_test.cpp +0 -0
  196. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/reflectance_library_test.cpp +0 -0
  197. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/regolith_test.cpp +0 -0
  198. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/scattering_test.cpp +0 -0
  199. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/solar_test.cpp +0 -0
  200. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/physics/spectrum_test.cpp +0 -0
  201. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/python/test_package.py +0 -0
  202. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/api_test.cpp +0 -0
  203. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/extent_cache_test.cpp +0 -0
  204. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/instancer_test.cpp +0 -0
  205. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/lux_test.cpp +0 -0
  206. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/path_test.cpp +0 -0
  207. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/planet_test.cpp +0 -0
  208. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/render_test.cpp +0 -0
  209. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/scene_test.cpp +0 -0
  210. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/shade_test.cpp +0 -0
  211. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/storage_test.cpp +0 -0
  212. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/vol_test.cpp +0 -0
  213. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/scene/xform_test.cpp +0 -0
  214. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/algorithm_test.cpp +0 -0
  215. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/bytes_test.cpp +0 -0
  216. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/disk_cache_test.cpp +0 -0
  217. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/file_test.cpp +0 -0
  218. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/hash_index_test.cpp +0 -0
  219. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/linear_algebra_test.cpp +0 -0
  220. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/log_test.cpp +0 -0
  221. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/math_test.cpp +0 -0
  222. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/noise_test.cpp +0 -0
  223. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/parallel_test.cpp +0 -0
  224. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/profiler_test.cpp +0 -0
  225. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/random_test.cpp +0 -0
  226. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/tensor_test.cpp +0 -0
  227. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/text_test.cpp +0 -0
  228. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/version_test.cpp +0 -0
  229. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/tests/util/worker_pool_test.cpp +0 -0
  230. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/CMakeLists.txt +0 -0
  231. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/LICENSE +0 -0
  232. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
  233. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
  234. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/LICENSES/MIT.txt +0 -0
  235. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/NOTICE +0 -0
  236. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/README.md +0 -0
  237. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu.h +0 -0
  238. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
  239. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
  240. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
  241. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_containers.h +0 -0
  242. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
  243. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
  244. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
  245. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
  246. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_idct.h +0 -0
  247. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
  248. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
  249. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
  250. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
  251. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
  252. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
  253. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
  254. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
  255. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
  256. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
  257. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
  258. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
  259. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
  260. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
  261. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
  262. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
  263. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/zstd/LICENSE +0 -0
  264. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/zstd/zstd.h +0 -0
  265. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/basisu/zstd/zstd_errors.h +0 -0
  266. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/third_party/nanovdb/LICENSE +0 -0
  267. {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev40}/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 ".dev37" CACHE STRING "Pre-release suffix of Ernie's version")
18
+ set(ERNIE_VERSION_SUFFIX ".dev40" 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.dev37
3
+ Version: 0.2.0.dev40
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
@@ -169,12 +169,16 @@ void Scene::Write(PrimId prim, std::string_view attribute, Tensor array) {
169
169
  store_.Set(prim, token, std::move(array));
170
170
  }
171
171
 
172
- const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
172
+ template <typename T> const T* Scene::Authored(PrimId prim, std::string_view attribute) const {
173
173
  const Column* column = AuthoredColumn(prim, attribute);
174
- if (column == nullptr || column->values->Type() != ColumnType::Tensor) {
174
+ if (column == nullptr || column->values->Type() != kColumnType<T>) {
175
175
  return nullptr;
176
176
  }
177
- return &store_.Read<Tensor>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
177
+ return &store_.Read<T>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
178
+ }
179
+
180
+ const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
181
+ return Authored<Tensor>(prim, attribute);
178
182
  }
179
183
 
180
184
  std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
@@ -277,11 +281,17 @@ void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visib
277
281
  bounds.Extend(extent->Transformed(world));
278
282
  return;
279
283
  }
284
+ bool loaded = false;
280
285
  store_.Paths().ForEachChild(path, [&](PathId child) {
281
286
  if (store_.Find(child)) {
287
+ loaded = true;
282
288
  AddTo(bounds, child, world, visibleOnly);
283
289
  }
284
290
  });
291
+ // A model whose subtree isn't loaded is bounded by its hint.
292
+ if (!loaded) {
293
+ bounds.Extend(ExtentsHint(prim, !visibleOnly).Transformed(world));
294
+ }
285
295
  }
286
296
 
287
297
  PrimId Scene::Require(const Path& path) const {
@@ -400,15 +410,24 @@ std::vector<std::string> Scene::AppliedApis(PrimId prim) const {
400
410
  }
401
411
 
402
412
  bool Scene::LeavesOutOfBounds(PrimId prim) const {
403
- const auto token = [&](std::string_view attribute) -> std::optional<Token> {
404
- const Column* column = AuthoredColumn(prim, attribute);
405
- return column ? std::optional(store_.Read<Token>(store_.PrimBucket(prim),
406
- column->attribute)[store_.PrimRow(prim)])
407
- : std::nullopt;
408
- };
413
+ const Token* visibility = Authored<Token>(prim, Imageable::kVisibility);
409
414
  // Purpose is inherited, so a subtree under another purpose is left out whole.
410
- const std::optional<Token> purpose = token(Imageable::kPurpose);
411
- return token(Imageable::kVisibility) == invisible_ || (purpose && *purpose != defaultPurpose_);
415
+ const Token* purpose = Authored<Token>(prim, Imageable::kPurpose);
416
+ return (visibility && *visibility == invisible_) || (purpose && *purpose != defaultPurpose_);
417
+ }
418
+
419
+ Box Scene::ExtentsHint(PrimId prim, bool allPurposes) const {
420
+ const auto* hint = Authored<std::vector<float>>(prim, GeomModelAPI::kExtentsHint);
421
+ if (hint == nullptr) {
422
+ return {};
423
+ }
424
+ // Six floats per purpose, the default purpose first.
425
+ const std::size_t floats = allPurposes ? hint->size() : std::min<std::size_t>(6, hint->size());
426
+ Box box;
427
+ for (std::size_t i = 0; i + 6 <= floats; i += 6) {
428
+ box.Extend(AuthoredExtent(std::span(*hint).subspan(i, 6)));
429
+ }
430
+ return box;
412
431
  }
413
432
 
414
433
  const Column* Scene::AuthoredColumn(PrimId prim, std::string_view attribute) const {
@@ -126,6 +126,8 @@ class Scene {
126
126
  std::vector<ApiName> AllApis(const SchemaDef* schema, std::span<const Token> applied) const;
127
127
  /// @return The attribute's column when the prim authors it, or null.
128
128
  const Column* AuthoredColumn(PrimId prim, std::string_view attribute) const;
129
+ /// @return The attribute's value when the prim authors it as a `T`, or null.
130
+ template <typename T> const T* Authored(PrimId prim, std::string_view attribute) const;
129
131
  const AttributeDef* Declared(BucketId bucket, AttributeId attribute) const;
130
132
  /// @return Whether the prim's type or an applied API schema leaves the attribute's namespace
131
133
  /// open; any attribute for a prim without a type.
@@ -133,6 +135,8 @@ class Scene {
133
135
  ColumnType TypeForUndeclared(PrimId prim, std::string_view attribute, const Value& value) const;
134
136
  /// @return Whether the prim and its subtree are invisible or of a purpose bounds leave out.
135
137
  bool LeavesOutOfBounds(PrimId prim) const;
138
+ /// @return GeomModelAPI's extentsHint: the default purpose's box, or with `allPurposes`, all.
139
+ Box ExtentsHint(PrimId prim, bool allPurposes) const;
136
140
  /// Adds a subtree's extents under `parent`'s transform; with `visibleOnly`, only its visible
137
141
  /// default-purpose prims'.
138
142
  void AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const;
@@ -60,6 +60,8 @@ ERNIE_DEFINE_SCHEMA(Xform, Concrete, kDescendantsExtent, ERNIE_NO_ATTRIBUTES,
60
60
  .openNamespaces = {"*"})
61
61
  ERNIE_DEFINE_SCHEMA(Scope, Concrete, kDescendantsExtent, ERNIE_NO_ATTRIBUTES,
62
62
  .openNamespaces = {"*"})
63
+ ERNIE_DEFINE_SCHEMA(GeomModelAPI, SingleApply, kInheritExtent, ERNIE_MODEL_API_ATTRIBUTES)
64
+ ERNIE_DEFINE_SCHEMA(GeomSubset, Concrete, kNoExtent, ERNIE_SUBSET_ATTRIBUTES)
63
65
  ERNIE_DEFINE_SCHEMA(Cube, Concrete, ComputedExtent(CentredExtent<CubeHalves>),
64
66
  ERNIE_CUBE_ATTRIBUTES)
65
67
  ERNIE_DEFINE_SCHEMA(Sphere, Concrete, ComputedExtent(CentredExtent<SphereHalves>),
@@ -10,6 +10,7 @@
10
10
  #include "ernie/scene/view.h"
11
11
 
12
12
  #include <array>
13
+ #include <span>
13
14
  #include <string>
14
15
  #include <string_view>
15
16
  #include <vector>
@@ -51,6 +52,47 @@
51
52
  "The winding of its front faces.", .group = "Geometry", \
52
53
  .options = {"rightHanded", "leftHanded"}, .dirty = Dirty::Topology)
53
54
 
55
+ #define ERNIE_CARD_TEXTURE(X, Name, usdName) \
56
+ X(std::string, Name, usdName, "", "The image on the card facing this way.", .group = "Model", \
57
+ .asset = true, .dirty = Dirty::Params)
58
+
59
+ #define ERNIE_MODEL_API_ATTRIBUTES(X) \
60
+ X(std::string, DrawMode, "model:drawMode", "inherited", \
61
+ "Draws the subtree as itself, or as a stand-in: its origin axes, its bounds or cards.", \
62
+ .group = "Model", .options = {"origin", "bounds", "cards", "default", "inherited"}, \
63
+ .dirty = Dirty::Visibility) \
64
+ X(bool, ApplyDrawMode, "model:applyDrawMode", false, \
65
+ "Whether this prim's draw mode replaces its subtree.", .group = "Model", \
66
+ .dirty = Dirty::Visibility) \
67
+ X(glm::dvec3, DrawModeColor, "model:drawModeColor", glm::dvec3(0.18), \
68
+ "Linear RGB of the stand-in.", .group = "Model", .lower = AtLeast(0.0), .color = true, \
69
+ .dirty = Dirty::Params) \
70
+ X(std::string, CardGeometry, "model:cardGeometry", "cross", \
71
+ "Cards through the centre, on the bounds' faces, or as the textures place them.", \
72
+ .group = "Model", .options = {"cross", "box", "fromTexture"}, .dirty = Dirty::Params) \
73
+ X(std::string, CardVisibility, "model:cardVisibility", "inherited", \
74
+ "Every textured card, or only one per axis.", .group = "Model", \
75
+ .options = {"full", "simple", "inherited"}, .dirty = Dirty::Params) \
76
+ ERNIE_CARD_TEXTURE(X, CardTextureXPos, "model:cardTextureXPos") \
77
+ ERNIE_CARD_TEXTURE(X, CardTextureYPos, "model:cardTextureYPos") \
78
+ ERNIE_CARD_TEXTURE(X, CardTextureZPos, "model:cardTextureZPos") \
79
+ ERNIE_CARD_TEXTURE(X, CardTextureXNeg, "model:cardTextureXNeg") \
80
+ ERNIE_CARD_TEXTURE(X, CardTextureYNeg, "model:cardTextureYNeg") \
81
+ ERNIE_CARD_TEXTURE(X, CardTextureZNeg, "model:cardTextureZNeg") \
82
+ X(std::vector<float>, ExtentsHint, "extentsHint", std::vector<float>{}, \
83
+ "The subtree's local bounds per purpose (default, render, proxy, guide), six floats each, " \
84
+ "read while it isn't loaded.", .group = "Model")
85
+
86
+ #define ERNIE_SUBSET_ATTRIBUTES(X) \
87
+ X(std::string, ElementType, "elementType", "face", "What its indices count.", \
88
+ .group = "Subset", .options = {"face", "point", "edge", "segment", "tetrahedron"}, \
89
+ .dirty = Dirty::Topology) \
90
+ X(Tensor, Indices, "indices", Tensor(), "The elements in the subset.", .group = "Subset", \
91
+ .integer = true, .dirty = Dirty::Topology) \
92
+ X(std::string, FamilyName, "familyName", "", \
93
+ "The family of subsets it is one of, as materialBind for per-face materials.", \
94
+ .group = "Subset", .dirty = Dirty::Topology)
95
+
54
96
  #define ERNIE_SHAPE_LENGTH .group = "Shape", .lower = AtLeast(0.0), .finite = true
55
97
 
56
98
  #define ERNIE_AXIS_ATTRIBUTE(X) \
@@ -86,7 +128,7 @@ namespace ernie {
86
128
 
87
129
  /// @return A Boundable's authored `extent` (min x, y, z, max x, y, z), which extent functions
88
130
  /// read while the data they bound isn't on the host; empty when unset.
89
- inline Box AuthoredExtent(const std::vector<float>& extent) {
131
+ inline Box AuthoredExtent(std::span<const float> extent) {
90
132
  if (extent.size() != 6) {
91
133
  return {};
92
134
  }
@@ -110,6 +152,11 @@ ERNIE_SCHEMA(Gprim, Boundable, ERNIE_GPRIM_ATTRIBUTES,
110
152
  ERNIE_CONCRETE_SCHEMA(Xform, Xformable, ERNIE_NO_ATTRIBUTES, "A transform grouping its children.");
111
153
  ERNIE_CONCRETE_SCHEMA(Scope, Imageable, ERNIE_NO_ATTRIBUTES,
112
154
  "A grouping without a transform of its own.");
155
+ ERNIE_API_SCHEMA(GeomModelAPI, ERNIE_MODEL_API_ATTRIBUTES,
156
+ "A model's stand-ins and the bounds hint used while its subtree isn't loaded.");
157
+ ERNIE_CONCRETE_SCHEMA(GeomSubset, SchemaView, ERNIE_SUBSET_ATTRIBUTES,
158
+ "Some faces, points, edges, segments or tetrahedra of its parent, to bind a "
159
+ "material to or select.");
113
160
  ERNIE_CONCRETE_SCHEMA(Cube, Gprim, ERNIE_CUBE_ATTRIBUTES,
114
161
  "A box centred on its origin, size along each axis.");
115
162
  ERNIE_CONCRETE_SCHEMA(Sphere, Gprim, ERNIE_SPHERE_ATTRIBUTES, "A sphere centred on its origin.");
@@ -3,14 +3,16 @@
3
3
  /// @brief Point-based geometry's registry entries and extents, as UsdGeom computes them.
4
4
  #include "ernie/scene/schemas/mesh.h"
5
5
 
6
+ #include <algorithm>
6
7
  #include <optional>
7
8
  #include <vector>
8
9
 
9
10
  namespace ernie {
10
11
  namespace {
11
12
 
12
- /// @return The box of a CPU tensor's points, each grown by half its width (one per point, one for
13
- /// all, or none); none for an empty tensor or one on a device.
13
+ /// @return The box of a CPU tensor's points, each grown by half its width when there is one per
14
+ /// point, else by half the widest (as UsdGeomCurves does); none for an empty tensor or one on a
15
+ /// device.
14
16
  std::optional<Box> BoundPoints(const Tensor& points, const Tensor& widths) {
15
17
  if (points.Empty() || IsGpu(points.Location().kind) ||
16
18
  (!widths.Empty() && IsGpu(widths.Location().kind))) {
@@ -20,10 +22,9 @@ std::optional<Box> BoundPoints(const Tensor& points, const Tensor& widths) {
20
22
  const std::vector<float> diameters =
21
23
  widths.Empty() ? std::vector<float>{} : CopyFloats(widths, "widths");
22
24
  const auto count = static_cast<std::size_t>(xyz.Elements() / 3);
25
+ const double widest = diameters.empty() ? 0.0 : *std::ranges::max_element(diameters);
23
26
  const auto half = [&](std::size_t i) {
24
- return diameters.size() == count ? 0.5 * diameters[i]
25
- : diameters.size() == 1 ? 0.5 * diameters[0]
26
- : 0.0;
27
+ return 0.5 * (diameters.size() == count ? diameters[i] : widest);
27
28
  };
28
29
  Box box;
29
30
  const auto extend = [&]<typename T>(const T* data) {
@@ -40,7 +41,8 @@ std::optional<Box> BoundPoints(const Tensor& points, const Tensor& widths) {
40
41
  return box;
41
42
  }
42
43
 
43
- /// Meshes from their points; point clouds grown by their widths.
44
+ /// Meshes from their points; point clouds and curves grown by their widths. Curves are bounded by
45
+ /// their control points, which hold every basis but catmullRom and Hermite closely, as in USD.
44
46
  template <bool kWidths>
45
47
  void PointBasedExtent(const ExtentRows& rows, RowRange range, std::span<Box> out) {
46
48
  const auto points = rows.Column<Tensor>(PointBased::kPoints);
@@ -58,5 +60,10 @@ ERNIE_DEFINE_SCHEMA(PointBased, Abstract, kInheritExtent, ERNIE_POINT_BASED_ATTR
58
60
  ERNIE_DEFINE_SCHEMA(Mesh, Concrete, ComputedExtent(PointBasedExtent<false>), ERNIE_MESH_ATTRIBUTES)
59
61
  ERNIE_DEFINE_SCHEMA(Points, Concrete, ComputedExtent(PointBasedExtent<true>),
60
62
  ERNIE_POINTS_ATTRIBUTES)
63
+ ERNIE_DEFINE_SCHEMA(Curves, Abstract, ComputedExtent(PointBasedExtent<true>),
64
+ ERNIE_CURVES_ATTRIBUTES)
65
+ ERNIE_DEFINE_SCHEMA(BasisCurves, Concrete, kInheritExtent, ERNIE_BASIS_CURVES_ATTRIBUTES)
66
+ ERNIE_DEFINE_SCHEMA(NurbsCurves, Concrete, kInheritExtent, ERNIE_NURBS_CURVES_ATTRIBUTES)
67
+ ERNIE_DEFINE_SCHEMA(HermiteCurves, Concrete, kInheritExtent, ERNIE_HERMITE_CURVES_ATTRIBUTES)
61
68
 
62
69
  } // namespace ernie
@@ -1,9 +1,10 @@
1
1
  // SPDX-License-Identifier: BSD-3-Clause
2
2
  /// @file mesh.h
3
- /// @brief UsdGeom's point-based geometry: meshes and point clouds.
3
+ /// @brief UsdGeom's point-based geometry: meshes, point clouds and curves.
4
4
  ///
5
5
  /// References:
6
- /// - Pixar, UsdGeomMesh and UsdGeomPoints, https://openusd.org/release/api/usd_geom_page_front.html
6
+ /// - Pixar, UsdGeomMesh, UsdGeomPoints and UsdGeomCurves,
7
+ /// https://openusd.org/release/api/usd_geom_page_front.html
7
8
  #pragma once
8
9
 
9
10
  #include "ernie/scene/schemas/geom.h"
@@ -52,13 +53,46 @@
52
53
  ERNIE_MESH_INDICES(X, CreaseLengths, "creaseLengths", "The number of points of each crease.") \
53
54
  X(Tensor, CreaseSharpnesses, "creaseSharpnesses", Tensor(), \
54
55
  "The sharpness of each crease, or of each crease edge.", .group = "Subdivision", \
55
- .dirty = Dirty::Topology)
56
+ .dirty = Dirty::Topology) \
57
+ X(int, SubdivisionRefineLevel, "ernie:subdivision:refineLevel", 1, \
58
+ "Uniform refinement of the surface: 2^level segments along each control edge.", \
59
+ .label = "Refine level", .group = "Subdivision", .lower = AtLeast(0.0), \
60
+ .upper = AtMost(8.0), .dirty = Dirty::Topology)
61
+
62
+ #define ERNIE_WIDTHS_ATTRIBUTE(X, text) \
63
+ X(Tensor, Widths, "widths", Tensor(), text, .group = "Geometry", .dirty = Dirty::Points)
56
64
 
57
65
  #define ERNIE_POINTS_ATTRIBUTES(X) \
58
- X(Tensor, Widths, "widths", Tensor(), "Diameters in metres: one per point, or one for all.", \
59
- .group = "Geometry", .dirty = Dirty::Points) \
66
+ ERNIE_WIDTHS_ATTRIBUTE(X, "Diameters in metres: one per point, or one for all.") \
60
67
  X(Tensor, Ids, "ids", Tensor(), "int64 ids that follow points across time samples.", \
61
68
  .group = "Geometry", .integer = true, .dirty = Dirty::Topology)
69
+
70
+ #define ERNIE_CURVES_ATTRIBUTES(X) \
71
+ ERNIE_MESH_INDICES(X, CurveVertexCounts, "curveVertexCounts", \
72
+ "The number of points of each curve.") \
73
+ ERNIE_WIDTHS_ATTRIBUTE(X, "Diameters in metres: per point, per segment end, or one for all.")
74
+
75
+ #define ERNIE_BASIS_CURVES_ATTRIBUTES(X) \
76
+ X(std::string, Type, "type", "cubic", "Linear segments, or cubic ones by the basis.", \
77
+ .group = "Topology", .options = {"linear", "cubic"}, .dirty = Dirty::Topology) \
78
+ X(std::string, Basis, "basis", "bezier", "The cubic basis.", .group = "Topology", \
79
+ .options = {"bezier", "bspline", "catmullRom"}, .dirty = Dirty::Topology) \
80
+ X(std::string, Wrap, "wrap", "nonperiodic", \
81
+ "Open curves, closed ones, or open ones through their end points.", .group = "Topology", \
82
+ .options = {"nonperiodic", "periodic", "pinned"}, .dirty = Dirty::Topology)
83
+
84
+ #define ERNIE_NURBS_CURVES_ATTRIBUTES(X) \
85
+ ERNIE_MESH_INDICES(X, Order, "order", "The order (degree + 1) of each curve.") \
86
+ X(Tensor, Knots, "knots", Tensor(), "Each curve's knots, curveVertexCount + order of them.", \
87
+ .group = "Topology", .dirty = Dirty::Topology) \
88
+ X(Tensor, Ranges, "ranges", Tensor(), "(n, 2) parametric range drawn of each curve.", \
89
+ .group = "Topology", .components = 2, .dirty = Dirty::Topology) \
90
+ X(Tensor, PointWeights, "pointWeights", Tensor(), "Rational weights, one per point.", \
91
+ .group = "Geometry", .dirty = Dirty::Points)
92
+
93
+ #define ERNIE_HERMITE_CURVES_ATTRIBUTES(X) \
94
+ X(Tensor, Tangents, "tangents", Tensor(), "(n, 3) tangent of each point.", \
95
+ .group = "Geometry", .components = 3, .dirty = Dirty::Points)
62
96
  // clang-format on
63
97
 
64
98
  namespace ernie {
@@ -68,5 +102,13 @@ ERNIE_CONCRETE_SCHEMA(Mesh, PointBased, ERNIE_MESH_ATTRIBUTES,
68
102
  "A polygon mesh, or the control mesh of a subdivision surface.");
69
103
  ERNIE_CONCRETE_SCHEMA(Points, PointBased, ERNIE_POINTS_ATTRIBUTES,
70
104
  "A point cloud of spheres, each its own width.");
105
+ ERNIE_SCHEMA(Curves, PointBased, ERNIE_CURVES_ATTRIBUTES,
106
+ "Batched curves, each a run of points, swept by its widths.");
107
+ ERNIE_CONCRETE_SCHEMA(BasisCurves, Curves, ERNIE_BASIS_CURVES_ATTRIBUTES,
108
+ "Linear or cubic curves: hair, fur, cables and wires.");
109
+ ERNIE_CONCRETE_SCHEMA(NurbsCurves, Curves, ERNIE_NURBS_CURVES_ATTRIBUTES,
110
+ "Rational B-spline curves of any order.");
111
+ ERNIE_CONCRETE_SCHEMA(HermiteCurves, Curves, ERNIE_HERMITE_CURVES_ATTRIBUTES,
112
+ "Cubic curves through their points with a tangent at each.");
71
113
 
72
114
  } // namespace ernie
@@ -23,6 +23,8 @@ std::span<const SchemaDef* const> Schemas() {
23
23
  &Gprim::Definition(),
24
24
  &Xform::Definition(),
25
25
  &Scope::Definition(),
26
+ &GeomModelAPI::Definition(),
27
+ &GeomSubset::Definition(),
26
28
  &Cube::Definition(),
27
29
  &Sphere::Definition(),
28
30
  &Cylinder::Definition(),
@@ -32,6 +34,10 @@ std::span<const SchemaDef* const> Schemas() {
32
34
  &PointBased::Definition(),
33
35
  &Mesh::Definition(),
34
36
  &Points::Definition(),
37
+ &Curves::Definition(),
38
+ &BasisCurves::Definition(),
39
+ &NurbsCurves::Definition(),
40
+ &HermiteCurves::Definition(),
35
41
  &PointInstancer::Definition(),
36
42
  &Volume::Definition(),
37
43
  &FieldBase::Definition(),
@@ -41,6 +41,8 @@ TEST(Mesh, ArraysAreSharedAndCheckedForTypeAndShape) {
41
41
  scene.Write(mesh.Id(), "primvars:st", Floats({0, 0, 1, 0, 0, 1}, {3, 2}));
42
42
  EXPECT_NE(scene.Read(mesh.Id(), "primvars:st"), nullptr) << "primvars take any name";
43
43
  EXPECT_EQ(mesh.GetSubdivisionScheme(), "catmullClark") << "USD's fallback";
44
+ EXPECT_EQ(mesh.GetSubdivisionRefineLevel(), 1);
45
+ EXPECT_THROW(mesh.SetSubdivisionRefineLevel(9), std::invalid_argument);
44
46
  }
45
47
 
46
48
  TEST(Mesh, ExtentsBoundPointsAndPointCloudsTheirWidths) {
@@ -62,6 +64,25 @@ TEST(Mesh, ExtentsBoundPointsAndPointCloudsTheirWidths) {
62
64
  EXPECT_EQ(scene.Extent(cloud.Id())->max, glm::dvec3(10.5, 0.5, 0.5)) << "one width for all";
63
65
  }
64
66
 
67
+ TEST(Curves, ExtentsBoundControlPointsGrownByTheWidestWidth) {
68
+ Scene scene;
69
+ BasisCurves hair = BasisCurves::Define(scene, "/Hair");
70
+ EXPECT_EQ(hair.GetType(), "cubic") << "USD's fallback";
71
+ hair.SetCurveVertexCounts(Tensor::Copy<std::int32_t>(std::vector<std::int32_t>{4}, {1}));
72
+ hair.SetPoints(Floats({0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 1}, {4, 3}));
73
+ hair.SetWidths(Floats({0.2f, 0.4f}, {2}));
74
+ const Box box = *scene.Extent(hair.Id());
75
+ EXPECT_NEAR(box.min.x, -0.2, 1e-6) << "varying widths grow by the widest";
76
+ EXPECT_NEAR(box.max.z, 1.2, 1e-6);
77
+
78
+ NurbsCurves nurbs = NurbsCurves::Define(scene, "/Nurbs");
79
+ nurbs.SetPoints(Floats({0, 0, 0, 1, 1, 1}, {2, 3}));
80
+ EXPECT_EQ(scene.Extent(nurbs.Id())->max, glm::dvec3(1.0)) << "no widths";
81
+ EXPECT_THROW(HermiteCurves::Define(scene, "/Hermite").SetTangents(Floats({1, 0}, {1, 2})),
82
+ std::invalid_argument)
83
+ << "tangents are threes";
84
+ }
85
+
65
86
  TEST(Mesh, PointsTheHostCannotReadFallBackToTheAuthoredExtent) {
66
87
  Scene scene;
67
88
  Mesh mesh = Mesh::Define(scene, "/Tri");
@@ -101,6 +101,34 @@ TEST(Extent, WorldBoundsGatherVisibleDescendantsThroughTheirTransforms) {
101
101
  EXPECT_TRUE(scene.WorldBounds("/World/Hidden").Empty());
102
102
  }
103
103
 
104
+ TEST(Extent, ModelsWithoutLoadedDescendantsAreBoundedByTheirHint) {
105
+ Scene scene;
106
+ Xform::Define(scene, "/World");
107
+ SetXform(scene, "/World", {.translate = glm::dvec3(10.0, 0.0, 0.0)});
108
+ Xform::Define(scene, "/World/Rover");
109
+ GeomModelAPI::Apply(scene, "/World/Rover")
110
+ .SetExtentsHint({-1, -1, 0, 1, 1, 2, -5, -5, -5, 5, 5, 5});
111
+ ExpectBox(scene.WorldBounds("/World"), {9.0, -1.0, 0.0}, {11.0, 1.0, 2.0});
112
+ SCOPED_TRACE("bounds in the parent take every purpose's box");
113
+ ExpectBox(scene.BoundsInParent(*scene.Find("/World/Rover")), glm::dvec3(-5.0), glm::dvec3(5.0));
114
+ Sphere::Define(scene, "/World/Rover/Body").SetRadius(0.5);
115
+ SCOPED_TRACE("loaded descendants replace the hint");
116
+ ExpectBox(scene.WorldBounds("/World"), {9.5, -0.5, -0.5}, {10.5, 0.5, 0.5});
117
+ Sphere(scene, "/World/Rover/Body").SetVisibility("invisible");
118
+ EXPECT_TRUE(scene.WorldBounds("/World").Empty()) << "hidden, not unloaded";
119
+ }
120
+
121
+ TEST(Extent, SubsetsAreNotBounded) {
122
+ Scene scene;
123
+ Cube::Define(scene, "/Box");
124
+ GeomSubset subset = GeomSubset::Define(scene, "/Box/Top");
125
+ subset.SetIndices(Tensor::Copy<std::int32_t>(std::vector<std::int32_t>{4}, {1}))
126
+ .SetFamilyName("materialBind");
127
+ EXPECT_EQ(subset.GetElementType(), "face");
128
+ EXPECT_FALSE(scene.Extent(subset.Id()));
129
+ ExpectBox(scene.WorldBounds("/Box"), glm::dvec3(-1.0), glm::dvec3(1.0));
130
+ }
131
+
104
132
  TEST(Extent, ResettingTheStackDropsAncestorsFromWorldBounds) {
105
133
  Scene scene;
106
134
  Xform::Define(scene, "/World");