1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5
6 // clang-format off
7
8 #ifndef _PyImathVec3Impl_h_
9 #define _PyImathVec3Impl_h_
10
11 //
12 // This .C file was turned into a header file so that instantiations
13 // of the various V3* 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 <ImathVec.h>
22 #include <ImathVecAlgo.h>
23 #include "PyImath.h"
24 #include "PyImathMathExc.h"
25 #include "PyImathVec.h"
26 #include "PyImathDecorators.h"
27
28 namespace PyImath {
29 using namespace boost::python;
30 using namespace IMATH_NAMESPACE;
31
32 template <class T> struct Vec3Name { static const char *value(); };
33
34 // create a new default constructor that initializes Vec3<T> to zero.
35 template <class T>
Vec3_construct_default()36 static Vec3<T> * Vec3_construct_default()
37 {
38 return new Vec3<T>(T(0),T(0),T(0));
39 }
40
41 template <class T>
Vec3_object_constructor1(const object & obj)42 static Vec3<T> * Vec3_object_constructor1(const object &obj)
43 {
44 Vec3<T> w;
45 extract<Vec3<int> > e1(obj);
46 extract<Vec3<float> > e2(obj);
47 extract<Vec3<double> > e3(obj);
48 extract<tuple> e4(obj);
49 extract<double> e5(obj);
50 extract<list> e6(obj);
51
52 if(e1.check()) { w = e1(); }
53 else if(e2.check()) { w = e2(); }
54 else if(e3.check()) { w = e3(); }
55 else if(e4.check())
56 {
57 tuple t = e4();
58 if(t.attr("__len__")() == 3)
59 {
60 w.x = extract<T>(t[0]);
61 w.y = extract<T>(t[1]);
62 w.z = extract<T>(t[2]);
63 }
64 else
65 throw std::invalid_argument ("tuple must have length of 3");
66
67 }
68 else if(e5.check()) { T a = e5(); w.setValue(a, a, a); }
69 else if(e6.check())
70 {
71 list l = e6();
72 if(l.attr("__len__")() == 3)
73 {
74 w.x = extract<T>(l[0]);
75 w.y = extract<T>(l[1]);
76 w.z = extract<T>(l[2]);
77 }
78 else
79 throw std::invalid_argument ("list must have length of 3");
80 }
81 else
82 throw std::invalid_argument ("invalid parameters passed to Vec3 constructor");
83
84 Vec3<T> *v = new Vec3<T>;
85 *v = w;
86
87 return v;
88
89 }
90
91 template <class T>
Vec3_object_constructor2(const object & obj1,const object & obj2,const object & obj3)92 static Vec3<T> * Vec3_object_constructor2(const object &obj1, const object &obj2, const object &obj3)
93 {
94 extract<double> e1(obj1);
95 extract<double> e2(obj2);
96 extract<double> e3(obj3);
97 Vec3<T> *v = new Vec3<T>;
98
99 if(e1.check()) { v->x = e1();}
100 else { throw std::invalid_argument ("invalid parameters passed to Vec3 constructor"); }
101
102 if(e2.check()) { v->y = e2();}
103 else { throw std::invalid_argument ("invalid parameters passed to Vec3 constructor"); }
104
105 if(e3.check()) { v->z = e3();}
106 else { throw std::invalid_argument ("invalid parameters passed to Vec3 constructor"); }
107
108 return v;
109 }
110
111
112
113 // Implementations of str and repr are same here,
114 // but we'll specialize repr for float and double to make them exact.
115 template <class T>
Vec3_str(const Vec3<T> & v)116 static std::string Vec3_str(const Vec3<T> &v)
117 {
118 std::stringstream stream;
119 stream << Vec3Name<T>::value() << "(" << v.x << ", " << v.y << ", " << v.z << ")";
120 return stream.str();
121 }
122 template <class T>
Vec3_repr(const Vec3<T> & v)123 static std::string Vec3_repr(const Vec3<T> &v)
124 {
125 std::stringstream stream;
126 stream << Vec3Name<T>::value() << "(" << v.x << ", " << v.y << ", " << v.z << ")";
127 return stream.str();
128 }
129
130 template <class T>
131 static IMATH_NAMESPACE::Vec3<T>
Vec3_cross(const IMATH_NAMESPACE::Vec3<T> & v,const IMATH_NAMESPACE::Vec3<T> & other)132 Vec3_cross(const IMATH_NAMESPACE::Vec3<T> &v, const IMATH_NAMESPACE::Vec3<T> &other)
133 {
134 MATH_EXC_ON;
135 return v.cross(other);
136 }
137
138 template <class T>
139 static FixedArray<IMATH_NAMESPACE::Vec3<T> >
Vec3_cross_Vec3Array(const IMATH_NAMESPACE::Vec3<T> & va,const FixedArray<IMATH_NAMESPACE::Vec3<T>> & vb)140 Vec3_cross_Vec3Array(const IMATH_NAMESPACE::Vec3<T> &va, const FixedArray<IMATH_NAMESPACE::Vec3<T> > &vb)
141 {
142 MATH_EXC_ON;
143 size_t len = vb.len();
144 FixedArray<IMATH_NAMESPACE::Vec3<T> > f(len);
145 for (size_t i = 0; i < len; ++i)
146 f[i] = va.cross(vb[i]);
147 return f;
148 }
149
150 template <class T>
151 static T
Vec3_dot(const IMATH_NAMESPACE::Vec3<T> & v,const IMATH_NAMESPACE::Vec3<T> & other)152 Vec3_dot(const IMATH_NAMESPACE::Vec3<T> &v, const IMATH_NAMESPACE::Vec3<T> &other)
153 {
154 MATH_EXC_ON;
155 return v.dot(other);
156 }
157
158 template <class T>
159 static FixedArray<T>
Vec3_dot_Vec3Array(const IMATH_NAMESPACE::Vec3<T> & va,const FixedArray<IMATH_NAMESPACE::Vec3<T>> & vb)160 Vec3_dot_Vec3Array(const IMATH_NAMESPACE::Vec3<T> &va, const FixedArray<IMATH_NAMESPACE::Vec3<T> > &vb)
161 {
162 MATH_EXC_ON;
163 size_t len = vb.len();
164 FixedArray<T> f(len);
165 for (size_t i = 0; i < len; ++i)
166 f[i] = va.dot(vb[i]);
167 return f;
168 }
169
170 template <class T>
171 static T
Vec3_length(const IMATH_NAMESPACE::Vec3<T> & v)172 Vec3_length(const IMATH_NAMESPACE::Vec3<T> &v)
173 {
174 MATH_EXC_ON;
175 return v.length();
176 }
177
178 template <class T>
179 static T
Vec3_length2(const IMATH_NAMESPACE::Vec3<T> & v)180 Vec3_length2(const IMATH_NAMESPACE::Vec3<T> &v)
181 {
182 MATH_EXC_ON;
183 return v.length2();
184 }
185
186 template <class T>
187 static const Vec3<T> &
Vec3_normalize(IMATH_NAMESPACE::Vec3<T> & v)188 Vec3_normalize(IMATH_NAMESPACE::Vec3<T> &v)
189 {
190 MATH_EXC_ON;
191 return v.normalize();
192 }
193
194 template <class T>
195 static const Vec3<T> &
Vec3_normalizeExc(IMATH_NAMESPACE::Vec3<T> & v)196 Vec3_normalizeExc(IMATH_NAMESPACE::Vec3<T> &v)
197 {
198 MATH_EXC_ON;
199 return v.normalizeExc();
200 }
201
202 template <class T>
203 static const Vec3<T> &
Vec3_normalizeNonNull(IMATH_NAMESPACE::Vec3<T> & v)204 Vec3_normalizeNonNull(IMATH_NAMESPACE::Vec3<T> &v)
205 {
206 MATH_EXC_ON;
207 return v.normalizeNonNull();
208 }
209
210 template <class T>
211 static Vec3<T>
Vec3_normalized(const IMATH_NAMESPACE::Vec3<T> & v)212 Vec3_normalized(const IMATH_NAMESPACE::Vec3<T> &v)
213 {
214 MATH_EXC_ON;
215 return v.normalized();
216 }
217
218 template <class T>
219 static Vec3<T>
Vec3_normalizedExc(const IMATH_NAMESPACE::Vec3<T> & v)220 Vec3_normalizedExc(const IMATH_NAMESPACE::Vec3<T> &v)
221 {
222 MATH_EXC_ON;
223 return v.normalizedExc();
224 }
225
226 template <class T>
227 static Vec3<T>
Vec3_normalizedNonNull(const IMATH_NAMESPACE::Vec3<T> & v)228 Vec3_normalizedNonNull(const IMATH_NAMESPACE::Vec3<T> &v)
229 {
230 MATH_EXC_ON;
231 return v.normalizedNonNull();
232 }
233
234 template <class T>
235 static Vec3<T>
closestVertex(Vec3<T> & p,const Vec3<T> & v0,const Vec3<T> & v1,const Vec3<T> & v2)236 closestVertex(Vec3<T> &p, const Vec3<T> &v0, const Vec3<T> &v1, const Vec3<T> &v2)
237 {
238 MATH_EXC_ON;
239 return IMATH_NAMESPACE::closestVertex(v0, v1, v2, p);
240 }
241
242 template <class T>
243 static const Vec3<T> &
Vec3_negate(IMATH_NAMESPACE::Vec3<T> & v)244 Vec3_negate(IMATH_NAMESPACE::Vec3<T> &v)
245 {
246 MATH_EXC_ON;
247 return v.negate();
248 }
249
250 template <class T>
251 static Vec3<T>
orthogonal(const Vec3<T> & v,const Vec3<T> & v0)252 orthogonal(const Vec3<T> &v, const Vec3<T> &v0)
253 {
254 MATH_EXC_ON;
255 return IMATH_NAMESPACE::orthogonal(v, v0);
256 }
257
258 template <class T>
259 static Vec3<T>
project(const Vec3<T> & v,const Vec3<T> & v0)260 project(const Vec3<T> &v, const Vec3<T> &v0)
261 {
262 MATH_EXC_ON;
263 return IMATH_NAMESPACE::project(v0, v);
264 }
265
266 template <class T>
267 static Vec3<T>
reflect(const Vec3<T> & v,const Vec3<T> & v0)268 reflect(const Vec3<T> &v, const Vec3<T> &v0)
269 {
270 MATH_EXC_ON;
271 return IMATH_NAMESPACE::reflect(v, v0);
272 }
273
274 template <class T>
275 static void
setValue(Vec3<T> & v,T a,T b,T c)276 setValue(Vec3<T> &v, T a, T b, T c)
277 {
278 v.x = a;
279 v.y = b;
280 v.z = c;
281 }
282
283 template <class T>
284 static Vec3<T>
Vec3_add(const Vec3<T> & v,const Vec3<T> & w)285 Vec3_add (const Vec3<T> &v, const Vec3<T> &w)
286 {
287 MATH_EXC_ON;
288 return v + w;
289 }
290
291 template <class T>
292 static Vec3<T>
Vec3_sub(const Vec3<T> & v,const Vec3<T> & w)293 Vec3_sub (const Vec3<T> &v, const Vec3<T> &w)
294 {
295 MATH_EXC_ON;
296 return v - w;
297 }
298
299 template <class T>
300 static Vec3<T>
Vec3_neg(const Vec3<T> & v)301 Vec3_neg (const Vec3<T> &v)
302 {
303 MATH_EXC_ON;
304 return -v;
305 }
306
307 template <class T, class U>
308 static Vec3<T>
Vec3_mul(const Vec3<T> & v,Vec3<U> & w)309 Vec3_mul (const Vec3<T> &v, Vec3<U> &w)
310 {
311 MATH_EXC_ON;
312 Vec3<T> w2 (w);
313 return v * w2;
314 }
315
316 template <class T>
317 static Vec3<T>
Vec3_mulT(const Vec3<T> & v,T t)318 Vec3_mulT (const Vec3<T> &v, T t)
319 {
320 MATH_EXC_ON;
321 return v * t;
322 }
323
324 template <class T>
325 static FixedArray<IMATH_NAMESPACE::Vec3<T> >
Vec3_mulTArray(const Vec3<T> & v,const FixedArray<T> & t)326 Vec3_mulTArray (const Vec3<T> &v, const FixedArray<T> &t)
327 {
328 MATH_EXC_ON;
329 size_t len = t.len();
330 FixedArray<IMATH_NAMESPACE::Vec3<T> > retval(len);
331 for (size_t i=0; i<len; ++i) retval[i] = v*t[i];
332 return retval;
333 }
334
335 template <class T>
336 static FixedArray<IMATH_NAMESPACE::Vec3<T> >
Vec3_rmulTArray(const Vec3<T> & v,const FixedArray<T> & t)337 Vec3_rmulTArray (const Vec3<T> &v, const FixedArray<T> &t)
338 {
339 return Vec3_mulTArray(v,t);
340 }
341
342 template <class T,class S>
343 static Vec3<T>
Vec3_div(Vec3<T> & v,Vec3<S> & w)344 Vec3_div (Vec3<T> &v, Vec3<S> &w)
345 {
346 MATH_EXC_ON;
347 return v / w;
348 }
349
350 template <class T>
351 static Vec3<T>
Vec3_rmulT(Vec3<T> & v,T t)352 Vec3_rmulT (Vec3<T> &v, T t)
353 {
354 MATH_EXC_ON;
355 return t * v;
356 }
357
358 template <class T, class U>
359 static const Vec3<T> &
Vec3_imulV(Vec3<T> & v,const Vec3<U> & w)360 Vec3_imulV(Vec3<T> &v, const Vec3<U> &w)
361 {
362 MATH_EXC_ON;
363 return v *= w;
364 }
365
366 template <class T>
367 static const Vec3<T> &
Vec3_imulT(IMATH_NAMESPACE::Vec3<T> & v,T t)368 Vec3_imulT(IMATH_NAMESPACE::Vec3<T> &v, T t)
369 {
370 MATH_EXC_ON;
371 return v *= t;
372 }
373
374 template <class T, class U>
375 static Vec3<T>
Vec3_mulM33(Vec3<T> & v,const Matrix33<U> & m)376 Vec3_mulM33 (Vec3<T> &v, const Matrix33<U> &m)
377 {
378 MATH_EXC_ON;
379 return v * m;
380 }
381
382 template <class T, class U>
383 static Vec3<T>
Vec3_mulM44(Vec3<T> & v,const Matrix44<U> & m)384 Vec3_mulM44 (Vec3<T> &v, const Matrix44<U> &m)
385 {
386 MATH_EXC_ON;
387 return v * m;
388 }
389
390 template <class T>
391 static const Vec3<T> &
Vec3_idivObj(IMATH_NAMESPACE::Vec3<T> & v,const object & o)392 Vec3_idivObj(IMATH_NAMESPACE::Vec3<T> &v, const object &o)
393 {
394 MATH_EXC_ON;
395 Vec3<T> v2;
396 if (PyImath::V3<T>::convert (o.ptr(), &v2))
397 {
398 return v /= v2;
399 }
400 else
401 {
402 extract<double> e(o);
403 if (e.check())
404 return v /= e();
405 else
406 throw std::invalid_argument ("V3 division expects an argument"
407 "convertible to a V3");
408 }
409 }
410
411 template <class T>
412 static Vec3<T>
Vec3_subT(const Vec3<T> & v,T a)413 Vec3_subT(const Vec3<T> &v, T a)
414 {
415 MATH_EXC_ON;
416 Vec3<T> w;
417 w.setValue(v.x - a, v.y - a, v.z - a);
418 return w;
419 }
420
421 template <class T,class BoostPyType>
422 static Vec3<T>
Vec3_subTuple(const Vec3<T> & v,const BoostPyType & t)423 Vec3_subTuple(const Vec3<T> &v, const BoostPyType &t)
424 {
425 MATH_EXC_ON;
426 Vec3<T> w;
427
428 if(t.attr("__len__")() == 3)
429 {
430 w.x = v.x - extract<T>(t[0]);
431 w.y = v.y - extract<T>(t[1]);
432 w.z = v.z - extract<T>(t[2]);
433 }
434 else
435 throw std::invalid_argument ("tuple must have length of 3");
436
437 return w;
438 }
439
440 template <class T>
441 static Vec3<T>
Vec3_rsubT(const Vec3<T> & v,T a)442 Vec3_rsubT(const Vec3<T> &v, T a)
443 {
444 MATH_EXC_ON;
445 Vec3<T> w;
446 w.setValue(a - v.x, a - v.y, a - v.z);
447 return w;
448 }
449
450 template <class T, class BoostPyType>
451 static Vec3<T>
Vec3_rsubTuple(const Vec3<T> & v,const BoostPyType & t)452 Vec3_rsubTuple(const Vec3<T> &v, const BoostPyType &t)
453 {
454 MATH_EXC_ON;
455 Vec3<T> w;
456
457 if(t.attr("__len__")() == 3)
458 {
459 w.x = extract<T>(t[0]) - v.x;
460 w.y = extract<T>(t[1]) - v.y;
461 w.z = extract<T>(t[2]) - v.z;
462 }
463 else
464 throw std::invalid_argument ("tuple must have length of 3");
465
466 return w;
467 }
468
469 template <class T, class BoostPyType>
470 static Vec3<T>
Vec3_addTuple(const Vec3<T> & v,const BoostPyType & t)471 Vec3_addTuple(const Vec3<T> &v, const BoostPyType &t)
472 {
473 MATH_EXC_ON;
474 Vec3<T> w;
475
476 if(t.attr("__len__")() == 3)
477 {
478 w.x = v.x + extract<T>(t[0]);
479 w.y = v.y + extract<T>(t[1]);
480 w.z = v.z + extract<T>(t[2]);
481 }
482 else
483 throw std::invalid_argument ("tuple must have length of 3");
484
485 return w;
486 }
487
488 template <class T>
489 static Vec3<T>
Vec3_addT(const Vec3<T> & v,T a)490 Vec3_addT(const Vec3<T> &v, T a)
491 {
492 MATH_EXC_ON;
493 Vec3<T> w;
494 w.setValue(v.x + a, v.y + a, v.z + a);
495 return w;
496 }
497
498 template <class T, class U>
499 static Vec3<T>
Vec3_addV(const Vec3<T> & v,const Vec3<U> & w)500 Vec3_addV(const Vec3<T> &v, const Vec3<U> &w)
501 {
502 MATH_EXC_ON;
503 return v + w;
504 }
505
506 template <class T, class U>
507 static const Vec3<T> &
Vec3_iaddV(Vec3<T> & v,const Vec3<U> & w)508 Vec3_iaddV(Vec3<T> &v, const Vec3<U> &w)
509 {
510 MATH_EXC_ON;
511 return v += w;
512 }
513
514 template <class T, class U>
515 static Vec3<T>
Vec3_subV(const Vec3<T> & v,const Vec3<U> & w)516 Vec3_subV(const Vec3<T> &v, const Vec3<U> &w)
517 {
518 MATH_EXC_ON;
519 return v - w;
520 }
521
522 template <class T, class U>
523 static const Vec3<T> &
Vec3_isubV(Vec3<T> & v,const Vec3<U> & w)524 Vec3_isubV(Vec3<T> &v, const Vec3<U> &w)
525 {
526 MATH_EXC_ON;
527 return v -= w;
528 }
529
530 template <class T>
531 static Vec3<T>
mult(const Vec3<T> & v,tuple t)532 mult(const Vec3<T> &v, tuple t)
533 {
534 MATH_EXC_ON;
535 Vec3<T> w;
536
537 if(t.attr("__len__")() == 1){
538 w.x = v.x*extract<T>(t[0]);
539 w.y = v.y*extract<T>(t[0]);
540 w.z = v.z*extract<T>(t[0]);
541 }
542 else if(t.attr("__len__")() == 3){
543 w.x = v.x*extract<T>(t[0]);
544 w.y = v.y*extract<T>(t[1]);
545 w.z = v.z*extract<T>(t[2]);
546 }
547 else
548 throw std::invalid_argument ("tuple must have length of 1 or 3");
549
550 return w;
551 }
552
553 template <class T, class U>
554 static const Vec3<T> &
Vec3_imulM44(Vec3<T> & v,const Matrix44<U> & m)555 Vec3_imulM44 (Vec3<T> &v, const Matrix44<U> &m)
556 {
557 MATH_EXC_ON;
558 return v *= m;
559 }
560
561 template <class T, class BoostPyType>
562 static Vec3<T>
Vec3_divTuple(const Vec3<T> & v,const BoostPyType & t)563 Vec3_divTuple(const Vec3<T> &v, const BoostPyType &t)
564 {
565 if(t.attr("__len__")() == 3)
566 {
567 T x = extract<T>(t[0]);
568 T y = extract<T>(t[1]);
569 T z = extract<T>(t[2]);
570 if(x != T(0) && y != T(0) && z != T(0))
571 return Vec3<T>(v.x / x, v.y / y, v.z / z);
572 else
573 throw std::domain_error ("Division by zero");
574 }
575 else
576 throw std::invalid_argument ("Vec3 expects tuple of length 3");
577 }
578
579 template <class T, class BoostPyType>
580 static Vec3<T>
Vec3_rdivTuple(const Vec3<T> & v,const BoostPyType & t)581 Vec3_rdivTuple(const Vec3<T> &v, const BoostPyType &t)
582 {
583 MATH_EXC_ON;
584 Vec3<T> w;
585 if(t.attr("__len__")() == 3)
586 {
587 T x = extract<T>(t[0]);
588 T y = extract<T>(t[1]);
589 T z = extract<T>(t[2]);
590
591 if(v.x != T(0) && v.y != T(0) && v.z != T(0)){
592 w.setValue(x / v.x, y / v.y, z / v.z);
593 }
594 else
595 throw std::domain_error ("Division by zero");
596 }
597 else
598 throw std::invalid_argument ("tuple must have length of 3");
599
600 return w;
601 }
602
603 template <class T>
604 static Vec3<T>
Vec3_divT(const Vec3<T> & v,T a)605 Vec3_divT(const Vec3<T> &v, T a)
606 {
607 MATH_EXC_ON;
608 Vec3<T> w;
609 if(a != T(0)){
610 w.setValue(v.x / a, v.y / a, v.z / a);
611 }
612 else
613 throw std::domain_error ("Division by zero");
614
615 return w;
616 }
617
618 template <class T>
619 static Vec3<T>
Vec3_rdivT(const Vec3<T> & v,T a)620 Vec3_rdivT(const Vec3<T> &v, T a)
621 {
622 MATH_EXC_ON;
623 Vec3<T> w;
624 if(v.x != T(0) && v.y != T(0) && v.z != T(0)){
625 w.setValue(a / v.x, a / v.y, a / v.z);
626 }
627 else
628 throw std::domain_error ("Division by zero");
629
630 return w;
631 }
632
633 template <class T>
634 static Vec3<T>
Vec3_Vec3_mulT(const Vec3<T> & v,const Vec3<T> & w)635 Vec3_Vec3_mulT(const Vec3<T>& v, const Vec3<T>& w)
636 {
637 MATH_EXC_ON;
638 return v*w;
639 }
640
641 template <class T>
642 static Vec3<T>
Vec3_Vec3_divT(const Vec3<T> & v,const Vec3<T> & w)643 Vec3_Vec3_divT(const Vec3<T>& v, const Vec3<T>& w)
644 {
645 MATH_EXC_ON;
646 return v/w;
647 }
648
649 template <class T>
650 static bool
lessThan(const Vec3<T> & v,const object & obj)651 lessThan(const Vec3<T> &v, const object &obj)
652 {
653 extract<Vec3<T> > e1(obj);
654 extract<tuple> e2(obj);
655
656 Vec3<T> w;
657 if(e1.check())
658 {
659 w = e1();
660 }
661 else if(e2.check())
662 {
663 tuple t = e2();
664 T x = extract<T>(t[0]);
665 T y = extract<T>(t[1]);
666 T z = extract<T>(t[2]);
667 w.setValue(x,y,z);
668 }
669 else
670 throw std::invalid_argument ("invalid parameters passed to operator <");
671
672 bool isLessThan = (v.x <= w.x && v.y <= w.y && v.z <= w.z)
673 && v != w;
674
675 return isLessThan;
676 }
677
678 template <class T>
679 static bool
greaterThan(const Vec3<T> & v,const object & obj)680 greaterThan(const Vec3<T> &v, const object &obj)
681 {
682 extract<Vec3<T> > e1(obj);
683 extract<tuple> e2(obj);
684
685 Vec3<T> w;
686 if(e1.check())
687 {
688 w = e1();
689 }
690 else if(e2.check())
691 {
692 tuple t = e2();
693 T x = extract<T>(t[0]);
694 T y = extract<T>(t[1]);
695 T z = extract<T>(t[2]);
696 w.setValue(x,y,z);
697 }
698 else
699 throw std::invalid_argument ("invalid parameters passed to operator >");
700
701 bool isGreaterThan = (v.x >= w.x && v.y >= w.y && v.z >= w.z)
702 && v != w;
703
704 return isGreaterThan;
705 }
706
707 template <class T>
708 static bool
lessThanEqual(const Vec3<T> & v,const object & obj)709 lessThanEqual(const Vec3<T> &v, const object &obj)
710 {
711 extract<Vec3<T> > e1(obj);
712 extract<tuple> e2(obj);
713
714 Vec3<T> w;
715 if(e1.check())
716 {
717 w = e1();
718 }
719 else if(e2.check())
720 {
721 tuple t = e2();
722 T x = extract<T>(t[0]);
723 T y = extract<T>(t[1]);
724 T z = extract<T>(t[2]);
725 w.setValue(x,y,z);
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 && v.z <= w.z);
731
732 return isLessThanEqual;
733 }
734
735 template <class T>
736 static bool
greaterThanEqual(const Vec3<T> & v,const object & obj)737 greaterThanEqual(const Vec3<T> &v, const object &obj)
738 {
739 extract<Vec3<T> > e1(obj);
740 extract<tuple> e2(obj);
741
742 Vec3<T> w;
743 if(e1.check())
744 {
745 w = e1();
746 }
747 else if(e2.check())
748 {
749 tuple t = e2();
750 T x = extract<T>(t[0]);
751 T y = extract<T>(t[1]);
752 T z = extract<T>(t[2]);
753 w.setValue(x,y,z);
754 }
755 else
756 throw std::invalid_argument ("invalid parameters passed to operator >=");
757
758 bool isGreaterThanEqual = (v.x >= w.x && v.y >= w.y && v.z >= w.z);
759
760 return isGreaterThanEqual;
761 }
762
763
764 template <class T>
765 static bool
equalWithAbsErrorObj(const Vec3<T> & v,const object & obj1,const object & obj2)766 equalWithAbsErrorObj(const Vec3<T> &v, const object &obj1, const object &obj2)
767 {
768 extract<Vec3<int> > e1(obj1);
769 extract<Vec3<float> > e2(obj1);
770 extract<Vec3<double> > e3(obj1);
771
772 extract<tuple> e4(obj1);
773 extract<double> e5(obj2);
774
775 Vec3<T> w;
776 if(e1.check()) { w = e1(); }
777 else if(e2.check()) { w = e2(); }
778 else if(e3.check()) { w = e3(); }
779 else if(e4.check())
780 {
781 tuple t = e4();
782 if(t.attr("__len__")() == 3)
783 {
784 w.x = extract<T>(t[0]);
785 w.y = extract<T>(t[1]);
786 w.z = extract<T>(t[2]);
787 }
788 else
789 throw std::invalid_argument ("tuple of length 3 expected");
790 }
791 else
792 throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
793
794 if(e5.check()) { return v.equalWithAbsError(w, e5()); }
795 else
796 throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
797 }
798
799 template <class T>
800 static bool
equalWithRelErrorObj(const Vec3<T> & v,const object & obj1,const object & obj2)801 equalWithRelErrorObj(const Vec3<T> &v, const object &obj1, const object &obj2)
802 {
803 extract<Vec3<int> > e1(obj1);
804 extract<Vec3<float> > e2(obj1);
805 extract<Vec3<double> > e3(obj1);
806
807 extract<tuple> e4(obj1);
808 extract<double> e5(obj2);
809
810 Vec3<T> w;
811 if(e1.check()) { w = e1(); }
812 else if(e2.check()) { w = e2(); }
813 else if(e3.check()) { w = e3(); }
814 else if(e4.check())
815 {
816 tuple t = e4();
817 if(t.attr("__len__")() == 3)
818 {
819 w.x = extract<T>(t[0]);
820 w.y = extract<T>(t[1]);
821 w.z = extract<T>(t[2]);
822 }
823 else
824 throw std::invalid_argument ("tuple of length 3 expected");
825 }
826 else
827 throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
828
829 if(e5.check()) { return v.equalWithRelError(w, e5()); }
830 else
831 throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
832
833 }
834
835
836 template <class T>
837 static bool
equal(const Vec3<T> & v,const tuple & t)838 equal(const Vec3<T> &v, const tuple &t)
839 {
840 Vec3<T> w;
841 if(t.attr("__len__")() == 3)
842 {
843 w.x = extract<T>(t[0]);
844 w.y = extract<T>(t[1]);
845 w.z = extract<T>(t[2]);
846
847 return (v == w);
848 }
849 else
850 throw std::invalid_argument ("tuple of length 3 expected");
851 }
852
853 template <class T>
854 static bool
notequal(const Vec3<T> & v,const tuple & t)855 notequal(const Vec3<T> &v, const tuple &t)
856 {
857 Vec3<T> w;
858 if(t.attr("__len__")() == 3)
859 {
860 w.x = extract<T>(t[0]);
861 w.y = extract<T>(t[1]);
862 w.z = extract<T>(t[2]);
863
864 return (v != w);
865 }
866 else
867 throw std::invalid_argument ("tuple of length 3 expected");
868 }
869
870
871
872 // Trick to register methods for float-only-based vectors
873 template <class T, IMATH_ENABLE_IF(!std::is_integral<T>::value)>
register_Vec3_floatonly(class_<Vec3<T>> & vec3_class)874 void register_Vec3_floatonly(class_<Vec3<T>>& vec3_class)
875 {
876 vec3_class
877 .def("length", &Vec3_length<T>,"length() magnitude of the vector")
878 .def("normalize", &Vec3_normalize<T>,return_internal_reference<>(),
879 "v.normalize() destructively normalizes v and returns a reference to it")
880 .def("normalizeExc", &Vec3_normalizeExc<T>,return_internal_reference<>(),
881 "v.normalizeExc() destructively normalizes V and returns a reference to it, throwing an exception if length() == 0")
882 .def("normalizeNonNull", &Vec3_normalizeNonNull<T>,return_internal_reference<>(),
883 "v.normalizeNonNull() destructively normalizes V and returns a reference to it, faster if lngth() != 0")
884 .def("normalized", &Vec3_normalized<T>, "v.normalized() returns a normalized copy of v")
885 .def("normalizedExc", &Vec3_normalizedExc<T>, "v.normalizedExc() returns a normalized copy of v, throwing an exception if length() == 0")
886 .def("normalizedNonNull", &Vec3_normalizedNonNull<T>, "v.normalizedNonNull() returns a normalized copy of v, faster if lngth() != 0")
887 .def("orthogonal", &orthogonal<T>)
888 .def("project", &project<T>)
889 .def("reflect", &reflect<T>)
890 ;
891 }
892
893 template <class T, IMATH_ENABLE_IF(std::is_integral<T>::value)>
register_Vec3_floatonly(class_<Vec3<T>> & vec2_class)894 void register_Vec3_floatonly(class_<Vec3<T>>& vec2_class)
895 {
896 }
897
898
899
900 template <class T>
901 class_<Vec3<T> >
register_Vec3()902 register_Vec3()
903 {
904 typedef PyImath::StaticFixedArray<Vec3<T>,T,3> Vec3_helper;
905
906 class_<Vec3<T> > vec3_class(Vec3Name<T>::value(), Vec3Name<T>::value(),init<Vec3<T> >("copy construction"));
907 vec3_class
908 .def("__init__",make_constructor(Vec3_construct_default<T>),"initialize to (0,0,0)")
909 .def("__init__",make_constructor(Vec3_object_constructor1<T>))
910 .def("__init__",make_constructor(Vec3_object_constructor2<T>))
911 .def_readwrite("x", &Vec3<T>::x)
912 .def_readwrite("y", &Vec3<T>::y)
913 .def_readwrite("z", &Vec3<T>::z)
914 .def("baseTypeEpsilon", &Vec3<T>::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the vector")
915 .staticmethod("baseTypeEpsilon")
916 .def("baseTypeMax", &Vec3<T>::baseTypeMax,"baseTypeMax() max value of the base type of the vector")
917 .staticmethod("baseTypeMax")
918 .def("baseTypeLowest", &Vec3<T>::baseTypeLowest,"baseTypeLowest() largest negative value of the base type of the vector")
919 .staticmethod("baseTypeLowest")
920 .def("baseTypeSmallest", &Vec3<T>::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the vector")
921 .staticmethod("baseTypeSmallest")
922 .def("cross", &Vec3_cross<T>,"v1.cross(v2) right handed cross product")
923 .def("cross", &Vec3_cross_Vec3Array<T>,"v1.cross(v2) right handed array cross product")
924 .def("dimensions", &Vec3<T>::dimensions,"dimensions() number of dimensions in the vector")
925 .staticmethod("dimensions")
926 .def("dot", &Vec3_dot<T>,"v1.dot(v2) inner product of the two vectors")
927 .def("dot", &Vec3_dot_Vec3Array<T>,"v1.dot(v2) array inner product")
928
929 .def("equalWithAbsError", &Vec3<T>::equalWithAbsError,
930 "v1.equalWithAbsError(v2) true if the elements "
931 "of v1 and v2 are the same with an absolute error of no more than e, "
932 "i.e., abs(v1[i] - v2[i]) <= e")
933 .def("equalWithAbsError", &equalWithAbsErrorObj<T>)
934
935 .def("equalWithRelError", &Vec3<T>::equalWithRelError,
936 "v1.equalWithAbsError(v2) true if the elements "
937 "of v1 and v2 are the same with an absolute error of no more than e, "
938 "i.e., abs(v1[i] - v2[i]) <= e * abs(v1[i])")
939 .def("equalWithRelError", &equalWithRelErrorObj<T>)
940
941 .def("length2", &Vec3_length2<T>,"length2() square magnitude of the vector")
942 .def("__len__", Vec3_helper::len)
943 .def("__getitem__", Vec3_helper::getitem,return_value_policy<copy_non_const_reference>())
944 .def("__setitem__", Vec3_helper::setitem)
945 .def("closestVertex", &closestVertex<T>)
946 .def("negate", &Vec3_negate<T>, return_internal_reference<>())
947 .def("setValue", &setValue<T>)
948 .def("__neg__", &Vec3_neg<T>)
949 .def("__mul__", &Vec3_mul<T, int>)
950 .def("__mul__", &Vec3_mul<T, float>)
951 .def("__mul__", &Vec3_mul<T, double>)
952 .def("__mul__", &Vec3_mulT<T>)
953 .def("__mul__", &Vec3_mulTArray<T>)
954 .def("__rmul__", &Vec3_rmulT<T>)
955 .def("__rmul__", &Vec3_rmulTArray<T>)
956 .def("__imul__", &Vec3_imulV<T, int>,return_internal_reference<>())
957 .def("__imul__", &Vec3_imulV<T, float>,return_internal_reference<>())
958 .def("__imul__", &Vec3_imulV<T, double>,return_internal_reference<>())
959 .def("__imul__", &Vec3_imulT<T>,return_internal_reference<>())
960 .def("__div__", &Vec3_Vec3_divT<T>)
961 .def("__truediv__", &Vec3_Vec3_divT<T>)
962 .def("__mul__", &Vec3_mulM33<T, float>)
963 .def("__mul__", &Vec3_mulM33<T, double>)
964 .def("__mul__", &Vec3_mulM44<T, float>)
965 .def("__mul__", &Vec3_mulM44<T, double>)
966 .def("__mul__", &Vec3_Vec3_mulT<T>)
967 .def("__div__", &Vec3_div<T,int>)
968 .def("__div__", &Vec3_div<T,float>)
969 .def("__div__", &Vec3_div<T,double>)
970 .def("__div__", &Vec3_divTuple<T,tuple>)
971 .def("__div__", &Vec3_divTuple<T,list>)
972 .def("__div__", &Vec3_divT<T>)
973 .def("__truediv__", &Vec3_div<T,int>)
974 .def("__truediv__", &Vec3_div<T,float>)
975 .def("__truediv__", &Vec3_div<T,double>)
976 .def("__truediv__", &Vec3_divTuple<T,tuple>)
977 .def("__truediv__", &Vec3_divTuple<T,list>)
978 .def("__truediv__", &Vec3_divT<T>)
979 .def("__rdiv__", &Vec3_rdivTuple<T,tuple>)
980 .def("__rdiv__", &Vec3_rdivTuple<T,list>)
981 .def("__rdiv__", &Vec3_rdivT<T>)
982 .def("__rtruediv__", &Vec3_rdivTuple<T,tuple>)
983 .def("__rtruediv__", &Vec3_rdivTuple<T,list>)
984 .def("__rtruediv__", &Vec3_rdivT<T>)
985 .def("__idiv__", &Vec3_idivObj<T>,return_internal_reference<>())
986 .def("__itruediv__", &Vec3_idivObj<T>,return_internal_reference<>())
987 .def("__xor__", &Vec3_dot<T>)
988 .def("__mod__", &Vec3_cross<T>)
989 .def(self == self) // NOSONAR - suppress SonarCloud bug report.
990 .def(self != self) // NOSONAR - suppress SonarCloud bug report.
991 .def("__add__", &Vec3_add<T>)
992 .def("__add__", &Vec3_addV<T, int>)
993 .def("__add__", &Vec3_addV<T, float>)
994 .def("__add__", &Vec3_addV<T, double>)
995 .def("__add__", &Vec3_addT<T>)
996 .def("__add__", &Vec3_addTuple<T,tuple>)
997 .def("__add__", &Vec3_addTuple<T,list>)
998 .def("__radd__", &Vec3_addT<T>)
999 .def("__radd__", &Vec3_addTuple<T,tuple>)
1000 .def("__radd__", &Vec3_addTuple<T,list>)
1001 .def("__radd__", &Vec3_add<T>)
1002 .def("__iadd__", &Vec3_iaddV<T, int>, return_internal_reference<>())
1003 .def("__iadd__", &Vec3_iaddV<T, float>, return_internal_reference<>())
1004 .def("__iadd__", &Vec3_iaddV<T, double>, return_internal_reference<>())
1005 .def("__sub__", &Vec3_sub<T>)
1006 .def("__sub__", &Vec3_subV<T, int>)
1007 .def("__sub__", &Vec3_subV<T, float>)
1008 .def("__sub__", &Vec3_subV<T, double>)
1009 .def("__sub__", &Vec3_subT<T>)
1010 .def("__sub__", &Vec3_subTuple<T,tuple>)
1011 .def("__sub__", &Vec3_subTuple<T,list>)
1012 .def("__rsub__", &Vec3_rsubT<T>)
1013 .def("__rsub__", &Vec3_rsubTuple<T,tuple>)
1014 .def("__rsub__", &Vec3_rsubTuple<T,list>)
1015 .def("__isub__", &Vec3_isubV<T, int>, return_internal_reference<>())
1016 .def("__isub__", &Vec3_isubV<T, float>, return_internal_reference<>())
1017 .def("__isub__", &Vec3_isubV<T, double>, return_internal_reference<>())
1018 .def("__mul__", &mult<T>)
1019 .def("__rmul__", &mult<T>)
1020 .def("__imul__", &Vec3_imulM44<T, float>, return_internal_reference<>())
1021 .def("__imul__", &Vec3_imulM44<T, double>, return_internal_reference<>())
1022 .def("__lt__", &lessThan<T>)
1023 .def("__gt__", &greaterThan<T>)
1024 .def("__le__", &lessThanEqual<T>)
1025 .def("__ge__", &greaterThanEqual<T>)
1026 .def("__eq__", &equal<T>)
1027 .def("__ne__", ¬equal<T>)
1028 //.def(self_ns::str(self))
1029 .def("__str__",&Vec3_str<T>)
1030 .def("__repr__",&Vec3_repr<T>)
1031 ;
1032
1033 register_Vec3_floatonly<T>(vec3_class);
1034
1035 decoratecopy(vec3_class);
1036
1037 //add_swizzle3_operators(v3f_class);
1038 return vec3_class;
1039 }
1040
1041
1042
1043 } // namespace PyImath
1044
1045 #endif // _PyImathVec3Impl_h_
1046