48 #include "PLYparser.h" 63 , scaledMeshData(nullptr)
67 , angularSpectrum(nullptr)
72 , is_ViewingWindow(false)
74 , tempFreqTermX(nullptr)
75 , tempFreqTermY(nullptr)
76 , streamTriMesh(nullptr)
77 , angularSpectrum_GPU(nullptr)
80 LOG(
"*** TRI MESH : BUILD DATE: %s %s ***\n\n", __DATE__, __TIME__);
85 this->is_ViewingWindow = is_ViewingWindow;
92 if (meshData !=
nullptr)
99 if (!strcmp(ext,
"ply")) {
102 cout <<
"Mesh Data Load Finished.." << endl;
105 LOG(
"<FAILED> Loading ply file.\n");
110 LOG(
"<FAILED> Wrong file ext.\n");
114 triMeshArray = meshData->
faces;
133 LOG(
"<FAILED> Wrong file ext.\n");
138 LOG(
"<FAILED> Loading file.\n");
143 char szNodeName[32] = { 0, };
144 sprintf(szNodeName,
"ScaleX");
147 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&objSize[
_X]))
149 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
152 sprintf(szNodeName,
"ScaleY");
154 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&objSize[
_Y]))
156 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
159 sprintf(szNodeName,
"ScaleZ");
161 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&objSize[
_Z]))
163 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
167 sprintf(szNodeName,
"LampDirectionX");
169 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&illumination[
_X]))
171 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
174 sprintf(szNodeName,
"LampDirectionY");
176 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&illumination[
_Y]))
178 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
181 sprintf(szNodeName,
"LampDirectionZ");
183 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&illumination[
_Z]))
185 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
189 sprintf(szNodeName,
"Random_Phase");
192 if (!next ||
XML_SUCCESS != next->QueryBoolText(&randPhase))
194 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
198 sprintf(szNodeName,
"Occlusion");
200 if (!next ||
XML_SUCCESS != next->QueryBoolText(&occlusion))
202 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
205 sprintf(szNodeName,
"Texture");
207 if (!next ||
XML_SUCCESS != next->QueryBoolText(&textureMapping))
209 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
212 if (textureMapping ==
true)
214 sprintf(szNodeName,
"TextureSizeX");
216 if (!next ||
XML_SUCCESS != next->QueryIntText(&texture.dim[
_X]))
218 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
221 sprintf(szNodeName,
"TextureSizeY");
223 if (!next ||
XML_SUCCESS != next->QueryIntText(&texture.dim[
_Y]))
225 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
228 sprintf(szNodeName,
"TexturePeriod");
230 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&texture.period))
232 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
238 LOG(
"**************************************************\n");
239 LOG(
" Read Config (Tri Mesh) \n");
240 LOG(
"1) Illumination Direction : %.5lf / %.5lf / %.5lf\n", illumination[
_X], illumination[
_Y], illumination[
_Z]);
241 LOG(
"2) Object Scale : %.5lf / %.5lf / %.5lf\n", objSize[
_X], objSize[
_Y], objSize[
_Z]);
242 LOG(
"**************************************************\n");
250 if (tempFreqTermX !=
nullptr)
delete[] tempFreqTermX;
251 if (tempFreqTermY !=
nullptr)
delete[] tempFreqTermY;
253 if (textFFT !=
nullptr)
delete[] textFFT;
260 int size[2] = { 0,0 };
272 tempFreqTermX =
new Real[N];
273 tempFreqTermY =
new Real[N];
276 void ophTri::initializeAS()
279 const int N = meshData->
n_faces;
281 if (scaledMeshData !=
nullptr) {
282 delete[] scaledMeshData;
285 scaledMeshData =
new Face[N];
286 memset(scaledMeshData, 0,
sizeof(
Face) * N);
288 if (angularSpectrum !=
nullptr) {
289 delete[] angularSpectrum;
294 if (rearAS !=
nullptr) {
300 if (refAS !=
nullptr) {
306 if (phaseTerm !=
nullptr) {
313 if (convol !=
nullptr) {
324 memset(no, 0,
sizeof(
vec3) * N);
331 memset(na, 0,
sizeof(
vec3) * N);
337 nv =
new vec3[N * 3];
338 memset(nv, 0,
sizeof(
vec3) * N * 3);
341 void ophTri::objSort(
bool isAscending)
348 #pragma omp parallel for 350 for (
int i = 0; i < N; i++) {
364 for (
int i = 0; i < N - 1; i++)
368 if (centerZ[i] > centerZ[j]) {
369 Real tmpZ = centerZ[i];
370 centerZ[i] = centerZ[j];
373 tmp = scaledMeshData[i];
374 scaledMeshData[i] = scaledMeshData[j];
375 scaledMeshData[j] = tmp;
387 for (
int i = 0; i < N - 1; i++)
391 if (centerZ[i] < centerZ[j]) {
392 Real tmpZ = centerZ[i];
393 centerZ[i] = centerZ[j];
396 tmp = scaledMeshData[i];
397 scaledMeshData[i] = scaledMeshData[j];
398 scaledMeshData[j] = tmp;
415 c(0) = a(0 + 1) * b(0 + 2) - a(0 + 2) * b(0 + 1);
417 c(1) = a(1 + 1) * b(1 + 2) - a(1 + 2) * b(1 + 1);
419 c(2) = a(2 + 1) * b(2 + 2) - a(2 + 2) * b(2 + 1);
431 int nFx = floor(rangeFx / stepFx);
432 int nFy = floor(rangeFy / stepFy);
434 for (
int iFy = 0; iFy <= nFy; iFy++) {
435 for (
int iFx = 0; iFx <= nFx; iFx++) {
437 tFx = cenFx - rangeFx / 2 + iFx*stepFx;
438 tFy = cenFy - rangeFy / 2 + iFy*stepFy;
450 sprintf(strFxFy,
"%s/holo_%d,%d.bmp", dirName, (
int)tFx, (
int)tFy);
459 sprintf(strFxFy,
"%s/AS_%d,%d.bmp", dirName, (
int)tFx, (
int)tFy);
468 LOG(
"<FAILED> WRONG SHADING_FLAG\n");
475 LOG(
"**************************************************\n");
476 LOG(
" Generate Hologram \n");
477 LOG(
"1) Algorithm Method : Tri Mesh\n");
487 LOG(
"4) Shading Flag : %s\n",
SHADING_FLAG == SHADING_FLAG::SHADING_FLAT ?
"Flat" :
"Continuous");
488 LOG(
"5) Number of Mesh : %llu\n", meshData->
n_faces);
489 LOG(
"**************************************************\n");
521 LOG(
"Total Elapsed Time: %.5lf (s)\n", elapsed_time);
544 for (
int j = 0; j < N; j++)
546 Face mesh = scaledMeshData[j];
551 if (!checkValidity(no[j]))
553 if (!findGeometricalRelations(mesh, no[j], geom))
565 refAS_Continuous(j, freqTermX, freqTermY);
568 LOG(
"<FAILED> WRONG SHADING_FLAG\n");
571 if (!refToGlobal(
complex_H[ch], freq, fl, geom))
582 delete[] scaledMeshData;
591 scaledMeshData =
nullptr;
596 for (
int i = 0; i < 3; i++) {
601 delete[] freq, fl, scaledMeshData, freqTermX, freqTermY, refAS, phaseTerm, convol;
602 scaledMeshData =
nullptr;
613 void ophTri::calGlobalFrequency(
Point* frequency,
Real lambda)
621 Real dfx = 1 / (ppX * pnX);
622 Real dfy = 1 / (ppY * pnY);
624 int startX = pnX >> 1;
625 int startY = pnY >> 1;
627 Real dfl = 1 / lambda;
628 Real sqdfl = dfl * dfl;
631 #pragma omp parallel for firstprivate(pnX, startX, dfy, dfx, sqdfl) 633 for (
int i = startY; i > -startY; i--) {
637 int base = (startY - i) * pnX;
639 for (
int j = -startX; j < startX; j++) {
640 int idx = base + (j + startX);
643 frequency[idx].
pos[
_X] = x;
644 frequency[idx].
pos[
_Y] = y;
645 frequency[idx].
pos[
_Z] = sqrt(sqdfl - xx - yy);
660 #pragma omp parallel for reduction(+:normNo) 662 for (
int i = 0; i < N; i++) {
665 scaledMeshData[i].vertices[
_FIRST].point.pos[
_X] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_X],
666 scaledMeshData[i].vertices[
_FIRST].point.pos[
_Y] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_Y],
667 scaledMeshData[i].vertices[
_FIRST].point.pos[
_Z] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_Z]
670 scaledMeshData[i].vertices[
_THIRD].point.pos[
_X] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_X],
671 scaledMeshData[i].vertices[
_THIRD].point.pos[
_Y] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_Y],
672 scaledMeshData[i].vertices[
_THIRD].point.pos[
_Z] - scaledMeshData[i].vertices[
_SECOND].point.pos[
_Z]
678 normNo = sqrt(normNo);
681 #pragma omp parallel for firstprivate(normNo) 683 for (
int i = 0; i < N; i++) {
684 na[i] = no[i] / normNo;
691 for (
uint i = 0; i < N3; i++)
694 int idxVertex = i % 3;
695 std::memcpy(&vertices[i], &scaledMeshData[idxFace].vertices[idxVertex].point,
sizeof(
Point));
701 for (
uint idx1 = 0; idx1 < N3; idx1++) {
702 if (vertices[idx1] == zeros)
708 for (
uint idx2 = idx1 + 1; idx2 < N3; idx2++) {
709 if (vertices[idx2] == zeros)
711 if ((vertices[idx1][0] == vertices[idx2][0])
712 && (vertices[idx1][1] == vertices[idx2][1])
713 && (vertices[idx1][2] == vertices[idx2][2])) {
716 vertices[idx2] = zeros;
717 idxes[count++] = idx2;
720 vertices[idx1] = zeros;
724 for (
uint i = 0; i < count; i++)
738 bool ophTri::checkValidity(
vec3 no)
740 if (no[
_Z] < 0 || (no[
_X] == 0 && no[
_Y] == 0 && no[
_Z] == 0))
754 if (n[
_X] == 0 && n[
_Z] == 0)
757 th = atan(n[
_X] / n[
_Z]);
762 Real costh = cos(th);
763 Real cosph = cos(ph);
764 Real sinth = sin(th);
765 Real sinph = sin(ph);
768 geom.
glRot[3] = -sinph * sinth; geom.
glRot[4] = cosph; geom.
glRot[5] = -sinph * costh;
769 geom.
glRot[6] = cosph * sinth; geom.
glRot[7] = sinph; geom.
glRot[8] = cosph * costh;
772 for (
int i = 0; i < 3; i++)
799 Real refTri[9] = { 0,0,0,1,1,0,1,0,0 };
821 Real divDet = 1 / det;
824 invLoRot[0] = divDet * geom.
loRot[3];
825 invLoRot[1] = -divDet * geom.
loRot[2];
826 invLoRot[2] = -divDet * geom.
loRot[1];
827 invLoRot[3] = divDet * geom.
loRot[0];
829 Real carrierWaveLoc[3];
831 memcpy(glRot, geom.
glRot,
sizeof(glRot));
832 memcpy(carrierWaveLoc, carrierWave,
sizeof(carrierWaveLoc));
835 #pragma omp parallel for firstprivate(w, ww, glRot, carrierWaveLoc, invLoRot) 837 for (
int i = 0; i < pnXY; i++)
839 fl[i].
pos[
_X] = glRot[0] * frequency[i].
pos[
_X] + glRot[1] * frequency[i].
pos[
_Y] + glRot[2] * frequency[i].
pos[
_Z];
840 fl[i].
pos[
_Y] = glRot[3] * frequency[i].
pos[
_X] + glRot[4] * frequency[i].
pos[
_Y] + glRot[5] * frequency[i].
pos[
_Z];
841 fl[i].
pos[
_Z] = sqrt(ww - fl[i].pos[
_X] * fl[i].pos[
_X] - fl[i].pos[
_Y] * fl[i].pos[
_Y]);
843 Real flxShifted = fl[i].
pos[
_X] -
w * (glRot[0] * carrierWaveLoc[
_X] + glRot[1] * carrierWaveLoc[
_Y] + glRot[2] * carrierWaveLoc[
_Z]);
844 Real flyShifted = fl[i].
pos[
_Y] -
w * (glRot[3] * carrierWaveLoc[
_X] + glRot[4] * carrierWaveLoc[
_Y] + glRot[5] * carrierWaveLoc[
_Z]);
846 freqTermX[i] = invLoRot[0] * flxShifted + invLoRot[1] * flyShifted;
847 freqTermY[i] = invLoRot[2] * flxShifted + invLoRot[3] * flyShifted;
858 Real w = 1 / waveLength;
862 Real divDet = 1 / det;
865 invLoRot[0] = divDet * geom.
loRot[3];
866 invLoRot[1] = -divDet * geom.
loRot[2];
867 invLoRot[2] = -divDet * geom.
loRot[1];
868 invLoRot[3] = divDet * geom.
loRot[0];
870 Real carrierWaveLoc[3];
872 memcpy(glRot, geom.
glRot,
sizeof(glRot));
873 memcpy(carrierWaveLoc, carrierWave,
sizeof(carrierWaveLoc));
876 #pragma omp parallel for firstprivate(w, ww, glRot, carrierWaveLoc, invLoRot) 878 for (
int i = 0; i < pnXY; i++) {
882 fl[
_X][i] = glRot[0] * frequency[
_X][i] + glRot[1] * frequency[
_Y][i] + glRot[2] * frequency[
_Z][i];
883 fl[
_Y][i] = glRot[3] * frequency[
_X][i] + glRot[4] * frequency[
_Y][i] + glRot[5] * frequency[
_Z][i];
884 fl[
_Z][i] = sqrt(ww - fl[
_X][i] * fl[
_X][i] - fl[
_Y][i] * fl[
_Y][i]);
885 flxShifted = fl[
_X][i] -
w * (glRot[0] * carrierWaveLoc[
_X] + glRot[1] * carrierWaveLoc[
_Y] + glRot[2] * carrierWaveLoc[
_Z]);
886 flyShifted = fl[
_Y][i] -
w * (glRot[3] * carrierWaveLoc[
_X] + glRot[4] * carrierWaveLoc[
_Y] + glRot[5] * carrierWaveLoc[
_Z]);
888 freqTermX[i] = invLoRot[0] * flxShifted + invLoRot[1] * flyShifted;
889 freqTermY[i] = invLoRot[2] * flxShifted + invLoRot[3] * flyShifted;
904 Real sqPI2 = PI2 * PI2;
907 term1[
_IM] = -PI2 / lambda * (
913 if (illumination[
_X] == 0 && illumination[
_Y] == 0 && illumination[
_Z] == 0) {
914 shadingFactor = exp(term1);
917 vec3 normIllu = illumination /
norm(illumination);
918 shadingFactor = (2 * (n[
_X] * normIllu[
_X] + n[
_Y] * normIllu[
_Y] + n[
_Z] * normIllu[
_Z]) + 0.3) * exp(term1);
919 if (shadingFactor[
_RE] * shadingFactor[
_RE] + shadingFactor[
_IM] * shadingFactor[
_IM] < 0)
927 Real dfxy = dfx * dfy;
930 #pragma omp parallel for firstprivate(PI2, dfxy, mesh, term1) 932 for (
int i = 0; i < pnXY; i++) {
937 rearAS[i] = angularSpectrum[i] * exp(term1) * dfxy;
940 refASInner_flat(freqTermX, freqTermY);
944 #pragma omp parallel for firstprivate(PI2, shadingFactor) 946 for (
int i = 0; i < pnXY; i++) {
948 phase[
_IM] = PI2 *
rand(0.0, 1.0, i);
949 convol[i] = shadingFactor * exp(phase) - rearAS[i];
956 #pragma omp parallel for firstprivate(shadingFactor) 958 for (
int i = 0; i < pnXY; i++) {
959 refAS[i] = refAS[i] * shadingFactor - convol[i];
964 refASInner_flat(freqTermX, freqTermY);
966 if (randPhase ==
true) {
969 #pragma omp parallel for firstprivate(PI2, shadingFactor) 971 for (
int i = 0; i < pnXY; i++) {
973 phase[
_IM] = PI2 * randVal;
974 phaseTerm[i] = shadingFactor * exp(phase);
980 #pragma omp parallel for firstprivate(shadingFactor) 982 for (
int i = 0; i < pnXY; i++) {
983 refAS[i] *= shadingFactor;
989 void ophTri::refASInner_flat(
Real* freqTermX,
Real* freqTermY)
997 for (
int i = 0; i < pnXY; i++) {
998 if (textureMapping ==
true) {
1000 for (
int idxFy = -texture.
dim[
_Y] / 2; idxFy < texture.
dim[
_Y] / 2; idxFy++) {
1001 for (
int idxFx = -texture.
dim[
_X] / 2; idxFx < texture.
dim[
_X] / 2; idxFy++) {
1002 textFreqX = idxFx * texture.
freq;
1003 textFreqY = idxFy * texture.
freq;
1005 tempFreqTermX[i] = freqTermX[i] - textFreqX;
1006 tempFreqTermY[i] = freqTermY[i] - textFreqY;
1008 if (tempFreqTermX[i] == -tempFreqTermY[i] && tempFreqTermY[i] != 0.0) {
1009 refTerm1[
_IM] = PI2 * tempFreqTermY[i];
1010 refTerm2[
_IM] = 1.0;
1011 refTemp = ((
Complex<Real>)1.0 - exp(refTerm1)) / (4.0 *
M_PI*
M_PI*tempFreqTermY[i] * tempFreqTermY[i]) + refTerm2 / (PI2*tempFreqTermY[i]);
1012 refAS[i] = refAS[i] + textFFT[idxFx + texture.
dim[
_X] / 2 + (idxFy + texture.
dim[
_Y] / 2)*texture.
dim[
_X]] * refTemp;
1015 else if (tempFreqTermX[i] == tempFreqTermY[i] && tempFreqTermX[i] == 0.0) {
1016 refTemp = (
Real)(1.0 / 2.0);
1017 refAS[i] = refAS[i] + textFFT[idxFx + texture.
dim[
_X] / 2 + (idxFy + texture.
dim[
_Y] / 2)*texture.
dim[
_X]] * refTemp;
1019 else if (tempFreqTermX[i] != 0.0 && tempFreqTermY[i] == 0.0) {
1020 refTerm1[
_IM] = -PI2 * tempFreqTermX[i];
1021 refTerm2[
_IM] = 1.0;
1022 refTemp = (exp(refTerm1) - (
Complex<Real>)1.0) / (PI2*tempFreqTermX[i] * PI2*tempFreqTermX[i]) + (refTerm2 * exp(refTerm1)) / (PI2*tempFreqTermX[i]);
1023 refAS[i] = refAS[i] + textFFT[idxFx + texture.
dim[
_X] / 2 + (idxFy + texture.
dim[
_Y] / 2)*texture.
dim[
_X]] * refTemp;
1025 else if (tempFreqTermX[i] == 0.0 && tempFreqTermY[i] != 0.0) {
1026 refTerm1[
_IM] = PI2 * tempFreqTermY[i];
1027 refTerm2[
_IM] = 1.0;
1028 refTemp = ((
Complex<Real>)1.0 - exp(refTerm1)) / (4.0 *
M_PI*
M_PI*tempFreqTermY[i] * tempFreqTermY[i]) - refTerm2 / (PI2*tempFreqTermY[i]);
1029 refAS[i] = refAS[i] + textFFT[idxFx + texture.
dim[
_X] / 2 + (idxFy + texture.
dim[
_Y] / 2)*texture.
dim[
_X]] * refTemp;
1032 refTerm1[
_IM] = -PI2 * tempFreqTermX[i];
1033 refTerm2[
_IM] = -PI2 * (tempFreqTermX[i] + tempFreqTermY[i]);
1034 refTemp = (exp(refTerm1) - (
Complex<Real>)1.0) / (4.0 *
M_PI*
M_PI*tempFreqTermX[i] * tempFreqTermY[i]) + ((
Complex<Real>)1.0 - exp(refTerm2)) / (4.0 *
M_PI*
M_PI*tempFreqTermY[i] * (tempFreqTermX[i] + tempFreqTermY[i]));
1035 refAS[i] = refAS[i] + textFFT[idxFx + texture.
dim[
_X] / 2 + (idxFy + texture.
dim[
_Y] / 2)*texture.
dim[
_X]] * refTemp;
1041 if (freqTermX[i] == -freqTermY[i] && freqTermY[i] != 0.0) {
1042 refTerm1[
_IM] = PI2 * freqTermY[i];
1043 refTerm2[
_IM] = 1.0;
1044 refAS[i] = ((
Complex<Real>)1.0 - exp(refTerm1)) / (4.0 *
M_PI*
M_PI*freqTermY[i] * freqTermY[i]) + refTerm2 / (PI2*freqTermY[i]);
1046 else if (freqTermX[i] == freqTermY[i] && freqTermX[i] == 0.0) {
1047 refAS[i] = (
Real)(1.0 / 2.0);
1049 else if (freqTermX[i] != 0 && freqTermY[i] == 0.0) {
1050 refTerm1[
_IM] = -PI2 * freqTermX[i];
1051 refTerm2[
_IM] = 1.0;
1052 refAS[i] = (exp(refTerm1) - (
Complex<Real>)1.0) / (PI2 * freqTermX[i] * PI2 * freqTermX[i]) + (refTerm2 * exp(refTerm1)) / (PI2*freqTermX[i]);
1054 else if (freqTermX[i] == 0 && freqTermY[i] != 0.0) {
1055 refTerm1[
_IM] = PI2 * freqTermY[i];
1056 refTerm2[
_IM] = 1.0;
1057 refAS[i] = ((
Complex<Real>)1.0 - exp(refTerm1)) / (PI2 * PI2 * freqTermY[i] * freqTermY[i]) - refTerm2 / (PI2*freqTermY[i]);
1060 refTerm1[
_IM] = -PI2 * freqTermX[i];
1061 refTerm2[
_IM] = -PI2 * (freqTermX[i] + freqTermY[i]);
1062 refAS[i] = (exp(refTerm1) - (
Complex<Real>)1.0) / (PI2 * PI2 * freqTermX[i] * freqTermY[i]) + ((
Complex<Real>)1.0 - exp(refTerm2)) / (4.0 *
M_PI*
M_PI*freqTermY[i] * (freqTermX[i] + freqTermY[i]));
1068 bool ophTri::refAS_Continuous(
uint n,
Real* freqTermX,
Real* freqTermY)
1072 av =
vec3(0.0, 0.0, 0.0);
1073 av[0] = nv[3 * n + 0][0] * illumination[0] + nv[3 * n + 0][1] * illumination[1] + nv[3 * n + 0][2] * illumination[2] + 0.1;
1074 av[2] = nv[3 * n + 1][0] * illumination[0] + nv[3 * n + 1][1] * illumination[1] + nv[3 * n + 1][2] * illumination[2] + 0.1;
1075 av[1] = nv[3 * n + 2][0] * illumination[0] + nv[3 * n + 2][1] * illumination[1] + nv[3 * n + 2][2] * illumination[2] + 0.1;
1082 for (
int i = 0; i < pnXY; i++) {
1083 if (freqTermX[i] == 0.0 && freqTermY[i] == 0.0) {
1089 else if (freqTermX[i] == 0.0 && freqTermY[i] != 0.0) {
1090 refTerm1[
_IM] = -2 *
M_PI*freqTermY[i];
1093 D1 = (refTerm1 - 1.0)*refTerm1.
exp() / (8.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * freqTermY[i])
1094 - refTerm1 / (4.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * freqTermY[i]);
1095 D2 = -(
M_PI*freqTermY[i] + refTerm2) / (4.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * freqTermY[i])*exp(refTerm1)
1096 + refTerm1 / (8.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * freqTermY[i]);
1097 D3 = exp(refTerm1) / (2.0 *
M_PI*freqTermY[i]) + (1.0 - refTerm2) / (2.0 *
M_PI*freqTermY[i]);
1099 else if (freqTermX[i] != 0.0 && freqTermY[i] == 0.0) {
1100 refTerm1[
_IM] = 4.0 *
M_PI*
M_PI*freqTermX[i] * freqTermX[i];
1101 refTerm2[
_IM] = 1.0;
1102 refTerm3[
_IM] = 2.0 *
M_PI*freqTermX[i];
1104 D1 = (refTerm1 + 4.0 *
M_PI*freqTermX[i] - 2.0 * refTerm2) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * freqTermY[i])*exp(-refTerm3)
1105 + refTerm2 / (4.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermX[i]);
1106 D2 = 1.0 / 2.0 * D1;
1107 D3 = ((refTerm3 + 1.0)*exp(-refTerm3) - 1.0) / (4.0 *
M_PI*
M_PI*freqTermX[i] * freqTermX[i]);
1109 else if (freqTermX[i] == -freqTermY[i]) {
1110 refTerm1[
_IM] = 1.0;
1111 refTerm2[
_IM] = 2.0 *
M_PI*freqTermX[i];
1112 refTerm3[
_IM] = 2.0 *
M_PI*
M_PI*freqTermX[i] * freqTermX[i];
1114 D1 = (-2.0 *
M_PI*freqTermX[i] + refTerm1) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermX[i])*exp(-refTerm2)
1115 - (refTerm3 + refTerm1) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermX[i]);
1116 D2 = (-refTerm1) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermX[i])*exp(-refTerm2)
1117 + (-refTerm3 + refTerm1 + 2.0 *
M_PI*freqTermX[i]) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermX[i]);
1118 D3 = (-refTerm1) / (4.0 *
M_PI*
M_PI*freqTermX[i] * freqTermX[i])*exp(-refTerm2)
1119 + (-refTerm2 + 1.0) / (4.0 *
M_PI*
M_PI*freqTermX[i] * freqTermX[i]);
1122 refTerm1[
_IM] = -2.0 *
M_PI*(freqTermX[i] + freqTermY[i]);
1123 refTerm2[
_IM] = 1.0;
1124 refTerm3[
_IM] = -2.0 *
M_PI*freqTermX[i];
1126 D1 = exp(refTerm1)*(refTerm2 - 2.0 *
M_PI*(freqTermX[i] + freqTermY[i])) / (8 *
M_PI*
M_PI*
M_PI*freqTermY[i] * (freqTermX[i] + freqTermY[i])*(freqTermX[i] + freqTermY[i]))
1127 + exp(refTerm3)*(2.0 *
M_PI*freqTermX[i] - refTerm2) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * freqTermY[i])
1128 + ((2.0 * freqTermX[i] + freqTermY[i])*refTerm2) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermX[i] * (freqTermX[i] + freqTermY[i])*(freqTermX[i] + freqTermY[i]));
1129 D2 = exp(refTerm1)*(refTerm2*(freqTermX[i] + 2.0 * freqTermY[i]) - 2.0 *
M_PI*freqTermY[i] * (freqTermX[i] + freqTermY[i])) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermY[i] * freqTermY[i] * (freqTermX[i] + freqTermY[i])*(freqTermX[i] + freqTermY[i]))
1130 + exp(refTerm3)*(-refTerm2) / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * freqTermY[i] * freqTermY[i])
1131 + refTerm2 / (8.0 *
M_PI*
M_PI*
M_PI*freqTermX[i] * (freqTermX[i] + freqTermY[i])* (freqTermX[i] + freqTermY[i]));
1132 D3 = -exp(refTerm1) / (4.0 *
M_PI*
M_PI*freqTermY[i] * (freqTermX[i] + freqTermY[i]))
1133 + exp(refTerm3) / (4.0 *
M_PI*
M_PI*freqTermX[i] * freqTermY[i])
1134 - 1.0 / (4.0 *
M_PI*
M_PI*freqTermX[i] * (freqTermX[i] + freqTermY[i]));
1136 refAS[i] = (av[1] - av[0])*D1 + (av[2] - av[1])*D2 + av[0] * D3;
1138 if (randPhase ==
true) {
1141 for (
int i = 0; i < pnXY; i++) {
1143 phase[
_IM] = PI2 * randVal;
1144 phaseTerm[i] = exp(phase);
1170 #pragma omp parallel for firstprivate(det, g) 1172 for (
int i = 0; i < pnXY; i++)
1177 if (frequency[i].pos[
_Z] == 0)
1182 term2 = refAS[i] / det * fl[i].
pos[
_Z] / frequency[i].
pos[
_Z] * exp(term1);
1215 #pragma omp parallel for firstprivate(det, g, term1, term2) 1217 for (
int i = 0; i < pnXY; i++) {
1218 if (frequency[
_Z][i] == 0)
1222 term2 = refAS[i] / det * fl[
_Z][i] / frequency[
_Z][i] * exp(term1);
1249 const int N = size[
_X] * size[
_Y];
1263 for (
int i = 0; i < N; i++)
1264 dstFT[i] = src1FT[i] * src2FT[i] * scale;
1273 void ophTri::prepareMeshData()
1276 const int N = meshData->
n_faces;
1277 const int N3 = N * 3;
1280 Real x_max, x_min, y_max, y_min, z_max, z_min;
1284 for (
int i = 0; i < N3; i++)
1286 int idxFace = i / 3;
1287 int idxPoint = i % 3;
1289 if (x_max < triMeshArray[idxFace].vertices[idxPoint].point.pos[
_X]) x_max = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_X];
1290 if (x_min > triMeshArray[idxFace].vertices[idxPoint].point.pos[
_X]) x_min = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_X];
1291 if (y_max < triMeshArray[idxFace].vertices[idxPoint].point.pos[
_Y]) y_max = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Y];
1292 if (y_min > triMeshArray[idxFace].vertices[idxPoint].point.pos[
_Y]) y_min = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Y];
1293 if (z_max < triMeshArray[idxFace].vertices[idxPoint].point.pos[
_Z]) z_max = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Z];
1294 if (z_min > triMeshArray[idxFace].vertices[idxPoint].point.pos[
_Z]) z_min = triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Z];
1297 Real x_cen = (x_max + x_min) / 2;
1298 Real y_cen = (y_max + y_min) / 2;
1299 Real z_cen = (z_max + z_min) / 2;
1300 vec3 cen(x_cen, y_cen, z_cen);
1302 Real x_del = x_max - x_min;
1303 Real y_del = y_max - y_min;
1304 Real z_del = z_max - z_min;
1309 vec3 locObjSize = objSize;
1311 #pragma omp parallel for firstprivate(cen, del, locObjSize, shift) 1313 for (
int i = 0; i < N3; i++)
1315 int idxFace = i / 3;
1316 int idxPoint = i % 3;
1317 scaledMeshData[idxFace].vertices[idxPoint].point.pos[
_X] = (triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_X] - cen[
_X]) / del * locObjSize[
_X] + shift[
_X];
1318 scaledMeshData[idxFace].vertices[idxPoint].point.pos[
_Y] = (triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Y] - cen[
_Y]) / del * locObjSize[
_Y] + shift[
_Y];
1319 scaledMeshData[idxFace].vertices[idxPoint].point.pos[
_Z] = (triMeshArray[idxFace].
vertices[idxPoint].
point.
pos[
_Z] - cen[
_Z]) / del * locObjSize[
_Z] + shift[
_Z];
1332 for (
uint ch = 0; ch < nChannel; ch++) {
1339 for (
uint ch = 0; ch < nChannel; ch++)
bool loadPLY(const std::string &fileName, ulonglong &n_points, Vertex **vertices)
void abs(const oph::Complex< T > &src, oph::Complex< T > &dst)
OphConfig & getContext(void)
Function for getting the current context.
ulonglong n_faces
The number of faces in object.
void setViewingWindow(bool is_ViewingWindow)
Set the value of a variable is_ViewingWindow(true or false)
SHADING_FLAG
Mesh object data scaling and shifting.
void initialize(void)
Initialize variables for Hologram complex field, encoded data, normalized data.
bool checkExtension(const char *fname, const char *ext)
Functions for extension checking.
structure for 2-dimensional integer vector and its arithmetic.
void loadTexturePattern(const char *fileName, const char *ext)
bool GetRandomPhase()
Function for getting the random phase.
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Real generateHologram(uint SHADING_FLAG)
Hologram generation.
void reconTest(const char *fname)
void normalize(void)
Normalization function to save as image file after hologram creation.
void setEncodeMethod(unsigned int ENCODE_FLAG)
void triTimeMultiplexing(char *dirName, uint ENCODE_METHOD, Real cenFx, Real cenFy, Real rangeFx, Real rangeFy, Real stepFx, Real stepFy)
bool save(const char *fname, uint8_t bitsperpixel=8, uchar *src=nullptr, uint px=0, uint py=0)
Function for saving image files.
ivec2 m_vecEncodeSize
Encoded hologram size, varied from encoding type.
bool getImgSize(int &w, int &h, int &bytesperpixel, const char *fname)
Function for getting the image size.
Complex< Real > * pattern
Real ** m_lpEncoded
buffer to encoded.
void fftExecute(Complex< Real > *out, bool bReverse=false)
Execution functions to be called after fft1, fft2, and fft3.
void fft2(ivec2 n, Complex< Real > *in, int sign=OPH_FORWARD, uint flag=OPH_ESTIMATE)
Functions for performing fftw 2-dimension operations inside Openholo.
bool loadMeshData(const char *fileName, const char *ext)
Mesh data load.
void fresnelPropagation(OphConfig context, Complex< Real > *in, Complex< Real > *out, Real distance)
Fresnel propagation.
Data for triangular mesh.
structure for 3-dimensional Real type vector and its arithmetic.
bool readConfig(const char *fname)
load to configuration file.
XMLError LoadFile(const char *filename)
Real rand(const Real min, const Real max, oph::ulong _SEED_VALUE=0)
Get random Real value from min to max.
Complex< Real > ** complex_H
Complex< Real > * AS
Binary Encoding - Error diffusion.
bool readConfig(const char *fname)
Triangular mesh basc CGH configuration file load.
Real maxOfArr(const std::vector< Real > &arr)
void resetBuffer()
reset buffer
#define ELAPSED_TIME(x, y)
int ENCODE_METHOD
Encoding method flag.
const XMLElement * FirstChildElement(const char *name=0) const
vec3 vecCross(const vec3 &a, const vec3 &b)