warp-lang 1.7.0__py3-none-manylinux_2_34_aarch64.whl
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 warp-lang might be problematic. Click here for more details.
- warp/__init__.py +139 -0
- warp/__init__.pyi +1 -0
- warp/autograd.py +1142 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +557 -0
- warp/build_dll.py +405 -0
- warp/builtins.py +6855 -0
- warp/codegen.py +3969 -0
- warp/config.py +158 -0
- warp/constants.py +57 -0
- warp/context.py +6812 -0
- warp/dlpack.py +462 -0
- warp/examples/__init__.py +24 -0
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nonuniform.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/nvidia_logo.png +0 -0
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +389 -0
- warp/examples/benchmarks/benchmark_cloth.py +296 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
- warp/examples/benchmarks/benchmark_gemm.py +164 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
- warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
- warp/examples/benchmarks/benchmark_launches.py +301 -0
- warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
- warp/examples/browse.py +37 -0
- warp/examples/core/example_cupy.py +86 -0
- warp/examples/core/example_dem.py +241 -0
- warp/examples/core/example_fluid.py +299 -0
- warp/examples/core/example_graph_capture.py +150 -0
- warp/examples/core/example_marching_cubes.py +194 -0
- warp/examples/core/example_mesh.py +180 -0
- warp/examples/core/example_mesh_intersect.py +211 -0
- warp/examples/core/example_nvdb.py +182 -0
- warp/examples/core/example_raycast.py +111 -0
- warp/examples/core/example_raymarch.py +205 -0
- warp/examples/core/example_render_opengl.py +193 -0
- warp/examples/core/example_sample_mesh.py +300 -0
- warp/examples/core/example_sph.py +411 -0
- warp/examples/core/example_torch.py +211 -0
- warp/examples/core/example_wave.py +269 -0
- warp/examples/fem/example_adaptive_grid.py +286 -0
- warp/examples/fem/example_apic_fluid.py +423 -0
- warp/examples/fem/example_burgers.py +261 -0
- warp/examples/fem/example_convection_diffusion.py +178 -0
- warp/examples/fem/example_convection_diffusion_dg.py +204 -0
- warp/examples/fem/example_deformed_geometry.py +172 -0
- warp/examples/fem/example_diffusion.py +196 -0
- warp/examples/fem/example_diffusion_3d.py +225 -0
- warp/examples/fem/example_diffusion_mgpu.py +220 -0
- warp/examples/fem/example_distortion_energy.py +228 -0
- warp/examples/fem/example_magnetostatics.py +240 -0
- warp/examples/fem/example_mixed_elasticity.py +291 -0
- warp/examples/fem/example_navier_stokes.py +261 -0
- warp/examples/fem/example_nonconforming_contact.py +298 -0
- warp/examples/fem/example_stokes.py +213 -0
- warp/examples/fem/example_stokes_transfer.py +262 -0
- warp/examples/fem/example_streamlines.py +352 -0
- warp/examples/fem/utils.py +1000 -0
- warp/examples/interop/example_jax_callable.py +116 -0
- warp/examples/interop/example_jax_ffi_callback.py +132 -0
- warp/examples/interop/example_jax_kernel.py +205 -0
- warp/examples/optim/example_bounce.py +266 -0
- warp/examples/optim/example_cloth_throw.py +228 -0
- warp/examples/optim/example_diffray.py +561 -0
- warp/examples/optim/example_drone.py +870 -0
- warp/examples/optim/example_fluid_checkpoint.py +497 -0
- warp/examples/optim/example_inverse_kinematics.py +182 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
- warp/examples/optim/example_softbody_properties.py +400 -0
- warp/examples/optim/example_spring_cage.py +245 -0
- warp/examples/optim/example_trajectory.py +227 -0
- warp/examples/sim/example_cartpole.py +143 -0
- warp/examples/sim/example_cloth.py +225 -0
- warp/examples/sim/example_cloth_self_contact.py +322 -0
- warp/examples/sim/example_granular.py +130 -0
- warp/examples/sim/example_granular_collision_sdf.py +202 -0
- warp/examples/sim/example_jacobian_ik.py +244 -0
- warp/examples/sim/example_particle_chain.py +124 -0
- warp/examples/sim/example_quadruped.py +203 -0
- warp/examples/sim/example_rigid_chain.py +203 -0
- warp/examples/sim/example_rigid_contact.py +195 -0
- warp/examples/sim/example_rigid_force.py +133 -0
- warp/examples/sim/example_rigid_gyroscopic.py +115 -0
- warp/examples/sim/example_rigid_soft_contact.py +140 -0
- warp/examples/sim/example_soft_body.py +196 -0
- warp/examples/tile/example_tile_cholesky.py +87 -0
- warp/examples/tile/example_tile_convolution.py +66 -0
- warp/examples/tile/example_tile_fft.py +55 -0
- warp/examples/tile/example_tile_filtering.py +113 -0
- warp/examples/tile/example_tile_matmul.py +85 -0
- warp/examples/tile/example_tile_mlp.py +383 -0
- warp/examples/tile/example_tile_nbody.py +199 -0
- warp/examples/tile/example_tile_walker.py +327 -0
- warp/fabric.py +355 -0
- warp/fem/__init__.py +106 -0
- warp/fem/adaptivity.py +508 -0
- warp/fem/cache.py +572 -0
- warp/fem/dirichlet.py +202 -0
- warp/fem/domain.py +411 -0
- warp/fem/field/__init__.py +125 -0
- warp/fem/field/field.py +619 -0
- warp/fem/field/nodal_field.py +326 -0
- warp/fem/field/restriction.py +37 -0
- warp/fem/field/virtual.py +848 -0
- warp/fem/geometry/__init__.py +32 -0
- warp/fem/geometry/adaptive_nanogrid.py +857 -0
- warp/fem/geometry/closest_point.py +84 -0
- warp/fem/geometry/deformed_geometry.py +221 -0
- warp/fem/geometry/element.py +776 -0
- warp/fem/geometry/geometry.py +362 -0
- warp/fem/geometry/grid_2d.py +392 -0
- warp/fem/geometry/grid_3d.py +452 -0
- warp/fem/geometry/hexmesh.py +911 -0
- warp/fem/geometry/nanogrid.py +571 -0
- warp/fem/geometry/partition.py +389 -0
- warp/fem/geometry/quadmesh.py +663 -0
- warp/fem/geometry/tetmesh.py +855 -0
- warp/fem/geometry/trimesh.py +806 -0
- warp/fem/integrate.py +2335 -0
- warp/fem/linalg.py +419 -0
- warp/fem/operator.py +293 -0
- warp/fem/polynomial.py +229 -0
- warp/fem/quadrature/__init__.py +17 -0
- warp/fem/quadrature/pic_quadrature.py +299 -0
- warp/fem/quadrature/quadrature.py +591 -0
- warp/fem/space/__init__.py +228 -0
- warp/fem/space/basis_function_space.py +468 -0
- warp/fem/space/basis_space.py +667 -0
- warp/fem/space/dof_mapper.py +251 -0
- warp/fem/space/function_space.py +309 -0
- warp/fem/space/grid_2d_function_space.py +177 -0
- warp/fem/space/grid_3d_function_space.py +227 -0
- warp/fem/space/hexmesh_function_space.py +257 -0
- warp/fem/space/nanogrid_function_space.py +201 -0
- warp/fem/space/partition.py +367 -0
- warp/fem/space/quadmesh_function_space.py +223 -0
- warp/fem/space/restriction.py +179 -0
- warp/fem/space/shape/__init__.py +143 -0
- warp/fem/space/shape/cube_shape_function.py +1105 -0
- warp/fem/space/shape/shape_function.py +133 -0
- warp/fem/space/shape/square_shape_function.py +926 -0
- warp/fem/space/shape/tet_shape_function.py +834 -0
- warp/fem/space/shape/triangle_shape_function.py +672 -0
- warp/fem/space/tetmesh_function_space.py +271 -0
- warp/fem/space/topology.py +424 -0
- warp/fem/space/trimesh_function_space.py +194 -0
- warp/fem/types.py +99 -0
- warp/fem/utils.py +420 -0
- warp/jax.py +187 -0
- warp/jax_experimental/__init__.py +16 -0
- warp/jax_experimental/custom_call.py +351 -0
- warp/jax_experimental/ffi.py +698 -0
- warp/jax_experimental/xla_ffi.py +602 -0
- warp/math.py +244 -0
- warp/native/array.h +1145 -0
- warp/native/builtin.h +1800 -0
- warp/native/bvh.cpp +492 -0
- warp/native/bvh.cu +791 -0
- warp/native/bvh.h +554 -0
- warp/native/clang/clang.cpp +536 -0
- warp/native/coloring.cpp +613 -0
- warp/native/crt.cpp +51 -0
- warp/native/crt.h +362 -0
- warp/native/cuda_crt.h +1058 -0
- warp/native/cuda_util.cpp +646 -0
- warp/native/cuda_util.h +307 -0
- warp/native/error.cpp +77 -0
- warp/native/error.h +36 -0
- warp/native/exports.h +1878 -0
- warp/native/fabric.h +245 -0
- warp/native/hashgrid.cpp +311 -0
- warp/native/hashgrid.cu +87 -0
- warp/native/hashgrid.h +240 -0
- warp/native/initializer_array.h +41 -0
- warp/native/intersect.h +1230 -0
- warp/native/intersect_adj.h +375 -0
- warp/native/intersect_tri.h +339 -0
- warp/native/marching.cpp +19 -0
- warp/native/marching.cu +514 -0
- warp/native/marching.h +19 -0
- warp/native/mat.h +2220 -0
- warp/native/mathdx.cpp +87 -0
- warp/native/matnn.h +343 -0
- warp/native/mesh.cpp +266 -0
- warp/native/mesh.cu +404 -0
- warp/native/mesh.h +1980 -0
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +6624 -0
- warp/native/nanovdb/PNanoVDB.h +3390 -0
- warp/native/noise.h +859 -0
- warp/native/quat.h +1371 -0
- warp/native/rand.h +342 -0
- warp/native/range.h +139 -0
- warp/native/reduce.cpp +174 -0
- warp/native/reduce.cu +364 -0
- warp/native/runlength_encode.cpp +79 -0
- warp/native/runlength_encode.cu +61 -0
- warp/native/scan.cpp +47 -0
- warp/native/scan.cu +53 -0
- warp/native/scan.h +23 -0
- warp/native/solid_angle.h +466 -0
- warp/native/sort.cpp +251 -0
- warp/native/sort.cu +277 -0
- warp/native/sort.h +33 -0
- warp/native/sparse.cpp +378 -0
- warp/native/sparse.cu +524 -0
- warp/native/spatial.h +657 -0
- warp/native/svd.h +702 -0
- warp/native/temp_buffer.h +46 -0
- warp/native/tile.h +2584 -0
- warp/native/tile_reduce.h +264 -0
- warp/native/vec.h +1426 -0
- warp/native/volume.cpp +501 -0
- warp/native/volume.cu +67 -0
- warp/native/volume.h +969 -0
- warp/native/volume_builder.cu +477 -0
- warp/native/volume_builder.h +52 -0
- warp/native/volume_impl.h +70 -0
- warp/native/warp.cpp +1082 -0
- warp/native/warp.cu +3636 -0
- warp/native/warp.h +381 -0
- warp/optim/__init__.py +17 -0
- warp/optim/adam.py +163 -0
- warp/optim/linear.py +1137 -0
- warp/optim/sgd.py +112 -0
- warp/paddle.py +407 -0
- warp/render/__init__.py +18 -0
- warp/render/render_opengl.py +3518 -0
- warp/render/render_usd.py +784 -0
- warp/render/utils.py +160 -0
- warp/sim/__init__.py +65 -0
- warp/sim/articulation.py +793 -0
- warp/sim/collide.py +2395 -0
- warp/sim/graph_coloring.py +300 -0
- warp/sim/import_mjcf.py +790 -0
- warp/sim/import_snu.py +227 -0
- warp/sim/import_urdf.py +579 -0
- warp/sim/import_usd.py +894 -0
- warp/sim/inertia.py +324 -0
- warp/sim/integrator.py +242 -0
- warp/sim/integrator_euler.py +1997 -0
- warp/sim/integrator_featherstone.py +2101 -0
- warp/sim/integrator_vbd.py +2048 -0
- warp/sim/integrator_xpbd.py +3292 -0
- warp/sim/model.py +4791 -0
- warp/sim/particles.py +121 -0
- warp/sim/render.py +427 -0
- warp/sim/utils.py +428 -0
- warp/sparse.py +2057 -0
- warp/stubs.py +3333 -0
- warp/tape.py +1203 -0
- warp/tests/__init__.py +1 -0
- warp/tests/__main__.py +4 -0
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/mlp_golden.npy +0 -0
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/assets/spiky.usd +0 -0
- warp/tests/assets/test_grid.nvdb +0 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/assets/test_int32_grid.nvdb +0 -0
- warp/tests/assets/test_vec_grid.nvdb +0 -0
- warp/tests/assets/torus.nvdb +0 -0
- warp/tests/assets/torus.usda +105 -0
- warp/tests/aux_test_class_kernel.py +34 -0
- warp/tests/aux_test_compile_consts_dummy.py +18 -0
- warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
- warp/tests/aux_test_dependent.py +29 -0
- warp/tests/aux_test_grad_customs.py +29 -0
- warp/tests/aux_test_instancing_gc.py +26 -0
- warp/tests/aux_test_module_unload.py +23 -0
- warp/tests/aux_test_name_clash1.py +40 -0
- warp/tests/aux_test_name_clash2.py +40 -0
- warp/tests/aux_test_reference.py +9 -0
- warp/tests/aux_test_reference_reference.py +8 -0
- warp/tests/aux_test_square.py +16 -0
- warp/tests/aux_test_unresolved_func.py +22 -0
- warp/tests/aux_test_unresolved_symbol.py +22 -0
- warp/tests/cuda/__init__.py +0 -0
- warp/tests/cuda/test_async.py +676 -0
- warp/tests/cuda/test_ipc.py +124 -0
- warp/tests/cuda/test_mempool.py +233 -0
- warp/tests/cuda/test_multigpu.py +169 -0
- warp/tests/cuda/test_peer.py +139 -0
- warp/tests/cuda/test_pinned.py +84 -0
- warp/tests/cuda/test_streams.py +634 -0
- warp/tests/geometry/__init__.py +0 -0
- warp/tests/geometry/test_bvh.py +200 -0
- warp/tests/geometry/test_hash_grid.py +221 -0
- warp/tests/geometry/test_marching_cubes.py +74 -0
- warp/tests/geometry/test_mesh.py +316 -0
- warp/tests/geometry/test_mesh_query_aabb.py +399 -0
- warp/tests/geometry/test_mesh_query_point.py +932 -0
- warp/tests/geometry/test_mesh_query_ray.py +311 -0
- warp/tests/geometry/test_volume.py +1103 -0
- warp/tests/geometry/test_volume_write.py +346 -0
- warp/tests/interop/__init__.py +0 -0
- warp/tests/interop/test_dlpack.py +729 -0
- warp/tests/interop/test_jax.py +371 -0
- warp/tests/interop/test_paddle.py +800 -0
- warp/tests/interop/test_torch.py +1001 -0
- warp/tests/run_coverage_serial.py +39 -0
- warp/tests/sim/__init__.py +0 -0
- warp/tests/sim/disabled_kinematics.py +244 -0
- warp/tests/sim/flaky_test_sim_grad.py +290 -0
- warp/tests/sim/test_collision.py +604 -0
- warp/tests/sim/test_coloring.py +258 -0
- warp/tests/sim/test_model.py +224 -0
- warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
- warp/tests/sim/test_sim_kinematics.py +98 -0
- warp/tests/sim/test_vbd.py +597 -0
- warp/tests/test_adam.py +163 -0
- warp/tests/test_arithmetic.py +1096 -0
- warp/tests/test_array.py +2972 -0
- warp/tests/test_array_reduce.py +156 -0
- warp/tests/test_assert.py +250 -0
- warp/tests/test_atomic.py +153 -0
- warp/tests/test_bool.py +220 -0
- warp/tests/test_builtins_resolution.py +1298 -0
- warp/tests/test_closest_point_edge_edge.py +327 -0
- warp/tests/test_codegen.py +810 -0
- warp/tests/test_codegen_instancing.py +1495 -0
- warp/tests/test_compile_consts.py +215 -0
- warp/tests/test_conditional.py +252 -0
- warp/tests/test_context.py +42 -0
- warp/tests/test_copy.py +238 -0
- warp/tests/test_ctypes.py +638 -0
- warp/tests/test_dense.py +73 -0
- warp/tests/test_devices.py +97 -0
- warp/tests/test_examples.py +482 -0
- warp/tests/test_fabricarray.py +996 -0
- warp/tests/test_fast_math.py +74 -0
- warp/tests/test_fem.py +2003 -0
- warp/tests/test_fp16.py +136 -0
- warp/tests/test_func.py +454 -0
- warp/tests/test_future_annotations.py +98 -0
- warp/tests/test_generics.py +656 -0
- warp/tests/test_grad.py +893 -0
- warp/tests/test_grad_customs.py +339 -0
- warp/tests/test_grad_debug.py +341 -0
- warp/tests/test_implicit_init.py +411 -0
- warp/tests/test_import.py +45 -0
- warp/tests/test_indexedarray.py +1140 -0
- warp/tests/test_intersect.py +73 -0
- warp/tests/test_iter.py +76 -0
- warp/tests/test_large.py +177 -0
- warp/tests/test_launch.py +411 -0
- warp/tests/test_lerp.py +151 -0
- warp/tests/test_linear_solvers.py +193 -0
- warp/tests/test_lvalue.py +427 -0
- warp/tests/test_mat.py +2089 -0
- warp/tests/test_mat_lite.py +122 -0
- warp/tests/test_mat_scalar_ops.py +2913 -0
- warp/tests/test_math.py +178 -0
- warp/tests/test_mlp.py +282 -0
- warp/tests/test_module_hashing.py +258 -0
- warp/tests/test_modules_lite.py +44 -0
- warp/tests/test_noise.py +252 -0
- warp/tests/test_operators.py +299 -0
- warp/tests/test_options.py +129 -0
- warp/tests/test_overwrite.py +551 -0
- warp/tests/test_print.py +339 -0
- warp/tests/test_quat.py +2315 -0
- warp/tests/test_rand.py +339 -0
- warp/tests/test_reload.py +302 -0
- warp/tests/test_rounding.py +185 -0
- warp/tests/test_runlength_encode.py +196 -0
- warp/tests/test_scalar_ops.py +105 -0
- warp/tests/test_smoothstep.py +108 -0
- warp/tests/test_snippet.py +318 -0
- warp/tests/test_sparse.py +582 -0
- warp/tests/test_spatial.py +2229 -0
- warp/tests/test_special_values.py +361 -0
- warp/tests/test_static.py +592 -0
- warp/tests/test_struct.py +734 -0
- warp/tests/test_tape.py +204 -0
- warp/tests/test_transient_module.py +93 -0
- warp/tests/test_triangle_closest_point.py +145 -0
- warp/tests/test_types.py +562 -0
- warp/tests/test_utils.py +588 -0
- warp/tests/test_vec.py +1487 -0
- warp/tests/test_vec_lite.py +80 -0
- warp/tests/test_vec_scalar_ops.py +2327 -0
- warp/tests/test_verify_fp.py +100 -0
- warp/tests/tile/__init__.py +0 -0
- warp/tests/tile/test_tile.py +780 -0
- warp/tests/tile/test_tile_load.py +407 -0
- warp/tests/tile/test_tile_mathdx.py +208 -0
- warp/tests/tile/test_tile_mlp.py +402 -0
- warp/tests/tile/test_tile_reduce.py +447 -0
- warp/tests/tile/test_tile_shared_memory.py +247 -0
- warp/tests/tile/test_tile_view.py +173 -0
- warp/tests/unittest_serial.py +47 -0
- warp/tests/unittest_suites.py +427 -0
- warp/tests/unittest_utils.py +468 -0
- warp/tests/walkthrough_debug.py +93 -0
- warp/thirdparty/__init__.py +0 -0
- warp/thirdparty/appdirs.py +598 -0
- warp/thirdparty/dlpack.py +145 -0
- warp/thirdparty/unittest_parallel.py +570 -0
- warp/torch.py +391 -0
- warp/types.py +5230 -0
- warp/utils.py +1137 -0
- warp_lang-1.7.0.dist-info/METADATA +516 -0
- warp_lang-1.7.0.dist-info/RECORD +429 -0
- warp_lang-1.7.0.dist-info/WHEEL +5 -0
- warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
- warp_lang-1.7.0.dist-info/top_level.txt +1 -0
warp/native/volume.h
ADDED
|
@@ -0,0 +1,969 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#pragma once
|
|
19
|
+
|
|
20
|
+
#include "array.h"
|
|
21
|
+
#include "builtin.h"
|
|
22
|
+
|
|
23
|
+
#define PNANOVDB_C
|
|
24
|
+
#define PNANOVDB_MEMCPY_CUSTOM
|
|
25
|
+
#define pnanovdb_memcpy memcpy
|
|
26
|
+
|
|
27
|
+
#if defined(WP_NO_CRT) && !defined(__CUDACC__)
|
|
28
|
+
// PNanoVDB will try to include <stdint.h> unless __CUDACC_RTC__ is defined
|
|
29
|
+
#define __CUDACC_RTC__
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#include "nanovdb/PNanoVDB.h"
|
|
33
|
+
|
|
34
|
+
#if defined(WP_NO_CRT) && !defined(__CUDACC__)
|
|
35
|
+
#undef __CUDACC_RTC__
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
namespace wp
|
|
39
|
+
{
|
|
40
|
+
namespace volume
|
|
41
|
+
{
|
|
42
|
+
|
|
43
|
+
// Need to kept in sync with constants in python-side Volume class
|
|
44
|
+
static constexpr int CLOSEST = 0;
|
|
45
|
+
static constexpr int LINEAR = 1;
|
|
46
|
+
|
|
47
|
+
// pnanovdb helper function
|
|
48
|
+
|
|
49
|
+
CUDA_CALLABLE inline pnanovdb_buf_t id_to_buffer(uint64_t id)
|
|
50
|
+
{
|
|
51
|
+
pnanovdb_buf_t buf;
|
|
52
|
+
buf.data = (uint32_t *)id;
|
|
53
|
+
return buf;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
CUDA_CALLABLE inline pnanovdb_grid_handle_t get_grid(pnanovdb_buf_t buf)
|
|
57
|
+
{
|
|
58
|
+
return {0u};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
CUDA_CALLABLE inline pnanovdb_uint32_t get_grid_type(pnanovdb_buf_t buf)
|
|
62
|
+
{
|
|
63
|
+
return pnanovdb_grid_get_grid_type(buf, get_grid(buf));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
CUDA_CALLABLE inline pnanovdb_tree_handle_t get_tree(pnanovdb_buf_t buf)
|
|
67
|
+
{
|
|
68
|
+
return pnanovdb_grid_get_tree(buf, get_grid(buf));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
CUDA_CALLABLE inline pnanovdb_root_handle_t get_root(pnanovdb_buf_t buf)
|
|
72
|
+
{
|
|
73
|
+
return pnanovdb_tree_get_root(buf, get_tree(buf));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
template <typename T> struct pnano_traits
|
|
77
|
+
{
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// to add support for more grid types, extend this
|
|
81
|
+
// and update _volume_supported_value_types in builtins.py
|
|
82
|
+
|
|
83
|
+
template <> struct pnano_traits<int32_t>
|
|
84
|
+
{
|
|
85
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_INT32;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
template <> struct pnano_traits<int64_t>
|
|
89
|
+
{
|
|
90
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_INT64;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
template <> struct pnano_traits<uint32_t>
|
|
94
|
+
{
|
|
95
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_UINT32;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
template <> struct pnano_traits<float>
|
|
99
|
+
{
|
|
100
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_FLOAT;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
template <> struct pnano_traits<double>
|
|
104
|
+
{
|
|
105
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_DOUBLE;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
template <> struct pnano_traits<vec3f>
|
|
109
|
+
{
|
|
110
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_VEC3F;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
template <> struct pnano_traits<vec3d>
|
|
114
|
+
{
|
|
115
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_VEC3D;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
template <> struct pnano_traits<vec4f>
|
|
119
|
+
{
|
|
120
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_VEC4F;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
template <> struct pnano_traits<vec4d>
|
|
124
|
+
{
|
|
125
|
+
static constexpr int GRID_TYPE = PNANOVDB_GRID_TYPE_VEC4D;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// common accessors over various grid types
|
|
129
|
+
// WARNING: implementation below only for >=32b values, but that's the case for all types above
|
|
130
|
+
// for smaller types add a specialization
|
|
131
|
+
|
|
132
|
+
template <typename T> CUDA_CALLABLE inline void pnano_read(T &result, pnanovdb_buf_t buf, pnanovdb_address_t address)
|
|
133
|
+
{
|
|
134
|
+
result = *reinterpret_cast<const T *>(buf.data + (address.byte_offset >> 2));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
template <typename T>
|
|
138
|
+
CUDA_CALLABLE inline void pnano_write(const T &value, pnanovdb_buf_t buf, pnanovdb_address_t address)
|
|
139
|
+
{
|
|
140
|
+
*reinterpret_cast<T *>(buf.data + (address.byte_offset >> 2)) = value;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
template <typename T>
|
|
144
|
+
CUDA_CALLABLE inline void pnano_read(T &result, pnanovdb_buf_t buf, pnanovdb_root_handle_t root,
|
|
145
|
+
PNANOVDB_IN(pnanovdb_coord_t) ijk)
|
|
146
|
+
{
|
|
147
|
+
using traits = pnano_traits<T>;
|
|
148
|
+
const pnanovdb_address_t address = pnanovdb_root_get_value_address(traits::GRID_TYPE, buf, root, ijk);
|
|
149
|
+
pnano_read<T>(result, buf, address);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
template <typename T>
|
|
153
|
+
CUDA_CALLABLE inline void pnano_read(T &result, pnanovdb_buf_t buf, PNANOVDB_INOUT(pnanovdb_readaccessor_t) acc,
|
|
154
|
+
PNANOVDB_IN(pnanovdb_coord_t) ijk)
|
|
155
|
+
{
|
|
156
|
+
using traits = pnano_traits<T>;
|
|
157
|
+
// pnanovdb_address_t address = pnanovdb_readaccessor_get_value_address(traits::GRID_TYPE, buf, acc, ijk);
|
|
158
|
+
pnanovdb_uint32_t level;
|
|
159
|
+
const pnanovdb_address_t address =
|
|
160
|
+
pnanovdb_readaccessor_get_value_address_and_level(traits::GRID_TYPE, buf, acc, ijk, PNANOVDB_REF(level));
|
|
161
|
+
pnano_read<T>(result, buf, address);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/// regular grid accessor (values stored in leafs)
|
|
165
|
+
|
|
166
|
+
struct value_accessor_base
|
|
167
|
+
{
|
|
168
|
+
pnanovdb_buf_t buf;
|
|
169
|
+
pnanovdb_root_handle_t root;
|
|
170
|
+
pnanovdb_readaccessor_t accessor;
|
|
171
|
+
|
|
172
|
+
explicit inline CUDA_CALLABLE value_accessor_base(const pnanovdb_buf_t buf) : buf(buf), root(get_root(buf))
|
|
173
|
+
{
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
CUDA_CALLABLE inline void init_cache()
|
|
177
|
+
{
|
|
178
|
+
pnanovdb_readaccessor_init(PNANOVDB_REF(accessor), root);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
template <typename T> struct leaf_value_accessor : value_accessor_base
|
|
183
|
+
{
|
|
184
|
+
using ValueType = T;
|
|
185
|
+
|
|
186
|
+
explicit inline CUDA_CALLABLE leaf_value_accessor(const pnanovdb_buf_t buf) : value_accessor_base(buf)
|
|
187
|
+
{
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
CUDA_CALLABLE inline bool is_valid() const
|
|
191
|
+
{
|
|
192
|
+
return get_grid_type(buf) == pnano_traits<T>::GRID_TYPE;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
CUDA_CALLABLE inline T read_single(const pnanovdb_coord_t &ijk) const
|
|
196
|
+
{
|
|
197
|
+
T val;
|
|
198
|
+
pnano_read(val, buf, root, PNANOVDB_REF(ijk));
|
|
199
|
+
return val;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
CUDA_CALLABLE inline T read_cache(const pnanovdb_coord_t &ijk)
|
|
203
|
+
{
|
|
204
|
+
T val;
|
|
205
|
+
pnano_read(val, buf, PNANOVDB_REF(accessor), PNANOVDB_REF(ijk));
|
|
206
|
+
return val;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
CUDA_CALLABLE inline void adj_read_single(const pnanovdb_coord_t &ijk, const T &adj_ret)
|
|
210
|
+
{
|
|
211
|
+
// NOP
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
CUDA_CALLABLE inline void adj_read_cache(const pnanovdb_coord_t &ijk, const T &adj_ret)
|
|
215
|
+
{
|
|
216
|
+
// NOP
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
CUDA_CALLABLE inline pnanovdb_uint64_t leaf_regular_get_voxel_index(pnanovdb_buf_t buf,
|
|
221
|
+
pnanovdb_address_t value_address,
|
|
222
|
+
PNANOVDB_IN(pnanovdb_coord_t) ijk)
|
|
223
|
+
{
|
|
224
|
+
// compute leaf index from value address, assuming all leaf voxels are allocated
|
|
225
|
+
const pnanovdb_grid_type_t grid_type = get_grid_type(buf);
|
|
226
|
+
const pnanovdb_uint32_t n = pnanovdb_leaf_coord_to_offset(ijk);
|
|
227
|
+
const pnanovdb_uint32_t byte_offset = PNANOVDB_GRID_TYPE_GET(grid_type, leaf_off_table) +
|
|
228
|
+
((PNANOVDB_GRID_TYPE_GET(grid_type, value_stride_bits) * n) >> 3u);
|
|
229
|
+
const pnanovdb_address_t leaf_address = pnanovdb_address_offset_neg(value_address, byte_offset);
|
|
230
|
+
|
|
231
|
+
const pnanovdb_uint64_t first_leaf_offset = pnanovdb_tree_get_node_offset_leaf(buf, get_tree(buf));
|
|
232
|
+
const pnanovdb_uint32_t leaf_size = PNANOVDB_GRID_TYPE_GET(grid_type, leaf_size);
|
|
233
|
+
const pnanovdb_uint64_t leaf_index = (leaf_address.byte_offset - first_leaf_offset) / leaf_size;
|
|
234
|
+
|
|
235
|
+
return leaf_index * PNANOVDB_LEAF_TABLE_COUNT + n + 1;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
CUDA_CALLABLE inline pnanovdb_uint64_t get_grid_voxel_index(pnanovdb_grid_type_t grid_type, pnanovdb_buf_t buf,
|
|
239
|
+
pnanovdb_address_t value_address,
|
|
240
|
+
const pnanovdb_coord_t &ijk)
|
|
241
|
+
{
|
|
242
|
+
switch (grid_type)
|
|
243
|
+
{
|
|
244
|
+
case PNANOVDB_GRID_TYPE_INDEX:
|
|
245
|
+
return pnanovdb_leaf_index_get_value_index(buf, value_address, PNANOVDB_REF(ijk));
|
|
246
|
+
case PNANOVDB_GRID_TYPE_ONINDEX:
|
|
247
|
+
return pnanovdb_leaf_onindex_get_value_index(buf, value_address, PNANOVDB_REF(ijk));
|
|
248
|
+
case PNANOVDB_GRID_TYPE_INDEXMASK:
|
|
249
|
+
return pnanovdb_leaf_indexmask_get_value_index(buf, value_address, PNANOVDB_REF(ijk));
|
|
250
|
+
case PNANOVDB_GRID_TYPE_ONINDEXMASK:
|
|
251
|
+
return pnanovdb_leaf_onindexmask_get_value_index(buf, value_address, PNANOVDB_REF(ijk));
|
|
252
|
+
default:
|
|
253
|
+
return leaf_regular_get_voxel_index(buf, value_address, PNANOVDB_REF(ijk));
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/// index grid accessor
|
|
258
|
+
template <typename T> struct index_value_accessor : value_accessor_base
|
|
259
|
+
{
|
|
260
|
+
using ValueType = T;
|
|
261
|
+
|
|
262
|
+
pnanovdb_grid_type_t grid_type;
|
|
263
|
+
array_t<T> data;
|
|
264
|
+
const T &background;
|
|
265
|
+
T *adj_background;
|
|
266
|
+
|
|
267
|
+
explicit inline CUDA_CALLABLE index_value_accessor(const pnanovdb_buf_t buf, const array_t<T> &data,
|
|
268
|
+
const T &background, T *adj_background = nullptr)
|
|
269
|
+
: value_accessor_base(buf), grid_type(get_grid_type(buf)), data(data), background(background),
|
|
270
|
+
adj_background(adj_background)
|
|
271
|
+
{
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
CUDA_CALLABLE inline bool is_valid() const
|
|
275
|
+
{
|
|
276
|
+
// Accessor is valid for all grid types
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
CUDA_CALLABLE inline T read_single(const pnanovdb_coord_t &ijk) const
|
|
281
|
+
{
|
|
282
|
+
pnanovdb_uint32_t level;
|
|
283
|
+
const pnanovdb_address_t address =
|
|
284
|
+
pnanovdb_root_get_value_address_and_level(grid_type, buf, root, PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
285
|
+
return read_at(level, address, ijk);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
CUDA_CALLABLE inline T read_cache(const pnanovdb_coord_t &ijk)
|
|
289
|
+
{
|
|
290
|
+
pnanovdb_uint32_t level;
|
|
291
|
+
const pnanovdb_address_t address = pnanovdb_readaccessor_get_value_address_and_level(
|
|
292
|
+
grid_type, buf, PNANOVDB_REF(accessor), PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
293
|
+
return read_at(level, address, ijk);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
CUDA_CALLABLE inline T read_at(pnanovdb_uint32_t level, const pnanovdb_address_t address,
|
|
297
|
+
const pnanovdb_coord_t &ijk) const
|
|
298
|
+
{
|
|
299
|
+
if (level == 0)
|
|
300
|
+
{
|
|
301
|
+
pnanovdb_uint64_t voxel_index = get_grid_voxel_index(grid_type, buf, address, ijk);
|
|
302
|
+
|
|
303
|
+
if (voxel_index > 0)
|
|
304
|
+
{
|
|
305
|
+
return *wp::address(data, voxel_index - 1);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return background;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
CUDA_CALLABLE inline void adj_read_single(const pnanovdb_coord_t &ijk, const T &adj_ret)
|
|
313
|
+
{
|
|
314
|
+
pnanovdb_uint32_t level;
|
|
315
|
+
const pnanovdb_address_t address =
|
|
316
|
+
pnanovdb_root_get_value_address_and_level(grid_type, buf, root, PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
317
|
+
adj_read_at(level, address, ijk, adj_ret);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
CUDA_CALLABLE inline void adj_read_cache(const pnanovdb_coord_t &ijk, const T &adj_ret)
|
|
321
|
+
{
|
|
322
|
+
pnanovdb_uint32_t level;
|
|
323
|
+
const pnanovdb_address_t address = pnanovdb_readaccessor_get_value_address_and_level(
|
|
324
|
+
grid_type, buf, PNANOVDB_REF(accessor), PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
325
|
+
adj_read_at(level, address, ijk, adj_ret);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
CUDA_CALLABLE inline void adj_read_at(pnanovdb_uint32_t level, const pnanovdb_address_t address,
|
|
329
|
+
const pnanovdb_coord_t &ijk, const T &adj_ret) const
|
|
330
|
+
{
|
|
331
|
+
if (level == 0)
|
|
332
|
+
{
|
|
333
|
+
pnanovdb_uint64_t voxel_index = get_grid_voxel_index(grid_type, buf, address, ijk);
|
|
334
|
+
|
|
335
|
+
if (voxel_index > 0)
|
|
336
|
+
{
|
|
337
|
+
adj_atomic_add(&index_grad(data, voxel_index - 1), adj_ret);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
*adj_background += adj_ret;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
CUDA_CALLABLE inline pnanovdb_coord_t vec3_round_to_coord(const pnanovdb_vec3_t a)
|
|
346
|
+
{
|
|
347
|
+
pnanovdb_coord_t v;
|
|
348
|
+
v.x = pnanovdb_float_to_int32(roundf(a.x));
|
|
349
|
+
v.y = pnanovdb_float_to_int32(roundf(a.y));
|
|
350
|
+
v.z = pnanovdb_float_to_int32(roundf(a.z));
|
|
351
|
+
return v;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
template <typename T> struct val_traits
|
|
355
|
+
{
|
|
356
|
+
using grad_t = vec_t<3, T>;
|
|
357
|
+
using scalar_t = T;
|
|
358
|
+
|
|
359
|
+
// multiplies the gradient on the right
|
|
360
|
+
// needs to be specialized for scalar types as gradient is stored as column rather than row vector
|
|
361
|
+
static CUDA_CALLABLE inline T rmul(const grad_t &grad, const vec_t<3, scalar_t> &rhs)
|
|
362
|
+
{
|
|
363
|
+
return dot(grad, rhs);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
template <unsigned Length, typename T> struct val_traits<vec_t<Length, T>>
|
|
368
|
+
{
|
|
369
|
+
using grad_t = mat_t<3, Length, T>;
|
|
370
|
+
using scalar_t = T;
|
|
371
|
+
|
|
372
|
+
static CUDA_CALLABLE inline vec_t<Length, T> rmul(const grad_t &grad, const vec_t<3, scalar_t> &rhs)
|
|
373
|
+
{
|
|
374
|
+
return mul(grad, rhs);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// Sampling the volume at the given index-space coordinates, uvw can be fractional
|
|
379
|
+
template <typename Accessor>
|
|
380
|
+
CUDA_CALLABLE inline typename Accessor::ValueType volume_sample(Accessor &accessor, vec3 uvw, int sampling_mode)
|
|
381
|
+
{
|
|
382
|
+
using T = typename Accessor::ValueType;
|
|
383
|
+
using w_t = typename val_traits<T>::scalar_t;
|
|
384
|
+
|
|
385
|
+
if (!accessor.is_valid())
|
|
386
|
+
{
|
|
387
|
+
return 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const pnanovdb_buf_t buf = accessor.buf;
|
|
391
|
+
const pnanovdb_vec3_t uvw_pnano{uvw[0], uvw[1], uvw[2]};
|
|
392
|
+
|
|
393
|
+
if (sampling_mode == CLOSEST)
|
|
394
|
+
{
|
|
395
|
+
const pnanovdb_coord_t ijk = vec3_round_to_coord(uvw_pnano);
|
|
396
|
+
return accessor.read_single(ijk);
|
|
397
|
+
}
|
|
398
|
+
else if (sampling_mode == LINEAR)
|
|
399
|
+
{
|
|
400
|
+
// NB. linear sampling is not used on int volumes
|
|
401
|
+
constexpr pnanovdb_coord_t OFFSETS[] = {
|
|
402
|
+
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1},
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const pnanovdb_vec3_t ijk_base{floorf(uvw_pnano.x), floorf(uvw_pnano.y), floorf(uvw_pnano.z)};
|
|
406
|
+
const pnanovdb_vec3_t ijk_frac{uvw_pnano.x - ijk_base.x, uvw_pnano.y - ijk_base.y, uvw_pnano.z - ijk_base.z};
|
|
407
|
+
const pnanovdb_coord_t ijk{(pnanovdb_int32_t)ijk_base.x, (pnanovdb_int32_t)ijk_base.y,
|
|
408
|
+
(pnanovdb_int32_t)ijk_base.z};
|
|
409
|
+
|
|
410
|
+
accessor.init_cache();
|
|
411
|
+
T val = 0;
|
|
412
|
+
const float wx[2]{1 - ijk_frac.x, ijk_frac.x};
|
|
413
|
+
const float wy[2]{1 - ijk_frac.y, ijk_frac.y};
|
|
414
|
+
const float wz[2]{1 - ijk_frac.z, ijk_frac.z};
|
|
415
|
+
for (int idx = 0; idx < 8; ++idx)
|
|
416
|
+
{
|
|
417
|
+
const pnanovdb_coord_t &offs = OFFSETS[idx];
|
|
418
|
+
const pnanovdb_coord_t ijk_shifted = pnanovdb_coord_add(ijk, offs);
|
|
419
|
+
const T v = accessor.read_cache(ijk_shifted);
|
|
420
|
+
|
|
421
|
+
const w_t w = wx[offs.x] * wy[offs.y] * wz[offs.z];
|
|
422
|
+
val = add(val, w * v);
|
|
423
|
+
}
|
|
424
|
+
return val;
|
|
425
|
+
}
|
|
426
|
+
return 0;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
template <typename Accessor>
|
|
430
|
+
CUDA_CALLABLE inline void adj_volume_sample(Accessor &accessor, vec3 uvw, int sampling_mode, vec3 &adj_uvw,
|
|
431
|
+
const typename Accessor::ValueType &adj_ret)
|
|
432
|
+
{
|
|
433
|
+
// TODO: accessor data gradients
|
|
434
|
+
|
|
435
|
+
using T = typename Accessor::ValueType;
|
|
436
|
+
using w_t = typename val_traits<T>::scalar_t;
|
|
437
|
+
using w_grad_t = vec_t<3, w_t>;
|
|
438
|
+
|
|
439
|
+
if (!accessor.is_valid())
|
|
440
|
+
{
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const pnanovdb_buf_t buf = accessor.buf;
|
|
445
|
+
const pnanovdb_vec3_t uvw_pnano{uvw[0], uvw[1], uvw[2]};
|
|
446
|
+
|
|
447
|
+
if (sampling_mode != LINEAR)
|
|
448
|
+
{
|
|
449
|
+
const pnanovdb_coord_t ijk = vec3_round_to_coord(uvw_pnano);
|
|
450
|
+
accessor.adj_read_single(ijk, adj_ret);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
constexpr pnanovdb_coord_t OFFSETS[] = {
|
|
455
|
+
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1},
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const pnanovdb_vec3_t ijk_base{floorf(uvw_pnano.x), floorf(uvw_pnano.y), floorf(uvw_pnano.z)};
|
|
459
|
+
const pnanovdb_vec3_t ijk_frac{uvw_pnano.x - ijk_base.x, uvw_pnano.y - ijk_base.y, uvw_pnano.z - ijk_base.z};
|
|
460
|
+
const pnanovdb_coord_t ijk{(pnanovdb_int32_t)ijk_base.x, (pnanovdb_int32_t)ijk_base.y,
|
|
461
|
+
(pnanovdb_int32_t)ijk_base.z};
|
|
462
|
+
|
|
463
|
+
accessor.init_cache();
|
|
464
|
+
|
|
465
|
+
const float wx[2]{1 - ijk_frac.x, ijk_frac.x};
|
|
466
|
+
const float wy[2]{1 - ijk_frac.y, ijk_frac.y};
|
|
467
|
+
const float wz[2]{1 - ijk_frac.z, ijk_frac.z};
|
|
468
|
+
for (int idx = 0; idx < 8; ++idx)
|
|
469
|
+
{
|
|
470
|
+
const pnanovdb_coord_t &offs = OFFSETS[idx];
|
|
471
|
+
const pnanovdb_coord_t ijk_shifted = pnanovdb_coord_add(ijk, offs);
|
|
472
|
+
const T v = accessor.read_cache(ijk_shifted);
|
|
473
|
+
|
|
474
|
+
const vec3 signs(offs.x * 2 - 1, offs.y * 2 - 1, offs.z * 2 - 1);
|
|
475
|
+
|
|
476
|
+
const w_t w = wx[offs.x] * wy[offs.y] * wz[offs.z];
|
|
477
|
+
const w_grad_t grad_w(signs[0] * wy[offs.y] * wz[offs.z], signs[1] * wx[offs.x] * wz[offs.z],
|
|
478
|
+
signs[2] * wx[offs.x] * wy[offs.y]);
|
|
479
|
+
|
|
480
|
+
adj_uvw += vec3(mul(w_t(dot(v, adj_ret)), grad_w));
|
|
481
|
+
|
|
482
|
+
const T adj_v = w * adj_ret;
|
|
483
|
+
accessor.adj_read_cache(ijk_shifted, adj_v);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Sampling the volume at the given index-space coordinates, uvw can be fractional
|
|
488
|
+
template <typename Accessor>
|
|
489
|
+
CUDA_CALLABLE inline typename Accessor::ValueType volume_sample_grad(
|
|
490
|
+
Accessor &accessor, vec3 uvw, int sampling_mode, typename val_traits<typename Accessor::ValueType>::grad_t &grad)
|
|
491
|
+
{
|
|
492
|
+
using T = typename Accessor::ValueType;
|
|
493
|
+
using grad_T = typename val_traits<T>::grad_t;
|
|
494
|
+
using w_t = typename val_traits<T>::scalar_t;
|
|
495
|
+
using w_grad_t = vec_t<3, w_t>;
|
|
496
|
+
|
|
497
|
+
grad = grad_T{};
|
|
498
|
+
|
|
499
|
+
if (!accessor.is_valid())
|
|
500
|
+
{
|
|
501
|
+
return 0;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const pnanovdb_buf_t buf = accessor.buf;
|
|
505
|
+
const pnanovdb_vec3_t uvw_pnano{uvw[0], uvw[1], uvw[2]};
|
|
506
|
+
|
|
507
|
+
if (sampling_mode == CLOSEST)
|
|
508
|
+
{
|
|
509
|
+
const pnanovdb_coord_t ijk = vec3_round_to_coord(uvw_pnano);
|
|
510
|
+
return accessor.read_single(ijk);
|
|
511
|
+
}
|
|
512
|
+
else if (sampling_mode == LINEAR)
|
|
513
|
+
{
|
|
514
|
+
// NB. linear sampling is not used on int volumes
|
|
515
|
+
constexpr pnanovdb_coord_t OFFSETS[] = {
|
|
516
|
+
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1},
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
const pnanovdb_vec3_t ijk_base{floorf(uvw_pnano.x), floorf(uvw_pnano.y), floorf(uvw_pnano.z)};
|
|
520
|
+
const pnanovdb_vec3_t ijk_frac{uvw_pnano.x - ijk_base.x, uvw_pnano.y - ijk_base.y, uvw_pnano.z - ijk_base.z};
|
|
521
|
+
const pnanovdb_coord_t ijk{(pnanovdb_int32_t)ijk_base.x, (pnanovdb_int32_t)ijk_base.y,
|
|
522
|
+
(pnanovdb_int32_t)ijk_base.z};
|
|
523
|
+
|
|
524
|
+
accessor.init_cache();
|
|
525
|
+
T val = 0;
|
|
526
|
+
const float wx[2]{1 - ijk_frac.x, ijk_frac.x};
|
|
527
|
+
const float wy[2]{1 - ijk_frac.y, ijk_frac.y};
|
|
528
|
+
const float wz[2]{1 - ijk_frac.z, ijk_frac.z};
|
|
529
|
+
for (int idx = 0; idx < 8; ++idx)
|
|
530
|
+
{
|
|
531
|
+
const pnanovdb_coord_t &offs = OFFSETS[idx];
|
|
532
|
+
const pnanovdb_coord_t ijk_shifted = pnanovdb_coord_add(ijk, offs);
|
|
533
|
+
const T v = accessor.read_cache(ijk_shifted);
|
|
534
|
+
|
|
535
|
+
const vec3 signs(offs.x * 2 - 1, offs.y * 2 - 1, offs.z * 2 - 1);
|
|
536
|
+
|
|
537
|
+
const w_t w = wx[offs.x] * wy[offs.y] * wz[offs.z];
|
|
538
|
+
const w_grad_t grad_w(signs[0] * wy[offs.y] * wz[offs.z], signs[1] * wx[offs.x] * wz[offs.z],
|
|
539
|
+
signs[2] * wx[offs.x] * wy[offs.y]);
|
|
540
|
+
|
|
541
|
+
val = add(val, w * v);
|
|
542
|
+
grad += outer(v, grad_w);
|
|
543
|
+
}
|
|
544
|
+
return val;
|
|
545
|
+
}
|
|
546
|
+
return 0;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
template <typename Accessor>
|
|
550
|
+
CUDA_CALLABLE inline void adj_volume_sample_grad(Accessor &accessor, vec3 uvw, int sampling_mode,
|
|
551
|
+
typename val_traits<typename Accessor::ValueType>::grad_t &grad,
|
|
552
|
+
vec3 &adj_uvw,
|
|
553
|
+
typename val_traits<typename Accessor::ValueType>::grad_t &adj_grad,
|
|
554
|
+
const typename Accessor::ValueType &adj_ret)
|
|
555
|
+
{
|
|
556
|
+
// TODO: accessor data gradients
|
|
557
|
+
|
|
558
|
+
using T = typename Accessor::ValueType;
|
|
559
|
+
using grad_T = typename val_traits<T>::grad_t;
|
|
560
|
+
using w_t = typename val_traits<T>::scalar_t;
|
|
561
|
+
using w_grad_t = vec_t<3, w_t>;
|
|
562
|
+
using w_hess_t = mat_t<3, 3, w_t>;
|
|
563
|
+
|
|
564
|
+
if (!accessor.is_valid())
|
|
565
|
+
{
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const pnanovdb_buf_t buf = accessor.buf;
|
|
570
|
+
const pnanovdb_vec3_t uvw_pnano{uvw[0], uvw[1], uvw[2]};
|
|
571
|
+
|
|
572
|
+
if (sampling_mode != LINEAR)
|
|
573
|
+
{
|
|
574
|
+
const pnanovdb_coord_t ijk = vec3_round_to_coord(uvw_pnano);
|
|
575
|
+
accessor.adj_read_single(ijk, adj_ret);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
constexpr pnanovdb_coord_t OFFSETS[] = {
|
|
580
|
+
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1},
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
const pnanovdb_vec3_t ijk_base{floorf(uvw_pnano.x), floorf(uvw_pnano.y), floorf(uvw_pnano.z)};
|
|
584
|
+
const pnanovdb_vec3_t ijk_frac{uvw_pnano.x - ijk_base.x, uvw_pnano.y - ijk_base.y, uvw_pnano.z - ijk_base.z};
|
|
585
|
+
const pnanovdb_coord_t ijk{(pnanovdb_int32_t)ijk_base.x, (pnanovdb_int32_t)ijk_base.y,
|
|
586
|
+
(pnanovdb_int32_t)ijk_base.z};
|
|
587
|
+
|
|
588
|
+
accessor.init_cache();
|
|
589
|
+
|
|
590
|
+
const float wx[2]{1 - ijk_frac.x, ijk_frac.x};
|
|
591
|
+
const float wy[2]{1 - ijk_frac.y, ijk_frac.y};
|
|
592
|
+
const float wz[2]{1 - ijk_frac.z, ijk_frac.z};
|
|
593
|
+
for (int idx = 0; idx < 8; ++idx)
|
|
594
|
+
{
|
|
595
|
+
const pnanovdb_coord_t &offs = OFFSETS[idx];
|
|
596
|
+
const pnanovdb_coord_t ijk_shifted = pnanovdb_coord_add(ijk, offs);
|
|
597
|
+
const T v = accessor.read_cache(ijk_shifted);
|
|
598
|
+
|
|
599
|
+
const vec3 signs(offs.x * 2 - 1, offs.y * 2 - 1, offs.z * 2 - 1);
|
|
600
|
+
|
|
601
|
+
const w_t w = wx[offs.x] * wy[offs.y] * wz[offs.z];
|
|
602
|
+
const w_grad_t grad_w(signs[0] * wy[offs.y] * wz[offs.z], signs[1] * wx[offs.x] * wz[offs.z],
|
|
603
|
+
signs[2] * wx[offs.x] * wy[offs.y]);
|
|
604
|
+
adj_uvw += vec3(mul(w_t(dot(v, adj_ret)), grad_w));
|
|
605
|
+
|
|
606
|
+
const w_hess_t hess_w(0.0, signs[1] * signs[0] * wz[offs.z], signs[2] * signs[0] * wy[offs.y],
|
|
607
|
+
signs[0] * signs[1] * wz[offs.z], 0.0, signs[2] * signs[1] * wx[offs.x],
|
|
608
|
+
signs[0] * signs[2] * wy[offs.y], signs[1] * signs[2] * wx[offs.x], 0.0);
|
|
609
|
+
adj_uvw += vec3(mul(mul(v, adj_grad), hess_w));
|
|
610
|
+
|
|
611
|
+
const T adj_v = w * adj_ret + val_traits<T>::rmul(adj_grad, grad_w);
|
|
612
|
+
accessor.adj_read_cache(ijk_shifted, adj_v);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
} // namespace volume
|
|
617
|
+
// namespace volume
|
|
618
|
+
|
|
619
|
+
// exposed kernel builtins
|
|
620
|
+
|
|
621
|
+
// volume_sample
|
|
622
|
+
|
|
623
|
+
template <typename T> CUDA_CALLABLE inline T volume_sample(uint64_t id, vec3 uvw, int sampling_mode)
|
|
624
|
+
{
|
|
625
|
+
volume::leaf_value_accessor<T> accessor(volume::id_to_buffer(id));
|
|
626
|
+
return volume::volume_sample(accessor, uvw, sampling_mode);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
template <typename T>
|
|
630
|
+
CUDA_CALLABLE inline void adj_volume_sample(uint64_t id, vec3 uvw, int sampling_mode, uint64_t &adj_id, vec3 &adj_uvw,
|
|
631
|
+
int &adj_sampling_mode, const T &adj_ret)
|
|
632
|
+
{
|
|
633
|
+
volume::leaf_value_accessor<T> accessor(volume::id_to_buffer(id));
|
|
634
|
+
volume::adj_volume_sample(accessor, uvw, sampling_mode, adj_uvw, adj_ret);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
template <typename T>
|
|
638
|
+
CUDA_CALLABLE inline T volume_sample_grad(uint64_t id, vec3 uvw, int sampling_mode,
|
|
639
|
+
typename volume::val_traits<T>::grad_t &grad)
|
|
640
|
+
{
|
|
641
|
+
volume::leaf_value_accessor<T> accessor(volume::id_to_buffer(id));
|
|
642
|
+
return volume::volume_sample_grad(accessor, uvw, sampling_mode, grad);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
template <typename T>
|
|
646
|
+
CUDA_CALLABLE inline void adj_volume_sample_grad(uint64_t id, vec3 uvw, int sampling_mode,
|
|
647
|
+
typename volume::val_traits<T>::grad_t &grad, uint64_t &adj_id,
|
|
648
|
+
vec3 &adj_uvw, int &adj_sampling_mode,
|
|
649
|
+
typename volume::val_traits<T>::grad_t &adj_grad, const T &adj_ret)
|
|
650
|
+
{
|
|
651
|
+
volume::leaf_value_accessor<T> accessor(volume::id_to_buffer(id));
|
|
652
|
+
volume::adj_volume_sample_grad(accessor, uvw, sampling_mode, grad, adj_uvw, adj_grad, adj_ret);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// Sampling a float volume at the given index-space coordinates, uvw can be fractional
|
|
656
|
+
CUDA_CALLABLE inline float volume_sample_f(uint64_t id, vec3 uvw, int sampling_mode)
|
|
657
|
+
{
|
|
658
|
+
return volume_sample<float>(id, uvw, sampling_mode);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// Sampling an int volume at the given index-space coordinates, uvw can be fractional
|
|
662
|
+
CUDA_CALLABLE inline int32_t volume_sample_i(uint64_t id, vec3 uvw)
|
|
663
|
+
{
|
|
664
|
+
return volume_sample<int32_t>(id, uvw, volume::CLOSEST);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Sampling a vector volume at the given index-space coordinates, uvw can be fractional
|
|
668
|
+
CUDA_CALLABLE inline vec3 volume_sample_v(uint64_t id, vec3 uvw, int sampling_mode)
|
|
669
|
+
{
|
|
670
|
+
return volume_sample<vec3>(id, uvw, sampling_mode);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
CUDA_CALLABLE inline void adj_volume_sample_f(uint64_t id, vec3 uvw, int sampling_mode, uint64_t &adj_id, vec3 &adj_uvw,
|
|
674
|
+
int &adj_sampling_mode, const float &adj_ret)
|
|
675
|
+
{
|
|
676
|
+
adj_volume_sample(id, uvw, sampling_mode, adj_id, adj_uvw, adj_sampling_mode, adj_ret);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
CUDA_CALLABLE inline void adj_volume_sample_v(uint64_t id, vec3 uvw, int sampling_mode, uint64_t &adj_id, vec3 &adj_uvw,
|
|
680
|
+
int &adj_sampling_mode, const vec3 &adj_ret)
|
|
681
|
+
{
|
|
682
|
+
adj_volume_sample(id, uvw, sampling_mode, adj_id, adj_uvw, adj_sampling_mode, adj_ret);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
CUDA_CALLABLE inline void adj_volume_sample_i(uint64_t id, vec3 uvw, uint64_t &adj_id, vec3 &adj_uvw,
|
|
686
|
+
const int32_t &adj_ret)
|
|
687
|
+
{
|
|
688
|
+
// NOP
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Sampling the volume at the given index-space coordinates, uvw can be fractional
|
|
692
|
+
CUDA_CALLABLE inline float volume_sample_grad_f(uint64_t id, vec3 uvw, int sampling_mode, vec3 &grad)
|
|
693
|
+
{
|
|
694
|
+
return volume_sample_grad<float>(id, uvw, sampling_mode, grad);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
CUDA_CALLABLE inline void adj_volume_sample_grad_f(uint64_t id, vec3 uvw, int sampling_mode, vec3 &grad,
|
|
698
|
+
uint64_t &adj_id, vec3 &adj_uvw, int &adj_sampling_mode,
|
|
699
|
+
vec3 &adj_grad, const float &adj_ret)
|
|
700
|
+
{
|
|
701
|
+
adj_volume_sample_grad<float>(id, uvw, sampling_mode, grad, adj_id, adj_uvw, adj_sampling_mode, adj_grad, adj_ret);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// volume_sample_index
|
|
705
|
+
|
|
706
|
+
template <typename T>
|
|
707
|
+
CUDA_CALLABLE inline T volume_sample_index(uint64_t id, vec3 uvw, int sampling_mode, const array_t<T> &voxel_data,
|
|
708
|
+
const T &background)
|
|
709
|
+
{
|
|
710
|
+
volume::index_value_accessor<T> accessor(volume::id_to_buffer(id), voxel_data, background);
|
|
711
|
+
return volume::volume_sample(accessor, uvw, sampling_mode);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
template <typename T>
|
|
715
|
+
CUDA_CALLABLE inline void adj_volume_sample_index(uint64_t id, vec3 uvw, int sampling_mode,
|
|
716
|
+
const array_t<T> &voxel_data, const T &background, uint64_t &adj_id,
|
|
717
|
+
vec3 &adj_uvw, int &adj_sampling_mode, array_t<T> &adj_voxel_data,
|
|
718
|
+
T &adj_background, const T &adj_ret)
|
|
719
|
+
{
|
|
720
|
+
volume::index_value_accessor<T> accessor(volume::id_to_buffer(id), voxel_data, background, &adj_background);
|
|
721
|
+
volume::adj_volume_sample(accessor, uvw, sampling_mode, adj_uvw, adj_ret);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
template <typename T>
|
|
725
|
+
CUDA_CALLABLE inline T volume_sample_grad_index(uint64_t id, vec3 uvw, int sampling_mode, const array_t<T> &voxel_data,
|
|
726
|
+
const T &background, typename volume::val_traits<T>::grad_t &grad)
|
|
727
|
+
{
|
|
728
|
+
volume::index_value_accessor<T> accessor(volume::id_to_buffer(id), voxel_data, background);
|
|
729
|
+
return volume::volume_sample_grad(accessor, uvw, sampling_mode, grad);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
template <typename T>
|
|
733
|
+
CUDA_CALLABLE inline void adj_volume_sample_grad_index(
|
|
734
|
+
uint64_t id, vec3 uvw, int sampling_mode, const array_t<T> &voxel_data, const T &background,
|
|
735
|
+
typename volume::val_traits<T>::grad_t &grad, uint64_t &adj_id, vec3 &adj_uvw, int &adj_sampling_mode,
|
|
736
|
+
array_t<T> &adj_voxel_data, T &adj_background, typename volume::val_traits<T>::grad_t &adj_grad, const T &adj_ret)
|
|
737
|
+
{
|
|
738
|
+
volume::index_value_accessor<T> accessor(volume::id_to_buffer(id), voxel_data, background, &adj_background);
|
|
739
|
+
volume::adj_volume_sample_grad(accessor, uvw, sampling_mode, grad, adj_uvw, adj_grad, adj_ret);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// volume_lookup
|
|
743
|
+
|
|
744
|
+
template <typename T> CUDA_CALLABLE inline T volume_lookup(uint64_t id, int32_t i, int32_t j, int32_t k)
|
|
745
|
+
{
|
|
746
|
+
using traits = volume::pnano_traits<T>;
|
|
747
|
+
|
|
748
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
749
|
+
if (volume::get_grid_type(buf) != traits::GRID_TYPE)
|
|
750
|
+
return 0;
|
|
751
|
+
|
|
752
|
+
const pnanovdb_root_handle_t root = volume::get_root(buf);
|
|
753
|
+
|
|
754
|
+
const pnanovdb_coord_t ijk{i, j, k};
|
|
755
|
+
T val;
|
|
756
|
+
volume::pnano_read(val, buf, root, PNANOVDB_REF(ijk));
|
|
757
|
+
return val;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
template <typename T>
|
|
761
|
+
CUDA_CALLABLE inline void adj_volume_lookup(uint64_t id, int32_t i, int32_t j, int32_t k, uint64_t &adj_id,
|
|
762
|
+
int32_t &adj_i, int32_t &adj_j, int32_t &adj_k, const T &adj_ret)
|
|
763
|
+
{
|
|
764
|
+
// NOP -- adjoint of grid values is not available
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
CUDA_CALLABLE inline float volume_lookup_f(uint64_t id, int32_t i, int32_t j, int32_t k)
|
|
768
|
+
{
|
|
769
|
+
return volume_lookup<float>(id, i, j, k);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
CUDA_CALLABLE inline int32_t volume_lookup_i(uint64_t id, int32_t i, int32_t j, int32_t k)
|
|
773
|
+
{
|
|
774
|
+
return volume_lookup<int32_t>(id, i, j, k);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
CUDA_CALLABLE inline vec3 volume_lookup_v(uint64_t id, int32_t i, int32_t j, int32_t k)
|
|
778
|
+
{
|
|
779
|
+
return volume_lookup<vec3>(id, i, j, k);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
CUDA_CALLABLE inline void adj_volume_lookup_f(uint64_t id, int32_t i, int32_t j, int32_t k, uint64_t &adj_id,
|
|
783
|
+
int32_t &adj_i, int32_t &adj_j, int32_t &adj_k, const float &adj_ret)
|
|
784
|
+
{
|
|
785
|
+
adj_volume_lookup(id, i, j, k, adj_id, adj_i, adj_j, adj_k, adj_ret);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
CUDA_CALLABLE inline void adj_volume_lookup_i(uint64_t id, int32_t i, int32_t j, int32_t k, uint64_t &adj_id,
|
|
789
|
+
int32_t &adj_i, int32_t &adj_j, int32_t &adj_k, const int32_t &adj_ret)
|
|
790
|
+
{
|
|
791
|
+
adj_volume_lookup(id, i, j, k, adj_id, adj_i, adj_j, adj_k, adj_ret);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
CUDA_CALLABLE inline void adj_volume_lookup_v(uint64_t id, int32_t i, int32_t j, int32_t k, uint64_t &adj_id,
|
|
795
|
+
int32_t &adj_i, int32_t &adj_j, int32_t &adj_k, const vec3 &adj_ret)
|
|
796
|
+
{
|
|
797
|
+
adj_volume_lookup(id, i, j, k, adj_id, adj_i, adj_j, adj_k, adj_ret);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
CUDA_CALLABLE inline int32_t volume_lookup_index(uint64_t id, int32_t i, int32_t j, int32_t k)
|
|
801
|
+
{
|
|
802
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
803
|
+
const pnanovdb_root_handle_t root = volume::get_root(buf);
|
|
804
|
+
const pnanovdb_grid_type_t grid_type = volume::get_grid_type(buf);
|
|
805
|
+
|
|
806
|
+
const pnanovdb_coord_t ijk{i, j, k};
|
|
807
|
+
|
|
808
|
+
pnanovdb_uint32_t level;
|
|
809
|
+
const pnanovdb_address_t address =
|
|
810
|
+
pnanovdb_root_get_value_address_and_level(grid_type, buf, root, PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
811
|
+
|
|
812
|
+
if (level == 0)
|
|
813
|
+
{
|
|
814
|
+
pnanovdb_uint64_t voxel_index = volume::get_grid_voxel_index(grid_type, buf, address, ijk);
|
|
815
|
+
|
|
816
|
+
return static_cast<int32_t>(voxel_index) - 1;
|
|
817
|
+
}
|
|
818
|
+
return -1;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
CUDA_CALLABLE inline void adj_volume_lookup_index(uint64_t id, int32_t i, int32_t j, int32_t k, uint64_t &adj_id,
|
|
822
|
+
int32_t &adj_i, int32_t &adj_j, int32_t &adj_k, const vec3 &adj_ret)
|
|
823
|
+
{
|
|
824
|
+
// NOP
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// volume_store
|
|
828
|
+
|
|
829
|
+
template <typename T>
|
|
830
|
+
CUDA_CALLABLE inline void volume_store(uint64_t id, int32_t i, int32_t j, int32_t k, const T &value)
|
|
831
|
+
{
|
|
832
|
+
using traits = volume::pnano_traits<T>;
|
|
833
|
+
|
|
834
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
835
|
+
if (volume::get_grid_type(buf) != traits::GRID_TYPE)
|
|
836
|
+
return;
|
|
837
|
+
|
|
838
|
+
const pnanovdb_root_handle_t root = volume::get_root(buf);
|
|
839
|
+
const pnanovdb_coord_t ijk{i, j, k};
|
|
840
|
+
|
|
841
|
+
pnanovdb_uint32_t level;
|
|
842
|
+
const pnanovdb_address_t address =
|
|
843
|
+
pnanovdb_root_get_value_address_and_level(traits::GRID_TYPE, buf, root, PNANOVDB_REF(ijk), PNANOVDB_REF(level));
|
|
844
|
+
|
|
845
|
+
if (level == 0)
|
|
846
|
+
{
|
|
847
|
+
// only write at at leaf level (prevent modifying background value)
|
|
848
|
+
// TODO is this the intended semantics? or should be allow writing to background?
|
|
849
|
+
volume::pnano_write(value, buf, address);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
template <typename T>
|
|
854
|
+
CUDA_CALLABLE inline void adj_volume_store(uint64_t id, int32_t i, int32_t j, int32_t k, const T &value,
|
|
855
|
+
uint64_t &adj_id, int32_t &adj_i, int32_t &adj_j, int32_t &adj_k,
|
|
856
|
+
T &adj_value)
|
|
857
|
+
{
|
|
858
|
+
// NOP -- adjoint of grid values is not available
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
CUDA_CALLABLE inline void volume_store_f(uint64_t id, int32_t i, int32_t j, int32_t k, const float &value)
|
|
862
|
+
{
|
|
863
|
+
volume_store(id, i, j, k, value);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
CUDA_CALLABLE inline void adj_volume_store_f(uint64_t id, int32_t i, int32_t j, int32_t k, const float &value,
|
|
867
|
+
uint64_t &adj_id, int32_t &adj_i, int32_t &adj_j, int32_t &adj_k,
|
|
868
|
+
float &adj_value)
|
|
869
|
+
{
|
|
870
|
+
adj_volume_store(id, i, j, k, value, adj_id, adj_i, adj_j, adj_k, adj_value);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
CUDA_CALLABLE inline void volume_store_v(uint64_t id, int32_t i, int32_t j, int32_t k, const vec3 &value)
|
|
874
|
+
{
|
|
875
|
+
volume_store(id, i, j, k, value);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
CUDA_CALLABLE inline void adj_volume_store_v(uint64_t id, int32_t i, int32_t j, int32_t k, const vec3 &value,
|
|
879
|
+
uint64_t &adj_id, int32_t &adj_i, int32_t &adj_j, int32_t &adj_k,
|
|
880
|
+
vec3 &adj_value)
|
|
881
|
+
{
|
|
882
|
+
adj_volume_store(id, i, j, k, value, adj_id, adj_i, adj_j, adj_k, adj_value);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
CUDA_CALLABLE inline void volume_store_i(uint64_t id, int32_t i, int32_t j, int32_t k, const int32_t &value)
|
|
886
|
+
{
|
|
887
|
+
volume_store(id, i, j, k, value);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
CUDA_CALLABLE inline void adj_volume_store_i(uint64_t id, int32_t i, int32_t j, int32_t k, const int32_t &value,
|
|
891
|
+
uint64_t &adj_id, int32_t &adj_i, int32_t &adj_j, int32_t &adj_k,
|
|
892
|
+
int32_t &adj_value)
|
|
893
|
+
{
|
|
894
|
+
adj_volume_store(id, i, j, k, value, adj_id, adj_i, adj_j, adj_k, adj_value);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Transform position from index space to world space
|
|
898
|
+
CUDA_CALLABLE inline vec3 volume_index_to_world(uint64_t id, vec3 uvw)
|
|
899
|
+
{
|
|
900
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
901
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
902
|
+
const pnanovdb_vec3_t pos{uvw[0], uvw[1], uvw[2]};
|
|
903
|
+
const pnanovdb_vec3_t xyz = pnanovdb_grid_index_to_worldf(buf, grid, PNANOVDB_REF(pos));
|
|
904
|
+
return {xyz.x, xyz.y, xyz.z};
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// Transform position from world space to index space
|
|
908
|
+
CUDA_CALLABLE inline vec3 volume_world_to_index(uint64_t id, vec3 xyz)
|
|
909
|
+
{
|
|
910
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
911
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
912
|
+
const pnanovdb_vec3_t pos{xyz[0], xyz[1], xyz[2]};
|
|
913
|
+
const pnanovdb_vec3_t uvw = pnanovdb_grid_world_to_indexf(buf, grid, PNANOVDB_REF(pos));
|
|
914
|
+
return {uvw.x, uvw.y, uvw.z};
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
CUDA_CALLABLE inline void adj_volume_index_to_world(uint64_t id, vec3 uvw, uint64_t &adj_id, vec3 &adj_uvw,
|
|
918
|
+
const vec3 &adj_ret)
|
|
919
|
+
{
|
|
920
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
921
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
922
|
+
const pnanovdb_vec3_t pos{adj_ret[0], adj_ret[1], adj_ret[2]};
|
|
923
|
+
const pnanovdb_vec3_t xyz = pnanovdb_grid_index_to_world_dirf(buf, grid, PNANOVDB_REF(pos));
|
|
924
|
+
adj_uvw = add(adj_uvw, vec3{xyz.x, xyz.y, xyz.z});
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
CUDA_CALLABLE inline void adj_volume_world_to_index(uint64_t id, vec3 xyz, uint64_t &adj_id, vec3 &adj_xyz,
|
|
928
|
+
const vec3 &adj_ret)
|
|
929
|
+
{
|
|
930
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
931
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
932
|
+
const pnanovdb_vec3_t pos{adj_ret[0], adj_ret[1], adj_ret[2]};
|
|
933
|
+
const pnanovdb_vec3_t uvw = pnanovdb_grid_world_to_index_dirf(buf, grid, PNANOVDB_REF(pos));
|
|
934
|
+
adj_xyz = add(adj_xyz, vec3{uvw.x, uvw.y, uvw.z});
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// Transform direction from index space to world space
|
|
938
|
+
CUDA_CALLABLE inline vec3 volume_index_to_world_dir(uint64_t id, vec3 uvw)
|
|
939
|
+
{
|
|
940
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
941
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
942
|
+
const pnanovdb_vec3_t pos{uvw[0], uvw[1], uvw[2]};
|
|
943
|
+
const pnanovdb_vec3_t xyz = pnanovdb_grid_index_to_world_dirf(buf, grid, PNANOVDB_REF(pos));
|
|
944
|
+
return {xyz.x, xyz.y, xyz.z};
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Transform direction from world space to index space
|
|
948
|
+
CUDA_CALLABLE inline vec3 volume_world_to_index_dir(uint64_t id, vec3 xyz)
|
|
949
|
+
{
|
|
950
|
+
const pnanovdb_buf_t buf = volume::id_to_buffer(id);
|
|
951
|
+
const pnanovdb_grid_handle_t grid = {0u};
|
|
952
|
+
const pnanovdb_vec3_t pos{xyz[0], xyz[1], xyz[2]};
|
|
953
|
+
const pnanovdb_vec3_t uvw = pnanovdb_grid_world_to_index_dirf(buf, grid, PNANOVDB_REF(pos));
|
|
954
|
+
return {uvw.x, uvw.y, uvw.z};
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
CUDA_CALLABLE inline void adj_volume_index_to_world_dir(uint64_t id, vec3 uvw, uint64_t &adj_id, vec3 &adj_uvw,
|
|
958
|
+
const vec3 &adj_ret)
|
|
959
|
+
{
|
|
960
|
+
adj_volume_index_to_world(id, uvw, adj_id, adj_uvw, adj_ret);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
CUDA_CALLABLE inline void adj_volume_world_to_index_dir(uint64_t id, vec3 xyz, uint64_t &adj_id, vec3 &adj_xyz,
|
|
964
|
+
const vec3 &adj_ret)
|
|
965
|
+
{
|
|
966
|
+
adj_volume_world_to_index(id, xyz, adj_id, adj_xyz, adj_ret);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
} // namespace wp
|