TTK
Loading...
Searching...
No Matches
CinemaImagingEmbree.cpp
Go to the documentation of this file.
2
4 this->setDebugMsgPrefix("CinemaImaging(Embree)");
5}
7
8#ifdef TTK_ENABLE_EMBREE
9
10int ttk::CinemaImagingEmbree::deallocateScene(RTCDevice &device,
11 RTCScene &scene) const {
12 ttk::Timer timer;
13 this->printMsg("Deallocating Scene", 0, 0, ttk::debug::LineMode::REPLACE);
14
15 rtcReleaseScene(scene);
16 rtcReleaseDevice(device);
17
18 this->printMsg("Deallocating Scene", 1, timer.getElapsedTime());
19
20 return 1;
21};
22
23int ttk::CinemaImagingEmbree::initializeDevice(RTCDevice &device) const {
24 ttk::Timer timer;
25 this->printMsg("Initializing Device", 0, 0, ttk::debug::LineMode::REPLACE);
26
27 device = rtcNewDevice("hugepages=1,threads=1");
28
29 if(!device) {
30 this->printErr("Unable to create device");
31 this->printErr(std::to_string(rtcGetDeviceError(nullptr)));
32 return 0;
33 }
34
35 auto errorFunction
36 = [](void *ttkNotUsed(userPtr), enum RTCError error, const char *str) {
37 printf("error %d: %s\n", error, str);
38 };
39
40 rtcSetDeviceErrorFunction(device, errorFunction, nullptr);
41
42 this->printMsg("Initializing Device", 1, timer.getElapsedTime());
43
44 return 1;
45};
46
47int ttk::CinemaImagingEmbree::renderImage(
48 float *depthBuffer,
49 unsigned int *primitiveIds,
50 float *barycentricCoordinates,
51
52 const RTCScene &scene,
53 const double resolution[2],
54 const double camPos[3],
55 const double camDirRaw[3],
56 const double camUp[3],
57 const double &camFactor,
58 const bool &orthographicProjection) const {
59
60 ttk::Timer timer;
61 const int resX = resolution[0];
62 const int resY = resolution[1];
63
64 this->printMsg("Rendering Image ("
65 + std::string(orthographicProjection ? "O" : "P") + "|"
66 + std::to_string(resX) + "x" + std::to_string(resY) + ")",
67 0, 0, this->threadNumber_, ttk::debug::LineMode::REPLACE);
68
69 struct RTCIntersectContext context;
70 rtcInitIntersectContext(&context);
71
72 const auto normalize = [](double out[3], const double in[3]) {
73 const double temp = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
74 out[0] = in[0] / temp;
75 out[1] = in[1] / temp;
76 out[2] = in[2] / temp;
77 };
78
79 double camDir[3]{0, 0, 0};
80 normalize(camDir, camDirRaw);
81
82 // Compute camRight = camDir x CamUp
83 double camRight[3]{camDir[1] * camUp[2] - camDir[2] * camUp[1],
84 camDir[2] * camUp[0] - camDir[0] * camUp[2],
85 camDir[0] * camUp[1] - camDir[1] * camUp[0]};
86 normalize(camRight, camRight);
87
88 // Compute true up std::vector
89 double camUpTrue[3]{camDir[1] * (-camRight[2]) - camDir[2] * (-camRight[1]),
90 camDir[2] * (-camRight[0]) - camDir[0] * (-camRight[2]),
91 camDir[0] * (-camRight[1]) - camDir[1] * (-camRight[0])};
92 normalize(camUpTrue, camUpTrue);
93
94 struct RTCRayHit rayhit;
95 rayhit.ray.dir_x = -1;
96 rayhit.ray.dir_y = -1;
97 rayhit.ray.dir_z = -1;
98
99 size_t pixelIndex = 0;
100 size_t bcIndex = 0;
101 const float nan = std::numeric_limits<float>::quiet_NaN();
102
103 if(orthographicProjection) {
104
105 // Compute camera size
106 const double aspect = resolution[0] / resolution[1];
107 const double camSize[2] = {aspect * camFactor, camFactor};
108
109 // Compute pixel size in world coordinates
110 const double pixelWidthWorld = camSize[0] / resolution[0];
111 const double pixelHeightWorld = camSize[1] / resolution[1];
112
113 // Optimization: precompute half of the camera size to reduce the number of
114 // operations in the for loop. Include a half pixel offset (-0.5) to center
115 // vertices at pixel centers
116 const double camWidthWorldHalf = 0.5 * camSize[0] - 0.5 * pixelWidthWorld;
117 const double camHeightWorldHalf = 0.5 * camSize[1] - 0.5 * pixelHeightWorld;
118
119 // Optimization: reorient camera model to bottom left corner to reduce
120 // operations in for loop
121 const double camPosCorner[3] = {camPos[0] - camRight[0] * camWidthWorldHalf
122 - camUpTrue[0] * camHeightWorldHalf,
123 camPos[1] - camRight[1] * camWidthWorldHalf
124 - camUpTrue[1] * camHeightWorldHalf,
125 camPos[2] - camRight[2] * camWidthWorldHalf
126 - camUpTrue[2] * camHeightWorldHalf};
127
128 for(int y = 0; y < resY; y++) {
129 const double v = ((double)y) * pixelHeightWorld;
130
131 for(int x = 0; x < resX; x++) {
132 const double u = ((double)x) * pixelWidthWorld;
133
134 // set origin
135 rayhit.ray.org_x = camPosCorner[0] + u * camRight[0] + v * camUpTrue[0];
136 rayhit.ray.org_y = camPosCorner[1] + u * camRight[1] + v * camUpTrue[1];
137 rayhit.ray.org_z = camPosCorner[2] + u * camRight[2] + v * camUpTrue[2];
138
139 // set dir
140 rayhit.ray.dir_x = camDir[0];
141 rayhit.ray.dir_y = camDir[1];
142 rayhit.ray.dir_z = camDir[2];
143
144 // compute hit
145 rayhit.ray.tnear = 0.01;
146 rayhit.ray.tfar = INFINITY;
147 rayhit.ray.mask = 0;
148 rayhit.ray.flags = 0;
149 rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
150 rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
151 rtcIntersect1(scene, &context, &rayhit);
152
153 // write depth
154 const bool hitPrimitive = rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID;
155 if(hitPrimitive) {
156 depthBuffer[pixelIndex] = std::max(0.0f, rayhit.ray.tfar);
157 primitiveIds[pixelIndex] = rayhit.hit.primID;
158 barycentricCoordinates[bcIndex++] = rayhit.hit.u;
159 barycentricCoordinates[bcIndex++] = rayhit.hit.v;
160 } else {
161 depthBuffer[pixelIndex] = nan;
162 primitiveIds[pixelIndex] = CinemaImaging::INVALID_ID;
163 barycentricCoordinates[bcIndex++] = nan;
164 barycentricCoordinates[bcIndex++] = nan;
165 }
166 pixelIndex++;
167 }
168 }
169 } else {
170
171 const double factor
172 = (camFactor / 180.0 * 3.141592653589793) / resolution[0];
173
174 for(int y = 0; y < resY; y++) {
175 const double v = (y - resY * 0.5) * factor;
176
177 for(int x = 0; x < resX; x++) {
178 const double u = (x - resX * 0.5) * factor;
179
180 // set origin
181 rayhit.ray.org_x = camPos[0];
182 rayhit.ray.org_y = camPos[1];
183 rayhit.ray.org_z = camPos[2];
184
185 // // set dir
186 rayhit.ray.dir_x = camDir[0] + u * camRight[0] + v * camUpTrue[0];
187 rayhit.ray.dir_y = camDir[1] + u * camRight[1] + v * camUpTrue[1];
188 rayhit.ray.dir_z = camDir[2] + u * camRight[2] + v * camUpTrue[2];
189
190 // compute hit
191 rayhit.ray.tnear = 0.01;
192 rayhit.ray.tfar = INFINITY;
193 rayhit.ray.mask = 0;
194 rayhit.ray.flags = 0;
195 rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
196 rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
197 rtcIntersect1(scene, &context, &rayhit);
198
199 // write depth
200 const bool hitPrimitive = rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID;
201 if(hitPrimitive) {
202 depthBuffer[pixelIndex] = std::max(0.0f, rayhit.ray.tfar);
203 primitiveIds[pixelIndex] = rayhit.hit.primID;
204 barycentricCoordinates[bcIndex++] = rayhit.hit.u;
205 barycentricCoordinates[bcIndex++] = rayhit.hit.v;
206 } else {
207 depthBuffer[pixelIndex] = nan;
208 primitiveIds[pixelIndex] = CinemaImaging::INVALID_ID;
209 barycentricCoordinates[bcIndex++] = nan;
210 barycentricCoordinates[bcIndex++] = nan;
211 }
212 pixelIndex++;
213 }
214 }
215 }
216
217 this->printMsg("Rendering Image ("
218 + std::string(orthographicProjection ? "O" : "P") + "|"
219 + std::to_string(resX) + "x" + std::to_string(resY) + ")",
220 1, timer.getElapsedTime(), this->threadNumber_);
221
222 return 1;
223};
224
225#endif // TTK_ENABLE_EMBREE
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
~CinemaImagingEmbree() override
static const unsigned int INVALID_ID
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
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)