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