Open3D (C++ API)  0.18.0
TriangleMeshImpl.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2023 www.open3d.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 #include "open3d/core/Dispatch.h"
10 #include "open3d/core/Dtype.h"
12 #include "open3d/core/Tensor.h"
16 #include "open3d/utility/Logging.h"
17 
18 namespace open3d {
19 namespace t {
20 namespace geometry {
21 namespace kernel {
22 namespace trianglemesh {
23 
24 #ifndef __CUDACC__
25 using std::isnan;
26 #endif
27 
28 #if defined(__CUDACC__)
29 void NormalizeNormalsCUDA
30 #else
32 #endif
33  (core::Tensor& normals) {
34  const core::Dtype dtype = normals.GetDtype();
35  const int64_t n = normals.GetLength();
36 
38  scalar_t* ptr = normals.GetDataPtr<scalar_t>();
39 
40  core::ParallelFor(normals.GetDevice(), n,
41  [=] OPEN3D_DEVICE(int64_t workload_idx) {
42  int64_t idx = 3 * workload_idx;
43  scalar_t x = ptr[idx];
44  scalar_t y = ptr[idx + 1];
45  scalar_t z = ptr[idx + 2];
46  if (isnan(x)) {
47  x = 0.0;
48  y = 0.0;
49  z = 1.0;
50  } else {
51  scalar_t norm = sqrt(x * x + y * y + z * z);
52  if (norm > 0) {
53  x /= norm;
54  y /= norm;
55  z /= norm;
56  }
57  ptr[idx] = x;
58  ptr[idx + 1] = y;
59  ptr[idx + 2] = z;
60  }
61  });
62  });
63 }
64 
65 #if defined(__CUDACC__)
66 void ComputeTriangleNormalsCUDA
67 #else
69 #endif
70  (const core::Tensor& vertices,
71  const core::Tensor& triangles,
72  core::Tensor& normals) {
73  const core::Dtype dtype = normals.GetDtype();
74  const int64_t n = normals.GetLength();
75  const core::Tensor triangles_d = triangles.To(core::Int64);
76 
78  scalar_t* normal_ptr = normals.GetDataPtr<scalar_t>();
79  const int64_t* triangle_ptr = triangles_d.GetDataPtr<int64_t>();
80  const scalar_t* vertex_ptr = vertices.GetDataPtr<scalar_t>();
81 
82  core::ParallelFor(normals.GetDevice(), n,
83  [=] OPEN3D_DEVICE(int64_t workload_idx) {
84  int64_t idx = 3 * workload_idx;
85 
86  int64_t triangle_id1 = triangle_ptr[idx];
87  int64_t triangle_id2 = triangle_ptr[idx + 1];
88  int64_t triangle_id3 = triangle_ptr[idx + 2];
89 
90  scalar_t v01[3], v02[3];
91  v01[0] = vertex_ptr[3 * triangle_id2] -
92  vertex_ptr[3 * triangle_id1];
93  v01[1] = vertex_ptr[3 * triangle_id2 + 1] -
94  vertex_ptr[3 * triangle_id1 + 1];
95  v01[2] = vertex_ptr[3 * triangle_id2 + 2] -
96  vertex_ptr[3 * triangle_id1 + 2];
97  v02[0] = vertex_ptr[3 * triangle_id3] -
98  vertex_ptr[3 * triangle_id1];
99  v02[1] = vertex_ptr[3 * triangle_id3 + 1] -
100  vertex_ptr[3 * triangle_id1 + 1];
101  v02[2] = vertex_ptr[3 * triangle_id3 + 2] -
102  vertex_ptr[3 * triangle_id1 + 2];
103 
105  &normal_ptr[idx]);
106  });
107  });
108 }
109 
110 #if defined(__CUDACC__)
111 void ComputeTriangleAreasCUDA
112 #else
114 #endif
115  (const core::Tensor& vertices,
116  const core::Tensor& triangles,
117  core::Tensor& triangle_areas) {
118  const int64_t n = triangle_areas.GetLength();
119  const core::Dtype dtype = triangle_areas.GetDtype();
120  const core::Tensor triangles_d = triangles.To(core::Int64);
121 
122  DISPATCH_FLOAT_DTYPE_TO_TEMPLATE(dtype, [&]() {
123  scalar_t* area_ptr = triangle_areas.GetDataPtr<scalar_t>();
124  const int64_t* triangle_ptr = triangles_d.GetDataPtr<int64_t>();
125  const scalar_t* vertex_ptr = vertices.GetDataPtr<scalar_t>();
126 
127  core::ParallelFor(triangle_areas.GetDevice(), n,
128  [=] OPEN3D_DEVICE(int64_t workload_idx) {
129  int64_t idx = 3 * workload_idx;
130 
131  int64_t triangle_id1 = triangle_ptr[idx];
132  int64_t triangle_id2 = triangle_ptr[idx + 1];
133  int64_t triangle_id3 = triangle_ptr[idx + 2];
134 
135  scalar_t v01[3], v02[3];
136  v01[0] = vertex_ptr[3 * triangle_id2] -
137  vertex_ptr[3 * triangle_id1];
138  v01[1] = vertex_ptr[3 * triangle_id2 + 1] -
139  vertex_ptr[3 * triangle_id1 + 1];
140  v01[2] = vertex_ptr[3 * triangle_id2 + 2] -
141  vertex_ptr[3 * triangle_id1 + 2];
142  v02[0] = vertex_ptr[3 * triangle_id3] -
143  vertex_ptr[3 * triangle_id1];
144  v02[1] = vertex_ptr[3 * triangle_id3 + 1] -
145  vertex_ptr[3 * triangle_id1 + 1];
146  v02[2] = vertex_ptr[3 * triangle_id3 + 2] -
147  vertex_ptr[3 * triangle_id1 + 2];
148 
149  area_ptr[workload_idx] =
151  v01, v02);
152  });
153  });
154 }
155 
156 } // namespace trianglemesh
157 } // namespace kernel
158 } // namespace geometry
159 } // namespace t
160 } // namespace open3d
Common CUDA utilities.
#define OPEN3D_DEVICE
Definition: CUDAUtils.h:45
#define DISPATCH_FLOAT_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition: Dispatch.h:77
Definition: Dtype.h:20
Definition: Tensor.h:32
T * GetDataPtr()
Definition: Tensor.h:1143
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:707
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE scalar_t cross_mag_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition: Matrix.h:77
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
const Dtype Int64
Definition: Dtype.cpp:47
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition: ParallelFor.h:103
void NormalizeNormalsCPU(core::Tensor &normals)
Definition: TriangleMeshImpl.h:33
void ComputeTriangleAreasCPU(const core::Tensor &vertices, const core::Tensor &triangles, core::Tensor &triangle_areas)
Definition: TriangleMeshImpl.h:115
void ComputeTriangleNormalsCPU(const core::Tensor &vertices, const core::Tensor &triangles, core::Tensor &normals)
Definition: TriangleMeshImpl.h:70
Definition: PinholeCameraIntrinsic.cpp:16