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