70 float *pointCoordinates,
71 double *triangleDistortions,
76 const dataType *depthValues,
80 const double *camNearFar,
81 const double *camHeight,
82 const double *resolution)
const {
84 const double camDirMag = std::sqrt(
85 camDir[0] * camDir[0] + camDir[1] * camDir[1] + camDir[2] * camDir[2]);
86 const double camDirN[3]{
87 camDir[0] / camDirMag, camDir[1] / camDirMag, camDir[2] / camDirMag};
91 this->
printMsg({{
"Resolution", std::to_string((
int)resolution[0]) +
"x"
92 + std::to_string((
int)resolution[1])},
93 {
"CamPos",
"[" + std::to_string(camPos[0]) +
","
94 + std::to_string(camPos[1]) +
","
95 + std::to_string(camPos[2]) +
"]"},
96 {
"CamDir",
"[" + std::to_string(camDirN[0]) +
","
97 + std::to_string(camDirN[1]) +
","
98 + std::to_string(camDirN[2]) +
"]"},
99 {
"CamHeight", std::to_string(camHeight[0])},
100 {
"CamNearFar",
"[" + std::to_string(camNearFar[0]) +
","
101 + std::to_string(camNearFar[1]) +
"]"}},
108 const size_t resolutionST[2] = {(size_t)resolution[0], (
size_t)resolution[1]};
110 this->
printMsg(
"Processing image (" + std::to_string(resolutionST[0]) +
"x"
111 + std::to_string(resolutionST[1]) +
")",
118 const double camSize[2]
119 = {resolution[0] / resolution[1] * camHeight[0], camHeight[0]};
122 double camRight[3] = {camDirN[1] * camUp[2] - camDirN[2] * camUp[1],
123 camDirN[2] * camUp[0] - camDirN[0] * camUp[2],
124 camDirN[0] * camUp[1] - camDirN[1] * camUp[0]};
125 double temp = sqrt(camRight[0] * camRight[0] + camRight[1] * camRight[1]
126 + camRight[2] * camRight[2]);
133 = {camDirN[1] * (-camRight[2]) - camDirN[2] * (-camRight[1]),
134 camDirN[2] * (-camRight[0]) - camDirN[0] * (-camRight[2]),
135 camDirN[0] * (-camRight[1]) - camDirN[1] * (-camRight[0])};
136 temp = sqrt(camUpTrue[0] * camUpTrue[0] + camUpTrue[1] * camUpTrue[1]
137 + camUpTrue[2] * camUpTrue[2]);
138 camUpTrue[0] /= temp;
139 camUpTrue[1] /= temp;
140 camUpTrue[2] /= temp;
147 const double pixelWidthWorld = camSize[0] / resolution[0];
148 const double pixelHeightWorld = camSize[1] / resolution[1];
153 const double camWidthWorldHalf = 0.5 * camSize[0] - 0.5 * pixelWidthWorld;
154 const double camHeightWorldHalf = 0.5 * camSize[1] - 0.5 * pixelHeightWorld;
157 const double delta = camNearFar[1] - camNearFar[0];
161 const double camPosCorner[3] = {camPos[0] - camRight[0] * camWidthWorldHalf
162 - camUpTrue[0] * camHeightWorldHalf,
163 camPos[1] - camRight[1] * camWidthWorldHalf
164 - camUpTrue[1] * camHeightWorldHalf,
165 camPos[2] - camRight[2] * camWidthWorldHalf
166 - camUpTrue[2] * camHeightWorldHalf};
169#ifdef TTK_ENABLE_OPENMP
170#pragma omp parallel for num_threads(threadNumber_)
172 for(
size_t y = 0; y < resolutionST[1]; y++) {
173 const double v = ((double)y) * pixelHeightWorld;
174 const double vTimesUp[3]
175 = {v * camUpTrue[0], v * camUpTrue[1], v * camUpTrue[2]};
177 const size_t yOffset = y * resolutionST[0];
178 for(
size_t x = 0; x < resolutionST[0]; x++) {
179 const size_t pixelIndex = x + yOffset;
182 const double depth = ((double)depthValues[pixelIndex]);
184 const double d = depth * delta + camNearFar[0];
185 const double u = ((double)x) * pixelWidthWorld;
188 const size_t pointCoordinateOffset = pixelIndex * 3;
189 pointCoordinates[pointCoordinateOffset]
190 = camPosCorner[0] + u * camRight[0] + vTimesUp[0] + d * camDirN[0];
191 pointCoordinates[pointCoordinateOffset + 1]
192 = camPosCorner[1] + u * camRight[1] + vTimesUp[1] + d * camDirN[1];
193 pointCoordinates[pointCoordinateOffset + 2]
194 = camPosCorner[2] + u * camRight[2] + vTimesUp[2] + d * camDirN[2];
203 auto absDiff = [](
const dataType &a,
const dataType &b) {
204 return a > b ? a - b : b - a;
206 auto isNaN = [](
const double &a) {
return std::isnan(a) || a >= 1.0; };
208 const size_t nTriangles = 2 * (resolution[0] - 1) * (resolution[1] - 1);
210 for(
size_t t = 0; t < nTriangles; t++)
211 offsetArray[t] = t * 3;
212 offsetArray[nTriangles] = 3 * nTriangles;
219 const size_t xl = resolutionST[0] - 1;
220 const size_t yl = resolutionST[1] - 1;
221 const size_t trianglesPerRow = xl * 2;
223 const double myNan = std::numeric_limits<double>::quiet_NaN();
225#ifdef TTK_ENABLE_OPENMP
226#pragma omp parallel for num_threads(this->threadNumber_)
228 for(
size_t y = 0; y < yl; y++) {
229 size_t const yOffset = y * resolutionST[0];
230 size_t triangleIndexOffset = y * trianglesPerRow * 3;
231 size_t triangleDistortionOffset = y * trianglesPerRow;
233 for(
size_t x = 0; x < xl; x++) {
234 size_t const i0 = x + yOffset;
235 size_t const i1 = i0 + 1;
236 size_t const i2 = i0 + resolutionST[0];
237 size_t const i3 = i2 + 1;
239 connectivityList[triangleIndexOffset++] = i0;
240 connectivityList[triangleIndexOffset++] = i2;
241 connectivityList[triangleIndexOffset++] = i1;
243 connectivityList[triangleIndexOffset++] = i1;
244 connectivityList[triangleIndexOffset++] = i2;
245 connectivityList[triangleIndexOffset++] = i3;
247 const double i0Depth = (double)depthValues[i0];
248 const double i1Depth = (double)depthValues[i1];
249 const double i2Depth = (double)depthValues[i2];
250 const double i3Depth = (double)depthValues[i3];
253 triangleDistortions[triangleDistortionOffset++]
254 = isNaN(i0Depth) || isNaN(i2Depth) || isNaN(i1Depth)
257 absDiff(i0Depth, i1Depth),
258 std::max(absDiff(i1Depth, i2Depth), absDiff(i0Depth, i2Depth)));
260 triangleDistortions[triangleDistortionOffset++]
261 = isNaN(i1Depth) || isNaN(i2Depth) || isNaN(i3Depth)
264 absDiff(i1Depth, i3Depth),
265 std::max(absDiff(i3Depth, i2Depth), absDiff(i2Depth, i1Depth)));
271 this->
printMsg(
"Processing image (" + std::to_string(resolutionST[0]) +
"x"
272 + std::to_string(resolutionST[1]) +
")",