47 namespace voxel_grid {
52 #if defined(__CUDACC__) 53 void GetVoxelCoordinatesAndFlattenedIndicesCUDA
68 float* voxel_coords_ptr = voxel_coords.GetDataPtr<
float>();
69 int64_t* flattened_indices_ptr = flattened_indices.GetDataPtr<int64_t>();
71 index_t n = flattened_indices.GetLength();
72 ArrayIndexer voxel_indexer({resolution, resolution, resolution});
73 index_t resolution3 = resolution * resolution * resolution;
76 index_t block_idx = buf_indices_ptr[workload_idx / resolution3];
77 index_t voxel_idx = workload_idx % resolution3;
79 index_t block_key_offset = block_idx * 3;
80 index_t xb = block_key_ptr[block_key_offset + 0];
81 index_t yb = block_key_ptr[block_key_offset + 1];
82 index_t zb = block_key_ptr[block_key_offset + 2];
85 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
87 float x = (xb * resolution + xv) * voxel_size;
88 float y = (yb * resolution + yv) * voxel_size;
89 float z = (zb * resolution + zv) * voxel_size;
91 flattened_indices_ptr[workload_idx] =
92 block_idx * resolution3 + voxel_idx;
94 index_t voxel_coords_offset = workload_idx * 3;
95 voxel_coords_ptr[voxel_coords_offset + 0] = x;
96 voxel_coords_ptr[voxel_coords_offset + 1] = y;
97 voxel_coords_ptr[voxel_coords_offset + 2] = z;
109 index_t xn = (xo + resolution) % resolution;
110 index_t yn = (yo + resolution) % resolution;
111 index_t zn = (zo + resolution) % resolution;
117 index_t nb_idx = (dxb + 1) + (dyb + 1) * 3 + (dzb + 1) * 9;
120 *nb_block_masks_indexer.
GetDataPtr<
bool>(curr_block_idx, nb_idx);
121 if (!block_mask_i)
return -1;
124 curr_block_idx, nb_idx);
126 return (((block_idx_i * resolution) + zn) * resolution + yn) * resolution +
130 template <
typename tsdf_t>
132 const tsdf_t* tsdf_base_ptr,
144 nb_block_masks_indexer,
145 nb_block_indices_indexer);
147 index_t vxp = GetLinearIdx(xo + 1, yo, zo);
148 index_t vxn = GetLinearIdx(xo - 1, yo, zo);
149 index_t vyp = GetLinearIdx(xo, yo + 1, zo);
150 index_t vyn = GetLinearIdx(xo, yo - 1, zo);
151 index_t vzp = GetLinearIdx(xo, yo, zo + 1);
152 index_t vzn = GetLinearIdx(xo, yo, zo - 1);
153 if (vxp >= 0 && vxn >= 0) n[0] = tsdf_base_ptr[vxp] - tsdf_base_ptr[vxn];
154 if (vyp >= 0 && vyn >= 0) n[1] = tsdf_base_ptr[vyp] - tsdf_base_ptr[vyn];
155 if (vzp >= 0 && vzn >= 0) n[2] = tsdf_base_ptr[vzp] - tsdf_base_ptr[vzn];
158 template <
typename input_depth_t,
159 typename input_color_t,
163 #if defined(__CUDACC__) 181 index_t resolution2 = resolution * resolution;
182 index_t resolution3 = resolution2 * resolution;
186 ArrayIndexer voxel_indexer({resolution, resolution, resolution});
194 if (!block_value_map.Contains(
"tsdf") ||
195 !block_value_map.Contains(
"weight")) {
197 "TSDF and/or weight not allocated in blocks, please implement " 198 "customized integration.");
200 tsdf_t* tsdf_base_ptr = block_value_map.at(
"tsdf").GetDataPtr<tsdf_t>();
201 weight_t* weight_base_ptr =
202 block_value_map.at(
"weight").GetDataPtr<weight_t>();
204 bool integrate_color =
205 block_value_map.Contains(
"color") && color.NumElements() > 0;
206 color_t* color_base_ptr =
nullptr;
209 float color_multiplier = 1.0;
210 if (integrate_color) {
211 color_base_ptr = block_value_map.at(
"color").
GetDataPtr<color_t>();
216 color_multiplier = 255.0;
220 index_t n = indices.GetLength() * resolution3;
223 index_t block_idx = indices_ptr[workload_idx / resolution3];
224 index_t voxel_idx = workload_idx % resolution3;
229 block_keys_indexer.GetDataPtr<
index_t>(block_idx);
236 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
239 index_t x = xb * resolution + xv;
240 index_t y = yb * resolution + yv;
241 index_t z = zb * resolution + zv;
244 float xc, yc, zc, u, v;
246 static_cast<float>(y),
247 static_cast<float>(z), &xc, &yc, &zc);
250 transform_indexer.
Project(xc, yc, zc, &u, &v);
261 *depth_indexer.
GetDataPtr<input_depth_t>(ui, vi) / depth_scale;
263 float sdf = depth - zc;
264 if (depth <= 0 || depth > depth_max || zc <= 0 || sdf < -sdf_trunc) {
267 sdf = sdf < sdf_trunc ? sdf : sdf_trunc;
270 index_t linear_idx = block_idx * resolution3 + voxel_idx;
272 tsdf_t* tsdf_ptr = tsdf_base_ptr + linear_idx;
273 weight_t* weight_ptr = weight_base_ptr + linear_idx;
275 float inv_wsum = 1.0f / (*weight_ptr + 1);
276 float weight = *weight_ptr;
277 *tsdf_ptr = (weight * (*tsdf_ptr) + sdf) * inv_wsum;
279 if (integrate_color) {
280 color_t* color_ptr = color_base_ptr + 3 * linear_idx;
281 input_color_t* input_color_ptr =
282 color_indexer.
GetDataPtr<input_color_t>(ui, vi);
284 for (
index_t i = 0; i < 3; ++i) {
285 color_ptr[i] = (weight * color_ptr[i] +
286 input_color_ptr[i] * color_multiplier) *
290 *weight_ptr = weight + 1;
293 #if defined(__CUDACC__) 305 return (xin == x && yin == y && zin == z) ?
block_idx : -1;
315 block_idx = block_idx_in;
319 template <
typename tsdf_t,
typename weight_t,
typename color_t>
320 #if defined(__CUDACC__) 325 (std::shared_ptr<core::HashMap>& hashmap,
339 float weight_threshold) {
344 auto device_hashmap = hashmap->GetDeviceHashBackend();
345 #if defined(__CUDACC__) 349 if (cuda_hashmap ==
nullptr) {
351 "Unsupported backend: CUDA raycasting only supports STDGPU.");
353 auto hashmap_impl = cuda_hashmap->GetImpl();
358 if (cpu_hashmap ==
nullptr) {
360 "Unsupported backend: CPU raycasting only supports TBB.");
362 auto hashmap_impl = *cpu_hashmap->GetImpl();
385 if (!block_value_map.Contains(
"tsdf") ||
386 !block_value_map.Contains(
"weight")) {
388 "TSDF and/or weight not allocated in blocks, please implement " 389 "customized integration.");
391 const tsdf_t* tsdf_base_ptr =
392 block_value_map.at(
"tsdf").GetDataPtr<tsdf_t>();
393 const weight_t* weight_base_ptr =
394 block_value_map.at(
"weight").GetDataPtr<weight_t>();
397 if (renderings_map.Contains(
"depth")) {
398 depth_indexer =
ArrayIndexer(renderings_map.at(
"depth"), 2);
400 if (renderings_map.Contains(
"vertex")) {
401 vertex_indexer =
ArrayIndexer(renderings_map.at(
"vertex"), 2);
403 if (renderings_map.Contains(
"normal")) {
404 normal_indexer =
ArrayIndexer(renderings_map.at(
"normal"), 2);
408 if (renderings_map.Contains(
"index")) {
409 index_indexer =
ArrayIndexer(renderings_map.at(
"index"), 2);
411 if (renderings_map.Contains(
"mask")) {
412 mask_indexer =
ArrayIndexer(renderings_map.at(
"mask"), 2);
414 if (renderings_map.Contains(
"interp_ratio")) {
415 interp_ratio_indexer =
418 if (renderings_map.Contains(
"interp_ratio_dx")) {
419 interp_ratio_dx_indexer =
422 if (renderings_map.Contains(
"interp_ratio_dy")) {
423 interp_ratio_dy_indexer =
426 if (renderings_map.Contains(
"interp_ratio_dz")) {
427 interp_ratio_dz_indexer =
432 bool render_color =
false;
433 if (block_value_map.Contains(
"color") && renderings_map.Contains(
"color")) {
435 color_indexer =
ArrayIndexer(renderings_map.at(
"color"), 2);
437 const color_t* color_base_ptr =
438 render_color ? block_value_map.at(
"color").GetDataPtr<color_t>()
441 bool visit_neighbors = render_color || normal_indexer.
GetDataPtr() ||
457 float block_size = voxel_size * block_resolution;
458 index_t resolution2 = block_resolution * block_resolution;
459 index_t resolution3 = resolution2 * block_resolution;
472 index_t x_vn = (x_v + block_resolution) % block_resolution;
473 index_t y_vn = (y_v + block_resolution) % block_resolution;
474 index_t z_vn = (z_v + block_resolution) % block_resolution;
480 if (dx_b == 0 && dy_b == 0 && dz_b == 0) {
481 return block_buf_idx * resolution3 + z_v * resolution2 +
482 y_v * block_resolution + x_v;
484 Key key(x_b + dx_b, y_b + dy_b, z_b + dz_b);
486 index_t block_buf_idx = cache.
Check(key[0], key[1], key[2]);
487 if (block_buf_idx < 0) {
488 auto iter = hashmap_impl.find(key);
489 if (iter == hashmap_impl.end())
return -1;
490 block_buf_idx = iter->second;
491 cache.
Update(key[0], key[1], key[2], block_buf_idx);
494 return block_buf_idx * resolution3 + z_vn * resolution2 +
495 y_vn * block_resolution + x_vn;
500 float x_o,
float y_o,
float z_o,
501 float x_d,
float y_d,
float z_d,
float t,
503 float x_g = x_o + t * x_d;
504 float y_g = y_o + t * y_d;
505 float z_g = z_o + t * z_d;
512 Key key(x_b, y_b, z_b);
514 if (block_buf_idx < 0) {
515 auto iter = hashmap_impl.find(key);
516 if (iter == hashmap_impl.end())
return -1;
517 block_buf_idx = iter->second;
518 cache.
Update(x_b, y_b, z_b, block_buf_idx);
526 return block_buf_idx * resolution3 + z_v * resolution2 +
527 y_v * block_resolution + x_v;
533 const float* range = range_indexer.
GetDataPtr<
float>(x / 8, y / 8);
535 float* depth_ptr =
nullptr;
536 float* vertex_ptr =
nullptr;
537 float* color_ptr =
nullptr;
538 float* normal_ptr =
nullptr;
540 int64_t* index_ptr =
nullptr;
541 bool* mask_ptr =
nullptr;
542 float* interp_ratio_ptr =
nullptr;
543 float* interp_ratio_dx_ptr =
nullptr;
544 float* interp_ratio_dy_ptr =
nullptr;
545 float* interp_ratio_dz_ptr =
nullptr;
569 for (
int i = 0; i < 8; ++i) {
578 for (
int i = 0; i < 8; ++i) {
583 interp_ratio_ptr = interp_ratio_indexer.
GetDataPtr<
float>(
x,
y);
587 for (
int i = 0; i < 8; ++i) {
588 interp_ratio_ptr[i] = 0;
592 interp_ratio_dx_ptr =
597 for (
int i = 0; i < 8; ++i) {
598 interp_ratio_dx_ptr[i] = 0;
602 interp_ratio_dy_ptr =
607 for (
int i = 0; i < 8; ++i) {
608 interp_ratio_dy_ptr[i] = 0;
612 interp_ratio_dz_ptr =
617 for (
int i = 0; i < 8; ++i) {
618 interp_ratio_dz_ptr[i] = 0;
630 const float t_max = range[1];
631 if (t >= t_max)
return;
634 float x_c = 0, y_c = 0, z_c = 0;
635 float x_g = 0, y_g = 0, z_g = 0;
636 float x_o = 0, y_o = 0, z_o = 0;
641 float tsdf_prev = -1.0f;
649 c2w_transform_indexer.
Unproject(static_cast<float>(x),
650 static_cast<float>(y), 1.0f, &x_c, &y_c,
652 c2w_transform_indexer.
RigidTransform(x_c, y_c, z_c, &x_g, &y_g, &z_g);
653 float x_d = (x_g - x_o);
654 float y_d = (y_g - y_o);
655 float z_d = (z_g - z_o);
658 bool surface_found =
false;
661 GetLinearIdxAtT(x_o, y_o, z_o, x_d, y_d, z_d, t, cache);
663 if (linear_idx < 0) {
668 tsdf = tsdf_base_ptr[linear_idx];
669 w = weight_base_ptr[linear_idx];
670 if (tsdf_prev > 0 && w >= weight_threshold && tsdf <= 0) {
671 surface_found =
true;
675 float delta = tsdf * sdf_trunc;
676 t += delta < voxel_size ? voxel_size : delta;
682 (t * tsdf_prev - t_prev * tsdf) / (tsdf_prev - tsdf);
683 x_g = x_o + t_intersect * x_d;
684 y_g = y_o + t_intersect * y_d;
685 z_g = z_o + t_intersect * z_d;
689 *depth_ptr = t_intersect * depth_scale;
693 x_g, y_g, z_g, vertex_ptr + 0, vertex_ptr + 1,
696 if (!visit_neighbors)
return;
704 float x_v = (x_g -
float(x_b) * block_size) / voxel_size;
705 float y_v = (y_g -
float(y_b) * block_size) / voxel_size;
706 float z_v = (z_g -
float(z_b) * block_size) / voxel_size;
708 Key key(x_b, y_b, z_b);
711 if (block_buf_idx < 0) {
712 auto iter = hashmap_impl.find(key);
713 if (iter == hashmap_impl.end())
return;
714 block_buf_idx = iter->second;
715 cache.
Update(x_b, y_b, z_b, block_buf_idx);
722 float ratio_x = x_v -
float(x_v_floor);
723 float ratio_y = y_v -
float(y_v_floor);
724 float ratio_z = z_v -
float(z_v_floor);
727 for (
index_t k = 0; k < 8; ++k) {
728 index_t dx_v = (k & 1) > 0 ? 1 : 0;
729 index_t dy_v = (k & 2) > 0 ? 1 : 0;
730 index_t dz_v = (k & 4) > 0 ? 1 : 0;
732 index_t linear_idx_k = GetLinearIdxAtP(
733 x_b, y_b, z_b, x_v_floor + dx_v, y_v_floor + dy_v,
734 z_v_floor + dz_v, block_buf_idx, cache);
736 if (linear_idx_k >= 0 && weight_base_ptr[linear_idx_k] > 0) {
737 float rx = dx_v * (ratio_x) + (1 - dx_v) * (1 - ratio_x);
738 float ry = dy_v * (ratio_y) + (1 - dy_v) * (1 - ratio_y);
739 float rz = dz_v * (ratio_z) + (1 - dz_v) * (1 - ratio_z);
740 float r = rx * ry * rz;
742 if (interp_ratio_ptr) {
743 interp_ratio_ptr[k] = r;
749 index_ptr[k] = linear_idx_k;
752 float tsdf_k = tsdf_base_ptr[linear_idx_k];
753 float interp_ratio_dx = ry * rz * (2 * dx_v - 1);
754 float interp_ratio_dy = rx * rz * (2 * dy_v - 1);
755 float interp_ratio_dz = rx * ry * (2 * dz_v - 1);
757 if (interp_ratio_dx_ptr) {
758 interp_ratio_dx_ptr[k] = interp_ratio_dx;
760 if (interp_ratio_dy_ptr) {
761 interp_ratio_dy_ptr[k] = interp_ratio_dy;
763 if (interp_ratio_dz_ptr) {
764 interp_ratio_dz_ptr[k] = interp_ratio_dz;
768 normal_ptr[0] += interp_ratio_dx * tsdf_k;
769 normal_ptr[1] += interp_ratio_dy * tsdf_k;
770 normal_ptr[2] += interp_ratio_dz * tsdf_k;
774 index_t color_linear_idx = linear_idx_k * 3;
776 r * color_base_ptr[color_linear_idx + 0];
778 r * color_base_ptr[color_linear_idx + 1];
780 r * color_base_ptr[color_linear_idx + 2];
790 color_ptr[0] /= sum_r;
791 color_ptr[1] /= sum_r;
792 color_ptr[2] /= sum_r;
796 float norm = sqrt(normal_ptr[0] * normal_ptr[0] +
797 normal_ptr[1] * normal_ptr[1] +
798 normal_ptr[2] * normal_ptr[2]);
799 w2c_transform_indexer.
Rotate(
800 -normal_ptr[0] / norm, -normal_ptr[1] / norm,
801 -normal_ptr[2] / norm, normal_ptr + 0,
802 normal_ptr + 1, normal_ptr + 2);
808 #if defined(__CUDACC__) 813 template <
typename tsdf_t,
typename weight_t,
typename color_t>
814 #if defined(__CUDACC__) 815 void ExtractPointCloudCUDA
829 float weight_threshold,
834 index_t resolution2 = resolution * resolution;
835 index_t resolution3 = resolution2 * resolution;
838 ArrayIndexer voxel_indexer({resolution, resolution, resolution});
848 if (!block_value_map.Contains(
"tsdf") ||
849 !block_value_map.Contains(
"weight")) {
851 "TSDF and/or weight not allocated in blocks, please implement " 852 "customized integration.");
854 const tsdf_t* tsdf_base_ptr =
855 block_value_map.at(
"tsdf").GetDataPtr<tsdf_t>();
856 const weight_t* weight_base_ptr =
857 block_value_map.at(
"weight").GetDataPtr<weight_t>();
858 const color_t* color_base_ptr =
nullptr;
859 if (block_value_map.Contains(
"color")) {
860 color_base_ptr = block_value_map.at(
"color").GetDataPtr<color_t>();
864 index_t n = n_blocks * resolution3;
867 #if defined(__CUDACC__) 869 block_keys.GetDevice());
872 std::atomic<index_t> count_atomic(0);
873 std::atomic<index_t>* count_ptr = &count_atomic;
876 if (valid_size < 0) {
878 "No estimated max point cloud size provided, using a 2-pass " 879 "estimation. Surface extraction could be slow.");
887 resolution, nb_block_masks_indexer,
888 nb_block_indices_indexer);
893 index_t workload_block_idx = workload_idx / resolution3;
895 index_t voxel_idx = workload_idx % resolution3;
899 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
901 index_t linear_idx = block_idx * resolution3 + voxel_idx;
902 float tsdf_o = tsdf_base_ptr[linear_idx];
903 float weight_o = weight_base_ptr[linear_idx];
904 if (weight_o <= weight_threshold)
return;
907 for (
index_t i = 0; i < 3; ++i) {
909 GetLinearIdx(xv + (i == 0), yv + (i == 1),
910 zv + (i == 2), workload_block_idx);
911 if (linear_idx_i < 0)
continue;
913 float tsdf_i = tsdf_base_ptr[linear_idx_i];
914 float weight_i = weight_base_ptr[linear_idx_i];
915 if (weight_i > weight_threshold && tsdf_i * tsdf_o < 0) {
921 #if defined(__CUDACC__) 925 valid_size = (*count_ptr).load();
930 if (points.GetLength() == 0) {
944 if (color_base_ptr) {
954 nb_block_masks_indexer,
955 nb_block_indices_indexer);
959 index_t curr_block_idx,
float* n) {
960 return DeviceGetNormal<tsdf_t>(
961 tsdf_base_ptr, xo, yo, zo, curr_block_idx, n, resolution,
962 nb_block_masks_indexer, nb_block_indices_indexer);
966 index_t workload_block_idx = workload_idx / resolution3;
968 index_t voxel_idx = workload_idx % resolution3;
980 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
982 index_t linear_idx = block_idx * resolution3 + voxel_idx;
983 float tsdf_o = tsdf_base_ptr[linear_idx];
984 float weight_o = weight_base_ptr[linear_idx];
985 if (weight_o <= weight_threshold)
return;
987 float no[3] = {0}, ne[3] = {0};
990 GetNormal(xv, yv, zv, workload_block_idx, no);
997 for (
index_t i = 0; i < 3; ++i) {
999 GetLinearIdx(xv + (i == 0), yv + (i == 1), zv + (i == 2),
1000 workload_block_idx);
1001 if (linear_idx_i < 0)
continue;
1003 float tsdf_i = tsdf_base_ptr[linear_idx_i];
1004 float weight_i = weight_base_ptr[linear_idx_i];
1005 if (weight_i > weight_threshold && tsdf_i * tsdf_o < 0) {
1006 float ratio = (0 - tsdf_o) / (tsdf_i - tsdf_o);
1009 if (idx >= valid_size) {
1010 printf(
"Point cloud size larger than " 1011 "estimated, please increase the " 1016 float* point_ptr = point_indexer.GetDataPtr<
float>(idx);
1017 point_ptr[0] = voxel_size * (x + ratio *
int(i == 0));
1018 point_ptr[1] = voxel_size * (y + ratio *
int(i == 1));
1019 point_ptr[2] = voxel_size * (z + ratio *
int(i == 2));
1022 float* normal_ptr = normal_indexer.
GetDataPtr<
float>(idx);
1023 GetNormal(xv + (i == 0), yv + (i == 1), zv + (i == 2),
1024 workload_block_idx, ne);
1025 float nx = (1 - ratio) * no[0] + ratio * ne[0];
1026 float ny = (1 - ratio) * no[1] + ratio * ne[1];
1027 float nz = (1 - ratio) * no[2] + ratio * ne[2];
1028 float norm =
static_cast<float>(
1029 sqrt(nx * nx + ny * ny + nz * nz) + 1e-5);
1030 normal_ptr[0] = nx / norm;
1031 normal_ptr[1] = ny / norm;
1032 normal_ptr[2] = nz / norm;
1034 if (color_base_ptr) {
1035 float* color_ptr = color_indexer.
GetDataPtr<
float>(idx);
1036 const color_t* color_o_ptr =
1037 color_base_ptr + 3 * linear_idx;
1038 float r_o = color_o_ptr[0];
1039 float g_o = color_o_ptr[1];
1040 float b_o = color_o_ptr[2];
1042 const color_t* color_i_ptr =
1043 color_base_ptr + 3 * linear_idx_i;
1044 float r_i = color_i_ptr[0];
1045 float g_i = color_i_ptr[1];
1046 float b_i = color_i_ptr[2];
1048 color_ptr[0] = ((1 - ratio) * r_o + ratio * r_i) / 255.0f;
1049 color_ptr[1] = ((1 - ratio) * g_o + ratio * g_i) / 255.0f;
1050 color_ptr[2] = ((1 - ratio) * b_o + ratio * b_i) / 255.0f;
1056 #if defined(__CUDACC__) 1059 index_t total_count = (*count_ptr).load();
1063 valid_size = total_count;
1065 #if defined(BUILD_CUDA_MODULE) && defined(__CUDACC__) 1070 template <
typename tsdf_t,
typename weight_t,
typename color_t>
1071 #if defined(__CUDACC__) 1072 void ExtractTriangleMeshCUDA
1088 float weight_threshold,
1092 index_t resolution = block_resolution;
1093 index_t resolution3 = resolution * resolution * resolution;
1096 ArrayIndexer voxel_indexer({resolution, resolution, resolution});
1105 {n_blocks, resolution, resolution, resolution, 4},
core::Int32,
1107 }
catch (
const std::runtime_error&) {
1109 "[MeshExtractionKernel] Unable to allocate assistance mesh " 1110 "structure for Marching " 1111 "Cubes with {} active voxel blocks. Please consider using a " 1112 "larger voxel size (currently {}) for TSDF " 1113 "integration, or using tsdf_volume.cpu() to perform mesh " 1114 "extraction on CPU.",
1115 n_blocks, voxel_size);
1119 ArrayIndexer mesh_structure_indexer(mesh_structure, 4);
1120 ArrayIndexer nb_block_masks_indexer(nb_block_masks, 2);
1121 ArrayIndexer nb_block_indices_indexer(nb_block_indices, 2);
1125 const index_t* inv_indices_ptr = inv_block_indices.GetDataPtr<
index_t>();
1127 if (!block_value_map.Contains(
"tsdf") ||
1128 !block_value_map.Contains(
"weight")) {
1130 "TSDF and/or weight not allocated in blocks, please implement " 1131 "customized integration.");
1133 const tsdf_t* tsdf_base_ptr =
1134 block_value_map.at(
"tsdf").GetDataPtr<tsdf_t>();
1135 const weight_t* weight_base_ptr =
1136 block_value_map.at(
"weight").GetDataPtr<weight_t>();
1137 const color_t* color_base_ptr =
nullptr;
1138 if (block_value_map.Contains(
"color")) {
1139 color_base_ptr = block_value_map.at(
"color").GetDataPtr<color_t>();
1142 index_t n = n_blocks * resolution3;
1151 static_cast<index_t>(resolution),
1152 nb_block_masks_indexer,
1153 nb_block_indices_indexer);
1157 index_t workload_block_idx = widx / resolution3;
1158 index_t voxel_idx = widx % resolution3;
1162 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
1167 for (
index_t i = 0; i < 8; ++i) {
1169 GetLinearIdx(xv + vtx_shifts[i][0], yv + vtx_shifts[i][1],
1170 zv + vtx_shifts[i][2], workload_block_idx);
1171 if (linear_idx_i < 0)
return;
1173 float tsdf_i = tsdf_base_ptr[linear_idx_i];
1174 float weight_i = weight_base_ptr[linear_idx_i];
1175 if (weight_i <= weight_threshold)
return;
1177 table_idx |= ((tsdf_i < 0) ? (1 << i) : 0);
1181 xv, yv, zv, workload_block_idx);
1182 mesh_struct_ptr[3] = table_idx;
1184 if (table_idx == 0 || table_idx == 255)
return;
1187 index_t edges_with_vertices = edge_table[table_idx];
1188 for (
index_t i = 0; i < 12; ++i) {
1189 if (edges_with_vertices & (1 << i)) {
1190 index_t xv_i = xv + edge_shifts[i][0];
1191 index_t yv_i = yv + edge_shifts[i][1];
1192 index_t zv_i = zv + edge_shifts[i][2];
1193 index_t edge_i = edge_shifts[i][3];
1195 index_t dxb = xv_i / resolution;
1196 index_t dyb = yv_i / resolution;
1197 index_t dzb = zv_i / resolution;
1199 index_t nb_idx = (dxb + 1) + (dyb + 1) * 3 + (dzb + 1) * 9;
1203 workload_block_idx, nb_idx);
1206 xv_i - dxb * resolution,
1207 yv_i - dyb * resolution,
1208 zv_i - dzb * resolution,
1209 inv_indices_ptr[block_idx_i]);
1212 mesh_ptr_i[edge_i] = -1;
1218 #if defined(__CUDACC__) 1223 std::atomic<index_t> count_atomic(0);
1224 std::atomic<index_t>* count_ptr = &count_atomic;
1227 if (vertex_count < 0) {
1230 index_t workload_block_idx = widx / resolution3;
1231 index_t voxel_idx = widx % resolution3;
1235 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
1240 xv, yv, zv, workload_block_idx);
1243 if (mesh_struct_ptr[0] != -1 && mesh_struct_ptr[1] != -1 &&
1244 mesh_struct_ptr[2] != -1) {
1249 for (
index_t e = 0; e < 3; ++e) {
1250 index_t vertex_idx = mesh_struct_ptr[e];
1251 if (vertex_idx != -1)
continue;
1257 #if defined(__CUDACC__) 1260 vertex_count = (*count_ptr).load();
1271 if (color_base_ptr) {
1279 #if defined(__CUDACC__) 1293 nb_block_masks_indexer,
1294 nb_block_indices_indexer);
1298 index_t curr_block_idx,
float* n) {
1299 return DeviceGetNormal<tsdf_t>(
1300 tsdf_base_ptr, xo, yo, zo, curr_block_idx, n, resolution,
1301 nb_block_masks_indexer, nb_block_indices_indexer);
1305 index_t workload_block_idx = widx / resolution3;
1307 index_t voxel_idx = widx % resolution3;
1312 index_t xb = block_key_ptr[0];
1313 index_t yb = block_key_ptr[1];
1314 index_t zb = block_key_ptr[2];
1318 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
1327 xv, yv, zv, workload_block_idx);
1330 if (mesh_struct_ptr[0] != -1 && mesh_struct_ptr[1] != -1 &&
1331 mesh_struct_ptr[2] != -1) {
1336 index_t linear_idx = resolution3 * block_idx + voxel_idx;
1337 float tsdf_o = tsdf_base_ptr[linear_idx];
1339 float no[3] = {0}, ne[3] = {0};
1342 GetNormal(xv, yv, zv, workload_block_idx, no);
1345 for (
index_t e = 0; e < 3; ++e) {
1346 index_t vertex_idx = mesh_struct_ptr[e];
1347 if (vertex_idx != -1)
continue;
1350 GetLinearIdx(xv + (e == 0), yv + (e == 1), zv + (e == 2),
1351 workload_block_idx);
1353 "Internal error: GetVoxelAt returns nullptr.");
1354 float tsdf_e = tsdf_base_ptr[linear_idx_e];
1355 float ratio = (0 - tsdf_o) / (tsdf_e - tsdf_o);
1358 mesh_struct_ptr[e] = idx;
1360 float ratio_x = ratio *
index_t(e == 0);
1361 float ratio_y = ratio *
index_t(e == 1);
1362 float ratio_z = ratio *
index_t(e == 2);
1364 float* vertex_ptr = vertex_indexer.
GetDataPtr<
float>(idx);
1365 vertex_ptr[0] = voxel_size * (x + ratio_x);
1366 vertex_ptr[1] = voxel_size * (y + ratio_y);
1367 vertex_ptr[2] = voxel_size * (z + ratio_z);
1370 float* normal_ptr = normal_indexer.GetDataPtr<
float>(idx);
1371 GetNormal(xv + (e == 0), yv + (e == 1), zv + (e == 2),
1372 workload_block_idx, ne);
1373 float nx = (1 - ratio) * no[0] + ratio * ne[0];
1374 float ny = (1 - ratio) * no[1] + ratio * ne[1];
1375 float nz = (1 - ratio) * no[2] + ratio * ne[2];
1376 float norm =
static_cast<float>(sqrt(nx * nx + ny * ny + nz * nz) +
1378 normal_ptr[0] = nx / norm;
1379 normal_ptr[1] = ny / norm;
1380 normal_ptr[2] = nz / norm;
1382 if (color_base_ptr) {
1383 float* color_ptr = color_indexer.
GetDataPtr<
float>(idx);
1384 float r_o = color_base_ptr[linear_idx * 3 + 0];
1385 float g_o = color_base_ptr[linear_idx * 3 + 1];
1386 float b_o = color_base_ptr[linear_idx * 3 + 2];
1388 float r_e = color_base_ptr[linear_idx_e * 3 + 0];
1389 float g_e = color_base_ptr[linear_idx_e * 3 + 1];
1390 float b_e = color_base_ptr[linear_idx_e * 3 + 2];
1392 color_ptr[0] = ((1 - ratio) * r_o + ratio * r_e) / 255.0f;
1393 color_ptr[1] = ((1 - ratio) * g_o + ratio * g_e) / 255.0f;
1394 color_ptr[2] = ((1 - ratio) * b_o + ratio * b_e) / 255.0f;
1400 index_t triangle_count = vertex_count * 3;
1404 #if defined(__CUDACC__) 1412 index_t workload_block_idx = widx / resolution3;
1413 index_t voxel_idx = widx % resolution3;
1417 voxel_indexer.WorkloadToCoord(voxel_idx, &xv, &yv, &zv);
1421 xv, yv, zv, workload_block_idx);
1423 index_t table_idx = mesh_struct_ptr[3];
1424 if (tri_count[table_idx] == 0)
return;
1426 for (
index_t tri = 0; tri < 16; tri += 3) {
1427 if (tri_table[table_idx][tri] == -1)
return;
1431 for (
index_t vertex = 0; vertex < 3; ++vertex) {
1432 index_t edge = tri_table[table_idx][tri + vertex];
1434 index_t xv_i = xv + edge_shifts[edge][0];
1435 index_t yv_i = yv + edge_shifts[edge][1];
1436 index_t zv_i = zv + edge_shifts[edge][2];
1437 index_t edge_i = edge_shifts[edge][3];
1439 index_t dxb = xv_i / resolution;
1440 index_t dyb = yv_i / resolution;
1441 index_t dzb = zv_i / resolution;
1443 index_t nb_idx = (dxb + 1) + (dyb + 1) * 3 + (dzb + 1) * 9;
1447 workload_block_idx, nb_idx);
1450 xv_i - dxb * resolution,
1451 yv_i - dyb * resolution,
1452 zv_i - dzb * resolution,
1453 inv_indices_ptr[block_idx_i]);
1456 triangle_indexer.GetDataPtr<
index_t>(tri_idx);
1457 triangle_ptr[2 - vertex] = mesh_struct_ptr_i[edge_i];
1462 #if defined(__CUDACC__) 1465 triangle_count = (*count_ptr).load();
1468 triangles = triangles.Slice(0, 0, triangle_count);
void RayCastCPU(std::shared_ptr< core::HashMap > &hashmap, const TensorMap &block_value_map, const core::Tensor &range_map, TensorMap &renderings_map, const core::Tensor &intrinsics, const core::Tensor &extrinsics, index_t h, index_t w, index_t block_resolution, float voxel_size, float sdf_trunc, float depth_scale, float depth_min, float depth_max, float weight_threshold)
Definition: VoxelBlockGridImpl.h:325
Definition: StdGPUHashBackend.h:134
Definition: GeometryIndexer.h:180
void IntegrateCPU(const core::Tensor &depth, const core::Tensor &color, const core::Tensor &block_indices, const core::Tensor &block_keys, TensorMap &block_value_map, const core::Tensor &intrinsics, const core::Tensor &extrinsics, index_t resolution, float voxel_size, float sdf_trunc, float depth_scale, float depth_max)
Definition: VoxelBlockGridImpl.h:168
TArrayIndexer< index_t > ArrayIndexer
Definition: VoxelBlockGridImpl.h:50
OPEN3D_DEVICE void DeviceGetNormal(const tsdf_t *tsdf_base_ptr, index_t xo, index_t yo, index_t zo, index_t curr_block_idx, float *n, index_t resolution, const ArrayIndexer &nb_block_masks_indexer, const ArrayIndexer &nb_block_indices_indexer)
Definition: VoxelBlockGridImpl.h:131
OPEN3D_HOST_DEVICE void * GetDataPtr() const
Definition: GeometryIndexer.h:335
OPEN3D_HOST_DEVICE int Sign(int x)
Definition: GeometryMacros.h:96
void ExtractTriangleMeshCPU(const core::Tensor &block_indices, const core::Tensor &inv_block_indices, const core::Tensor &nb_block_indices, const core::Tensor &nb_block_masks, const core::Tensor &block_keys, const TensorMap &block_value_map, core::Tensor &vertices, core::Tensor &triangles, core::Tensor &vertex_normals, core::Tensor &vertex_colors, index_t block_resolution, float voxel_size, float weight_threshold, index_t &vertex_count)
Definition: VoxelBlockGridImpl.h:1076
Definition: Dispatch.h:129
void OPEN3D_DEVICE Update(index_t xin, index_t yin, index_t zin, index_t block_idx_in)
Definition: VoxelBlockGridImpl.h:308
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition: ParallelFor.h:122
const Dtype Float32
Definition: Dtype.cpp:61
Device GetDevice() const
Definition: Tensor.cpp:1365
uint32_t buf_index_t
Definition: HashBackendBuffer.h:63
OPEN3D_DEVICE index_t DeviceGetLinearIdx(index_t xo, index_t yo, index_t zo, index_t curr_block_idx, index_t resolution, const ArrayIndexer &nb_block_masks_indexer, const ArrayIndexer &nb_block_indices_indexer)
Definition: VoxelBlockGridImpl.h:102
#define OPEN3D_DEVICE
Definition: CUDAUtils.h:64
void ExtractPointCloudCPU(const core::Tensor &block_indices, const core::Tensor &nb_block_indices, const core::Tensor &nb_block_masks, const core::Tensor &block_keys, const TensorMap &block_value_map, core::Tensor &points, core::Tensor &normals, core::Tensor &colors, index_t block_resolution, float voxel_size, float weight_threshold, index_t &valid_size)
Definition: VoxelBlockGridImpl.h:819
#define OPEN3D_ATOMIC_ADD(X, Y)
Definition: GeometryMacros.h:58
void Synchronize()
Definition: CUDAUtils.cpp:78
Definition: Dispatch.h:113
index_t OPEN3D_DEVICE Check(index_t xin, index_t yin, index_t zin)
Definition: VoxelBlockGridImpl.h:304
#define LogDebug(...)
Definition: Logging.h:103
math::float4 color
Definition: LineSetBuffers.cpp:64
core::Tensor InverseTransformation(const core::Tensor &T)
TODO(wei): find a proper place for such functionalities.
Definition: Utility.h:96
const Dtype Int32
Definition: Dtype.cpp:65
void GetVoxelCoordinatesAndFlattenedIndicesCPU(const core::Tensor &buf_indices, const core::Tensor &block_keys, core::Tensor &voxel_coords, core::Tensor &flattened_indices, index_t block_resolution, float voxel_size)
Definition: VoxelBlockGridImpl.h:57
Definition: TBBHashBackend.h:41
int index_t
Definition: VoxelBlockGrid.h:41
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c int
Definition: K4aPlugin.cpp:479
static Tensor Zeros(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor fill with zeros.
Definition: Tensor.cpp:380
Definition: VoxelBlockGridImpl.h:298
Definition: PinholeCameraIntrinsic.cpp:35
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle float
Definition: K4aPlugin.cpp:465
T * GetDataPtr()
Definition: Tensor.h:1074
#define OPEN3D_ASSERT(...)
Definition: Macro.h:67
index_t x
Definition: VoxelBlockGridImpl.h:299
index_t z
Definition: VoxelBlockGridImpl.h:301
index_t y
Definition: VoxelBlockGridImpl.h:300
int64_t GetLength() const
Definition: Tensor.h:1055
OPEN3D_HOST_DEVICE bool InBoundary(float x, float y) const
Definition: GeometryIndexer.h:314
index_t block_idx
Definition: VoxelBlockGridImpl.h:302
#define LogError(...)
Definition: Logging.h:72
Definition: TensorMap.h:49