HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PyImathVec2Impl.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 // clang-format off
7 
8 #ifndef _PyImathVec2Impl_h_
9 #define _PyImathVec2Impl_h_
10 
11 //
12 // This .C file was turned into a header file so that instantiations
13 // of the various V2* types can be spread across multiple files in
14 // order to work around MSVC limitations.
15 //
16 
17 #include <Python.h>
18 #define HBOOST_BIND_GLOBAL_PLACEHOLDERS
19 #include <hboost/python.hpp>
20 #include <hboost/python/make_constructor.hpp>
21 #include <hboost/format.hpp>
22 #include <hboost/cast.hpp>
23 #include <ImathVec.h>
24 #include <ImathVecAlgo.h>
25 #include "PyImath.h"
26 #include "PyImathMathExc.h"
27 #include "PyImathBox.h"
28 #include "PyImathVec.h"
29 #include "PyImathDecorators.h"
30 #include "PyImathOperators.h"
31 #include "PyImathVecOperators.h"
32 
33 namespace PyImath {
34 using namespace hboost::python;
35 using namespace IMATH_NAMESPACE;
36 
37 template <class T> struct Vec2Name { static const char *value; };
38 
39 // create a new default constructor that initializes Vec2<T> to zero.
40 template <class T>
41 static Vec2<T> * Vec2_construct_default()
42 {
43  return new Vec2<T>(T(0),T(0));
44 }
45 
46 template <class T,class BoostPyType>
47 static Vec2<T> * Vec2_tuple_constructor(const BoostPyType &t)
48 {
49  if(t.attr("__len__")() == 1)
50  return new Vec2<T>(extract<T>(t[0]), extract<T>(t[0]));
51  else if(t.attr("__len__")() == 2)
52  return new Vec2<T>(extract<T>(t[0]), extract<T>(t[1]));
53  else
54  throw std::invalid_argument ("Vec2 constructor expects tuple of length 1 or 2");
55 }
56 
57 template <class T>
58 static Vec2<T> * Vec2_object_constructor1(const object &obj)
59 {
60  Vec2<T> w;
61  extract<Vec2<int> > e1(obj);
62  extract<Vec2<float> > e2(obj);
63  extract<Vec2<double> > e3(obj);
64  extract<tuple> e4(obj);
65  extract<double> e5(obj);
66  extract<list> e6(obj);
67 
68  if(e1.check()){ w = e1(); }
69  else if(e2.check()) { w = e2(); }
70  else if(e3.check()) { w = e3(); }
71  else if(e4.check())
72  {
73  tuple t = e4();
74  if(t.attr("__len__")() == 2)
75  {
76  w.x = extract<T>(t[0]);
77  w.y = extract<T>(t[1]);
78  }
79  else
80  throw std::invalid_argument ("tuple must have length of 2");
81  }
82  else if(e5.check()) { T a = e5(); w.setValue(a, a); }
83  else if(e6.check())
84  {
85  list l = e6();
86  if(l.attr("__len__")() == 2)
87  {
88  w.x = extract<T>(l[0]);
89  w.y = extract<T>(l[1]);
90  }
91  else
92  throw std::invalid_argument ("list must have length of 2");
93  }
94  else
95  throw std::invalid_argument ("invalid parameters passed to Vec2 constructor");
96 
97  Vec2<T> *v = new Vec2<T>;
98  *v = w;
99 
100  return v;
101 
102 }
103 
104 template <class T>
105 static Vec2<T> * Vec2_object_constructor2(const object &obj1, const object &obj2)
106 {
107  extract<double> e1(obj1);
108  extract<double> e2(obj2);
109 
110  Vec2<T> *v = new Vec2<T>;
111 
112  if(e1.check()) { v->x = hboost::numeric_cast<T>(e1());}
113  else { throw std::invalid_argument ("invalid parameters passed to Vec2 constructor"); }
114 
115  if(e2.check()) { v->y = hboost::numeric_cast<T>(e2());}
116  else { throw std::invalid_argument ("invalid parameters passed to Vec2 constructor"); }
117 
118  return v;
119 }
120 
121 // Implementations of str and repr are same here,
122 // but we'll specialize repr for float and double to make them exact.
123 template <class T>
124 static std::string Vec2_str(const Vec2<T> &v)
125 {
126  std::stringstream stream;
127  stream << Vec2Name<T>::value << "(" << v.x << ", " << v.y << ")";
128  return stream.str();
129 }
130 template <class T>
131 static std::string Vec2_repr(const Vec2<T> &v)
132 {
133  std::stringstream stream;
134  stream << Vec2Name<T>::value << "(" << v.x << ", " << v.y << ")";
135  return stream.str();
136 }
137 
138 template <class T>
139 static T
140 Vec2_cross(const IMATH_NAMESPACE::Vec2<T> &v, const IMATH_NAMESPACE::Vec2<T> &other)
141 {
142  MATH_EXC_ON;
143  return v.cross(other);
144 }
145 
146 template <class T>
147 static FixedArray<T>
148 Vec2_cross_Vec2Array(const IMATH_NAMESPACE::Vec2<T> &va, const FixedArray<IMATH_NAMESPACE::Vec2<T> > &vb)
149 {
151  size_t len = vb.len();
152  FixedArray<T> f(len);
153  for (size_t i = 0; i < len; ++i)
154  f[i] = va.cross(vb[i]);
155  return f;
156 }
157 
158 template <class T>
159 static T
160 Vec2_dot(const IMATH_NAMESPACE::Vec2<T> &v, const IMATH_NAMESPACE::Vec2<T> &other)
161 {
162  MATH_EXC_ON;
163  return v.dot(other);
164 }
165 
166 template <class T>
167 static FixedArray<T>
168 Vec2_dot_Vec2Array(const IMATH_NAMESPACE::Vec2<T> &va, const FixedArray<IMATH_NAMESPACE::Vec2<T> > &vb)
169 {
171  size_t len = vb.len();
172  FixedArray<T> f(len);
173  for (size_t i = 0; i < len; ++i)
174  f[i] = va.dot(vb[i]);
175  return f;
176 }
177 
178 template <class T>
179 static T
180 Vec2_length(const IMATH_NAMESPACE::Vec2<T> &v)
181 {
182  MATH_EXC_ON;
183  return v.length();
184 }
185 
186 template <class T>
187 static T
188 Vec2_length2(const IMATH_NAMESPACE::Vec2<T> &v)
189 {
190  MATH_EXC_ON;
191  return v.length2();
192 }
193 
194 template <class T>
195 static const Vec2<T> &
196 Vec2_normalize(IMATH_NAMESPACE::Vec2<T> &v)
197 {
198  MATH_EXC_ON;
199  return v.normalize();
200 }
201 
202 template <class T>
203 static const Vec2<T> &
204 Vec2_normalizeExc(IMATH_NAMESPACE::Vec2<T> &v)
205 {
206  MATH_EXC_ON;
207  return v.normalizeExc();
208 }
209 
210 template <class T>
211 static const Vec2<T> &
212 Vec2_normalizeNonNull(IMATH_NAMESPACE::Vec2<T> &v)
213 {
214  MATH_EXC_ON;
215  return v.normalizeNonNull();
216 }
217 
218 template <class T>
219 static Vec2<T>
220 Vec2_normalized(const IMATH_NAMESPACE::Vec2<T> &v)
221 {
222  MATH_EXC_ON;
223  return v.normalized();
224 }
225 
226 template <class T>
227 static Vec2<T>
228 Vec2_normalizedExc(const IMATH_NAMESPACE::Vec2<T> &v)
229 {
230  MATH_EXC_ON;
231  return v.normalizedExc();
232 }
233 
234 template <class T>
235 static Vec2<T>
236 Vec2_normalizedNonNull(const IMATH_NAMESPACE::Vec2<T> &v)
237 {
238  MATH_EXC_ON;
239  return v.normalizedNonNull();
240 }
241 
242 template <class T>
243 static Vec2<T>
244 closestVertex(Vec2<T> &p, const Vec2<T> &v0, const Vec2<T> &v1, const Vec2<T> &v2)
245 {
246  MATH_EXC_ON;
247  return IMATH_NAMESPACE::closestVertex(v0, v1, v2, p);
248 }
249 
250 template <class T>
251 static const Vec2<T> &
252 Vec2_negate(IMATH_NAMESPACE::Vec2<T> &v)
253 {
254  MATH_EXC_ON;
255  return v.negate();
256 }
257 
258 template <class T>
259 static Vec2<T>
260 orthogonal(const Vec2<T> &v, const Vec2<T> &v0)
261 {
262  MATH_EXC_ON;
263  return IMATH_NAMESPACE::orthogonal(v, v0);
264 }
265 
266 template <class T>
267 static Vec2<T>
268 project(const Vec2<T> &v, const Vec2<T> &v0)
269 {
270  MATH_EXC_ON;
271  return IMATH_NAMESPACE::project(v0, v);
272 }
273 
274 template <class T>
275 static Vec2<T>
276 reflect(const Vec2<T> &v, const Vec2<T> &v0)
277 {
278  MATH_EXC_ON;
279  return IMATH_NAMESPACE::reflect(v, v0);
280 }
281 
282 template <class T>
283 static void
284 setValue(Vec2<T> &v, T a, T b)
285 {
286  v.x = a;
287  v.y = b;
288 }
289 
290 template <class T>
291 static Vec2<T>
292 Vec2_add (const Vec2<T> &v, const Vec2<T> &w)
293 {
294  MATH_EXC_ON;
295  return v + w;
296 }
297 
298 template <class T>
299 static Vec2<T>
300 Vec2_sub (const Vec2<T> &v, const Vec2<T> &w)
301 {
302  MATH_EXC_ON;
303  return v - w;
304 }
305 
306 template <class T>
307 static Vec2<T>
308 Vec2_neg (const Vec2<T> &v)
309 {
310  MATH_EXC_ON;
311  return -v;
312 }
313 
314 template <class T, class U>
315 static Vec2<T>
316 Vec2_mul (const Vec2<T> &v, const Vec2<U> &w)
317 {
318  MATH_EXC_ON;
319  Vec2<T> w2 (w);
320  return v * w2;
321 }
322 
323 template <class T>
324 static Vec2<T>
325 Vec2_mulT (const Vec2<T> &v, T t)
326 {
327  MATH_EXC_ON;
328  return v * t;
329 }
330 
331 template <class T>
332 static FixedArray<IMATH_NAMESPACE::Vec2<T> >
333 Vec2_mulTArray (const Vec2<T> &v, const FixedArray<T> &t)
334 {
336  size_t len = t.len();
337  FixedArray<IMATH_NAMESPACE::Vec2<T> > retval(len);
338  for (size_t i=0; i<len; ++i) retval[i] = v*t[i];
339  return retval;
340 }
341 
342 template <class T>
343 static FixedArray<IMATH_NAMESPACE::Vec2<T> >
344 Vec2_rmulTArray (const Vec2<T> &v, const FixedArray<T> &t)
345 {
346  return Vec2_mulTArray(v,t);
347 }
348 
349 template <class T,class S>
350 static Vec2<T>
351 Vec2_div (Vec2<T> &v, Vec2<S> &w)
352 {
353  MATH_EXC_ON;
354  return v / w;
355 }
356 
357 template <class T>
358 static Vec2<T>
359 Vec2_rmulT (Vec2<T> &v, T t)
360 {
361  MATH_EXC_ON;
362  return t * v;
363 }
364 
365 template <class T, class U>
366 static const Vec2<T> &
367 Vec2_imulV(Vec2<T> &v, const Vec2<U> &w)
368 {
369  MATH_EXC_ON;
370  return v *= w;
371 }
372 
373 template <class T>
374 static const Vec2<T> &
375 Vec2_imulT(IMATH_NAMESPACE::Vec2<T> &v, T t)
376 {
377  MATH_EXC_ON;
378  return v *= t;
379 }
380 
381 template <class T, class U>
382 static Vec2<T>
383 Vec2_mulM22 (Vec2<T> &v, const Matrix22<U> &m)
384 {
385  MATH_EXC_ON;
386  return v * m;
387 }
388 
389 template <class T, class U>
390 static Vec2<T>
391 Vec2_mulM33 (Vec2<T> &v, const Matrix33<U> &m)
392 {
393  MATH_EXC_ON;
394  return v * m;
395 }
396 
397 template <class T>
398 static const Vec2<T> &
399 Vec2_idivObj(IMATH_NAMESPACE::Vec2<T> &v, const object &o)
400 {
401  MATH_EXC_ON;
402  Vec2<T> v2;
403  if (PyImath::V2<T>::convert (o.ptr(), &v2))
404  {
405  return v /= v2;
406  }
407  else
408  {
409  extract<double> e(o);
410  if (e.check())
411  return v /= e();
412  else
413  throw std::invalid_argument ("V2 division expects an argument"
414  "convertible to a V2");
415  }
416 }
417 
418 template <class T>
419 static Vec2<T>
420 Vec2_subT(const Vec2<T> &v, T a)
421 {
422  MATH_EXC_ON;
423  Vec2<T> w;
424  w.setValue(v.x - a, v.y - a);
425  return w;
426 }
427 
428 template <class T,class BoostPyType>
429 static Vec2<T>
430 Vec2_subTuple(const Vec2<T> &v, const BoostPyType &t)
431 {
432  MATH_EXC_ON;
433  Vec2<T> w;
434 
435  if(t.attr("__len__")() == 2)
436  {
437  w.x = v.x - extract<T>(t[0]);
438  w.y = v.y - extract<T>(t[1]);
439  }
440  else
441  throw std::invalid_argument ("tuple must have length of 2");
442 
443  return w;
444 }
445 
446 template <class T>
447 static Vec2<T>
448 Vec2_rsubT(const Vec2<T> &v, T a)
449 {
450  MATH_EXC_ON;
451  Vec2<T> w;
452  w.setValue(a - v.x, a - v.y);
453  return w;
454 }
455 
456 template <class T,class BoostPyType>
457 static Vec2<T>
458 Vec2_rsubTuple(const Vec2<T> &v, const BoostPyType &t)
459 {
460  MATH_EXC_ON;
461  Vec2<T> w;
462 
463  if(t.attr("__len__")() == 2)
464  {
465  w.x = extract<T>(t[0]) - v.x;
466  w.y = extract<T>(t[1]) - v.y;
467  }
468  else
469  throw std::invalid_argument ("tuple must have length of 2");
470 
471  return w;
472 }
473 
474 template <class T,class BoostPyType>
475 static Vec2<T>
476 Vec2_addTuple(const Vec2<T> &v, const BoostPyType &t)
477 {
478  MATH_EXC_ON;
479  Vec2<T> w;
480 
481  if(t.attr("__len__")() == 2)
482  {
483  w.x = v.x + extract<T>(t[0]);
484  w.y = v.y + extract<T>(t[1]);
485  }
486  else
487  throw std::invalid_argument ("tuple must have length of 2");
488 
489  return w;
490 }
491 
492 template <class T>
493 static Vec2<T>
494 Vec2_addT(const Vec2<T> &v, T a)
495 {
496  MATH_EXC_ON;
497  Vec2<T> w;
498  w.setValue(v.x + a, v.y + a);
499  return w;
500 }
501 
502 template <class T, class U>
503 static Vec2<T>
504 Vec2_addV(const Vec2<T> &v, const Vec2<U> &w)
505 {
506  MATH_EXC_ON;
507  return v + w;
508 }
509 
510 template <class T, class U>
511 static const Vec2<T> &
512 Vec2_iaddV(Vec2<T> &v, const Vec2<U> &w)
513 {
514  MATH_EXC_ON;
515  return v += w;
516 }
517 
518 template <class T, class U>
519 static Vec2<T>
520 Vec2_subV(const Vec2<T> &v, const Vec2<U> &w)
521 {
522  MATH_EXC_ON;
523  return v - w;
524 }
525 
526 template <class T, class U>
527 static const Vec2<T> &
528 Vec2_isubV(Vec2<T> &v, const Vec2<U> &w)
529 {
530  MATH_EXC_ON;
531  return v -= w;
532 }
533 
534 template <class T,class BoostPyType>
535 static Vec2<T>
536 Vec2_mulTuple(const Vec2<T> &v, BoostPyType t)
537 {
538  MATH_EXC_ON;
539  Vec2<T> w;
540 
541  if(t.attr("__len__")() == 1){
542  w.x = v.x*extract<T>(t[0]);
543  w.y = v.y*extract<T>(t[0]);
544  }
545  else if(t.attr("__len__")() == 2){
546  w.x = v.x*extract<T>(t[0]);
547  w.y = v.y*extract<T>(t[1]);
548  }
549  else
550  throw std::invalid_argument ("tuple must have length of 1 or 2");
551 
552  return w;
553 }
554 
555 template <class T, class U>
556 static const Vec2<T> &
557 Vec2_imulM22 (Vec2<T> &v, const Matrix22<U> &m)
558 {
559  MATH_EXC_ON;
560  return v *= m;
561 }
562 
563 template <class T, class U>
564 static const Vec2<T> &
565 Vec2_imulM33 (Vec2<T> &v, const Matrix33<U> &m)
566 {
567  MATH_EXC_ON;
568  return v *= m;
569 }
570 
571 template <class T,class BoostPyType>
572 static Vec2<T>
573 Vec2_divTuple(const Vec2<T> &v, const BoostPyType &t)
574 {
575  if(t.attr("__len__")() == 2)
576  {
577  T x = extract<T>(t[0]);
578  T y = extract<T>(t[1]);
579  if(x != T(0) && y != T(0))
580  return Vec2<T>(v.x / x, v.y / y);
581  else
582  throw std::domain_error ("Division by zero");
583  }
584  else
585  throw std::invalid_argument ("Vec2 expects tuple of length 2");
586 }
587 
588 template <class T,class BoostPyType>
589 static Vec2<T>
590 Vec2_rdivTuple(const Vec2<T> &v, const BoostPyType &t)
591 {
592  MATH_EXC_ON;
593  Vec2<T> w;
594  if(t.attr("__len__")() == 2)
595  {
596  T x = extract<T>(t[0]);
597  T y = extract<T>(t[1]);
598 
599  if(v.x != T(0) && v.y != T(0)){
600  w.setValue(x / v.x, y / v.y);
601  }
602  else
603  throw std::domain_error ("Division by zero");
604  }
605  else
606  throw std::invalid_argument ("tuple must have length of 2");
607 
608  return w;
609 }
610 
611 template <class T>
612 static Vec2<T>
613 Vec2_divT(const Vec2<T> &v, T a)
614 {
615  MATH_EXC_ON;
616  Vec2<T> w;
617  if(a != T(0)){
618  w.setValue(v.x / a, v.y / a);
619  }
620  else
621  throw std::domain_error ("Division by zero");
622 
623  return w;
624 }
625 
626 template <class T>
627 static Vec2<T>
628 Vec2_rdivT(const Vec2<T> &v, T a)
629 {
630  MATH_EXC_ON;
631  Vec2<T> w;
632  if(v.x != T(0) && v.y != T(0)){
633  w.setValue(a / v.x, a / v.y);
634  }
635  else
636  throw std::domain_error ("Division by zero");
637 
638  return w;
639 }
640 
641 template <class T>
642 static bool
643 lessThan(const Vec2<T> &v, const object &obj)
644 {
645  extract<Vec2<T> > e1(obj);
646  extract<tuple> e2(obj);
647 
648  Vec2<T> w;
649  if(e1.check())
650  {
651  w = e1();
652  }
653  else if(e2.check())
654  {
655  tuple t = e2();
656  if(t.attr("__len__")() == 2){
657  T x = extract<T>(t[0]);
658  T y = extract<T>(t[1]);
659  w.setValue(x,y);
660  }
661  else
662  throw std::invalid_argument ("Vec2 expects tuple of length 2");
663  }
664  else
665  throw std::invalid_argument ("invalid parameters passed to operator <");
666 
667  bool isLessThan = (v.x <= w.x && v.y <= w.y)
668  && v != w;
669 
670  return isLessThan;
671 }
672 
673 template <class T>
674 static bool
675 greaterThan(const Vec2<T> &v, const object &obj)
676 {
677  extract<Vec2<T> > e1(obj);
678  extract<tuple> e2(obj);
679 
680  Vec2<T> w;
681  if(e1.check())
682  {
683  w = e1();
684  }
685  else if(e2.check())
686  {
687  tuple t = e2();
688  if(t.attr("__len__")() == 2){
689  T x = extract<T>(t[0]);
690  T y = extract<T>(t[1]);
691  w.setValue(x,y);
692  }
693  else
694  throw std::invalid_argument ("Vec2 expects tuple of length 2");
695  }
696  else
697  throw std::invalid_argument ("invalid parameters passed to operator >");
698 
699  bool isGreaterThan = (v.x >= w.x && v.y >= w.y)
700  && v != w;
701 
702  return isGreaterThan;
703 }
704 
705 template <class T>
706 static bool
707 lessThanEqual(const Vec2<T> &v, const object &obj)
708 {
709  extract<Vec2<T> > e1(obj);
710  extract<tuple> e2(obj);
711 
712  Vec2<T> w;
713  if(e1.check())
714  {
715  w = e1();
716  }
717  else if(e2.check())
718  {
719  tuple t = e2();
720  if(t.attr("__len__")() == 2){
721  T x = extract<T>(t[0]);
722  T y = extract<T>(t[1]);
723  w.setValue(x,y);
724  }
725  else
726  throw std::invalid_argument ("Vec2 expects tuple of length 2");
727  }
728  else
729  throw std::invalid_argument ("invalid parameters passed to operator <=");
730 
731  bool isLessThanEqual = (v.x <= w.x && v.y <= w.y);
732 
733  return isLessThanEqual;
734 }
735 
736 template <class T>
737 static bool
738 greaterThanEqual(const Vec2<T> &v, const object &obj)
739 {
740  extract<Vec2<T> > e1(obj);
741  extract<tuple> e2(obj);
742 
743  Vec2<T> w;
744  if(e1.check())
745  {
746  w = e1();
747  }
748  else if(e2.check())
749  {
750  tuple t = e2();
751  if(t.attr("__len__")() == 2){
752  T x = extract<T>(t[0]);
753  T y = extract<T>(t[1]);
754  w.setValue(x,y);
755  }
756  else
757  throw std::invalid_argument ("Vec2 expects tuple of length 2");
758  }
759  else
760  throw std::invalid_argument ("invalid parameters passed to operator >=");
761 
762  bool isGreaterThanEqual = (v.x >= w.x && v.y >= w.y);
763 
764  return isGreaterThanEqual;
765 }
766 
767 template <class T,class BoostPyType>
768 static void
769 setItemTuple(FixedArray<IMATH_NAMESPACE::Vec2<T> > &va, Py_ssize_t index, const BoostPyType &t)
770 {
771  if(t.attr("__len__")() == 2)
772  {
773  Vec2<T> v;
774  v.x = extract<T>(t[0]);
775  v.y = extract<T>(t[1]);
776  va[va.canonical_index(index)] = v;
777  }
778  else
779  throw std::invalid_argument ("tuple of length 2 expected");
780 }
781 
782 template <class T>
783 static bool
784 equalWithAbsErrorObj(const Vec2<T> &v, const object &obj1, const object &obj2)
785 {
786  extract<Vec2<int> > e1(obj1);
787  extract<Vec2<float> > e2(obj1);
788  extract<Vec2<double> > e3(obj1);
789 
790  extract<tuple> e4(obj1);
791  extract<double> e5(obj2);
792 
793  Vec2<T> w;
794  if(e1.check()) { w = e1(); }
795  else if(e2.check()) { w = e2(); }
796  else if(e3.check()) { w = e3(); }
797  else if(e4.check())
798  {
799  tuple t = e4();
800  if(t.attr("__len__")() == 2)
801  {
802  w.x = extract<T>(t[0]);
803  w.y = extract<T>(t[1]);
804  }
805  else
806  throw std::invalid_argument ("tuple of length 2 expected");
807  }
808  else
809  throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
810 
811  if(e5.check()) { return v.equalWithAbsError(w, e5()); }
812  else
813  throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
814 }
815 
816 template <class T>
817 static bool
818 equalWithRelErrorObj(const Vec2<T> &v, const object &obj1, const object &obj2)
819 {
820  extract<Vec2<int> > e1(obj1);
821  extract<Vec2<float> > e2(obj1);
822  extract<Vec2<double> > e3(obj1);
823 
824  extract<tuple> e4(obj1);
825  extract<double> e5(obj2);
826 
827  Vec2<T> w;
828  if(e1.check()) { w = e1(); }
829  else if(e2.check()) { w = e2(); }
830  else if(e3.check()) { w = e3(); }
831  else if(e4.check())
832  {
833  tuple t = e4();
834  if(t.attr("__len__")() == 2)
835  {
836  w.x = extract<T>(t[0]);
837  w.y = extract<T>(t[1]);
838  }
839  else
840  throw std::invalid_argument ("tuple of length 2 expected");
841  }
842  else
843  throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
844 
845  if(e5.check()) { return v.equalWithRelError(w, e5()); }
846  else
847  throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
848 
849 }
850 
851 /*
852 template <class T>
853 static bool
854 equalWithAbsErrorTuple(Vec2<T> &v, const tuple &t, T e)
855 {
856  Vec2<T> w;
857  if(t.attr("__len__")() == 2)
858  {
859  w.x = extract<T>(t[0]);
860  w.y = extract<T>(t[1]);
861  }
862  else
863  throw std::invalid_argument ("tuple of length 2 expected");
864 
865  return v.equalWithAbsError(w, e);
866 }
867 
868 template <class T>
869 static bool
870 equalWithRelErrorTuple(Vec2<T> &v, const tuple &t, T e)
871 {
872  std::cout << "RelError Tuple called" << std::endl;
873  Vec2<T> w;
874  if(t.attr("__len__")() == 2)
875  {
876  w.x = extract<T>(t[0]);
877  w.y = extract<T>(t[1]);
878  }
879  else
880  throw std::invalid_argument ("tuple of length 2 expected");
881 
882  return v.equalWithRelError(w, e);
883 }
884 */
885 template <class T,class BoostPyType>
886 static bool
887 equal(const Vec2<T> &v, const BoostPyType &t)
888 {
889  Vec2<T> w;
890  if(t.attr("__len__")() == 2)
891  {
892  w.x = extract<T>(t[0]);
893  w.y = extract<T>(t[1]);
894 
895  return (v == w);
896  }
897  else
898  throw std::invalid_argument ("tuple of length 2 expected");
899 }
900 
901 template <class T,class BoostPyType>
902 static bool
903 notequal(const Vec2<T> &v, const BoostPyType &t)
904 {
905  Vec2<T> w;
906  if(t.attr("__len__")() == 2)
907  {
908  w.x = extract<T>(t[0]);
909  w.y = extract<T>(t[1]);
910 
911  return (v != w);
912  }
913  else
914  throw std::invalid_argument ("tuple of length 2 expected");
915 }
916 
917 
918 
919 // Trick to register methods for float-only-based vectors
921 void register_Vec2_floatonly(class_<Vec2<T>>& vec2_class)
922 {
923  vec2_class
924  .def("length", &Vec2_length<T>,"length() magnitude of the vector")
925  .def("normalize", &Vec2_normalize<T>,return_internal_reference<>(),
926  "v.normalize() destructively normalizes v and returns a reference to it")
927  .def("normalizeExc", &Vec2_normalizeExc<T>,return_internal_reference<>(),
928  "v.normalizeExc() destructively normalizes V and returns a reference to it, throwing an exception if length() == 0")
929  .def("normalizeNonNull", &Vec2_normalizeNonNull<T>,return_internal_reference<>(),
930  "v.normalizeNonNull() destructively normalizes V and returns a reference to it, faster if lngth() != 0")
931  .def("normalized", &Vec2_normalized<T>, "v.normalized() returns a normalized copy of v")
932  .def("normalizedExc", &Vec2_normalizedExc<T>, "v.normalizedExc() returns a normalized copy of v, throwing an exception if length() == 0")
933  .def("normalizedNonNull", &Vec2_normalizedNonNull<T>, "v.normalizedNonNull() returns a normalized copy of v, faster if lngth() != 0")
934  .def("orthogonal", &orthogonal<T>)
935  .def("project", &project<T>)
936  .def("reflect", &reflect<T>)
937  ;
938 }
939 
941 void register_Vec2_floatonly(class_<Vec2<T>>& vec2_class)
942 {
943 }
944 
945 
946 
947 template <class T>
948 class_<Vec2<T> >
950 {
951  typedef PyImath::StaticFixedArray<Vec2<T>,T,2> Vec2_helper;
952 
953  class_<Vec2<T> > vec2_class(Vec2Name<T>::value, Vec2Name<T>::value,init<Vec2<T> >("copy construction"));
954  vec2_class
955  .def("__init__",make_constructor(Vec2_construct_default<T>),"initialize to (0,0)")
956  .def("__init__",make_constructor(Vec2_object_constructor1<T>))
957  .def("__init__",make_constructor(Vec2_object_constructor2<T>))
958  .def_readwrite("x", &Vec2<T>::x)
959  .def_readwrite("y", &Vec2<T>::y)
960  .def("baseTypeEpsilon", &Vec2<T>::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the vector")
961  .staticmethod("baseTypeEpsilon")
962  .def("baseTypeMax", &Vec2<T>::baseTypeMax,"baseTypeMax() max value of the base type of the vector")
963  .staticmethod("baseTypeMax")
964  .def("baseTypeLowest", &Vec2<T>::baseTypeLowest,"baseTypeLowest() largest negative value of the base type of the vector")
965  .staticmethod("baseTypeLowest")
966  .def("baseTypeSmallest", &Vec2<T>::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the vector")
967  .staticmethod("baseTypeSmallest")
968  .def("cross", &Vec2_cross<T>,"v1.cross(v2) right handed cross product")
969  .def("cross", &Vec2_cross_Vec2Array<T>,"v1.cross(v2) right handed array cross product")
970  .def("dimensions", &Vec2<T>::dimensions,"dimensions() number of dimensions in the vector")
971  .staticmethod("dimensions")
972  .def("dot", &Vec2_dot<T>,"v1.dot(v2) inner product of the two vectors")
973  .def("dot", &Vec2_dot_Vec2Array<T>,"v1.dot(v2) array inner product")
974  .def("equalWithAbsError", &Vec2<T>::equalWithAbsError,
975  "v1.equalWithAbsError(v2) true if the elements "
976  "of v1 and v2 are the same with an absolute error of no more than e, "
977  "i.e., abs(v1[i] - v2[i]) <= e")
978  .def("equalWithAbsError", &equalWithAbsErrorObj<T>)
979 
980  .def("equalWithRelError", &Vec2<T>::equalWithRelError,
981  "v1.equalWithAbsError(v2) true if the elements "
982  "of v1 and v2 are the same with an absolute error of no more than e, "
983  "i.e., abs(v1[i] - v2[i]) <= e * abs(v1[i])")
984  .def("equalWithRelError", &equalWithRelErrorObj<T>)
985 
986  .def("length2", &Vec2_length2<T>,"length2() square magnitude of the vector")
987  .def("__len__", Vec2_helper::len)
988  .def("__getitem__", Vec2_helper::getitem,return_value_policy<copy_non_const_reference>())
989  .def("__setitem__", Vec2_helper::setitem)
990  .def("closestVertex", &closestVertex<T>)
991  .def("negate", &Vec2_negate<T>, return_internal_reference<>())
992  .def("setValue", &setValue<T>)
993  .def("__neg__", &Vec2_neg<T>)
994  .def("__mul__", &Vec2_mul<T, int>)
995  .def("__mul__", &Vec2_mul<T, float>)
996  .def("__mul__", &Vec2_mul<T, double>)
997  .def("__mul__", &Vec2_mulT<T>)
998  .def("__mul__", &Vec2_mulTArray<T>)
999  .def("__mul__", &Vec2_mulTuple<T,tuple>)
1000  .def("__mul__", &Vec2_mulTuple<T,list>)
1001  .def("__rmul__", &Vec2_rmulT<T>)
1002  .def("__rmul__", &Vec2_rmulTArray<T>)
1003  .def("__rmul__", &Vec2_mulTuple<T,tuple>)
1004  .def("__rmul__", &Vec2_mulTuple<T,list>)
1005  .def("__imul__", &Vec2_imulV<T, int>,return_internal_reference<>())
1006  .def("__imul__", &Vec2_imulV<T, float>,return_internal_reference<>())
1007  .def("__imul__", &Vec2_imulV<T, double>,return_internal_reference<>())
1008  .def("__imul__", &Vec2_imulT<T>,return_internal_reference<>())
1009  .def(self * self)
1010  .def("__mul__", &Vec2_mulM22<T, float>)
1011  .def("__mul__", &Vec2_mulM22<T, double>)
1012  .def("__mul__", &Vec2_mulM33<T, float>)
1013  .def("__mul__", &Vec2_mulM33<T, double>)
1014  .def("__imul__", &Vec2_imulM22<T, float>, return_internal_reference<>())
1015  .def("__imul__", &Vec2_imulM22<T, double>, return_internal_reference<>())
1016  .def("__imul__", &Vec2_imulM33<T, float>, return_internal_reference<>())
1017  .def("__imul__", &Vec2_imulM33<T, double>, return_internal_reference<>())
1018  .def(self / self) // NOSONAR - suppress SonarCloud bug report.
1019  .def("__div__", &Vec2_div<T,int>)
1020  .def("__div__", &Vec2_div<T,float>)
1021  .def("__div__", &Vec2_div<T,double>)
1022  .def("__div__", &Vec2_divTuple<T,tuple>)
1023  .def("__div__", &Vec2_divTuple<T,list>)
1024  .def("__div__", &Vec2_divT<T>)
1025  .def("__truediv__", &Vec2_div<T,int>)
1026  .def("__truediv__", &Vec2_div<T,float>)
1027  .def("__truediv__", &Vec2_div<T,double>)
1028  .def("__truediv__", &Vec2_divTuple<T,tuple>)
1029  .def("__truediv__", &Vec2_divTuple<T,list>)
1030  .def("__truediv__", &Vec2_divT<T>)
1031  .def("__rdiv__", &Vec2_rdivTuple<T,tuple>)
1032  .def("__rdiv__", &Vec2_rdivTuple<T,list>)
1033  .def("__rdiv__", &Vec2_rdivT<T>)
1034  .def("__rtruediv__", &Vec2_rdivTuple<T,tuple>)
1035  .def("__rtruediv__", &Vec2_rdivTuple<T,list>)
1036  .def("__rtruediv__", &Vec2_rdivT<T>)
1037  .def("__idiv__", &Vec2_idivObj<T>,return_internal_reference<>())
1038  .def("__itruediv__", &Vec2_idivObj<T>,return_internal_reference<>())
1039  .def("__xor__", &Vec2_dot<T>)
1040  .def("__mod__", &Vec2_cross<T>)
1041  .def(self == self) // NOSONAR - suppress SonarCloud bug report.
1042  .def(self != self) // NOSONAR - suppress SonarCloud bug report.
1043  .def("__eq__", &equal<T,tuple>)
1044  .def("__ne__", &notequal<T,tuple>)
1045  .def("__add__", &Vec2_add<T>)
1046  .def("__add__", &Vec2_addV<T, int>)
1047  .def("__add__", &Vec2_addV<T, float>)
1048  .def("__add__", &Vec2_addV<T, double>)
1049  .def("__add__", &Vec2_addT<T>)
1050  .def("__add__", &Vec2_addTuple<T,tuple>)
1051  .def("__add__", &Vec2_addTuple<T,list>)
1052  .def("__radd__", &Vec2_add<T>)
1053  .def("__radd__", &Vec2_addT<T>)
1054  .def("__radd__", &Vec2_addTuple<T,tuple>)
1055  .def("__radd__", &Vec2_addTuple<T,list>)
1056  .def("__iadd__", &Vec2_iaddV<T, int>, return_internal_reference<>())
1057  .def("__iadd__", &Vec2_iaddV<T, float>, return_internal_reference<>())
1058  .def("__iadd__", &Vec2_iaddV<T, double>, return_internal_reference<>())
1059  .def("__sub__", &Vec2_sub<T>)
1060  .def("__sub__", &Vec2_subV<T, int>)
1061  .def("__sub__", &Vec2_subV<T, float>)
1062  .def("__sub__", &Vec2_subV<T, double>)
1063  .def("__sub__", &Vec2_subT<T>)
1064  .def("__sub__", &Vec2_subTuple<T,tuple>)
1065  .def("__sub__", &Vec2_subTuple<T,list>)
1066  .def("__rsub__", &Vec2_rsubT<T>)
1067  .def("__rsub__", &Vec2_rsubTuple<T,tuple>)
1068  .def("__rsub__", &Vec2_rsubTuple<T,list>)
1069  .def("__isub__", &Vec2_isubV<T, int>, return_internal_reference<>())
1070  .def("__isub__", &Vec2_isubV<T, float>, return_internal_reference<>())
1071  .def("__isub__", &Vec2_isubV<T, double>, return_internal_reference<>())
1072  .def("__lt__", &lessThan<T>)
1073  .def("__gt__", &greaterThan<T>)
1074  .def("__le__", &lessThanEqual<T>)
1075  .def("__ge__", &greaterThanEqual<T>)
1076  //.def(self_ns::str(self))
1077  .def("__str__",&Vec2_str<T>)
1078  .def("__repr__",&Vec2_repr<T>)
1079  ;
1080 
1081  register_Vec2_floatonly<T>(vec2_class);
1082 
1083  decoratecopy(vec2_class);
1084 
1085  //add_swizzle2_operators(v2f_class);
1086  return vec2_class;
1087 }
1088 
1089 // XXX fixme - template this
1090 // really this should get generated automatically...
1091 
1092 template <class T,int index>
1093 static FixedArray<T>
1094 Vec2Array_get(FixedArray<IMATH_NAMESPACE::Vec2<T> > &va)
1095 {
1096  return FixedArray<T>(va.unchecked_index(0).getValue () + index,
1097  va.len(), 2*va.stride(), va.handle(), va.writable());
1098 }
1099 
1100 template <class T>
1101 static IMATH_NAMESPACE::Vec2<T>
1102 Vec2Array_min(const FixedArray<IMATH_NAMESPACE::Vec2<T> > &a)
1103 {
1104  Vec2<T> tmp(Vec2<T>(0));
1105  size_t len = a.len();
1106  if (len > 0)
1107  tmp = a[0];
1108  for (size_t i=1; i < len; ++i)
1109  {
1110  if (a[i].x < tmp.x)
1111  tmp.x = a[i].x;
1112  if (a[i].y < tmp.y)
1113  tmp.y = a[i].y;
1114  }
1115  return tmp;
1116 }
1117 
1118 template <class T>
1119 static IMATH_NAMESPACE::Vec2<T>
1120 Vec2Array_max(const FixedArray<IMATH_NAMESPACE::Vec2<T> > &a)
1121 {
1122  Vec2<T> tmp(Vec2<T>(0));
1123  size_t len = a.len();
1124  if (len > 0)
1125  tmp = a[0];
1126  for (size_t i=1; i < len; ++i)
1127  {
1128  if (a[i].x > tmp.x)
1129  tmp.x = a[i].x;
1130  if (a[i].y > tmp.y)
1131  tmp.y = a[i].y;
1132  }
1133  return tmp;
1134 }
1135 
1136 template <class T>
1137 static IMATH_NAMESPACE::Box<IMATH_NAMESPACE::Vec2<T> >
1138 Vec2Array_bounds(const FixedArray<IMATH_NAMESPACE::Vec2<T> > &a)
1139 {
1140  Box<Vec2<T> > tmp;
1141  size_t len = a.len();
1142  for (size_t i=0; i < len; ++i)
1143  tmp.extendBy(a[i]);
1144  return tmp;
1145 }
1146 
1147 
1148 // Trick to register methods for float-only-based vectors
1150 void register_Vec2Array_floatonly(class_<FixedArray<Vec2<T>>>& vec2Array_class)
1151 {
1152  generate_member_bindings<op_vecLength<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"length","");
1153  generate_member_bindings<op_vecNormalize<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"normalize","");
1154  generate_member_bindings<op_vecNormalized<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"normalized","");
1155  generate_member_bindings<op_vecNormalizeExc<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"normalizeExc","");
1156  generate_member_bindings<op_vecNormalizedExc<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"normalizedExc","");
1157 }
1158 
1160 void register_Vec2Array_floatonly(class_<FixedArray<Vec2<T>>>& vec2Array_class)
1161 {
1162 }
1163 
1164 
1165 
1166 template <class T>
1167 class_<FixedArray<IMATH_NAMESPACE::Vec2<T> > >
1169 {
1170  using hboost::mpl::true_;
1171  using hboost::mpl::false_;
1172 
1173  class_<FixedArray<IMATH_NAMESPACE::Vec2<T> > > vec2Array_class = FixedArray<IMATH_NAMESPACE::Vec2<T> >::register_("Fixed length array of IMATH_NAMESPACE::Vec2");
1174  vec2Array_class
1175  .add_property("x",&Vec2Array_get<T,0>)
1176  .add_property("y",&Vec2Array_get<T,1>)
1177  .def("__setitem__", &setItemTuple<T,tuple>)
1178  .def("__setitem__", &setItemTuple<T,list>)
1179  .def("min", &Vec2Array_min<T>)
1180  .def("max", &Vec2Array_max<T>)
1181  .def("bounds", &Vec2Array_bounds<T>)
1182  ;
1183 
1184  add_arithmetic_math_functions(vec2Array_class);
1185  add_comparison_functions(vec2Array_class);
1186 
1187  register_Vec2Array_floatonly(vec2Array_class);
1188  generate_member_bindings<op_vecLength2<IMATH_NAMESPACE::Vec2<T> > >(vec2Array_class,"length2","");
1189  generate_member_bindings<op_vec2Cross<T>, true_>(vec2Array_class,"cross","return the cross product of (self,x)",hboost::python::args("x"));
1190  generate_member_bindings<op_vecDot<IMATH_NAMESPACE::Vec2<T> >,true_>(vec2Array_class,"dot","return the inner product of (self,x)",hboost::python::args("x"));
1191 
1192  generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__mul__" ,"self*x", hboost::python::args("x"));
1193  generate_member_bindings<op_mul<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__rmul__","x*self", hboost::python::args("x"));
1194  generate_member_bindings<op_imul<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__imul__","self*=x",hboost::python::args("x"));
1195  generate_member_bindings<op_div<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__div__" ,"self/x", hboost::python::args("x"));
1196  generate_member_bindings<op_div<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__truediv__" ,"self/x", hboost::python::args("x"));
1197  generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__idiv__","self/=x",hboost::python::args("x"));
1198  generate_member_bindings<op_idiv<IMATH_NAMESPACE::Vec2<T>,T>, true_>(vec2Array_class,"__itruediv__","self/=x",hboost::python::args("x"));
1199 
1200  decoratecopy(vec2Array_class);
1201 
1202  return vec2Array_class;
1203 }
1204 
1205 }
1206 
1207 #endif
GLuint GLuint stream
Definition: glcorearb.h:1832
#define MATH_EXC_ON
void register_Vec2Array_floatonly(class_< FixedArray< Vec2< T >>> &vec2Array_class)
void register_Vec2_floatonly(class_< Vec2< T >> &vec2_class)
#define IMATH_NAMESPACE
Definition: ImathConfig.h:43
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
IMATH_CONSTEXPR14 Vec3< T > closestVertex(const Vec3< T > &v0, const Vec3< T > &v1, const Vec3< T > &v2, const Line3< T > &l) IMATH_NOEXCEPT
IMATH_HOSTDEVICE void extendBy(const V &point) IMATH_NOEXCEPT
Extend the box to include the given point.
Definition: ImathBox.h:234
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
Definition: ImathFun.h:105
GLint y
Definition: glcorearb.h:103
hboost::python::class_< IMATH_NAMESPACE::Vec2< T > > register_Vec2()
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
GLfloat f
Definition: glcorearb.h:1926
T x
Definition: ImathVec.h:59
hboost::python::class_< FixedArray< IMATH_NAMESPACE::Vec2< T > > > register_Vec2Array()
static const char * value
T y
Definition: ImathVec.h:59
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
GLdouble t
Definition: glad.h:2397
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError(const Vec2< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1406
GLfloat v0
Definition: glcorearb.h:816
#define PY_IMATH_LEAVE_PYTHON
Definition: ImathVec.h:39
GLuint index
Definition: glcorearb.h:786
GLfloat GLfloat v1
Definition: glcorearb.h:817
**If you just want to fire and args
Definition: thread.h:618
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
Definition: ImathBox.h:37
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError(const Vec2< T > &v, T e) const IMATH_NOEXCEPT
Definition: ImathVec.h:1394
hboost::python::class_< T, X1, X2, X3 > & decoratecopy(hboost::python::class_< T, X1, X2, X3 > &cls)
IMATH_HOSTDEVICE void setValue(S a, S b) IMATH_NOEXCEPT
Set the value.
Definition: ImathVec.h:1329