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__", ¬equal<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