2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
8 #ifndef _PyImathVec3Impl_h_
9 #define _PyImathVec3Impl_h_
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.
18 #define BOOST_BIND_GLOBAL_PLACEHOLDERS
19 #include <boost/python.hpp>
20 #include <boost/python/make_constructor.hpp>
21 #include <boost/format.hpp>
23 #include <ImathVecAlgo.h>
25 #include "PyImathVec.h"
26 #include "PyImathDecorators.h"
27 #include "PyImathMathExc.h"
30 using namespace boost::python;
31 using namespace IMATH_NAMESPACE;
33 template <class T> struct Vec4Name { static const char *value(); };
35 // create a new default constructor that initializes Vec3<T> to zero.
37 static Vec4<T> * Vec4_construct_default()
39 return new Vec4<T>(T(0),T(0),T(0),T(0));
43 static Vec4<T> * Vec4_object_constructor1(const object &obj)
46 extract<Vec4<int> > e1(obj);
47 extract<Vec4<float> > e2(obj);
48 extract<Vec4<double> > e3(obj);
49 extract<tuple> e4(obj);
50 extract<double> e5(obj);
51 extract<list> e6(obj);
53 if(e1.check()) { res = e1(); }
54 else if(e2.check()) { res = e2(); }
55 else if(e3.check()) { res = e3(); }
59 if(t.attr("__len__")() == 4)
61 res.x = extract<T>(t[0]);
62 res.y = extract<T>(t[1]);
63 res.z = extract<T>(t[2]);
64 res.w = extract<T>(t[3]);
67 throw std::invalid_argument ("tuple must have length of 4");
70 else if(e5.check()) { T a = (T) e5(); res = IMATH_NAMESPACE::Vec4<T>(a, a, a, a); }
74 if(l.attr("__len__")() == 4)
76 res.x = extract<T>(l[0]);
77 res.y = extract<T>(l[1]);
78 res.z = extract<T>(l[2]);
79 res.w = extract<T>(l[3]);
82 throw std::invalid_argument ("list must have length of 4");
85 throw std::invalid_argument ("invalid parameters passed to Vec4 constructor");
87 Vec4<T> *v = new Vec4<T>;
95 static Vec4<T> * Vec4_object_constructor2(const object &obj1, const object &obj2, const object &obj3, const object& obj4)
97 extract<double> e1(obj1);
98 extract<double> e2(obj2);
99 extract<double> e3(obj3);
100 extract<double> e4(obj4);
101 Vec4<T> *v = new Vec4<T>;
103 if(e1.check()) { v->x = (T) e1();}
104 else { throw std::invalid_argument ("invalid parameters passed to Vec4 constructor"); }
106 if(e2.check()) { v->y = (T) e2();}
107 else { throw std::invalid_argument ("invalid parameters passed to Vec4 constructor"); }
109 if(e3.check()) { v->z = (T) e3();}
110 else { throw std::invalid_argument ("invalid parameters passed to Vec4 constructor"); }
112 if(e4.check()) { v->w = (T) e4();}
113 else { throw std::invalid_argument ("invalid parameters passed to Vec4 constructor"); }
120 // Implementations of str and repr are same here,
121 // but we'll specialize repr for float and double to make them exact.
123 static std::string Vec4_str(const Vec4<T> &v)
125 std::stringstream stream;
126 stream << Vec4Name<T>::value() << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")";
130 static std::string Vec4_repr(const Vec4<T> &v)
132 std::stringstream stream;
133 stream << Vec4Name<T>::value() << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")";
139 Vec4_dot(const IMATH_NAMESPACE::Vec4<T> &v, const IMATH_NAMESPACE::Vec4<T> &other)
147 Vec4_dot_Vec4Array(const IMATH_NAMESPACE::Vec4<T> &va, const FixedArray<IMATH_NAMESPACE::Vec4<T> > &vb)
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.dot(vb[i]);
159 Vec4_length(const IMATH_NAMESPACE::Vec4<T> &v)
167 Vec4_length2(const IMATH_NAMESPACE::Vec4<T> &v)
174 static const Vec4<T> &
175 Vec4_normalize(IMATH_NAMESPACE::Vec4<T> &v)
178 return v.normalize();
182 static const Vec4<T> &
183 Vec4_normalizeExc(IMATH_NAMESPACE::Vec4<T> &v)
186 return v.normalizeExc();
190 static const Vec4<T> &
191 Vec4_normalizeNonNull(IMATH_NAMESPACE::Vec4<T> &v)
194 return v.normalizeNonNull();
199 Vec4_normalized(const IMATH_NAMESPACE::Vec4<T> &v)
202 return v.normalized();
207 Vec4_normalizedExc(const IMATH_NAMESPACE::Vec4<T> &v)
210 return v.normalizedExc();
215 Vec4_normalizedNonNull(const IMATH_NAMESPACE::Vec4<T> &v)
218 return v.normalizedNonNull();
222 static const Vec4<T> &
223 Vec4_negate(IMATH_NAMESPACE::Vec4<T> &v)
231 orthogonal(const Vec4<T> &v, const Vec4<T> &v0)
234 return IMATH_NAMESPACE::orthogonal(v, v0);
239 project(const Vec4<T> &v, const Vec4<T> &v0)
242 return IMATH_NAMESPACE::project(v0, v);
247 reflect(const Vec4<T> &v, const Vec4<T> &v0)
250 return IMATH_NAMESPACE::reflect(v, v0);
255 setValue(Vec4<T> &v, T a, T b, T c, T d)
265 Vec4_add (const Vec4<T> &v, const Vec4<T> &w)
273 Vec4_sub (const Vec4<T> &v, const Vec4<T> &w)
281 Vec4_neg (const Vec4<T> &v)
287 template <class T, class U>
289 Vec4_mul (const Vec4<T> &v, Vec4<U> &w)
298 Vec4_mulT (const Vec4<T> &v, T t)
305 static FixedArray<IMATH_NAMESPACE::Vec4<T> >
306 Vec4_mulTArray (const Vec4<T> &v, const FixedArray<T> &t)
308 PY_IMATH_LEAVE_PYTHON;
309 size_t len = t.len();
310 FixedArray<IMATH_NAMESPACE::Vec4<T> > retval(len);
311 for (size_t i=0; i<len; ++i) retval[i] = v*t[i];
316 static FixedArray<IMATH_NAMESPACE::Vec4<T> >
317 Vec4_rmulTArray (const Vec4<T> &v, const FixedArray<T> &t)
319 return Vec4_mulTArray(v,t);
322 template <class T,class S>
324 Vec4_div (Vec4<T> &v, Vec4<S> &w)
332 Vec4_rmulT (Vec4<T> &v, T t)
338 template <class T, class U>
339 static const Vec4<T> &
340 Vec4_imulV(Vec4<T> &v, const Vec4<U> &w)
347 static const Vec4<T> &
348 Vec4_imulT(IMATH_NAMESPACE::Vec4<T> &v, T t)
354 template <class T, class U>
356 Vec4_mulM44 (Vec4<T> &v, const Matrix44<U> &m)
363 static const Vec4<T> &
364 Vec4_idivObj(IMATH_NAMESPACE::Vec4<T> &v, const object &o)
368 if (PyImath::V4<T>::convert (o.ptr(), &v2))
374 extract<double> e(o);
378 throw std::invalid_argument ("V4 division expects an argument "
379 "convertible to a V4");
385 Vec4_subT(const Vec4<T> &v, T a)
389 setValue(w, (T) (v.x - a), (T) (v.y - a), (T) (v.z - a), (T) (v.w - a));
393 template <class T,class BoostPyType>
395 Vec4_subTuple(const Vec4<T> &v, const BoostPyType &t)
400 if(t.attr("__len__")() == 4)
402 w.x = v.x - extract<T>(t[0]);
403 w.y = v.y - extract<T>(t[1]);
404 w.z = v.z - extract<T>(t[2]);
405 w.w = v.w - extract<T>(t[3]);
408 throw std::invalid_argument ("tuple must have length of 4");
415 Vec4_rsubT(const Vec4<T> &v, T a)
418 Vec4<T> w(a - v.x, a - v.y, a - v.z, a - v.w);
422 template <class T, class BoostPyType>
424 Vec4_rsubTuple(const Vec4<T> &v, const BoostPyType &t)
429 if(t.attr("__len__")() == 4)
431 w.x = extract<T>(t[0]) - v.x;
432 w.y = extract<T>(t[1]) - v.y;
433 w.z = extract<T>(t[2]) - v.z;
434 w.w = extract<T>(t[3]) - v.w;
437 throw std::invalid_argument ("tuple must have length of 4");
442 template <class T, class BoostPyType>
444 Vec4_addTuple(const Vec4<T> &v, const BoostPyType &t)
449 if(t.attr("__len__")() == 4)
451 w.x = v.x + extract<T>(t[0]);
452 w.y = v.y + extract<T>(t[1]);
453 w.z = v.z + extract<T>(t[2]);
454 w.w = v.w + extract<T>(t[3]);
457 throw std::invalid_argument ("tuple must have length of 4");
464 Vec4_addT(const Vec4<T> &v, T a)
468 setValue(w, (T) (v.x + a), (T) (v.y + a), (T) (v.z + a), (T) (v.w + a));
472 template <class T, class U>
474 Vec4_addV(const Vec4<T> &v, const Vec4<U> &w)
480 template <class T, class U>
481 static const Vec4<T> &
482 Vec4_iaddV(Vec4<T> &v, const Vec4<U> &w)
488 template <class T, class U>
490 Vec4_subV(const Vec4<T> &v, const Vec4<U> &w)
496 template <class T, class U>
497 static const Vec4<T> &
498 Vec4_isubV(Vec4<T> &v, const Vec4<U> &w)
506 mult(const Vec4<T> &v, tuple t)
511 if(t.attr("__len__")() == 1){
512 w.x = v.x*extract<T>(t[0]);
513 w.y = v.y*extract<T>(t[0]);
514 w.z = v.z*extract<T>(t[0]);
515 w.w = v.w*extract<T>(t[0]);
517 else if(t.attr("__len__")() == 4){
518 w.x = v.x*extract<T>(t[0]);
519 w.y = v.y*extract<T>(t[1]);
520 w.z = v.z*extract<T>(t[2]);
521 w.w = v.w*extract<T>(t[3]);
524 throw std::invalid_argument ("tuple must have length of 1 or 4");
529 template <class T, class U>
530 static const Vec4<T> &
531 Vec4_imulM44 (Vec4<T> &v, const Matrix44<U> &m)
537 template <class T, class BoostPyType>
539 Vec4_divTuple(const Vec4<T> &v, const BoostPyType &t)
541 if(t.attr("__len__")() == 4)
543 T x = extract<T>(t[0]);
544 T y = extract<T>(t[1]);
545 T z = extract<T>(t[2]);
546 T w = extract<T>(t[3]);
547 if(x != T(0) && y != T(0) && z != T(0) && w != T(0))
548 return Vec4<T>(v.x / x, v.y / y, v.z / z, v.w / w);
550 throw std::domain_error ("Division by zero");
553 throw std::invalid_argument ("Vec4 expects tuple of length 4");
556 template <class T, class BoostPyType>
558 Vec4_rdivTuple(const Vec4<T> &v, const BoostPyType &t)
562 if(t.attr("__len__")() == 4)
564 T x = extract<T>(t[0]);
565 T y = extract<T>(t[1]);
566 T z = extract<T>(t[2]);
567 T w = extract<T>(t[3]);
569 if(v.x != T(0) && v.y != T(0) && v.z != T(0) && v.w != T(0)){
570 setValue(res, (T) (x / v.x), (T) (y / v.y), (T) (z / v.z), (T) (w / v.w));
573 throw std::domain_error ("Division by zero");
576 throw std::invalid_argument ("tuple must have length of 4");
583 Vec4_divT(const Vec4<T> &v, T a)
588 setValue(res, (T) (v.x / a), (T) (v.y / a), (T) (v.z / a), (T) (v.w / a));
591 throw std::domain_error ("Division by zero");
598 Vec4_rdivT(const Vec4<T> &v, T a)
602 if(v.x != T(0) && v.y != T(0) && v.z != T(0) && v.w != T(0)){
603 setValue(res, (T) (a / v.x), (T) (a / v.y), (T) (a / v.z), (T) (a / v.w));
606 throw std::domain_error ("Division by zero");
613 Vec4_Vec4_mulT(const Vec4<T>& v, const Vec4<T>& w)
621 Vec4_Vec4_divT(const Vec4<T>& v, const Vec4<T>& w)
629 lessThan(const Vec4<T> &v, const object &obj)
631 extract<Vec4<T> > e1(obj);
632 extract<tuple> e2(obj);
642 T x = extract<T>(t[0]);
643 T y = extract<T>(t[1]);
644 T z = extract<T>(t[2]);
645 T w = extract<T>(t[3]);
646 setValue(res,x,y,z,w);
649 throw std::invalid_argument ("invalid parameters passed to operator <");
651 bool isLessThan = (v.x <= res.x && v.y <= res.y && v.z <= res.z && v.w <= res.w)
659 greaterThan(const Vec4<T> &v, const object &obj)
661 extract<Vec4<T> > e1(obj);
662 extract<tuple> e2(obj);
672 T x = extract<T>(t[0]);
673 T y = extract<T>(t[1]);
674 T z = extract<T>(t[2]);
675 T w = extract<T>(t[3]);
676 setValue(res,x,y,z,w);
679 throw std::invalid_argument ("invalid parameters passed to operator >");
681 bool isGreaterThan = (v.x >= res.x && v.y >= res.y && v.z >= res.z && v.w >= res.w)
684 return isGreaterThan;
689 lessThanEqual(const Vec4<T> &v, const object &obj)
691 extract<Vec4<T> > e1(obj);
692 extract<tuple> e2(obj);
702 T x = extract<T>(t[0]);
703 T y = extract<T>(t[1]);
704 T z = extract<T>(t[2]);
705 T w = extract<T>(t[2]);
706 setValue(res,x,y,z,w);
709 throw std::invalid_argument ("invalid parameters passed to operator <=");
711 bool isLessThanEqual = (v.x <= res.x && v.y <= res.y && v.z <= res.z && v.w <= res.w);
713 return isLessThanEqual;
718 greaterThanEqual(const Vec4<T> &v, const object &obj)
720 extract<Vec4<T> > e1(obj);
721 extract<tuple> e2(obj);
731 T x = extract<T>(t[0]);
732 T y = extract<T>(t[1]);
733 T z = extract<T>(t[2]);
734 T w = extract<T>(t[3]);
735 setValue(res,x,y,z,w);
738 throw std::invalid_argument ("invalid parameters passed to operator >=");
740 bool isGreaterThanEqual = (v.x >= res.x && v.y >= res.y && v.z >= res.z && v.w >= res.w);
742 return isGreaterThanEqual;
748 equalWithAbsErrorObj(const Vec4<T> &v, const object &obj1, const object &obj2)
750 extract<Vec4<int> > e1(obj1);
751 extract<Vec4<float> > e2(obj1);
752 extract<Vec4<double> > e3(obj1);
754 extract<tuple> e4(obj1);
755 extract<double> e5(obj2);
758 if(e1.check()) { res = e1(); }
759 else if(e2.check()) { res = e2(); }
760 else if(e3.check()) { res = e3(); }
764 if(t.attr("__len__")() == 4)
766 res.x = extract<T>(t[0]);
767 res.y = extract<T>(t[1]);
768 res.z = extract<T>(t[2]);
769 res.z = extract<T>(t[3]);
772 throw std::invalid_argument ("tuple of length 4 expected");
775 throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
777 if(e5.check()) { return v.equalWithAbsError(res, (T) e5()); }
779 throw std::invalid_argument ("invalid parameters passed to equalWithAbsError");
784 equalWithRelErrorObj(const Vec4<T> &v, const object &obj1, const object &obj2)
786 extract<Vec4<int> > e1(obj1);
787 extract<Vec4<float> > e2(obj1);
788 extract<Vec4<double> > e3(obj1);
790 extract<tuple> e4(obj1);
791 extract<double> e5(obj2);
794 if(e1.check()) { res = e1(); }
795 else if(e2.check()) { res = e2(); }
796 else if(e3.check()) { res = e3(); }
800 if(t.attr("__len__")() == 4)
802 res.x = extract<T>(t[0]);
803 res.y = extract<T>(t[1]);
804 res.z = extract<T>(t[2]);
805 res.w = extract<T>(t[3]);
808 throw std::invalid_argument ("tuple of length 4 expected");
811 throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
813 if(e5.check()) { return v.equalWithRelError(res, (T) e5()); }
815 throw std::invalid_argument ("invalid parameters passed to equalWithRelError");
822 equal(const Vec4<T> &v, const tuple &t)
825 if(t.attr("__len__")() == 4)
827 res.x = extract<T>(t[0]);
828 res.y = extract<T>(t[1]);
829 res.z = extract<T>(t[2]);
830 res.w = extract<T>(t[3]);
835 throw std::invalid_argument ("tuple of length 4 expected");
840 notequal(const Vec4<T> &v, const tuple &t)
843 if(t.attr("__len__")() == 4)
845 res.x = extract<T>(t[0]);
846 res.y = extract<T>(t[1]);
847 res.z = extract<T>(t[2]);
848 res.w = extract<T>(t[3]);
853 throw std::invalid_argument ("tuple of length 4 expected");
856 // Trick to register methods for float-only-based vectors
857 template <class T, IMATH_ENABLE_IF(!std::is_integral<T>::value)>
858 void register_Vec4_floatonly(class_<Vec4<T>>& vec4_class)
861 .def("length", &Vec4_length<T>,"length() magnitude of the vector")
862 .def("normalize", &Vec4_normalize<T>,return_internal_reference<>(),
863 "v.normalize() destructively normalizes v and returns a reference to it")
864 .def("normalizeExc", &Vec4_normalizeExc<T>,return_internal_reference<>(),
865 "v.normalizeExc() destructively normalizes V and returns a reference to it, throwing an exception if length() == 0")
866 .def("normalizeNonNull", &Vec4_normalizeNonNull<T>,return_internal_reference<>(),
867 "v.normalizeNonNull() destructively normalizes V and returns a reference to it, faster if lngth() != 0")
868 .def("normalized", &Vec4_normalized<T>, "v.normalized() returns a normalized copy of v")
869 .def("normalizedExc", &Vec4_normalizedExc<T>, "v.normalizedExc() returns a normalized copy of v, throwing an exception if length() == 0")
870 .def("normalizedNonNull", &Vec4_normalizedNonNull<T>, "v.normalizedNonNull() returns a normalized copy of v, faster if lngth() != 0")
871 .def("orthogonal", &orthogonal<T>)
872 .def("project", &project<T>)
873 .def("reflect", &reflect<T>)
877 template <class T, IMATH_ENABLE_IF(std::is_integral<T>::value)>
878 void register_Vec4_floatonly(class_<Vec4<T>>& vec4_class)
886 typedef PyImath::StaticFixedArray<Vec4<T>,T,4> Vec4_helper;
887 class_<Vec4<T> > vec4_class(Vec4Name<T>::value(), Vec4Name<T>::value(),init<Vec4<T> >("copy construction"));
889 .def("__init__",make_constructor(Vec4_construct_default<T>),"initialize to (0,0,0,0)")
890 .def("__init__",make_constructor(Vec4_object_constructor1<T>))
891 .def("__init__",make_constructor(Vec4_object_constructor2<T>))
892 .def_readwrite("x", &Vec4<T>::x)
893 .def_readwrite("y", &Vec4<T>::y)
894 .def_readwrite("z", &Vec4<T>::z)
895 .def_readwrite("w", &Vec4<T>::w)
896 .def("baseTypeEpsilon", &Vec4<T>::baseTypeEpsilon,"baseTypeEpsilon() epsilon value of the base type of the vector")
897 .staticmethod("baseTypeEpsilon")
898 .def("baseTypeMax", &Vec4<T>::baseTypeMax,"baseTypeMax() max value of the base type of the vector")
899 .staticmethod("baseTypeMax")
900 .def("baseTypeLowest", &Vec4<T>::baseTypeLowest,"baseTypeLowest() largest negative value of the base type of the vector")
901 .staticmethod("baseTypeLowest")
902 .def("baseTypeSmallest", &Vec4<T>::baseTypeSmallest,"baseTypeSmallest() smallest value of the base type of the vector")
903 .staticmethod("baseTypeSmallest")
904 .def("dimensions", &Vec4<T>::dimensions,"dimensions() number of dimensions in the vector")
905 .staticmethod("dimensions")
906 .def("dot", &Vec4_dot<T>,"v1.dot(v2) inner product of the two vectors")
907 .def("dot", &Vec4_dot_Vec4Array<T>,"v1.dot(v2) array inner product")
909 .def("equalWithAbsError", &Vec4<T>::equalWithAbsError,
910 "v1.equalWithAbsError(v2) true if the elements "
911 "of v1 and v2 are the same with an absolute error of no more than e, "
912 "i.e., abs(v1[i] - v2[i]) <= e")
913 .def("equalWithAbsError", &equalWithAbsErrorObj<T>)
915 .def("equalWithRelError", &Vec4<T>::equalWithRelError,
916 "v1.equalWithAbsError(v2) true if the elements "
917 "of v1 and v2 are the same with an absolute error of no more than e, "
918 "i.e., abs(v1[i] - v2[i]) <= e * abs(v1[i])")
919 .def("equalWithRelError", &equalWithRelErrorObj<T>)
921 .def("length2", &Vec4_length2<T>,"length2() square magnitude of the vector")
922 .def("__len__", Vec4_helper::len)
923 .def("__getitem__", Vec4_helper::getitem,return_value_policy<copy_non_const_reference>())
924 .def("__setitem__", Vec4_helper::setitem)
925 .def("negate", &Vec4_negate<T>, return_internal_reference<>())
926 .def("setValue", &setValue<T>)
927 .def("__neg__", &Vec4_neg<T>)
928 .def("__mul__", &Vec4_mul<T, int>)
929 .def("__mul__", &Vec4_mul<T, float>)
930 .def("__mul__", &Vec4_mul<T, double>)
931 .def("__mul__", &Vec4_mulT<T>)
932 .def("__mul__", &Vec4_mulTArray<T>)
933 .def("__rmul__", &Vec4_rmulT<T>)
934 .def("__rmul__", &Vec4_rmulTArray<T>)
935 .def("__imul__", &Vec4_imulV<T, int>,return_internal_reference<>())
936 .def("__imul__", &Vec4_imulV<T, float>,return_internal_reference<>())
937 .def("__imul__", &Vec4_imulV<T, double>,return_internal_reference<>())
938 .def("__imul__", &Vec4_imulT<T>,return_internal_reference<>())
939 .def("__div__", &Vec4_Vec4_divT<T>)
940 .def("__truediv__", &Vec4_Vec4_divT<T>)
941 .def("__mul__", &Vec4_mulM44<T, float>)
942 .def("__mul__", &Vec4_mulM44<T, double>)
943 .def("__mul__", &Vec4_Vec4_mulT<T>)
944 .def("__div__", &Vec4_div<T,int>)
945 .def("__div__", &Vec4_div<T,float>)
946 .def("__div__", &Vec4_div<T,double>)
947 .def("__div__", &Vec4_divTuple<T,tuple>)
948 .def("__div__", &Vec4_divTuple<T,list>)
949 .def("__div__", &Vec4_divT<T>)
950 .def("__truediv__", &Vec4_div<T,int>)
951 .def("__truediv__", &Vec4_div<T,float>)
952 .def("__truediv__", &Vec4_div<T,double>)
953 .def("__truediv__", &Vec4_divTuple<T,tuple>)
954 .def("__truediv__", &Vec4_divTuple<T,list>)
955 .def("__truediv__", &Vec4_divT<T>)
956 .def("__rdiv__", &Vec4_rdivTuple<T,tuple>)
957 .def("__rdiv__", &Vec4_rdivTuple<T,list>)
958 .def("__rdiv__", &Vec4_rdivT<T>)
959 .def("__rtruediv__", &Vec4_rdivTuple<T,tuple>)
960 .def("__rtruediv__", &Vec4_rdivTuple<T,list>)
961 .def("__rtruediv__", &Vec4_rdivT<T>)
962 .def("__idiv__", &Vec4_idivObj<T>,return_internal_reference<>())
963 .def("__itruediv__", &Vec4_idivObj<T>,return_internal_reference<>())
964 .def("__xor__", &Vec4_dot<T>)
965 .def(self == self) // NOSONAR - suppress SonarCloud bug report.
966 .def(self != self) // NOSONAR - suppress SonarCloud bug report.
967 .def("__add__", &Vec4_add<T>)
968 .def("__add__", &Vec4_addV<T, int>)
969 .def("__add__", &Vec4_addV<T, float>)
970 .def("__add__", &Vec4_addV<T, double>)
971 .def("__add__", &Vec4_addT<T>)
972 .def("__add__", &Vec4_addTuple<T,tuple>)
973 .def("__add__", &Vec4_addTuple<T,list>)
974 .def("__radd__", &Vec4_addT<T>)
975 .def("__radd__", &Vec4_addTuple<T,tuple>)
976 .def("__radd__", &Vec4_addTuple<T,list>)
977 .def("__radd__", &Vec4_add<T>)
978 .def("__iadd__", &Vec4_iaddV<T, int>, return_internal_reference<>())
979 .def("__iadd__", &Vec4_iaddV<T, float>, return_internal_reference<>())
980 .def("__iadd__", &Vec4_iaddV<T, double>, return_internal_reference<>())
981 .def("__sub__", &Vec4_sub<T>)
982 .def("__sub__", &Vec4_subV<T, int>)
983 .def("__sub__", &Vec4_subV<T, float>)
984 .def("__sub__", &Vec4_subV<T, double>)
985 .def("__sub__", &Vec4_subT<T>)
986 .def("__sub__", &Vec4_subTuple<T,tuple>)
987 .def("__sub__", &Vec4_subTuple<T,list>)
988 .def("__rsub__", &Vec4_rsubT<T>)
989 .def("__rsub__", &Vec4_rsubTuple<T,tuple>)
990 .def("__rsub__", &Vec4_rsubTuple<T,list>)
991 .def("__isub__", &Vec4_isubV<T, int>, return_internal_reference<>())
992 .def("__isub__", &Vec4_isubV<T, float>, return_internal_reference<>())
993 .def("__isub__", &Vec4_isubV<T, double>, return_internal_reference<>())
994 .def("__mul__", &mult<T>)
995 .def("__rmul__", &mult<T>)
996 .def("__imul__", &Vec4_imulM44<T, float>, return_internal_reference<>())
997 .def("__imul__", &Vec4_imulM44<T, double>, return_internal_reference<>())
998 .def("__lt__", &lessThan<T>)
999 .def("__gt__", &greaterThan<T>)
1000 .def("__le__", &lessThanEqual<T>)
1001 .def("__ge__", &greaterThanEqual<T>)
1002 .def("__eq__", &equal<T>)
1003 .def("__ne__", ¬equal<T>)
1004 //.def(self_ns::str(self))
1005 .def("__str__",&Vec4_str<T>)
1006 .def("__repr__",&Vec4_repr<T>)
1009 register_Vec4_floatonly<T>(vec4_class);
1011 decoratecopy(vec4_class);
1013 //add_swizzle3_operators(v3f_class);
1019 } // namespace PyImath
1021 #endif // _PyImathVec4Impl_h_