ldpk
tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h
Go to the documentation of this file.
1 #ifndef tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy_sdv
2 #define tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy_sdv
3 
4 #include <ldpk/ldpk_ldp_builtin.h>
5 #include <ldpk/ldpk_generic_anamorphic_distortion.h>
6 #include <ldpk/ldpk_rotation_extender.h>
7 #include <ldpk/ldpk_squeeze_extender.h>
8 #include <ldpk/ldpk_linear_extender.h>
9 
10 #ifndef M_PI
11 #define M_PI 3.1415926535
12 #endif
13 
16 
17 template <class VEC2,class MAT2>
19  {
20 private:
21  typedef VEC2 vec2_type;
22  typedef MAT2 mat2_type;
24 
25 // Wir kombinieren hier anamorphische Verzeichung Grad 4
26 // mit einer Rotation und einem Squeeze. Das ist der anamorphe Anteil
32 
36 
37  static const char* _para[13];
38 
39  bool decypher(const char* name,int& i)
40  {
41  typedef base_type bt;
42  int n;
43  getNumParameters(n);
44  for(i = 0;i < n;++i)
45  {
46  if(0 == strcmp(name,_para[i]))
47  {
48  return true;
49  }
50  }
51  return false;
52  }
53  bool initializeParameters()
54  {
55  typedef base_type bt;
56  bt::check_builtin_parameters();
57  _pa.set_sq(bt::pa());
58 // This method is the last one invoked, before the object can be used,
59 // therefore we have to prepare the concatenated extenders here.
60  _rot_sqx_sqy_pa.set(_rotation,_squeeze_x,_squeeze_y,_pa);
61  if(_squeeze_x.get_sq() == 0)
62  { std::cerr << "tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy::initializeParameters, error: Squeeze-X is 0." << std::endl; }
63  if(_squeeze_y.get_sq() == 0)
64  { std::cerr << "tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy::initializeParameters, error: Squeeze-Y is 0." << std::endl; }
65  _pa_rot.set(_pa,_rotation);
66  _anamorphic.prepare();
67  return true;
68  }
69  bool getNumParameters(int& n)
70  {
71  n = 13;
72  return true;
73  }
74  bool getParameterName(int i,char* identifier)
75  {
76  strcpy(identifier,_para[i]);
77  return true;
78  }
79  bool setParameterValue(const char *identifier,double v)
80  {
81  typedef base_type bt;
82  int i;
83 // Does the base class know the parameter?
84  if(bt::set_builtin_parameter_value(identifier,v))
85  {
86  return true;
87  }
88  if(!decypher(identifier,i))
89  {
90  return false;
91  }
92  if(i < 10)
93  {
94  if(_anamorphic.get_coeff(i) != v)
95  { bt::no_longer_uptodate_lut(); }
96  _anamorphic.set_coeff(i,v);
97  }
98  else if(i == 10)
99  {
100  if(_rotation.get_phi() != v / 180.0 * M_PI)
101  { bt::no_longer_uptodate_lut(); }
102  _rotation.set_phi(v / 180.0 * M_PI);
103  }
104  else if(i == 11)
105  {
106  if(_squeeze_x.get_sq() != v)
107  { bt::no_longer_uptodate_lut(); }
108  _squeeze_x.set_sq(v);
109  }
110  else if(i == 12)
111  {
112  if(_squeeze_y.get_sq() != v)
113  { bt::no_longer_uptodate_lut(); }
114  _squeeze_y.set_sq(v);
115  }
116 
117  return true;
118  }
119 // slightly faster version
120  virtual bool undistort(double x0,double y0,double &x1,double &y1)
121  {
122  typedef base_type bt;
123  vec2_type q = bt::map_dn_to_unit(
124  _rot_sqx_sqy_pa.eval(
125  _anamorphic.eval(
126  _pa_rot.eval_inv(
127  bt::map_unit_to_dn(vec2_type(x0,y0))))));
128  x1 = q[0];
129  y1 = q[1];
130  return true;
131  }
132 /*
133 // original version
134  virtual bool undistort(double x0,double y0,double &x1,double &y1)
135  {
136  vec2_type q = bt::map_dn_to_unit(
137  _rotation.eval(
138  _squeeze_x.eval(
139  _squeeze_y.eval(
140  _pa.eval(
141  _anamorphic.eval(
142  _rotation.eval_inv(
143  _pa.eval_inv(
144  bt::map_unit_to_dn(vec2_type(x0,y0))))))))));
145  x1 = q[0];
146  y1 = q[1];
147  return true;
148  }
149 */
150  virtual bool distort(double x0,double y0,double &x1,double &y1)
151  {
152  typedef base_type bt;
153 // The distort-method without initial values is not constant by semantics,
154 // since it may cause an update of the lookup-tables. Implementing a Nuke node
155 // it turned out that we need to prevent threads from trying so simultaneously.
156 // By the following double check of is_uptodate_lut() we keep the mutex lock
157 // out of our frequently called distort stuff (for performance reasons) and
158 // prevent threads from updating without need.
159  if(!bt::is_uptodate_lut())
160  {
161  bt::lock();
162  if(!bt::is_uptodate_lut())
163  {
164  bt::update_lut();
165  }
166  bt::unlock();
167  }
168 
169 // Get initial value from lookup-table
170  vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
171 // vec2_type qs(x0,y0);
172 // Call version of distort with initial value.
173  vec2_type q = bt::map_dn_to_unit(
174  _pa_rot.eval(
175  _anamorphic.map_inverse(
176  _rot_sqx_sqy_pa.eval_inv(
177  bt::map_unit_to_dn(vec2_type(x0,y0))),
178  _rot_sqx_sqy_pa.eval_inv(
179  bt::map_unit_to_dn(qs)))));
180  x1 = q[0];
181  y1 = q[1];
182  return true;
183  }
184 /*
185 // original version
186  virtual bool distort(double x0,double y0,double &x1,double &y1)
187  {
188  typedef base_type bt;
189 // The distort-method without initial values is not constant by semantics,
190 // since it may cause an update of the lookup-tables. Implementing a Nuke node
191 // it turned out that we need to prevent threads from trying so simultaneously.
192 // By the following double check of is_uptodate_lut() we keep the mutex lock
193 // out of our frequently called distort stuff (for performance reasons) and
194 // prevent threads from updating without need.
195  if(!bt::is_uptodate_lut())
196  {
197  pthread_mutex_lock(&_mutex);
198  if(!bt::is_uptodate_lut())
199  {
200  bt::update_lut();
201  }
202  pthread_mutex_unlock(&_mutex);
203  }
204 
205 // Get initial value from lookup-table
206  vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
207 // vec2_type qs(x0,y0);
208 // Call version of distort with initial value.
209  vec2_type q = bt::map_dn_to_unit(
210  _pa.eval(
211  _rotation.eval(
212  _anamorphic.map_inverse(
213  _pa.eval_inv(
214  _squeeze_y.eval_inv(
215  _squeeze_x.eval_inv(
216  _rotation.eval_inv(
217  bt::map_unit_to_dn(vec2_type(x0,y0)))))),
218  _pa.eval_inv(
219  _squeeze_y.eval_inv(
220  _squeeze_x.eval_inv(
221  _rotation.eval_inv(
222  bt::map_unit_to_dn(qs)))))))));
223  x1 = q[0];
224  y1 = q[1];
225  return true;
226  }
227 */
228  virtual bool distort(double x0,double y0,double x1_start,double y1_start,double &x1,double &y1)
229  {
230  typedef base_type bt;
231  vec2_type q = bt::map_dn_to_unit(
232  _pa_rot.eval(
233  _anamorphic.map_inverse(
234  _rot_sqx_sqy_pa.eval_inv(
235  bt::map_unit_to_dn(vec2_type(x0,y0))),
236  _rot_sqx_sqy_pa.eval_inv(
237  bt::map_unit_to_dn(vec2_type(x1_start,y1_start))))));
238  x1 = q[0];
239  y1 = q[1];
240  return true;
241  }
242 /*
243 // original version
244  virtual bool distort(double x0,double y0,double x1_start,double y1_start,double &x1,double &y1)
245  {
246  vec2_type q = bt::map_dn_to_unit(
247  _pa.eval(
248  _rotation.eval(
249  _anamorphic.map_inverse(
250  _pa.eval_inv(
251  _squeeze_y.eval_inv(
252  _squeeze_x.eval_inv(
253  _rotation.eval_inv(
254  bt::map_unit_to_dn(vec2_type(x0,y0)))))),
255  _pa.eval_inv(
256  _squeeze_y.eval_inv(
257  _squeeze_x.eval_inv(
258  _rotation.eval_inv(
259  bt::map_unit_to_dn(vec2_type(x1_start,y1_start))))))))));
260  x1 = q[0];
261  y1 = q[1];
262  return true;
263  }
264 */
265 public:
266 // Mutex initialized and destroyed in baseclass.
268  { }
270  { }
271  bool getModelName(char *name)
272  {
273 #ifdef LDPK_COMPILE_AS_PLUGIN_SDV
274  strcpy(name,"3DE4 Anamorphic - Standard, Degree 4 [Plugin]");
275 #else
276  strcpy(name,"3DE4 Anamorphic - Standard, Degree 4");
277 #endif
278  return true;
279  }
280  bool getParameterType(const char* identifier,tde4_ldp_ptype& ptype)
281  {
282  typedef base_type bt;
283  int i;
284  if(bt::get_builtin_parameter_type(identifier,ptype)) return true;
285  if(!decypher(identifier,i)) return false;
286  ptype = TDE4_LDP_ADJUSTABLE_DOUBLE;
287  return true;
288  }
289  bool getParameterDefaultValue(const char* identifier,double& v)
290  {
291  typedef base_type bt;
292  int i;
293  if(!decypher(identifier,i)) return false;
294  if(i < 11)
295  {
296  v = 0.0;
297  }
298  else if((i == 11) || (i == 12))
299  {
300  v = 1.0;
301  }
302  return true;
303  }
304  bool getParameterRange(const char* identifier,double& a,double& b)
305  {
306  typedef base_type bt;
307  int i;
308  if(!decypher(identifier,i)) return false;
309  if(i < 10)
310  {
311  a = -0.5;
312  b = 0.5;
313  }
314  else if(i == 10)
315  {
316 // Lens Rotation in degree.
317  a = -2.0;
318  b = +2.0;
319  }
320  else if((i == 11) || (i == 12))
321  {
322 // Squeeze X/Y
323  a = 0.9;
324  b = 1.1;
325  }
326  else
327  {
328  std::cerr << "getParameterRange: i out of range" << std::endl;
329  }
330  return true;
331  }
333  bool getJacobianMatrix(double x0,double y0,double& m00,double& m01,double& m10,double& m11)
334  {
335  typedef base_type bt;
336  mat2_type m = _rot_sqx_sqy_pa.get_mat()
337  * _anamorphic.jacobi(
338  _pa_rot.eval_inv(
339  bt::map_unit_to_dn(vec2_type(x0,y0))))
340  * _pa_rot.get_mat_inv();
341  mat2_type u2d(bt::w_fb_cm() / bt::r_fb_cm(),0.0,0.0,bt::h_fb_cm() / bt::r_fb_cm());
342  mat2_type d2u(bt::r_fb_cm() / bt::w_fb_cm(),0.0,0.0,bt::r_fb_cm() / bt::h_fb_cm());
343  m = d2u * m * u2d;
344  m00 = m[0][0];m01 = m[0][1];m10 = m[1][0];m11 = m[1][1];
345  return true;
346  }
347  };
348 
349 template <class VEC2,class MAT2>
351  "Cx02 - Degree 2","Cy02 - Degree 2",
352  "Cx22 - Degree 2","Cy22 - Degree 2",
353 
354  "Cx04 - Degree 4","Cy04 - Degree 4",
355  "Cx24 - Degree 4","Cy24 - Degree 4",
356  "Cx44 - Degree 4","Cy44 - Degree 4",
357 
358  "Lens Rotation","Squeeze-X","Squeeze-Y"
359  };
360 
361 #endif
bool getParameterDefaultValue(const char *identifier, double &v)
returns default value for given parameter (maximum length of "char *v": 1000 bytes)......
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:289
virtual mat2_type jacobi(const vec2_type &p_dn) const
Jacobi-Matrix. The result is a matrix g_{ij} = d/dp_j f(p)_i, where f represents the undistort-functi...
Definition: ldpk_generic_distortion_base.h:107
vec2_type eval(const vec2_type &p) const
eval() is per definition removal of lens distortion (undistort).
Definition: ldpk_linear_extender.h:65
bool getParameterType(const char *identifier, tde4_ldp_ptype &ptype)
returns type of given parameter... The method should return false, if the parameter addressed by iden...
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:280
vec2_type eval(const vec2_type &p) const
Same as method instead of operator.
Definition: ldpk_generic_distortion_base.h:102
bool getJacobianMatrix(double x0, double y0, double &m00, double &m01, double &m10, double &m11)
Tested against difference quotients.
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:333
void set_coeff(int i, double q)
Set coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:77
bool getModelName(char *name)
returns a name for the model as to show up in the GUI (maximum length of "name": 100 bytes)...
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:271
double get_phi() const
Getter.
Definition: ldpk_rotation_extender.h:36
const mat2_type & get_mat_inv() const
The inverse matrix for this extender.
Definition: ldpk_linear_extender.h:77
void set(const mat2_type &m)
Passing the matrix.
Definition: ldpk_linear_extender.h:24
bool getParameterRange(const char *identifier, double &a, double &b)
returns range for adjustable double parameters...
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:304
This class handles the built-in parameter and the lookup table. You may find it useful for your own d...
Definition: ldpk_ldp_builtin.h:31
const mat2_type & get_mat() const
The matrix for this extender.
Definition: ldpk_linear_extender.h:74
virtual vec2_type map_inverse(const vec2_type &q) const
Inverse mapping by solving the fixed point equation without providing initial values. Virtual, because the derived class might use some smart data structure for calculating an initial value.
Definition: ldpk_generic_distortion_base.h:120
vec2_type eval_inv(const vec2_type &q) const
eval_inv() is applying lens distortion (distort)
Definition: ldpk_linear_extender.h:68
double get_coeff(int i) const
Get coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:71
void set_phi(double phi)
The rotation extender has one parameter called phi (in radians).
Definition: ldpk_rotation_extender.h:29
Definition: tde4_ldp_anamorphic_deg_4_rotate_squeeze_xy.h:18