31 namespace pointcloud {
40 #if defined(__CUDACC__)
46 std::optional<std::reference_wrapper<const core::Tensor>> image_colors,
48 std::optional<std::reference_wrapper<core::Tensor>> colors,
55 const bool have_colors = image_colors.has_value();
71 const auto& imcol = image_colors.value().get();
73 colors.value().get() =
core::Tensor({rows_strided * cols_strided, 3},
79 #if defined(__CUDACC__)
81 int* count_ptr =
count.GetDataPtr<
int>();
83 std::atomic<int> count_atomic(0);
84 std::atomic<int>* count_ptr = &count_atomic;
87 int64_t n = rows_strided * cols_strided;
91 depth.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
92 int64_t y = (workload_idx / cols_strided) * stride;
93 int64_t x = (workload_idx % cols_strided) * stride;
95 float d = *depth_indexer.GetDataPtr<scalar_t>(x, y) /
97 if (d > 0 && d < depth_max) {
98 int idx = OPEN3D_ATOMIC_ADD(count_ptr, 1);
100 float x_c = 0, y_c = 0, z_c = 0;
101 ti.Unproject(static_cast<float>(x),
102 static_cast<float>(y), d, &x_c, &y_c,
105 float* vertex = point_indexer.GetDataPtr<float>(idx);
106 ti.RigidTransform(x_c, y_c, z_c, vertex + 0, vertex + 1,
110 colors_indexer.GetDataPtr<float>(idx);
112 image_colors_indexer.GetDataPtr<float>(x,
114 *pcd_pixel = *image_pixel;
115 *(pcd_pixel + 1) = *(image_pixel + 1);
116 *(pcd_pixel + 2) = *(image_pixel + 2);
121 #if defined(__CUDACC__)
122 int total_pts_count =
count.Item<
int>();
124 int total_pts_count = (*count_ptr).load();
132 colors.value().get() =
133 colors.value().get().Slice(0, 0, total_pts_count);
137 #if defined(__CUDACC__)
138 void GetPointMaskWithinAABBCUDA
148 const scalar_t* points_ptr = points.GetDataPtr<scalar_t>();
149 const int64_t n = points.GetLength();
150 const scalar_t* min_bound_ptr = min_bound.GetDataPtr<scalar_t>();
151 const scalar_t* max_bound_ptr = max_bound.GetDataPtr<scalar_t>();
152 bool* mask_ptr = mask.GetDataPtr<bool>();
155 points.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
156 const scalar_t x = points_ptr[3 * workload_idx + 0];
157 const scalar_t y = points_ptr[3 * workload_idx + 1];
158 const scalar_t z = points_ptr[3 * workload_idx + 2];
160 if (x >= min_bound_ptr[0] && x <= max_bound_ptr[0] &&
161 y >= min_bound_ptr[1] && y <= max_bound_ptr[1] &&
162 z >= min_bound_ptr[2] && z <= max_bound_ptr[2]) {
163 mask_ptr[workload_idx] = true;
165 mask_ptr[workload_idx] = false;
171 #if defined(__CUDACC__)
172 void GetPointMaskWithinOBBCUDA
186 const int64_t n =
points.GetLength();
189 const scalar_t* pd_ptr = pd.GetDataPtr<scalar_t>();
191 const scalar_t* rotation_ptr = rotation_t.GetDataPtr<scalar_t>();
192 const scalar_t* half_extent_ptr = half_extent.GetDataPtr<scalar_t>();
193 bool* mask_ptr = mask.GetDataPtr<bool>();
195 core::ParallelFor(points.GetDevice(), n,
196 [=] OPEN3D_DEVICE(int64_t workload_idx) {
197 int64_t idx = 3 * workload_idx;
198 if (abs(core::linalg::kernel::dot_3x1(
199 pd_ptr + idx, rotation_ptr)) <=
200 half_extent_ptr[0] &&
201 abs(core::linalg::kernel::dot_3x1(
202 pd_ptr + idx, rotation_ptr + 3)) <=
203 half_extent_ptr[1] &&
204 abs(core::linalg::kernel::dot_3x1(
205 pd_ptr + idx, rotation_ptr + 6)) <=
206 half_extent_ptr[2]) {
207 mask_ptr[workload_idx] = true;
209 mask_ptr[workload_idx] = false;
215 #if defined(__CUDACC__)
216 void NormalizeNormalsCUDA
222 const int64_t n = normals.GetLength();
225 scalar_t* ptr = normals.GetDataPtr<scalar_t>();
229 int64_t idx = 3 * workload_idx;
230 scalar_t x = ptr[idx];
231 scalar_t y = ptr[idx + 1];
232 scalar_t z = ptr[idx + 2];
233 scalar_t norm = sqrt(x * x + y * y + z * z);
246 #if defined(__CUDACC__)
247 void OrientNormalsToAlignWithDirectionCUDA
253 const int64_t n = normals.GetLength();
256 scalar_t* ptr = normals.GetDataPtr<scalar_t>();
257 const scalar_t* direction_ptr = direction.GetDataPtr<scalar_t>();
261 int64_t idx = 3 * workload_idx;
262 scalar_t* normal = ptr + idx;
263 const scalar_t norm = sqrt(normal[0] * normal[0] +
264 normal[1] * normal[1] +
265 normal[2] * normal[2]);
267 normal[0] = direction_ptr[0];
268 normal[1] = direction_ptr[1];
269 normal[2] = direction_ptr[2];
271 normal, direction_ptr) < 0) {
280 #if defined(__CUDACC__)
281 void OrientNormalsTowardsCameraLocationCUDA
289 const int64_t n = normals.GetLength();
292 scalar_t* normals_ptr = normals.GetDataPtr<scalar_t>();
293 const scalar_t* camera_ptr = camera.GetDataPtr<scalar_t>();
294 const scalar_t* points_ptr =
points.GetDataPtr<scalar_t>();
297 normals.GetDevice(), n,
299 int64_t idx = 3 * workload_idx;
300 scalar_t* normal = normals_ptr + idx;
301 const scalar_t*
point = points_ptr + idx;
302 const scalar_t reference[3] = {camera_ptr[0] -
point[0],
303 camera_ptr[1] -
point[1],
304 camera_ptr[2] -
point[2]};
305 const scalar_t norm =
306 sqrt(normal[0] * normal[0] + normal[1] * normal[1] +
307 normal[2] * normal[2]);
309 normal[0] = reference[0];
310 normal[1] = reference[1];
311 normal[2] = reference[2];
312 const scalar_t norm_new = sqrt(normal[0] * normal[0] +
313 normal[1] * normal[1] +
314 normal[2] * normal[2]);
315 if (norm_new == 0.0) {
320 normal[0] /= norm_new;
321 normal[1] /= norm_new;
322 normal[2] /= norm_new;
334 template <
typename scalar_t>
343 if (!(abs(query[0] - query[2]) < 1e-6) ||
344 !(abs(query[1] - query[2]) < 1e-6)) {
345 const scalar_t norm2_inv =
346 1.0 / sqrt(query[0] * query[0] + query[1] * query[1]);
347 v[0] = -1 * query[1] * norm2_inv;
348 v[1] = query[0] * norm2_inv;
351 const scalar_t norm2_inv =
352 1.0 / sqrt(query[1] * query[1] + query[2] * query[2]);
354 v[1] = -1 * query[2] * norm2_inv;
355 v[2] = query[1] * norm2_inv;
361 template <
typename scalar_t>
368 template <
typename scalar_t>
371 int l = 2 * root + 1;
372 int r = 2 * root + 2;
374 if (l < n && arr[l] > arr[largest]) {
377 if (r < n && arr[r] > arr[largest]) {
380 if (largest != root) {
381 Swap<scalar_t>(&arr[root], &arr[largest]);
382 Heapify<scalar_t>(arr, n, largest);
386 template <
typename scalar_t>
388 for (
int i = n / 2 - 1; i >= 0; i--)
Heapify(arr, n, i);
390 for (
int i = n - 1; i > 0; i--) {
391 Swap<scalar_t>(&arr[0], &arr[i]);
392 Heapify<scalar_t>(arr, i, 0);
396 template <
typename scalar_t>
399 double angle_threshold) {
401 scalar_t max_diff = 0;
403 for (
int i = 0; i < counts - 1; i++) {
404 diff = angles[i + 1] - angles[i];
405 max_diff = max(max_diff, diff);
409 diff = 2 * M_PI - angles[counts - 1] + angles[0];
410 max_diff = max(max_diff, diff);
412 return max_diff > angle_threshold * M_PI / 180.0 ? true :
false;
415 #if defined(__CUDACC__)
416 void ComputeBoundaryPointsCUDA
425 double angle_threshold) {
426 const int nn_size = indices.GetShape()[1];
429 const scalar_t* points_ptr = points.GetDataPtr<scalar_t>();
430 const scalar_t* normals_ptr = normals.GetDataPtr<scalar_t>();
431 const int64_t n = points.GetLength();
432 const int32_t* indices_ptr = indices.GetDataPtr<int32_t>();
433 const int32_t* counts_ptr = counts.GetDataPtr<int32_t>();
434 bool* mask_ptr = mask.GetDataPtr<bool>();
436 core::Tensor angles = core::Tensor::Full(
437 indices.GetShape(), -10, points.GetDtype(), points.GetDevice());
438 scalar_t* angles_ptr = angles.GetDataPtr<scalar_t>();
441 points.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
443 GetCoordinateSystemOnPlane(normals_ptr + 3 * workload_idx,
447 int indices_size = counts_ptr[workload_idx] - 1;
448 if (indices_size > 0) {
449 const scalar_t* query = points_ptr + 3 * workload_idx;
450 for (int i = 1; i < indices_size + 1; i++) {
451 const int idx = workload_idx * nn_size + i;
453 const scalar_t* point_ref =
454 points_ptr + 3 * indices_ptr[idx];
455 const scalar_t delta[3] = {point_ref[0] - query[0],
456 point_ref[1] - query[1],
457 point_ref[2] - query[2]};
458 const scalar_t angle = atan2(
459 core::linalg::kernel::dot_3x1(v, delta),
460 core::linalg::kernel::dot_3x1(u, delta));
462 angles_ptr[idx] = angle;
467 angles_ptr + workload_idx * nn_size + 1,
470 mask_ptr[workload_idx] = IsBoundaryPoints<scalar_t>(
471 angles_ptr + workload_idx * nn_size + 1,
472 indices_size, angle_threshold);
480 template <
typename scalar_t>
482 const scalar_t* points_ptr,
485 scalar_t* covariance_ptr) {
486 if (indices_count < 3) {
487 covariance_ptr[0] = 1.0;
488 covariance_ptr[1] = 0.0;
489 covariance_ptr[2] = 0.0;
490 covariance_ptr[3] = 0.0;
491 covariance_ptr[4] = 1.0;
492 covariance_ptr[5] = 0.0;
493 covariance_ptr[6] = 0.0;
494 covariance_ptr[7] = 0.0;
495 covariance_ptr[8] = 1.0;
499 double centroid[3] = {0};
500 for (
int32_t i = 0; i < indices_count; ++i) {
501 int32_t idx = 3 * indices_ptr[i];
502 centroid[0] += points_ptr[idx];
503 centroid[1] += points_ptr[idx + 1];
504 centroid[2] += points_ptr[idx + 2];
507 centroid[0] /= indices_count;
508 centroid[1] /= indices_count;
509 centroid[2] /= indices_count;
512 double cumulants[6] = {0};
513 for (
int32_t i = 0; i < indices_count; ++i) {
514 int32_t idx = 3 * indices_ptr[i];
515 const double x =
static_cast<double>(points_ptr[idx]) - centroid[0];
516 const double y =
static_cast<double>(points_ptr[idx + 1]) - centroid[1];
517 const double z =
static_cast<double>(points_ptr[idx + 2]) - centroid[2];
519 cumulants[0] += x * x;
520 cumulants[1] += y * y;
521 cumulants[2] += z * z;
523 cumulants[3] += x * y;
524 cumulants[4] += x * z;
525 cumulants[5] += y * z;
531 const double normalization_factor =
static_cast<double>(indices_count - 1);
532 for (
int i = 0; i < 6; ++i) {
533 cumulants[i] /= normalization_factor;
537 covariance_ptr[0] =
static_cast<scalar_t
>(cumulants[0]);
539 covariance_ptr[4] =
static_cast<scalar_t
>(cumulants[1]);
541 covariance_ptr[8] =
static_cast<scalar_t
>(cumulants[2]);
544 covariance_ptr[1] =
static_cast<scalar_t
>(cumulants[3]);
545 covariance_ptr[3] = covariance_ptr[1];
548 covariance_ptr[2] =
static_cast<scalar_t
>(cumulants[4]);
549 covariance_ptr[6] = covariance_ptr[2];
552 covariance_ptr[5] =
static_cast<scalar_t
>(cumulants[5]);
553 covariance_ptr[7] = covariance_ptr[5];
556 #if defined(__CUDACC__)
557 void EstimateCovariancesUsingHybridSearchCUDA
563 const double& radius,
564 const int64_t& max_nn) {
566 int64_t n =
points.GetLength();
569 bool check =
tree.HybridIndex(radius);
575 std::tie(indices, distance, counts) =
579 const scalar_t* points_ptr =
points.GetDataPtr<scalar_t>();
582 scalar_t* covariances_ptr = covariances.GetDataPtr<scalar_t>();
587 const int32_t neighbour_offset = max_nn * workload_idx;
589 const int32_t neighbour_count =
590 neighbour_counts_ptr[workload_idx];
593 const int32_t covariances_offset = 9 * workload_idx;
597 neighbour_indices_ptr + neighbour_offset,
599 covariances_ptr + covariances_offset);
606 #if defined(__CUDACC__)
607 void EstimateCovariancesUsingRadiusSearchCUDA
613 const double& radius) {
615 int64_t n =
points.GetLength();
618 bool check =
tree.FixedRadiusIndex(radius);
624 std::tie(indices, distance, counts) =
628 const scalar_t* points_ptr =
points.GetDataPtr<scalar_t>();
631 scalar_t* covariances_ptr = covariances.GetDataPtr<scalar_t>();
635 const int32_t neighbour_offset =
636 neighbour_counts_ptr[workload_idx];
637 const int32_t neighbour_count =
638 (neighbour_counts_ptr[workload_idx + 1] -
639 neighbour_counts_ptr[workload_idx]);
642 const int32_t covariances_offset = 9 * workload_idx;
646 neighbour_indices_ptr + neighbour_offset,
648 covariances_ptr + covariances_offset);
655 #if defined(__CUDACC__)
656 void EstimateCovariancesUsingKNNSearchCUDA
662 const int64_t& max_nn) {
664 int64_t n =
points.GetLength();
667 bool check =
tree.KnnIndex();
673 std::tie(indices, distance) =
tree.KnnSearch(
points, max_nn);
680 "Not enough neighbors to compute Covariances / Normals. "
682 "increasing the max_nn parameter.");
686 auto points_ptr =
points.GetDataPtr<scalar_t>();
688 auto covariances_ptr = covariances.GetDataPtr<scalar_t>();
693 const int32_t neighbour_offset = nn_count * workload_idx;
696 const int32_t covariances_offset = 9 * workload_idx;
700 neighbour_indices_ptr + neighbour_offset, nn_count,
701 covariances_ptr + covariances_offset);
708 template <
typename scalar_t>
710 const scalar_t eval0,
711 scalar_t* eigen_vector0) {
712 scalar_t row0[3] = {A[0] - eval0, A[1], A[2]};
713 scalar_t row1[3] = {A[1], A[4] - eval0, A[5]};
714 scalar_t row2[3] = {A[2], A[5], A[8] - eval0};
716 scalar_t r0xr1[3], r0xr2[3], r1xr2[3];
737 scalar_t sqrt_d = sqrt(d0);
738 eigen_vector0[0] = r0xr1[0] / sqrt_d;
739 eigen_vector0[1] = r0xr1[1] / sqrt_d;
740 eigen_vector0[2] = r0xr1[2] / sqrt_d;
742 }
else if (imax == 1) {
743 scalar_t sqrt_d = sqrt(d1);
744 eigen_vector0[0] = r0xr2[0] / sqrt_d;
745 eigen_vector0[1] = r0xr2[1] / sqrt_d;
746 eigen_vector0[2] = r0xr2[2] / sqrt_d;
749 scalar_t sqrt_d = sqrt(d2);
750 eigen_vector0[0] = r1xr2[0] / sqrt_d;
751 eigen_vector0[1] = r1xr2[1] / sqrt_d;
752 eigen_vector0[2] = r1xr2[2] / sqrt_d;
757 template <
typename scalar_t>
759 const scalar_t* evec0,
760 const scalar_t eval1,
761 scalar_t* eigen_vector1) {
763 if (abs(evec0[0]) > abs(evec0[1])) {
764 scalar_t inv_length =
765 1.0 / sqrt(evec0[0] * evec0[0] + evec0[2] * evec0[2]);
766 U[0] = -evec0[2] * inv_length;
768 U[2] = evec0[0] * inv_length;
770 scalar_t inv_length =
771 1.0 / sqrt(evec0[1] * evec0[1] + evec0[2] * evec0[2]);
773 U[1] = evec0[2] * inv_length;
774 U[2] = -evec0[1] * inv_length;
776 scalar_t V[3], AU[3], AV[3];
778 core::linalg::kernel::matmul3x3_3x1(A, U, AU);
779 core::linalg::kernel::matmul3x3_3x1(A, V, AV);
785 scalar_t absM00 = abs(m00);
786 scalar_t absM01 = abs(m01);
787 scalar_t absM11 = abs(m11);
788 scalar_t max_abs_comp;
790 if (absM00 >= absM11) {
791 max_abs_comp = max(absM00, absM01);
792 if (max_abs_comp > 0) {
793 if (absM00 >= absM01) {
795 m00 = 1 / sqrt(1 + m01 * m01);
799 m01 = 1 / sqrt(1 + m00 * m00);
802 eigen_vector1[0] = m01 * U[0] - m00 * V[0];
803 eigen_vector1[1] = m01 * U[1] - m00 * V[1];
804 eigen_vector1[2] = m01 * U[2] - m00 * V[2];
807 eigen_vector1[0] = U[0];
808 eigen_vector1[1] = U[1];
809 eigen_vector1[2] = U[2];
813 max_abs_comp = max(absM11, absM01);
814 if (max_abs_comp > 0) {
815 if (absM11 >= absM01) {
817 m11 = 1 / sqrt(1 + m01 * m01);
821 m01 = 1 / sqrt(1 + m11 * m11);
824 eigen_vector1[0] = m11 * U[0] - m01 * V[0];
825 eigen_vector1[1] = m11 * U[1] - m01 * V[1];
826 eigen_vector1[2] = m11 * U[2] - m01 * V[2];
829 eigen_vector1[0] = U[0];
830 eigen_vector1[1] = U[1];
831 eigen_vector1[2] = U[2];
837 template <
typename scalar_t>
839 const scalar_t* covariance_ptr, scalar_t* normals_ptr) {
843 scalar_t max_coeff = covariance_ptr[0];
845 for (
int i = 1; i < 9; ++i) {
846 if (max_coeff < covariance_ptr[i]) {
847 max_coeff = covariance_ptr[i];
851 if (max_coeff == 0) {
852 normals_ptr[0] = 0.0;
853 normals_ptr[1] = 0.0;
854 normals_ptr[2] = 0.0;
860 for (
int i = 0; i < 9; ++i) {
861 A[i] = covariance_ptr[i] / max_coeff;
864 scalar_t norm = A[1] * A[1] + A[2] * A[2] + A[5] * A[5];
872 scalar_t q = (A[0] + A[4] + A[8]) / 3.0;
874 scalar_t b00 = A[0] - q;
875 scalar_t b11 = A[4] - q;
876 scalar_t b22 = A[8] - q;
879 sqrt((b00 * b00 + b11 * b11 + b22 * b22 + norm * 2.0) / 6.0);
881 scalar_t c00 = b11 * b22 - A[5] * A[5];
882 scalar_t c01 = A[1] * b22 - A[5] * A[2];
883 scalar_t c02 = A[1] * A[5] - b11 * A[2];
884 scalar_t det = (b00 * c00 - A[1] * c01 + A[2] * c02) / (p * p * p);
886 scalar_t half_det = det * 0.5;
887 half_det = min(max(half_det,
static_cast<scalar_t
>(-1.0)),
888 static_cast<scalar_t
>(1.0));
890 scalar_t angle = acos(half_det) / 3.0;
891 const scalar_t two_thrids_pi = 2.09439510239319549;
893 scalar_t beta2 = cos(angle) * 2.0;
894 scalar_t beta0 = cos(angle + two_thrids_pi) * 2.0;
895 scalar_t beta1 = -(beta0 + beta2);
897 eval[0] = q + p * beta0;
898 eval[1] = q + p * beta1;
899 eval[2] = q + p * beta2;
902 ComputeEigenvector0<scalar_t>(A, eval[2], evec2);
904 if (eval[2] < eval[0] && eval[2] < eval[1]) {
905 normals_ptr[0] = evec2[0];
906 normals_ptr[1] = evec2[1];
907 normals_ptr[2] = evec2[2];
912 ComputeEigenvector1<scalar_t>(A, evec2, eval[1], evec1);
914 if (eval[1] < eval[0] && eval[1] < eval[2]) {
915 normals_ptr[0] = evec1[0];
916 normals_ptr[1] = evec1[1];
917 normals_ptr[2] = evec1[2];
922 normals_ptr[0] = evec1[1] * evec2[2] - evec1[2] * evec2[1];
923 normals_ptr[1] = evec1[2] * evec2[0] - evec1[0] * evec2[2];
924 normals_ptr[2] = evec1[0] * evec2[1] - evec1[1] * evec2[0];
928 ComputeEigenvector0<scalar_t>(A, eval[0], evec0);
930 if (eval[0] < eval[1] && eval[0] < eval[2]) {
931 normals_ptr[0] = evec0[0];
932 normals_ptr[1] = evec0[1];
933 normals_ptr[2] = evec0[2];
937 ComputeEigenvector1<scalar_t>(A, evec0, eval[1], evec1);
939 if (eval[1] < eval[0] && eval[1] < eval[2]) {
940 normals_ptr[0] = evec1[0];
941 normals_ptr[1] = evec1[1];
942 normals_ptr[2] = evec1[2];
946 normals_ptr[0] = evec0[1] * evec1[2] - evec0[2] * evec1[1];
947 normals_ptr[1] = evec0[2] * evec1[0] - evec0[0] * evec1[2];
948 normals_ptr[2] = evec0[0] * evec1[1] - evec0[1] * evec1[0];
952 if (covariance_ptr[0] < covariance_ptr[4] &&
953 covariance_ptr[0] < covariance_ptr[8]) {
954 normals_ptr[0] = 1.0;
955 normals_ptr[1] = 0.0;
956 normals_ptr[2] = 0.0;
958 }
else if (covariance_ptr[4] < covariance_ptr[0] &&
959 covariance_ptr[4] < covariance_ptr[8]) {
960 normals_ptr[0] = 0.0;
961 normals_ptr[1] = 1.0;
962 normals_ptr[2] = 0.0;
965 normals_ptr[0] = 0.0;
966 normals_ptr[1] = 0.0;
967 normals_ptr[2] = 1.0;
973 #if defined(__CUDACC__)
974 void EstimateNormalsFromCovariancesCUDA
982 int64_t n = covariances.GetLength();
985 const scalar_t* covariances_ptr = covariances.GetDataPtr<scalar_t>();
986 scalar_t* normals_ptr = normals.GetDataPtr<scalar_t>();
989 covariances.GetDevice(), n,
991 int32_t covariances_offset = 9 * workload_idx;
992 int32_t normals_offset = 3 * workload_idx;
993 scalar_t normals_output[3] = {0};
994 EstimatePointWiseNormalsWithFastEigen3x3<scalar_t>(
995 covariances_ptr + covariances_offset,
998 if ((normals_output[0] * normals_output[0] +
999 normals_output[1] * normals_output[1] +
1000 normals_output[2] * normals_output[2]) == 0.0 &&
1002 normals_output[0] = 0.0;
1003 normals_output[1] = 0.0;
1004 normals_output[2] = 1.0;
1007 if ((normals_ptr[normals_offset] * normals_output[0] +
1008 normals_ptr[normals_offset + 1] *
1010 normals_ptr[normals_offset + 2] *
1011 normals_output[2]) < 0.0) {
1012 normals_output[0] *= -1;
1013 normals_output[1] *= -1;
1014 normals_output[2] *= -1;
1018 normals_ptr[normals_offset] = normals_output[0];
1019 normals_ptr[normals_offset + 1] = normals_output[1];
1020 normals_ptr[normals_offset + 2] = normals_output[2];
1027 template <
typename scalar_t>
1029 const scalar_t* points_ptr,
1030 const scalar_t* normals_ptr,
1031 const scalar_t* colors_ptr,
1035 scalar_t* color_gradients_ptr) {
1036 if (indices_count < 4) {
1037 color_gradients_ptr[idx_offset] = 0;
1038 color_gradients_ptr[idx_offset + 1] = 0;
1039 color_gradients_ptr[idx_offset + 2] = 0;
1041 scalar_t vt[3] = {points_ptr[idx_offset], points_ptr[idx_offset + 1],
1042 points_ptr[idx_offset + 2]};
1044 scalar_t nt[3] = {normals_ptr[idx_offset], normals_ptr[idx_offset + 1],
1045 normals_ptr[idx_offset + 2]};
1047 scalar_t it = (colors_ptr[idx_offset] + colors_ptr[idx_offset + 1] +
1048 colors_ptr[idx_offset + 2]) /
1051 scalar_t AtA[9] = {0};
1052 scalar_t Atb[3] = {0};
1062 scalar_t s = vt[0] * nt[0] + vt[1] * nt[1] + vt[2] * nt[2];
1065 for (; i < indices_count; i++) {
1066 int64_t neighbour_idx_offset = 3 * indices_ptr[i];
1068 if (neighbour_idx_offset == -1) {
1072 scalar_t vt_adj[3] = {points_ptr[neighbour_idx_offset],
1073 points_ptr[neighbour_idx_offset + 1],
1074 points_ptr[neighbour_idx_offset + 2]};
1078 scalar_t d = vt_adj[0] * nt[0] + vt_adj[1] * nt[1] +
1079 vt_adj[2] * nt[2] - s;
1082 scalar_t vt_proj[3] = {vt_adj[0] - d * nt[0], vt_adj[1] - d * nt[1],
1083 vt_adj[2] - d * nt[2]};
1085 scalar_t it_adj = (colors_ptr[neighbour_idx_offset + 0] +
1086 colors_ptr[neighbour_idx_offset + 1] +
1087 colors_ptr[neighbour_idx_offset + 2]) /
1090 scalar_t A[3] = {vt_proj[0] - vt[0], vt_proj[1] - vt[1],
1091 vt_proj[2] - vt[2]};
1093 AtA[0] += A[0] * A[0];
1094 AtA[1] += A[1] * A[0];
1095 AtA[2] += A[2] * A[0];
1096 AtA[4] += A[1] * A[1];
1097 AtA[5] += A[2] * A[1];
1098 AtA[8] += A[2] * A[2];
1100 scalar_t b = it_adj - it;
1108 scalar_t A[3] = {(i - 1) * nt[0], (i - 1) * nt[1], (i - 1) * nt[2]};
1110 AtA[0] += A[0] * A[0];
1111 AtA[1] += A[0] * A[1];
1112 AtA[2] += A[0] * A[2];
1113 AtA[4] += A[1] * A[1];
1114 AtA[5] += A[1] * A[2];
1115 AtA[8] += A[2] * A[2];
1123 color_gradients_ptr + idx_offset);
1127 #if defined(__CUDACC__)
1128 void EstimateColorGradientsUsingHybridSearchCUDA
1136 const double& radius,
1137 const int64_t& max_nn) {
1139 int64_t n =
points.GetLength();
1143 bool check =
tree.HybridIndex(radius);
1149 std::tie(indices, distance, counts) =
1153 auto points_ptr =
points.GetDataPtr<scalar_t>();
1154 auto normals_ptr = normals.GetDataPtr<scalar_t>();
1155 auto colors_ptr = colors.GetDataPtr<scalar_t>();
1158 auto color_gradients_ptr = color_gradients.GetDataPtr<scalar_t>();
1163 int32_t neighbour_offset = max_nn * workload_idx;
1166 neighbour_counts_ptr[workload_idx];
1167 int32_t idx_offset = 3 * workload_idx;
1170 points_ptr, normals_ptr, colors_ptr, idx_offset,
1171 neighbour_indices_ptr + neighbour_offset,
1172 neighbour_count, color_gradients_ptr);
1179 #if defined(__CUDACC__)
1180 void EstimateColorGradientsUsingKNNSearchCUDA
1188 const int64_t& max_nn) {
1190 int64_t n =
points.GetLength();
1194 bool check =
tree.KnnIndex();
1200 std::tie(indices, distance) =
tree.KnnSearch(
points, max_nn);
1203 int64_t nn_count = indices.
GetShape()[1];
1207 "Not enough neighbors to compute Covariances / Normals. "
1209 "changing the search parameter.");
1213 auto points_ptr =
points.GetDataPtr<scalar_t>();
1214 auto normals_ptr = normals.GetDataPtr<scalar_t>();
1215 auto colors_ptr = colors.GetDataPtr<scalar_t>();
1217 auto color_gradients_ptr = color_gradients.GetDataPtr<scalar_t>();
1221 int32_t neighbour_offset = max_nn * workload_idx;
1222 int32_t idx_offset = 3 * workload_idx;
1225 points_ptr, normals_ptr, colors_ptr, idx_offset,
1226 neighbour_indices_ptr + neighbour_offset, nn_count,
1227 color_gradients_ptr);
1234 #if defined(__CUDACC__)
1235 void EstimateColorGradientsUsingRadiusSearchCUDA
1243 const double& radius) {
1245 int64_t n =
points.GetLength();
1249 bool check =
tree.FixedRadiusIndex(radius);
1255 std::tie(indices, distance, counts) =
1262 auto points_ptr =
points.GetDataPtr<scalar_t>();
1263 auto normals_ptr = normals.GetDataPtr<scalar_t>();
1264 auto colors_ptr = colors.GetDataPtr<scalar_t>();
1267 auto color_gradients_ptr = color_gradients.GetDataPtr<scalar_t>();
1272 neighbour_counts_ptr[workload_idx];
1274 const int32_t neighbour_count =
1275 (neighbour_counts_ptr[workload_idx + 1] -
1276 neighbour_counts_ptr[workload_idx]);
1277 int32_t idx_offset = 3 * workload_idx;
1280 points_ptr, normals_ptr, colors_ptr, idx_offset,
1281 neighbour_indices_ptr + neighbour_offset,
1282 neighbour_count, color_gradients_ptr);
#define OPEN3D_HOST_DEVICE
Definition: CUDAUtils.h:43
#define OPEN3D_DEVICE
Definition: CUDAUtils.h:44
#define DISPATCH_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition: Dispatch.h:30
#define DISPATCH_FLOAT_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition: Dispatch.h:77
#define LogError(...)
Definition: Logging.h:51
double t
Definition: SurfaceReconstructionPoisson.cpp:172
Point< Real, 3 > point
Definition: SurfaceReconstructionPoisson.cpp:163
FEMTree< Dim, Real > & tree
Definition: SurfaceReconstructionPoisson.cpp:171
size_t stride
Definition: TriangleMeshBuffers.cpp:165
T * GetDataPtr()
Definition: Tensor.h:1143
SizeVector GetShape() const
Definition: Tensor.h:1126
Tensor Div(const Tensor &value) const
Divides a tensor and returns the resulting tensor.
Definition: Tensor.cpp:1204
Tensor Contiguous() const
Definition: Tensor.cpp:771
Tensor Transpose(int64_t dim0, int64_t dim1) const
Transpose a Tensor by swapping dimension dim0 and dim1.
Definition: Tensor.cpp:1067
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:738
A Class for nearest neighbor search.
Definition: NearestNeighborSearch.h:25
Definition: GeometryIndexer.h:161
OPEN3D_HOST_DEVICE index_t GetShape(int i) const
Definition: GeometryIndexer.h:311
void Synchronize()
Definition: CUDAUtils.cpp:58
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE void cross_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input, scalar_t *C_3x1_output)
Definition: Matrix.h:63
OPEN3D_DEVICE OPEN3D_FORCE_INLINE void solve_svd3x3(const scalar_t *A_3x3, const scalar_t *B_3x1, scalar_t *X_3x1)
Definition: SVD3x3.h:2171
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE scalar_t dot_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition: Matrix.h:89
const Dtype Int32
Definition: Dtype.cpp:46
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition: ParallelFor.h:108
const Dtype Float32
Definition: Dtype.cpp:42
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 int32_t
Definition: K4aPlugin.cpp:395
void EstimateCovariancesUsingHybridSearchCPU(const core::Tensor &points, core::Tensor &covariances, const double &radius, const int64_t &max_nn)
Definition: PointCloudImpl.h:561
void EstimateCovariancesUsingRadiusSearchCPU(const core::Tensor &points, core::Tensor &covariances, const double &radius)
Definition: PointCloudImpl.h:611
OPEN3D_HOST_DEVICE void GetCoordinateSystemOnPlane(const scalar_t *query, scalar_t *u, scalar_t *v)
Definition: PointCloudImpl.h:335
void EstimateNormalsFromCovariancesCPU(const core::Tensor &covariances, core::Tensor &normals, const bool has_normals)
Definition: PointCloudImpl.h:978
OPEN3D_HOST_DEVICE void ComputeEigenvector0(const scalar_t *A, const scalar_t eval0, scalar_t *eigen_vector0)
Definition: PointCloudImpl.h:709
void OrientNormalsTowardsCameraLocationCPU(const core::Tensor &points, core::Tensor &normals, const core::Tensor &camera)
Definition: PointCloudImpl.h:285
void UnprojectCPU(const core::Tensor &depth, std::optional< std::reference_wrapper< const core::Tensor >> image_colors, core::Tensor &points, std::optional< std::reference_wrapper< core::Tensor >> colors, const core::Tensor &intrinsics, const core::Tensor &extrinsics, float depth_scale, float depth_max, int64_t stride)
Definition: PointCloudImpl.h:45
OPEN3D_HOST_DEVICE void EstimatePointWiseRobustNormalizedCovarianceKernel(const scalar_t *points_ptr, const int32_t *indices_ptr, const int32_t &indices_count, scalar_t *covariance_ptr)
Definition: PointCloudImpl.h:481
void GetPointMaskWithinAABBCPU(const core::Tensor &points, const core::Tensor &min_bound, const core::Tensor &max_bound, core::Tensor &mask)
Definition: PointCloudImpl.h:142
OPEN3D_HOST_DEVICE void Swap(scalar_t *x, scalar_t *y)
Definition: PointCloudImpl.h:362
OPEN3D_HOST_DEVICE bool IsBoundaryPoints(const scalar_t *angles, int counts, double angle_threshold)
Definition: PointCloudImpl.h:397
void ComputeBoundaryPointsCPU(const core::Tensor &points, const core::Tensor &normals, const core::Tensor &indices, const core::Tensor &counts, core::Tensor &mask, double angle_threshold)
Definition: PointCloudImpl.h:420
void EstimateColorGradientsUsingKNNSearchCPU(const core::Tensor &points, const core::Tensor &normals, const core::Tensor &colors, core::Tensor &color_gradient, const int64_t &max_nn)
Definition: PointCloudImpl.h:1184
void NormalizeNormalsCPU(core::Tensor &normals)
Definition: PointCloudImpl.h:220
OPEN3D_HOST_DEVICE void ComputeEigenvector1(const scalar_t *A, const scalar_t *evec0, const scalar_t eval1, scalar_t *eigen_vector1)
Definition: PointCloudImpl.h:758
OPEN3D_HOST_DEVICE void EstimatePointWiseColorGradientKernel(const scalar_t *points_ptr, const scalar_t *normals_ptr, const scalar_t *colors_ptr, const int32_t &idx_offset, const int32_t *indices_ptr, const int32_t &indices_count, scalar_t *color_gradients_ptr)
Definition: PointCloudImpl.h:1028
void EstimateColorGradientsUsingRadiusSearchCPU(const core::Tensor &points, const core::Tensor &normals, const core::Tensor &colors, core::Tensor &color_gradient, const double &radius)
Definition: PointCloudImpl.h:1239
void GetPointMaskWithinOBBCPU(const core::Tensor &points, const core::Tensor ¢er, const core::Tensor &rotation, const core::Tensor &extent, core::Tensor &mask)
Definition: PointCloudImpl.h:176
void EstimateColorGradientsUsingHybridSearchCPU(const core::Tensor &points, const core::Tensor &normals, const core::Tensor &colors, core::Tensor &color_gradient, const double &radius, const int64_t &max_nn)
Definition: PointCloudImpl.h:1132
OPEN3D_HOST_DEVICE void EstimatePointWiseNormalsWithFastEigen3x3(const scalar_t *covariance_ptr, scalar_t *normals_ptr)
Definition: PointCloudImpl.h:838
OPEN3D_HOST_DEVICE void Heapify(scalar_t *arr, int n, int root)
Definition: PointCloudImpl.h:369
void OrientNormalsToAlignWithDirectionCPU(core::Tensor &normals, const core::Tensor &direction)
Definition: PointCloudImpl.h:251
void EstimateCovariancesUsingKNNSearchCPU(const core::Tensor &points, core::Tensor &covariances, const int64_t &max_nn)
Definition: PointCloudImpl.h:660
OPEN3D_HOST_DEVICE void HeapSort(scalar_t *arr, int n)
Definition: PointCloudImpl.h:387
TArrayIndexer< int64_t > NDArrayIndexer
Definition: GeometryIndexer.h:360
core::Tensor InverseTransformation(const core::Tensor &T)
TODO(wei): find a proper place for such functionalities.
Definition: Utility.h:77
Definition: PinholeCameraIntrinsic.cpp:16