Openholo  v5.0
Open Source Digital Holographic Library
ophWRP.cpp
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
7 //
8 //
9 // License Agreement
10 // For Open Source Digital Holographic Library
11 //
12 // Openholo library is free software;
13 // you can redistribute it and/or modify it under the terms of the BSD 2-Clause license.
14 //
15 // Copyright (C) 2017-2024, Korea Electronics Technology Institute. All rights reserved.
16 // E-mail : contact.openholo@gmail.com
17 // Web : http://www.openholo.org
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // 1. Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holder or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // This software contains opensource software released under GNU Generic Public License,
41 // NVDIA Software License Agreement, or CUDA supplement to Software License Agreement.
42 // Check whether software you use contains licensed software.
43 //
44 //M*/
45 
46 #include "ophWRP.h"
47 #include "sys.h"
48 #include "tinyxml2.h"
49 
51  : ophGen()
52  , scaledVertex(nullptr)
53  , m_nProgress(0)
54  , zmax_(0.0)
55 {
56  n_points = -1;
57  p_wrp_ = nullptr;
58  is_ViewingWindow = false;
59  LOG("*** WRP : BUILD DATE: %s %s ***\n\n", __DATE__, __TIME__);
60 }
61 
63 {
64 }
65 
66 void ophWRP::setViewingWindow(bool is_ViewingWindow)
67 {
68  this->is_ViewingWindow = is_ViewingWindow;
69 }
70 
72 {
73  LOG("%s : ", __FUNCTION__);
74  auto begin = CUR_TIME;
75 
76  const uint pnX = context_.pixel_number[_X];
77  const uint pnY = context_.pixel_number[_Y];
78  const Real ppX = context_.pixel_pitch[_X];
79  const Real ppY = context_.pixel_pitch[_Y];
80 
81  Real size = pnY * ppY * 0.8 / 2.0;
82 
83  if (scaledVertex) {
84  delete[] scaledVertex;
85  scaledVertex = nullptr;
86  }
88 
89  std::memcpy(scaledVertex, obj_.vertices, sizeof(Vertex) * n_points);
90 
91  vec3 scale = wrp_config_.scale;
92 
93 #if 1
94  zmax_ = MIN_DOUBLE;
95  for (int i = 0; i < n_points; i++)
96  {
97  scaledVertex[i].point.pos[_X] = scaledVertex[i].point.pos[_X] * scale[_X];
98  scaledVertex[i].point.pos[_Y] = scaledVertex[i].point.pos[_Y] * scale[_Y];
99  scaledVertex[i].point.pos[_Z] = scaledVertex[i].point.pos[_Z] * scale[_Z];
100 
101  if (zmax_ < scaledVertex[i].point.pos[_Z]) zmax_ = scaledVertex[i].point.pos[_Z];
102  }
103 #else
104 
105  Real x_max, y_max, z_max;
106  x_max = y_max = z_max = MIN_DOUBLE;
107 
108  for (int i = 0; i < n_points; i++)
109  {
110  if (x_max < scaledVertex[i].point.pos[_X]) x_max = scaledVertex[i].point.pos[_X];
111  if (y_max < scaledVertex[i].point.pos[_Y]) y_max = scaledVertex[i].point.pos[_Y];
112  if (z_max < scaledVertex[i].point.pos[_Z]) z_max = scaledVertex[i].point.pos[_Z];
113  }
114 
115  Real maxXY = (x_max > y_max) ? x_max : y_max;
116  zmax_ = MIN_DOUBLE;
117  for (int j = 0; j < n_points; ++j)
118  { //Create Fringe Pattern
119  scaledVertex[j].point.pos[_X] = scaledVertex[j].point.pos[_X] / maxXY * size;
120  scaledVertex[j].point.pos[_Y] = scaledVertex[j].point.pos[_Y] / maxXY * size;
121  scaledVertex[j].point.pos[_Z] = scaledVertex[j].point.pos[_Z] / z_max * size;
122 
123  if (zmax_ < scaledVertex[j].point.pos[_Z]) zmax_ = scaledVertex[j].point.pos[_Z];
124  }
125 
126 #endif
127  LOG("%lf (s)\n", ELAPSED_TIME(begin, CUR_TIME));
128 }
129 
130 int ophWRP::loadPointCloud(const char* pc_file)
131 {
132  n_points = ophGen::loadPointCloud(pc_file, &obj_);
133 
134  return n_points;
135 
136 }
137 
138 bool ophWRP::readConfig(const char* fname)
139 {
140  if (!ophGen::readConfig(fname))
141  return false;
142 
143  bool bRet = true;
144  using namespace tinyxml2;
145  /*XML parsing*/
146  tinyxml2::XMLDocument xml_doc;
147  XMLNode* xml_node;
148 
149  if (!checkExtension(fname, ".xml"))
150  {
151  LOG("<FAILED> Wrong file ext.\n");
152  return false;
153  }
154  if (xml_doc.LoadFile(fname) != XML_SUCCESS)
155  {
156  LOG("<FAILED> Loading file.\n");
157  return false;
158  }
159  xml_node = xml_doc.FirstChild();
160 
161  char szNodeName[32] = { 0, };
162  // about viewing window
163  sprintf(szNodeName, "FieldLength");
164  auto next = xml_node->FirstChildElement(szNodeName);
165  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.fieldLength))
166  {
167  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
168  bRet = false;
169  }
170  // about point
171  sprintf(szNodeName, "ScaleX");
172  next = xml_node->FirstChildElement(szNodeName);
173  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.scale[_X]))
174  {
175  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
176  bRet = false;
177  }
178  sprintf(szNodeName, "ScaleY");
179  next = xml_node->FirstChildElement(szNodeName);
180  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.scale[_Y]))
181  {
182  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
183  bRet = false;
184  }
185  sprintf(szNodeName, "ScaleZ");
186  next = xml_node->FirstChildElement(szNodeName);
187  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.scale[_Z]))
188  {
189  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
190  bRet = false;
191  }
192  sprintf(szNodeName, "Distance");
193  next = xml_node->FirstChildElement(szNodeName);
194  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.propagation_distance))
195  {
196  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
197  bRet = false;
198  }
199  sprintf(szNodeName, "LocationOfWRP");
200  next = xml_node->FirstChildElement(szNodeName);
201  if (!next || XML_SUCCESS != next->QueryDoubleText(&wrp_config_.wrp_location))
202  {
203  LOG("<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
204  bRet = false;
205  }
206  sprintf(szNodeName, "NumOfWRP");
207  next = xml_node->FirstChildElement(szNodeName);
208  if (!next || XML_SUCCESS != next->QueryIntText(&wrp_config_.num_wrp))
209  {
210  LOG("<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
211  bRet = false;
212  }
213  initialize();
214 
215 
216  LOG("**************************************************\n");
217  LOG(" Read Config (WRP) \n");
218  LOG("1) Focal Length : %.5lf\n", wrp_config_.propagation_distance);
219  LOG("2) Object Scale : %.5lf / %.5lf / %.5lf\n", wrp_config_.scale[_X], wrp_config_.scale[_Y], wrp_config_.scale[_Z]);
220  LOG("3) Number of WRP : %d\n", wrp_config_.num_wrp);
221  LOG("**************************************************\n");
222 
223  return bRet;
224 }
225 
226 void ophWRP::addPixel2WRP(int x, int y, Complex<Real> temp)
227 {
228  const uint pnX = context_.pixel_number[_X];
229  const uint pnY = context_.pixel_number[_Y];
230 
231  if (x >= 0 && x < (int)pnX && y >= 0 && y < (int)pnY) {
232  uint adr = x + y * pnX;
233  if (adr == 0)
234  std::cout << ".0";
235  p_wrp_[adr] = p_wrp_[adr] + temp;
236  }
237 
238 }
239 
240 void ophWRP::addPixel2WRP(int x, int y, oph::Complex<Real> temp, oph::Complex<Real>* wrp)
241 {
242  long long int Nx = context_.pixel_number.v[0];
243  long long int Ny = context_.pixel_number.v[1];
244 
245  if (x >= 0 && x < Nx && y >= 0 && y < Ny) {
246  long long int adr = x + y*Nx;
247  wrp[adr] += temp[adr];
248  }
249 }
250 
251 oph::Complex<Real>* ophWRP::calSubWRP(double wrp_d, Complex<Real>* wrp, OphPointCloudData* pc)
252 {
253 
254  Real wave_num = context_.k; // wave_number
255  Real wave_len = context_.wave_length[0]; //wave_length
256 
257  int Nx = context_.pixel_number.v[0]; //slm_pixelNumberX
258  int Ny = context_.pixel_number.v[1]; //slm_pixelNumberY
259 
260  Real wpx = context_.pixel_pitch.v[0];//wrp pitch
261  Real wpy = context_.pixel_pitch.v[1];
262 
263 
264  int Nx_h = Nx >> 1;
265  int Ny_h = Ny >> 1;
266 
267  int num = n_points;
268 
269 
270 #ifdef _OPENMP
271 #pragma omp parallel for firstprivate(wrp_d, wpx, wpy, Nx_h, Ny_h, wave_num, wave_len)
272 #endif
273  for (int k = 0; k < num; k++) {
274 
275  uint idx = 3 * k;
276  uint color_idx = pc->n_colors * k;
277 
278  Real x = pc->vertices[k].point.pos[_X];
279  Real y = pc->vertices[k].point.pos[_Y];
280  Real z = pc->vertices[k].point.pos[_Z];
281  Real amplitude = pc->vertices[k].color.color[_R];
282 
283  float dz = wrp_d - z;
284  // float tw = (int)fabs(wave_len*dz / wpx / wpx / 2 + 0.5) * 2 - 1;
285  float tw = fabs(dz)*wave_len / wpx / wpx / 2;
286 
287  int w = (int)tw;
288 
289  int tx = (int)(x / wpx) + Nx_h;
290  int ty = (int)(y / wpy) + Ny_h;
291 
292  printf("num=%d, tx=%d, ty=%d, w=%d\n", k, tx, ty, w);
293 
294  for (int wy = -w; wy < w; wy++) {
295  for (int wx = -w; wx<w; wx++) {//WRP coordinate
296 
297  double dx = wx*wpx;
298  double dy = wy*wpy;
299  double dz = wrp_d - z;
300 
301  double sign = (dz>0.0) ? (1.0) : (-1.0);
302  double r = sign*sqrt(dx*dx + dy*dy + dz*dz);
303 
304  //double tmp_re,tmp_im;
305  Complex<Real> tmp;
306 
307  tmp[_RE] = (amplitude*cosf(wave_num*r)*cosf(wave_num*wave_len*rand(0, 1))) / (r + 0.05);
308  tmp[_IM] = (-amplitude*sinf(wave_num*r)*sinf(wave_num*wave_len*rand(0, 1))) / (r + 0.05);
309 
310  if (tx + wx >= 0 && tx + wx < Nx && ty + wy >= 0 && ty + wy < Ny)
311  {
312  addPixel2WRP(wx + tx, wy + ty, tmp, wrp);
313  }
314  }
315  }
316  }
317 
318  return wrp;
319 }
320 
322 {
323  LOG("%s\n", __FUNCTION__);
324  auto begin = CUR_TIME;
325 
326  const int pnX = context_.pixel_number[_X]; //slm_pixelNumberX
327  const int pnY = context_.pixel_number[_Y]; //slm_pixelNumberY
328  const Real ppX = context_.pixel_pitch[_X]; //wrp pitch
329  const Real ppY = context_.pixel_pitch[_Y];
330  const long long int N = pnX * pnY;
331  const uint nChannel = context_.waveNum;
332  const Real distance = wrp_config_.propagation_distance;
333  int hpnX = pnX >> 1;
334  int hpnY = pnY >> 1;
335 
336  OphPointCloudData pc = obj_;
337  Real wrp_d = wrp_config_.wrp_location;
338 
339  // Memory Location for Result Image
340 
341  if (p_wrp_) {
342  delete[] p_wrp_;
343  p_wrp_ = nullptr;
344  }
345  p_wrp_ = new Complex<Real>[N];
346  memset(p_wrp_, 0.0, sizeof(Complex<Real>) * N);
347 
348  int sum = 0;
349  m_nProgress = 0;
350  Real ppXX = ppX * ppX * 2;
351  Real pi2 = 2 * M_PI;
352  Real dz = wrp_d - zmax_;
353  Real dzz = dz * dz;
354 
355  bool bRandomPhase = GetRandomPhase();
356 
357  for (uint ch = 0; ch < nChannel; ch++)
358  {
359  Real lambda = context_.wave_length[ch]; //wave_length
360  Real k = context_.k = pi2 / lambda;
361  int iColor = ch;
362  int sum = 0;
363 #ifdef _OPENMP
364 #pragma omp parallel for firstprivate(iColor, ppXX, pnX, pnY, ppX, ppY, hpnX, hpnY, wrp_d, k, pi2, dz, dzz)
365 #endif
366  for (int i = 0; i < n_points; ++i)
367  {
368  uint idx = 3 * i;
369  uint color_idx = pc.n_colors * i;
370 
371  Real x = scaledVertex[i].point.pos[_X];
372  Real y = scaledVertex[i].point.pos[_Y];
373  Real z = scaledVertex[i].point.pos[_Z];
374  Real amplitude = pc.vertices[i].color.color[_R + ch];
375 
376  //Real dz = wrp_d - z;
377  //Real dzz = dz * dz;
378  bool sign = (dz > 0.0) ? true : false;
379  //Real tw = fabs(lambda * dz / ppXX + 0.5) * 2 - 1;
380  Real tw = fabs(lambda * dz / ppXX) * 2;
381 
382  int w = (int)tw;
383 
384  int tx = (int)(x / ppX) + hpnX;
385  int ty = (int)(y / ppY) + hpnY;
386 
387  for (int wy = -w; wy < w; wy++)
388  {
389  Real dy = wy * ppY;
390  Real dyy = dy * dy;
391  int tmpY = wy + ty;
392  int baseY = tmpY * pnX;
393 
394  for (int wx = -w; wx < w; wx++) //WRP coordinate
395  {
396  int tmpX = wx + tx;
397  if (tmpX >= 0 && tmpX < pnX && tmpY >= 0 && tmpY < pnY) {
398  uint adr = tmpX + baseY;
399 
400  Real dx = wx * ppX;
401  Real r = sign ? sqrt(dx * dx + dyy + dzz) : -sqrt(dx * dx + dyy + dzz);
402  Real kr = k * r;
403  Real randVal = bRandomPhase ? rand(0.0, 1.0) : 1.0;
404  Real randpi2 = pi2 * randVal;
405  Complex<Real> tmp;
406  tmp[_RE] = (amplitude * cos(kr) * cos(randpi2)) / r;
407  tmp[_IM] = (-amplitude * sin(kr) * sin(randpi2)) / r;
408 
409  if (adr == 0)
410  std::cout << ".0";
411 #ifdef _OPENMP
412 #pragma omp atomic
413  p_wrp_[adr][_RE] += tmp[_RE];
414 #pragma omp atomic
415  p_wrp_[adr][_IM] += tmp[_IM];
416 #else
417  p_wrp_[adr] += tmp;
418 #endif
419  }
420  }
421  }
422  }
423  Fresnel_FFT(p_wrp_, complex_H[ch], lambda, distance);
424  //fresnelPropagation(p_wrp_, complex_H[ch], distance, ch);
425  memset(p_wrp_, 0.0, sizeof(Complex<Real>) * N);
426  }
427  delete[] p_wrp_;
428  delete[] scaledVertex;
429  p_wrp_ = nullptr;
430  scaledVertex = nullptr;
431 
432  LOG("Total : %lf (s)\n", ELAPSED_TIME(begin, CUR_TIME));
433 
434  //return 0.;
435 }
436 
438 {
439  resetBuffer();
440 
441  auto begin = CUR_TIME;
442  LOG("**************************************************\n");
443  LOG(" Generate Hologram \n");
444  LOG("1) Algorithm Method : WRP\n");
445  LOG("2) Generate Hologram with %s\n", m_mode & MODE_GPU ?
446  "GPU" :
447 #ifdef _OPENMP
448  "Multi Core CPU"
449 #else
450  "Single Core CPU"
451 #endif
452  );
453  LOG("3) Random Phase Use : %s\n", GetRandomPhase() ? "Y" : "N");
454  LOG("4) Number of Point Cloud : %d\n", n_points);
455  LOG("5) Precision Level : %s\n", m_mode & MODE_FLOAT ? "Single" : "Double");
456  if (m_mode & MODE_GPU)
457  LOG("6) Use FastMath : %s\n", m_mode & MODE_FASTMATH ? "Y" : "N");
458  LOG("**************************************************\n");
459 
460  autoScaling();
462 
463  fftFree();
464  LOG("Total Elapsed Time: %lf (s)\n", ELAPSED_TIME(begin, CUR_TIME));
465 }
466 
468 {
469  int wrp_num = wrp_config_.num_wrp;
470 
471  if (wrp_num < 1)
472  return nullptr;
473 
474  Complex<Real>** wrp_list = nullptr;
475 
476  Real k = context_.k; // wave_number
477  Real lambda = context_.wave_length[0]; //wave_length
478  const long long int pnXY = context_.pixel_number[_X] * context_.pixel_number[_Y];
479 
480  Complex<Real>* wrp = new Complex<Real>[pnXY];
481 
482  //OphPointCloudData pc = obj_;
483 
484  for (int i = 0; i < wrp_num; i++)
485  {
486 // wrp = calSubWRP(wrp_d, wrp, &pc);
487  wrp_list[i] = wrp;
488  }
489 
490  return wrp_list;
491 }
492 
493 void ophWRP::ophFree(void)
494 {
495  ophGen::ophFree();
496 
497  if (obj_.vertices) {
498  delete[] obj_.vertices;
499  obj_.vertices = nullptr;
500  }
501 }
502 
503 void ophWRP::transVW(Real* dst, Real* src, int size)
504 {
505  Real fieldLens = getFieldLens();
506  for (int i = 0; i < size; i++) {
507  dst[i] = (-fieldLens * src[i]) / (src[i] - fieldLens);
508  }
509 }
Color color
Definition: struct.h:104
Point point
Definition: struct.h:103
Real k
Definition: Openholo.h:103
void fftFree(void)
Resource release method.
Definition: Openholo.cpp:677
Real * wave_length
Definition: Openholo.h:106
#define MODE_FASTMATH
Definition: define.h:159
Real fieldLength
fieldLength variable for viewing window.
Definition: ophGen.h:648
#define MODE_GPU
Definition: define.h:156
#define MODE_FLOAT
Definition: define.h:158
OphPointCloudData obj_
Input Pointcloud Data.
Definition: ophWRP.h:225
float Real
Definition: typedef.h:55
void initialize(void)
Initialize variables for Hologram complex field, encoded data, normalized data.
Definition: ophGen.cpp:146
void setViewingWindow(bool is_ViewingWindow)
Set the value of a variable is_ViewingWindow(true or false)
Definition: ophWRP.cpp:66
#define CUR_TIME
Definition: function.h:58
int num_wrp
Number of wavefront recording plane(WRP)
Definition: ophGen.h:652
bool checkExtension(const char *fname, const char *ext)
Functions for extension checking.
Definition: Openholo.cpp:86
ophWRP(void)
Constructor.
Definition: ophWRP.cpp:50
bool GetRandomPhase()
Function for getting the random phase.
Definition: ophGen.h:528
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:761
virtual bool readConfig(const char *fname)
load to configuration file.
Definition: ophWRP.cpp:138
#define MIN_DOUBLE
Definition: define.h:148
#define _Y
Definition: define.h:96
#define _IM
Definition: complex.h:58
vec2 pixel_pitch
Definition: Openholo.h:101
vec3 scale
Scaling factor of coordinate of point cloud.
Definition: ophGen.h:650
int v[2]
Definition: ivec.h:67
Real v[2]
Definition: vec.h:67
#define _X
Definition: define.h:92
unsigned int m_mode
Definition: ophGen.h:350
return true
Definition: Openholo.cpp:434
#define _R
Definition: define.h:108
virtual int loadPointCloud(const char *pc_file)
load to point cloud data.
Definition: ophWRP.cpp:130
Real wrp_location
Location distance of WRP.
Definition: ophGen.h:654
Vertex * scaledVertex
Definition: ophWRP.h:226
void Fresnel_FFT(Complex< Real > *src, Complex< Real > *dst, Real lambda, Real distance)
Fresnel-fft method.
Definition: ophGen.cpp:516
OphWRPConfig wrp_config_
structure variable for WRP hologram configuration
Definition: ophWRP.h:227
void calculateWRPCPU(void)
Definition: ophWRP.cpp:321
#define _RE
Definition: complex.h:55
virtual ~ophWRP(void)
Destructor.
Definition: ophWRP.cpp:62
Definition: struct.h:102
Real pos[3]
Definition: struct.h:87
#define ELAPSED_TIME(x, y)
Definition: function.h:59
uint waveNum
Definition: Openholo.h:105
structure for 3-dimensional Real type vector and its arithmetic.
Definition: vec.h:466
int n_colors
Number of color channel.
Definition: ophGen.h:577
ivec2 pixel_number
Definition: Openholo.h:99
Vertex * vertices
Data of point clouds.
Definition: ophGen.h:579
bool readConfig(const char *fname)
load to configuration file.
Definition: ophGen.cpp:221
Complex< Real > * p_wrp_
wrp buffer - complex type
Definition: ophWRP.h:223
XMLError LoadFile(const char *filename)
Definition: tinyxml2.cpp:2150
Real rand(const Real min, const Real max, oph::ulong _SEED_VALUE=0)
Get random Real value from min to max.
Definition: function.h:294
int n_points
numbers of points
Definition: ophWRP.h:221
void autoScaling()
Definition: ophWRP.cpp:71
void calculateWRPGPU(void)
Definition: ophWRP_GPU.cpp:48
Data for Point Cloud.
Definition: ophGen.h:573
Real propagation_distance
Distance of Hologram plane.
Definition: ophGen.h:656
void resetBuffer()
reset buffer
Definition: ophGen.cpp:801
w
Definition: Openholo.cpp:429
OphConfig context_
Definition: Openholo.h:486
Complex< Real > ** complex_H
Definition: Openholo.h:490
#define _Z
Definition: define.h:100
Real sum(const vec2 &a)
Definition: vec.h:401
int loadPointCloud(const char *pc_file, OphPointCloudData *pc_data_)
load to point cloud data.
Definition: ophGen.cpp:207
Real color[3]
Definition: struct.h:95
const XMLElement * FirstChildElement(const char *name=0) const
Definition: tinyxml2.cpp:940
const Real & getFieldLens()
Definition: ophWRP.h:135
unsigned int uint
Definition: typedef.h:62
#define M_PI
Definition: define.h:52
Definition: ophGen.h:76
virtual void ophFree(void)
Pure virtual function for override in child classes.
Definition: ophGen.cpp:2072
void generateHologram(void)
Generate a hologram, main funtion.
Definition: ophWRP.cpp:437
Complex< Real > ** calculateMWRP(void)
Generate multiple wavefront recording planes, main funtion.
Definition: ophWRP.cpp:467