1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
* kernel.rs
*
* Copyright (c) 2026 ParkSangWoo
*
* Author(s):
*
* ParkSangWoo <dev.parksangwoo@gmail.com>
*
*
* This file is part of cumulus3d.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Third-party notices: parts of the algorithms, default parameters and data
* formats in this file follow other open-source projects. Their copyright
* notices and licenses are reproduced in THIRD_PARTY_NOTICES.md.
*
* SPDX-License-Identifier: Apache-2.0
*/
//! PatchMatch kernel boundary. The backend handles propagation, view selection and refinement at one scale (red-black iteration runs),
//! single-hypothesis cost evaluation and the final readout;
//! this crate handles multi-scale progression, upsampling, detail-restoration decisions, filter thresholds and fusion.
//!
//! # Rules the kernel must follow
//! Coordinates: integer pixel = pixel center. Ray `ray(x, y) = ((x−cx)/fx, (y−cy)/fy, 1)`, depth is camera z,
//! the normal is a unit vector in reference camera coordinates with `n·ray < 0`.
//!
//! - **Cost** `m = 1 − ρ`: bilateral-weighted NCC using only the reference image color. The window is the square grid of
//! `PmParams::window_offsets()`, weights `exp(−(dx²+dy²)/(2σs²) − (I_c − I_k)²/(2σc²))`, brightness outside the image is 0. Source
//! brightness is the bilinear value (0 outside) at the position moved by the plane-induced homography `H = K_j (R + t nᵀ/δ) K⁻¹`, `δ =
//! n·(d·ray)`. 2 if variance < 1e−5, otherwise `clamp(1 − cov/√(var_r var_s), 0, 2)`. 2 if the center projection is behind the camera or
//! outside the source image.
//! - **Geometric error** `Δe`: pixel distance after projecting the reference point into the source, going back to the reference through the
//! nearest value of the source depth map and reprojecting. Infinite on projection failure, outside the image or depth 0. In the cost it
//! is `min(Δe, geom_max_cost)`.
//! - **Priors** (once per view, using the current hypothesis at the start of a half step): product of the triangulation, incidence-angle
//! and resolution priors ([`crate::math`]).
//! - **Iteration**: red-black half steps. Color `(x+y) mod 2`. An active pixel evaluates 8 hypotheses plus the current one: for each of 8
//! regions (per up/right/down/left direction, 7 V-shaped offsets `(0,−1),(±1,−2),(±2,−3),(±3,−4)` and 11 band offsets
//! `(0,−3),(0,−5),…,(0,−23)`, rotated by 90° each), the plane of the neighbor with the smallest stored cost (the first one found on ties)
//! moved onto the own ray. If a region has no valid neighbor or the move fails, the current hypothesis is used instead.
//! - **View selection**: vote with the costs of the 8 propagated hypotheses (good `m < τ(t) = τ0·exp(−t²/α)`, bad `m > τ1`; adopted if the
//! good count exceeds n1 and the bad count is below n2). Weight of an adopted view `w = mean of exp(−m²/(2β²)) over the good costs`,
//! doubled if it was the most important view of the previous iteration. Even if not adopted, `prev_view_weight` if it was the previous
//! most important view. Multiplying by the priors gives `w''`, used for a per-hypothesis weighted average (for a geometric run, `m +
//! λ·min(Δe, δ)`). If the weight sum is 0, the prior-weighted average gathered in the same pass is used instead. Views whose prior is 0
//! are not evaluated. The minimum-cost hypothesis is adopted (ties go to the earlier index). Most important view = maximum `w''` (ties go
//! to the earlier view).
//! - **Refinement** (same half step): random depth (uniform in inverse depth `[1/dmax, 1/dmin]`), random normal (uniform on the sphere,
//! flipped toward the camera), perturbed depth `1/d' = (1/d)(1 + u·ε_t)`, perturbed normal (rotate by `u·φ_t` about a random
//! perpendicular axis, on failure retry up to 3 times halving the angle), with `ε_t = max(ε_min, ε0·2^−t)`, `φ_t = max(φ_min, φ0·2^−t)`,
//! forming 6 combinations `(d_r,n)(d,n_r)(d_r,n_r)(d_p,n)(d,n_p)(d_p,n_p)`. Aggregated with the same weights (positive views only);
//! adopted if smaller.
//! - **Random numbers**: per-pixel `splitmix64` sequence. Start state `mix64(seed ^ mix64(view_key ^ mix64(level·2⁴⁸ + run·2³² + t·2¹⁶ +
//! half)) ^ pixel)` (initialization uses t = 0xFFFF). A uniform (0,1] value is `((x >> 40) + 1)·2⁻²⁴`. Deterministic regardless of thread
//! layout.
//! - **Coarse-scale candidate**: if `use_prior` is set and the reference patch variance is below the threshold, the state's `prior` plane
//! is refined and evaluated as one more candidate.
//! - **Run start**: after random initialization (if requested), fill the stored cost with the top-K mean cost of the current hypothesis and
//! clear the most important view.
//! - **Numerics**: the kernel may use approximate division and exponential (speed first). Results are bit-reproducible on the same device
//! with the same input.
use crate;
use Result;
use Arc;
/// View image at one scale.
/// Reference → source relative geometry (source camera coordinates = r·X + t, source center in reference coordinates `center`).
/// Kernel input view.
/// Whole kernel input (fixed during one densification call).
/// Pixel state of one reference view (one scale).
/// Depth snapshot read by geometric runs (view index → depth map at that scale). Equal `id` implies equal content.
/// Parameters of one run.
/// Backend state during one densification call (device-resident data, etc.).
/// PatchMatch backend.
/// Pixel random-number start state (same definition as the kernel).
/// One splitmix64 step and a uniform (0,1] value.