TTK
Loading...
Searching...
No Matches
CinemaImagingNative.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "CinemaImaging.h"
14#include <Ray.h>
15
16namespace ttk {
18 public:
20 this->setDebugMsgPrefix("CinemaImaging(Native)");
21 }
22 ~CinemaImagingNative() override = default;
23
24 template <typename IT>
25 int renderImage(float *depthBuffer,
26 unsigned int *primitiveIds,
27 float *barycentricCoordinates,
28
29 const size_t &nVertices,
30 const float *vertexCoords,
31 const size_t &nTriangles,
32 const IT *connectivityList,
33
35
36 const double resolution[2],
37 const double camPos[3],
38 const double camDirRaw[3],
39 const double camUp[3],
40 const double &camHeight,
41 const bool &orthographicProjection,
42 const double &viewAngle) const;
43 };
44
45} // namespace ttk
46
47template <typename IT>
49 float *depthBuffer,
50 unsigned int *primitiveIds,
51 float *barycentricCoordinates,
52 const size_t &ttkNotUsed(nVertices),
53 const float *vertexCoords,
54 const size_t &ttkNotUsed(nTriangles),
55 const IT *connectivityList,
57 const double resolution[2],
58 const double camPos[3],
59 const double camDirRaw[3],
60 const double camUp[3],
61 const double &camHeight,
62 const bool &orthographicProjection,
63 const double &viewAngle) const {
64 ttk::Timer timer;
65 int const resX = resolution[0];
66 int const resY = resolution[1];
67
68 this->printMsg("Rendering Image ("
69 + std::string(orthographicProjection ? "O" : "P") + "|"
70 + std::to_string(resX) + "x" + std::to_string(resY) + ")",
72
73 // Compute camera size
74 const double aspect = resolution[0] / resolution[1];
75 const double camSize[2] = {aspect * camHeight, camHeight};
76
77 const auto normalize = [](double out[3], const double in[3]) {
78 double const temp = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
79 out[0] = in[0] / temp;
80 out[1] = in[1] / temp;
81 out[2] = in[2] / temp;
82 };
83
84 double camDir[3]{0, 0, 0};
85 normalize(camDir, camDirRaw);
86
87 // Compute camRight = camDir x CamUp
88 double camRight[3]{camDir[1] * camUp[2] - camDir[2] * camUp[1],
89 camDir[2] * camUp[0] - camDir[0] * camUp[2],
90 camDir[0] * camUp[1] - camDir[1] * camUp[0]};
91 normalize(camRight, camRight);
92
93 // Compute true up std::vector
94 double camUpTrue[3]{camDir[1] * (-camRight[2]) - camDir[2] * (-camRight[1]),
95 camDir[2] * (-camRight[0]) - camDir[0] * (-camRight[2]),
96 camDir[0] * (-camRight[1]) - camDir[1] * (-camRight[0])};
97 normalize(camUpTrue, camUpTrue);
98
99 // Compute pixel size in world coordinates
100 double const pixelWidthWorld = camSize[0] / resolution[0];
101 double const pixelHeightWorld = camSize[1] / resolution[1];
102
103 // Optimization: precompute half of the camera size to reduce the number of
104 // operations in the for loop. Include a half pixel offset (-0.5) to center
105 // vertices at pixel centers
106 double const camWidthWorldHalf = 0.5 * camSize[0] - 0.5 * pixelWidthWorld;
107 double const camHeightWorldHalf = 0.5 * camSize[1] - 0.5 * pixelHeightWorld;
108
109 // Optimization: reorient camera model to bottom left corner to reduce
110 // operations in for loop
111 double const camPosCorner[3] = {camPos[0] - camRight[0] * camWidthWorldHalf
112 - camUpTrue[0] * camHeightWorldHalf,
113 camPos[1] - camRight[1] * camWidthWorldHalf
114 - camUpTrue[1] * camHeightWorldHalf,
115 camPos[2] - camRight[2] * camWidthWorldHalf
116 - camUpTrue[2] * camHeightWorldHalf};
117
118 float const nan = std::numeric_limits<float>::quiet_NaN();
119 if(orthographicProjection) {
120#ifdef TTK_ENABLE_OPENMP
121#pragma omp parallel for num_threads(this->threadNumber_)
122#endif
123 for(int y = 0; y < resY; y++) {
124 double const v = ((double)y) * pixelHeightWorld;
125
126 size_t pixelIndex = y * resX;
127 size_t bcIndex = 2 * pixelIndex;
128
129 for(int x = 0; x < resX; x++) {
130 double const u = ((double)x) * pixelWidthWorld;
131
132 depthBuffer[pixelIndex] = nan;
133 primitiveIds[pixelIndex] = CinemaImaging::INVALID_ID;
134 barycentricCoordinates[bcIndex] = nan;
135 barycentricCoordinates[bcIndex + 1] = nan;
136
137 // set origin
138 float const org_x
139 = camPosCorner[0] + u * camRight[0] + v * camUpTrue[0];
140 float const org_y
141 = camPosCorner[1] + u * camRight[1] + v * camUpTrue[1];
142 float const org_z
143 = camPosCorner[2] + u * camRight[2] + v * camUpTrue[2];
144
145 float ray_origin[3] = {org_x, org_y, org_z};
146
147 // set dir
148 float const dir_x = camDir[0];
149 float const dir_y = camDir[1];
150 float const dir_z = camDir[2];
151
152 float ray_dir[3] = {dir_x, dir_y, dir_z};
153
154 Ray ray(ray_dir, ray_origin);
155 bool wasHit = false;
156 int triIdx;
157 float distance;
158 wasHit = bvh.intersect(
159 ray, connectivityList, vertexCoords, &triIdx, &distance);
160 if(wasHit) {
161 depthBuffer[pixelIndex] = distance;
162 primitiveIds[pixelIndex] = triIdx;
163 barycentricCoordinates[bcIndex] = ray.u;
164 barycentricCoordinates[bcIndex + 1] = ray.v;
165 }
166 pixelIndex++;
167 bcIndex += 2;
168 }
169 }
170 } else {
171 double const factor
172 = (viewAngle / 180.0 * 3.141592653589793) / resolution[0];
173
174#ifdef TTK_ENABLE_OPENMP
175#pragma omp parallel for num_threads(this->threadNumber_)
176#endif
177 for(int y = 0; y < resY; y++) {
178 double const v = (y - resY * 0.5) * factor;
179 size_t pixelIndex = y * resX;
180 size_t bcIndex = 2 * pixelIndex;
181
182 for(int x = 0; x < resX; x++) {
183 double const u = (x - resX * 0.5) * factor;
184
185 depthBuffer[pixelIndex] = nan;
186 primitiveIds[pixelIndex] = CinemaImaging::INVALID_ID;
187 barycentricCoordinates[bcIndex] = nan;
188 barycentricCoordinates[bcIndex + 1] = nan;
189
190 // set origin
191 float const org_x = camPos[0];
192 float const org_y = camPos[1];
193 float const org_z = camPos[2];
194
195 float ray_origin[3] = {org_x, org_y, org_z};
196 // set dir
197 float const dir_x = camDir[0] + u * camRight[0] + v * camUpTrue[0];
198 float const dir_y = camDir[1] + u * camRight[1] + v * camUpTrue[1];
199 float const dir_z = camDir[2] + u * camRight[2] + v * camUpTrue[2];
200
201 float ray_dir[3] = {dir_x, dir_y, dir_z};
202
203 Ray ray(ray_dir, ray_origin);
204 bool wasHit = false;
205 int triIdx;
206 float distance;
207 wasHit = bvh.intersect(
208 ray, connectivityList, vertexCoords, &triIdx, &distance);
209 if(wasHit) {
210 depthBuffer[pixelIndex] = distance;
211 primitiveIds[pixelIndex] = triIdx;
212 barycentricCoordinates[bcIndex] = ray.u;
213 barycentricCoordinates[bcIndex + 1] = ray.v;
214 }
215 pixelIndex++;
216 bcIndex += 2;
217 }
218 }
219 }
220 this->printMsg("Rendering Image ("
221 + std::string(orthographicProjection ? "O" : "P") + "|"
222 + std::to_string(resX) + "x" + std::to_string(resY) + ")",
223
224 1, timer.getElapsedTime(), this->threadNumber_);
225
226 return 1;
227}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
Acceleration structure for native ray tracer. Based on implementation described in Physically Based R...
bool intersect(Ray &r, const IT *connectivityList, const float *vertexCoords, int *triangleIndex, float *distance, std::vector< int > &triangles, std::vector< float > &distances, bool segmentIntersection=false) const
Native renderer that uses a bounding volume hierarchy for accelerated raycasting.
~CinemaImagingNative() override=default
int renderImage(float *depthBuffer, unsigned int *primitiveIds, float *barycentricCoordinates, const size_t &nVertices, const float *vertexCoords, const size_t &nTriangles, const IT *connectivityList, const BoundingVolumeHierarchy< IT > &bvh, const double resolution[2], const double camPos[3], const double camDirRaw[3], const double camUp[3], const double &camHeight, const bool &orthographicProjection, const double &viewAngle) const
TTK modules that generates images of a dataset.
static const unsigned int INVALID_ID
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
Data structure for a ray.
Definition Ray.h:11
float v
Definition Ray.h:24
float u
Definition Ray.h:23
double getElapsedTime()
Definition Timer.h:15
The Topology ToolKit.
coefficient_t normalize(const coefficient_t n, const coefficient_t modulus)
Definition ripserpy.cpp:159
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)