Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
FillInLinearSystemImpl.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2024 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
11
12namespace open3d {
13namespace t {
14namespace pipelines {
15namespace kernel {
16
17// Computes the 12-element point-to-plane rigid alignment Jacobian for a
18// correspondence pair (frame i, frame j), given the transformed target point
19// q_prime and the rotated source normal normal_p_prime. J_ij[0:6] is the
20// Jacobian w.r.t. frame i's 6-DoF pose; J_ij[6:12] w.r.t. frame j's pose is
21// its negation. Shared by the CPU/CUDA path below and
22// FillInLinearSystemSYCL.cpp.
24 const float *q_prime, const float *normal_p_prime, float *J_ij) {
25 J_ij[0] = -q_prime[2] * normal_p_prime[1] + q_prime[1] * normal_p_prime[2];
26 J_ij[1] = q_prime[2] * normal_p_prime[0] - q_prime[0] * normal_p_prime[2];
27 J_ij[2] = -q_prime[1] * normal_p_prime[0] + q_prime[0] * normal_p_prime[1];
28 J_ij[3] = normal_p_prime[0];
29 J_ij[4] = normal_p_prime[1];
30 J_ij[5] = normal_p_prime[2];
31 for (int k = 0; k < 6; ++k) {
32 J_ij[k + 6] = -J_ij[k];
33 }
34}
35
36#ifndef OPEN3D_SKIP_FILL_IN_LS_MAIN
37#if defined(__CUDACC__)
38void FillInRigidAlignmentTermCUDA
39#else
41#endif
42 (core::Tensor &AtA,
43 core::Tensor &Atb,
44 core::Tensor &residual,
45 const core::Tensor &Ti_ps,
46 const core::Tensor &Tj_qs,
47 const core::Tensor &Ri_normal_ps,
48 int i,
49 int j,
50 float threshold) {
51
52 core::Device device = AtA.GetDevice();
53 int64_t n = Ti_ps.GetLength();
54 if (Tj_qs.GetLength() != n || Ri_normal_ps.GetLength() != n) {
55 utility::LogError(
56 "Unable to setup linear system: input length mismatch.");
57 }
58
59 // First fill in a small 12 x 12 linear system
60 core::Tensor AtA_local =
61 core::Tensor::Zeros({12, 12}, core::Float32, device);
62 core::Tensor Atb_local = core::Tensor::Zeros({12}, core::Float32, device);
63
64 float *AtA_local_ptr = static_cast<float *>(AtA_local.GetDataPtr());
65 float *Atb_local_ptr = static_cast<float *>(Atb_local.GetDataPtr());
66 float *residual_ptr = static_cast<float *>(residual.GetDataPtr());
67
68 const float *Ti_ps_ptr = static_cast<const float *>(Ti_ps.GetDataPtr());
69 const float *Tj_qs_ptr = static_cast<const float *>(Tj_qs.GetDataPtr());
70 const float *Ri_normal_ps_ptr =
71 static_cast<const float *>(Ri_normal_ps.GetDataPtr());
72
74 AtA.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
75 const float *p_prime = Ti_ps_ptr + 3 * workload_idx;
76 const float *q_prime = Tj_qs_ptr + 3 * workload_idx;
77 const float *normal_p_prime =
78 Ri_normal_ps_ptr + 3 * workload_idx;
79
80 float r = (p_prime[0] - q_prime[0]) * normal_p_prime[0] +
81 (p_prime[1] - q_prime[1]) * normal_p_prime[1] +
82 (p_prime[2] - q_prime[2]) * normal_p_prime[2];
83 if (abs(r) > threshold) return;
84
85 float J_ij[12];
86 ComputeRigidAlignmentJacobian(q_prime, normal_p_prime, J_ij);
87
88 // Not optimized; Switch to reduction if necessary.
89#if defined(BUILD_CUDA_MODULE) && defined(__CUDACC__)
90 for (int i_local = 0; i_local < 12; ++i_local) {
91 for (int j_local = 0; j_local < 12; ++j_local) {
92 atomicAdd(&AtA_local_ptr[i_local * 12 + j_local],
93 J_ij[i_local] * J_ij[j_local]);
94 }
95 atomicAdd(&Atb_local_ptr[i_local], J_ij[i_local] * r);
96 }
97 atomicAdd(residual_ptr, r * r);
98#else
99#pragma omp critical(FillInRigidAlignmentTermCPU)
100 {
101 for (int i_local = 0; i_local < 12; ++i_local) {
102 for (int j_local = 0; j_local < 12; ++j_local) {
103 AtA_local_ptr[i_local * 12 + j_local]
104 += J_ij[i_local] * J_ij[j_local];
105 }
106 Atb_local_ptr[i_local] += J_ij[i_local] * r;
107 }
108 *residual_ptr += r * r;
109 }
110#endif
111 });
112
113 // Then fill-in the large linear system
114 std::vector<int64_t> indices_vec(12);
115 for (int k = 0; k < 6; ++k) {
116 indices_vec[k] = i * 6 + k;
117 indices_vec[k + 6] = j * 6 + k;
118 }
119
120 std::vector<int64_t> indices_i_vec;
121 std::vector<int64_t> indices_j_vec;
122 for (int local_i = 0; local_i < 12; ++local_i) {
123 for (int local_j = 0; local_j < 12; ++local_j) {
124 indices_i_vec.push_back(indices_vec[local_i]);
125 indices_j_vec.push_back(indices_vec[local_j]);
126 }
127 }
128
129 core::Tensor indices(indices_vec, {12}, core::Int64, device);
130 core::Tensor indices_i(indices_i_vec, {12 * 12}, core::Int64, device);
131 core::Tensor indices_j(indices_j_vec, {12 * 12}, core::Int64, device);
132
133 core::Tensor AtA_sub = AtA.IndexGet({indices_i, indices_j});
134 AtA.IndexSet({indices_i, indices_j}, AtA_sub + AtA_local.View({12 * 12}));
135
136 core::Tensor Atb_sub = Atb.IndexGet({indices});
137 Atb.IndexSet({indices}, Atb_sub + Atb_local.View({12, 1}));
138}
139
140#if defined(__CUDACC__)
141void FillInSLACAlignmentTermCUDA
142#else
144#endif
145 (core::Tensor &AtA,
146 core::Tensor &Atb,
147 core::Tensor &residual,
148 const core::Tensor &Ti_Cps,
149 const core::Tensor &Tj_Cqs,
150 const core::Tensor &Cnormal_ps,
151 const core::Tensor &Ri_Cnormal_ps,
152 const core::Tensor &RjT_Ri_Cnormal_ps,
153 const core::Tensor &cgrid_idx_ps,
154 const core::Tensor &cgrid_idx_qs,
155 const core::Tensor &cgrid_ratio_qs,
156 const core::Tensor &cgrid_ratio_ps,
157 int i,
158 int j,
159 int n_frags,
160 float threshold) {
161 int64_t n = Ti_Cps.GetLength();
162 if (Tj_Cqs.GetLength() != n || Cnormal_ps.GetLength() != n ||
163 Ri_Cnormal_ps.GetLength() != n || RjT_Ri_Cnormal_ps.GetLength() != n ||
164 cgrid_idx_ps.GetLength() != n || cgrid_ratio_ps.GetLength() != n ||
165 cgrid_idx_qs.GetLength() != n || cgrid_ratio_qs.GetLength() != n) {
166 utility::LogError(
167 "Unable to setup linear system: input length mismatch.");
168 }
169
170 int n_vars = Atb.GetLength();
171 float *AtA_ptr = static_cast<float *>(AtA.GetDataPtr());
172 float *Atb_ptr = static_cast<float *>(Atb.GetDataPtr());
173 float *residual_ptr = static_cast<float *>(residual.GetDataPtr());
174
175 // Geometric properties
176 const float *Ti_Cps_ptr = static_cast<const float *>(Ti_Cps.GetDataPtr());
177 const float *Tj_Cqs_ptr = static_cast<const float *>(Tj_Cqs.GetDataPtr());
178 const float *Cnormal_ps_ptr =
179 static_cast<const float *>(Cnormal_ps.GetDataPtr());
180 const float *Ri_Cnormal_ps_ptr =
181 static_cast<const float *>(Ri_Cnormal_ps.GetDataPtr());
182 const float *RjT_Ri_Cnormal_ps_ptr =
183 static_cast<const float *>(RjT_Ri_Cnormal_ps.GetDataPtr());
184
185 // Association properties
186 const int *cgrid_idx_ps_ptr =
187 static_cast<const int *>(cgrid_idx_ps.GetDataPtr());
188 const int *cgrid_idx_qs_ptr =
189 static_cast<const int *>(cgrid_idx_qs.GetDataPtr());
190 const float *cgrid_ratio_ps_ptr =
191 static_cast<const float *>(cgrid_ratio_ps.GetDataPtr());
192 const float *cgrid_ratio_qs_ptr =
193 static_cast<const float *>(cgrid_ratio_qs.GetDataPtr());
194
196 AtA.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
197 const float *Ti_Cp = Ti_Cps_ptr + 3 * workload_idx;
198 const float *Tj_Cq = Tj_Cqs_ptr + 3 * workload_idx;
199 const float *Cnormal_p = Cnormal_ps_ptr + 3 * workload_idx;
200 const float *Ri_Cnormal_p =
201 Ri_Cnormal_ps_ptr + 3 * workload_idx;
202 const float *RjTRi_Cnormal_p =
203 RjT_Ri_Cnormal_ps_ptr + 3 * workload_idx;
204
205 const int *cgrid_idx_p = cgrid_idx_ps_ptr + 8 * workload_idx;
206 const int *cgrid_idx_q = cgrid_idx_qs_ptr + 8 * workload_idx;
207 const float *cgrid_ratio_p =
208 cgrid_ratio_ps_ptr + 8 * workload_idx;
209 const float *cgrid_ratio_q =
210 cgrid_ratio_qs_ptr + 8 * workload_idx;
211
212 float r = (Ti_Cp[0] - Tj_Cq[0]) * Ri_Cnormal_p[0] +
213 (Ti_Cp[1] - Tj_Cq[1]) * Ri_Cnormal_p[1] +
214 (Ti_Cp[2] - Tj_Cq[2]) * Ri_Cnormal_p[2];
215 if (abs(r) > threshold) return;
216
217 // Now we fill in a 60 x 60 sub-matrix: 2 x (6 + 8 x 3)
218 float J[60];
219 int idx[60];
220
221 // Jacobian w.r.t. Ti: 0-6
222 J[0] = -Tj_Cq[2] * Ri_Cnormal_p[1] + Tj_Cq[1] * Ri_Cnormal_p[2];
223 J[1] = Tj_Cq[2] * Ri_Cnormal_p[0] - Tj_Cq[0] * Ri_Cnormal_p[2];
224 J[2] = -Tj_Cq[1] * Ri_Cnormal_p[0] + Tj_Cq[0] * Ri_Cnormal_p[1];
225 J[3] = Ri_Cnormal_p[0];
226 J[4] = Ri_Cnormal_p[1];
227 J[5] = Ri_Cnormal_p[2];
228
229 // Jacobian w.r.t. Tj: 6-12
230 for (int k = 0; k < 6; ++k) {
231 J[k + 6] = -J[k];
232
233 idx[k + 0] = 6 * i + k;
234 idx[k + 6] = 6 * j + k;
235 }
236
237 // Jacobian w.r.t. C over p: 12-36
238 for (int k = 0; k < 8; ++k) {
239 J[12 + k * 3 + 0] = cgrid_ratio_p[k] * Cnormal_p[0];
240 J[12 + k * 3 + 1] = cgrid_ratio_p[k] * Cnormal_p[1];
241 J[12 + k * 3 + 2] = cgrid_ratio_p[k] * Cnormal_p[2];
242
243 idx[12 + k * 3 + 0] = 6 * n_frags + cgrid_idx_p[k] * 3 + 0;
244 idx[12 + k * 3 + 1] = 6 * n_frags + cgrid_idx_p[k] * 3 + 1;
245 idx[12 + k * 3 + 2] = 6 * n_frags + cgrid_idx_p[k] * 3 + 2;
246 }
247
248 // Jacobian w.r.t. C over q: 36-60
249 for (int k = 0; k < 8; ++k) {
250 J[36 + k * 3 + 0] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[0];
251 J[36 + k * 3 + 1] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[1];
252 J[36 + k * 3 + 2] = -cgrid_ratio_q[k] * RjTRi_Cnormal_p[2];
253
254 idx[36 + k * 3 + 0] = 6 * n_frags + cgrid_idx_q[k] * 3 + 0;
255 idx[36 + k * 3 + 1] = 6 * n_frags + cgrid_idx_q[k] * 3 + 1;
256 idx[36 + k * 3 + 2] = 6 * n_frags + cgrid_idx_q[k] * 3 + 2;
257 }
258
259 // Not optimized; Switch to reduction if necessary.
260#if defined(__CUDACC__)
261 for (int ki = 0; ki < 60; ++ki) {
262 for (int kj = 0; kj < 60; ++kj) {
263 float AtA_ij = J[ki] * J[kj];
264 int ij = idx[ki] * n_vars + idx[kj];
265 atomicAdd(AtA_ptr + ij, AtA_ij);
266 }
267 float Atb_i = J[ki] * r;
268 atomicAdd(Atb_ptr + idx[ki], Atb_i);
269 }
270 atomicAdd(residual_ptr, r * r);
271#else
272#pragma omp critical(FillInSLACAlignmentTermCPU)
273 {
274 for (int ki = 0; ki < 60; ++ki) {
275 for (int kj = 0; kj < 60; ++kj) {
276 AtA_ptr[idx[ki] * n_vars + idx[kj]]
277 += J[ki] * J[kj];
278 }
279 Atb_ptr[idx[ki]] += J[ki] * r;
280 }
281 *residual_ptr += r * r;
282 }
283#endif
284 });
285}
286
287#if defined(__CUDACC__)
288void FillInSLACRegularizerTermCUDA
289#else
291#endif
292 (core::Tensor &AtA,
293 core::Tensor &Atb,
294 core::Tensor &residual,
295 const core::Tensor &grid_idx,
296 const core::Tensor &grid_nbs_idx,
297 const core::Tensor &grid_nbs_mask,
298 const core::Tensor &positions_init,
299 const core::Tensor &positions_curr,
300 float weight,
301 int n_frags,
302 int anchor_idx) {
303
304 int64_t n = grid_idx.GetLength();
305 int64_t n_vars = Atb.GetLength();
306
307 float *AtA_ptr = static_cast<float *>(AtA.GetDataPtr());
308 float *Atb_ptr = static_cast<float *>(Atb.GetDataPtr());
309 float *residual_ptr = static_cast<float *>(residual.GetDataPtr());
310
311 const int *grid_idx_ptr = static_cast<const int *>(grid_idx.GetDataPtr());
312 const int *grid_nbs_idx_ptr =
313 static_cast<const int *>(grid_nbs_idx.GetDataPtr());
314 const bool *grid_nbs_mask_ptr =
315 static_cast<const bool *>(grid_nbs_mask.GetDataPtr());
316
317 const float *positions_init_ptr =
318 static_cast<const float *>(positions_init.GetDataPtr());
319 const float *positions_curr_ptr =
320 static_cast<const float *>(positions_curr.GetDataPtr());
321
323 AtA.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
324 // Enumerate 6 neighbors
325 int idx_i = grid_idx_ptr[workload_idx];
326
327 const int *idx_nbs = grid_nbs_idx_ptr + 6 * workload_idx;
328 const bool *mask_nbs = grid_nbs_mask_ptr + 6 * workload_idx;
329
330 // Build a 3x3 linear system to compute the local R
331 float cov[3][3] = {{0}};
332 float U[3][3], V[3][3], S[3];
333
334 int cnt = 0;
335 for (int k = 0; k < 6; ++k) {
336 bool mask_k = mask_nbs[k];
337 if (!mask_k) continue;
338
339 int idx_k = idx_nbs[k];
340
341 // Now build linear systems
342 float diff_ik_init[3] = {
343 positions_init_ptr[idx_i * 3 + 0] -
344 positions_init_ptr[idx_k * 3 + 0],
345 positions_init_ptr[idx_i * 3 + 1] -
346 positions_init_ptr[idx_k * 3 + 1],
347 positions_init_ptr[idx_i * 3 + 2] -
348 positions_init_ptr[idx_k * 3 + 2]};
349 float diff_ik_curr[3] = {
350 positions_curr_ptr[idx_i * 3 + 0] -
351 positions_curr_ptr[idx_k * 3 + 0],
352 positions_curr_ptr[idx_i * 3 + 1] -
353 positions_curr_ptr[idx_k * 3 + 1],
354 positions_curr_ptr[idx_i * 3 + 2] -
355 positions_curr_ptr[idx_k * 3 + 2]};
356
357 // Build linear system by computing XY^T when formulating Y
358 // = RX Y: curr X: init
359 for (int i = 0; i < 3; ++i) {
360 for (int j = 0; j < 3; ++j) {
361 cov[i][j] += diff_ik_init[i] * diff_ik_curr[j];
362 }
363 }
364 ++cnt;
365 }
366
367 if (cnt < 3) {
368 return;
369 }
370
371 core::linalg::kernel::svd3x3(*cov, *U, S, *V);
372
373 float R[3][3];
376
377 float d = core::linalg::kernel::det3x3(*R);
378
379 if (d < 0) {
380 U[2][0] = -U[2][0];
381 U[2][1] = -U[2][1];
382 U[2][2] = -U[2][2];
384 }
385
386 // Now we have R, we build Hessian and residuals
387 // But first, we need to anchor a point
388 if (idx_i == anchor_idx) {
389 R[0][0] = R[1][1] = R[2][2] = 1;
390 R[0][1] = R[0][2] = R[1][0] = R[1][2] = R[2][0] = R[2][1] =
391 0;
392 }
393 for (int k = 0; k < 6; ++k) {
394 bool mask_k = mask_nbs[k];
395
396 if (mask_k) {
397 int idx_k = idx_nbs[k];
398
399 float diff_ik_init[3] = {
400 positions_init_ptr[idx_i * 3 + 0] -
401 positions_init_ptr[idx_k * 3 + 0],
402 positions_init_ptr[idx_i * 3 + 1] -
403 positions_init_ptr[idx_k * 3 + 1],
404 positions_init_ptr[idx_i * 3 + 2] -
405 positions_init_ptr[idx_k * 3 + 2]};
406 float diff_ik_curr[3] = {
407 positions_curr_ptr[idx_i * 3 + 0] -
408 positions_curr_ptr[idx_k * 3 + 0],
409 positions_curr_ptr[idx_i * 3 + 1] -
410 positions_curr_ptr[idx_k * 3 + 1],
411 positions_curr_ptr[idx_i * 3 + 2] -
412 positions_curr_ptr[idx_k * 3 + 2]};
413 float R_diff_ik_curr[3];
414
415 core::linalg::kernel::matmul3x3_3x1(*R, diff_ik_init,
416 R_diff_ik_curr);
417
418 float local_r[3];
419 local_r[0] = diff_ik_curr[0] - R_diff_ik_curr[0];
420 local_r[1] = diff_ik_curr[1] - R_diff_ik_curr[1];
421 local_r[2] = diff_ik_curr[2] - R_diff_ik_curr[2];
422
423 int offset_idx_i = 3 * idx_i + 6 * n_frags;
424 int offset_idx_k = 3 * idx_k + 6 * n_frags;
425
426#if defined(__CUDACC__)
427 // Update residual
428 atomicAdd(residual_ptr,
429 weight * (local_r[0] * local_r[0] +
430 local_r[1] * local_r[1] +
431 local_r[2] * local_r[2]));
432
433 for (int axis = 0; axis < 3; ++axis) {
434 // Update AtA: 2x2
435 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
436 offset_idx_i + axis],
437 weight);
438 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
439 offset_idx_k + axis],
440 weight);
441 atomicAdd(&AtA_ptr[(offset_idx_i + axis) * n_vars +
442 offset_idx_k + axis],
443 -weight);
444 atomicAdd(&AtA_ptr[(offset_idx_k + axis) * n_vars +
445 offset_idx_i + axis],
446 -weight);
447
448 // Update Atb: 2x1
449 atomicAdd(&Atb_ptr[offset_idx_i + axis],
450 +weight * local_r[axis]);
451 atomicAdd(&Atb_ptr[offset_idx_k + axis],
452 -weight * local_r[axis]);
453 }
454#else
455#pragma omp critical(FillInSLACRegularizerTermCPU)
456 {
457 // Update residual
458 *residual_ptr += weight * (local_r[0] * local_r[0] +
459 local_r[1] * local_r[1] +
460 local_r[2] * local_r[2]);
461
462 for (int axis = 0; axis < 3; ++axis) {
463 // Update AtA: 2x2
464 AtA_ptr[(offset_idx_i + axis) * n_vars +
465 offset_idx_i + axis] += weight;
466 AtA_ptr[(offset_idx_k + axis) * n_vars +
467 offset_idx_k + axis] += weight;
468
469 AtA_ptr[(offset_idx_i + axis) * n_vars +
470 offset_idx_k + axis] -= weight;
471 AtA_ptr[(offset_idx_k + axis) * n_vars +
472 offset_idx_i + axis] -= weight;
473
474 // Update Atb: 2x1
475 Atb_ptr[offset_idx_i + axis] += weight * local_r[axis];
476 Atb_ptr[offset_idx_k + axis] -= weight * local_r[axis];
477 }
478 }
479#endif
480 }
481 }
482 });
483}
484#endif // OPEN3D_SKIP_FILL_IN_LS_MAIN
485} // namespace kernel
486} // namespace pipelines
487} // namespace t
488} // namespace open3d
#define OPEN3D_HOST_DEVICE
Definition CUDAUtils.h:43
#define OPEN3D_DEVICE
Definition CUDAUtils.h:44
#define OPEN3D_FORCE_INLINE
Definition CUDAUtils.h:42
Real weight
Definition SurfaceReconstructionPoisson.cpp:267
double t
Definition SurfaceReconstructionPoisson.cpp:172
Definition Device.h:18
Definition Tensor.h:32
T * GetDataPtr()
Definition Tensor.h:1201
Tensor View(const SizeVector &dst_shape) const
Definition Tensor.cpp:766
static Tensor Zeros(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor fill with zeros.
Definition Tensor.cpp:405
void IndexSet(const std::vector< Tensor > &index_tensors, const Tensor &src_tensor)
Advanced indexing getter.
Definition Tensor.cpp:1009
Tensor IndexGet(const std::vector< Tensor > &index_tensors) const
Advanced indexing getter. This will always allocate a new Tensor.
Definition Tensor.cpp:978
OPEN3D_DEVICE OPEN3D_FORCE_INLINE void transpose3x3_(scalar_t *A_3x3)
Definition Matrix.h:163
OPEN3D_DEVICE OPEN3D_FORCE_INLINE void matmul3x3_3x3(const scalar_t *A_3x3, const scalar_t *B_3x3, scalar_t *C_3x3)
Definition Matrix.h:48
OPEN3D_DEVICE OPEN3D_FORCE_INLINE void svd3x3(const scalar_t *A_3x3, scalar_t *U_3x3, scalar_t *S_3x1, scalar_t *V_3x3)
OPEN3D_DEVICE OPEN3D_FORCE_INLINE scalar_t det3x3(const scalar_t *A_3x3)
Definition Matrix.h:101
const Dtype Int64
Definition Dtype.cpp:47
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition ParallelFor.h:135
const Dtype Float32
Definition Dtype.cpp:42
void FillInSLACAlignmentTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &Ti_qs, const core::Tensor &Tj_qs, const core::Tensor &normal_ps, const core::Tensor &Ri_normal_ps, const core::Tensor &RjT_Ri_normal_ps, const core::Tensor &cgrid_idx_ps, const core::Tensor &cgrid_idx_qs, const core::Tensor &cgrid_ratio_qs, const core::Tensor &cgrid_ratio_ps, int i, int j, int n, float threshold)
Definition FillInLinearSystemImpl.h:145
void FillInRigidAlignmentTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &Ti_qs, const core::Tensor &Tj_qs, const core::Tensor &Ri_normal_ps, int i, int j, float threshold)
Definition FillInLinearSystemImpl.h:42
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE void ComputeRigidAlignmentJacobian(const float *q_prime, const float *normal_p_prime, float *J_ij)
Definition FillInLinearSystemImpl.h:23
void FillInSLACRegularizerTermCPU(core::Tensor &AtA, core::Tensor &Atb, core::Tensor &residual, const core::Tensor &grid_idx, const core::Tensor &grid_nbs_idx, const core::Tensor &grid_nbs_mask, const core::Tensor &positions_init, const core::Tensor &positions_curr, float weight, int n, int anchor_idx)
Definition FillInLinearSystemImpl.h:292
Definition PinholeCameraIntrinsic.cpp:16
const core::Tensor * indices
Definition TriangleMesh.cpp:2128