1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5
6 // clang-format off
7
8 #include <Python.h>
9 #include <boost/python.hpp>
10 #include <boost/python/make_constructor.hpp>
11 #include <boost/format.hpp>
12 #include "PyImath.h"
13 #include "PyImathMathExc.h"
14 #include "PyImathShear.h"
15 #include "PyImathPlane.h"
16 #include "PyImathDecorators.h"
17 #include "PyImathExport.h"
18
19
20 namespace PyImath{
21 using namespace boost::python;
22 using namespace IMATH_NAMESPACE;
23
24 template <class T> struct ShearName {static const char *value;};
25 template <> const char *ShearName<float>::value = "Shear6f";
26 template <> const char *ShearName<double>::value = "Shear6d";
27
28 template <class T>
Shear_str(const Shear6<T> & v)29 static std::string Shear_str(const Shear6<T> &v)
30 {
31 std::stringstream stream;
32 stream << ShearName<T>::value << "("
33 << v[0] << ", " << v[1] << ", " << v[2] << ", "
34 << v[3] << ", " << v[4] << ", " << v[5] << ")";
35 return stream.str();
36 }
37
38 // Non-specialized repr is same as str
39 template <class T>
Shear_repr(const Shear6<T> & v)40 static std::string Shear_repr(const Shear6<T> &v)
41 {
42 return Shear_str(v);
43 }
44
45 // Specialization for float to full precision
46 template <>
Shear_repr(const Shear6<float> & v)47 std::string Shear_repr(const Shear6<float> &v)
48 {
49 return (boost::format("%s(%.9g, %.9g, %.9g, %.9g, %.9g, %.9g)")
50 % ShearName<float>::value
51 % v[0] % v[1] % v[2]
52 % v[3] % v[4] % v[5]).str();
53 }
54
55 // Specialization for double to full precision
56 template <>
Shear_repr(const Shear6<double> & v)57 std::string Shear_repr(const Shear6<double> &v)
58 {
59 return (boost::format("%s(%.17g, %.17g, %.17g, %.17g, %.17g, %.17g)")
60 % ShearName<double>::value
61 % v[0] % v[1] % v[2]
62 % v[3] % v[4] % v[5]).str();
63 }
64
65 template <class T>
shearTupleConstructor(tuple t)66 static Shear6<T> * shearTupleConstructor(tuple t)
67 {
68 if(t.attr("__len__")() == 3){
69 return new Shear6<T>(extract<T>(t[0]), extract<T>(t[1]), extract<T>(t[2]),
70 T(0), T(0), T(0));
71 }
72 else if(t.attr("__len__")() == 6){
73 return new Shear6<T>(extract<T>(t[0]), extract<T>(t[1]), extract<T>(t[2]),
74 extract<T>(t[3]), extract<T>(t[4]), extract<T>(t[5]));
75 }
76 else
77 throw std::invalid_argument ("Shear6 expects tuple of length 3 or 6");
78 }
79
80 template <class T>
shearConstructor1(T a)81 static Shear6<T> * shearConstructor1(T a)
82 {
83 return new Shear6<T>(a, a, a, a, a, a);
84 }
85
86 template <class T, class S>
shearConversionConstructor(const Shear6<S> & shear)87 static Shear6<T> * shearConversionConstructor(const Shear6<S> &shear)
88 {
89 Shear6<T> *s = new Shear6<T>;
90 *s = shear;
91 return s;
92 }
93
94 template <class T>
95 static const Shear6<T> &
iadd(Shear6<T> & shear,const Shear6<T> & other)96 iadd(Shear6<T> &shear, const Shear6<T> &other)
97 {
98 MATH_EXC_ON;
99 return shear += other;
100 }
101
102 template <class T>
103 static Shear6<T>
add(const Shear6<T> & shear,const Shear6<T> & other)104 add(const Shear6<T> &shear, const Shear6<T> &other)
105 {
106 MATH_EXC_ON;
107 return shear + other;
108 }
109
110 template <class T>
111 static const Shear6<T> &
isub(Shear6<T> & shear,const Shear6<T> & other)112 isub(Shear6<T> &shear, const Shear6<T> &other)
113 {
114 MATH_EXC_ON;
115 return shear -= other;
116 }
117
118 template <class T>
119 static Shear6<T>
sub(const Shear6<T> & shear,const Shear6<T> & other)120 sub(const Shear6<T> &shear, const Shear6<T> &other)
121 {
122 MATH_EXC_ON;
123 return shear - other;
124 }
125
126 template <class T>
127 static Shear6<T>
neg(const Shear6<T> & shear)128 neg(const Shear6<T> &shear)
129 {
130 MATH_EXC_ON;
131 return -shear;
132 }
133
134 template <class T>
135 static const Shear6<T> &
imul(Shear6<T> & shear,const Shear6<T> & other)136 imul(Shear6<T> &shear, const Shear6<T> &other)
137 {
138 MATH_EXC_ON;
139 return shear *= other;
140 }
141
142 template <class T>
143 static const Shear6<T> &
imulT(Shear6<T> & shear,T t)144 imulT(Shear6<T> &shear, T t)
145 {
146 MATH_EXC_ON;
147 return shear *= t;
148 }
149
150 template <class T>
151 static Shear6<T>
mul(const Shear6<T> & shear,const Shear6<T> & other)152 mul(const Shear6<T> &shear, const Shear6<T> &other)
153 {
154 MATH_EXC_ON;
155 return shear * other;
156 }
157
158 template <class T>
159 static Shear6<T>
mulT(const Shear6<T> & shear,T t)160 mulT(const Shear6<T> &shear, T t)
161 {
162 MATH_EXC_ON;
163 return shear * t;
164 }
165
166 template <class T>
167 static const Shear6<T> &
idiv(Shear6<T> & shear,const Shear6<T> & other)168 idiv(Shear6<T> &shear, const Shear6<T> &other)
169 {
170 MATH_EXC_ON;
171 return shear /= other;
172 }
173
174 template <class T>
175 static const Shear6<T> &
idivT(Shear6<T> & shear,T t)176 idivT(Shear6<T> &shear, T t)
177 {
178 MATH_EXC_ON;
179 return shear /= t;
180 }
181
182 template <class T>
183 static Shear6<T>
div(const Shear6<T> & shear,const Shear6<T> & other)184 div(const Shear6<T> &shear, const Shear6<T> &other)
185 {
186 MATH_EXC_ON;
187 return shear / other;
188 }
189
190 template <class T>
191 static Shear6<T>
divT(const Shear6<T> & shear,T t)192 divT(const Shear6<T> &shear, T t)
193 {
194 MATH_EXC_ON;
195 return shear / t;
196 }
197
198 template <class T>
199 static Shear6<T>
subtract1(Shear6<T> & v,tuple t)200 subtract1(Shear6<T> &v, tuple t)
201 {
202 MATH_EXC_ON;
203 Shear6<T> w;
204
205 if(t.attr("__len__")() == 6){
206 w[0] = v[0] - extract<T>(t[0]);
207 w[1] = v[1] - extract<T>(t[1]);
208 w[2] = v[2] - extract<T>(t[2]);
209 w[3] = v[3] - extract<T>(t[3]);
210 w[4] = v[4] - extract<T>(t[4]);
211 w[5] = v[5] - extract<T>(t[5]);
212 }
213 else
214 throw std::domain_error ("tuple must have length of 6");
215
216 return w;
217 }
218
219 template <class T>
220 static Shear6<T>
subtract2(Shear6<T> & v,tuple t)221 subtract2(Shear6<T> &v, tuple t)
222 {
223 MATH_EXC_ON;
224 Shear6<T> w;
225
226 if(t.attr("__len__")() == 6){
227 w[0] = extract<T>(t[0]) - v[0];
228 w[1] = extract<T>(t[1]) - v[1];
229 w[2] = extract<T>(t[2]) - v[2];
230 w[3] = extract<T>(t[3]) - v[3];
231 w[4] = extract<T>(t[4]) - v[4];
232 w[5] = extract<T>(t[5]) - v[5];
233 }
234 else
235 throw std::domain_error ("tuple must have length of 6");
236
237 return w;
238 }
239
240 template <class T>
241 static Shear6<T>
subtractT1(Shear6<T> & v,T a)242 subtractT1(Shear6<T> &v, T a)
243 {
244 MATH_EXC_ON;
245 Shear6<T> w;
246
247 w[0] = v[0] - a;
248 w[1] = v[1] - a;
249 w[2] = v[2] - a;
250 w[3] = v[3] - a;
251 w[4] = v[4] - a;
252 w[5] = v[5] - a;
253
254 return w;
255 }
256
257 template <class T>
258 static Shear6<T>
subtractT2(Shear6<T> & v,T a)259 subtractT2(Shear6<T> &v, T a)
260 {
261 MATH_EXC_ON;
262 Shear6<T> w;
263
264 w[0] = a - v[0];
265 w[1] = a - v[1];
266 w[2] = a - v[2];
267 w[3] = a - v[3];
268 w[4] = a - v[4];
269 w[5] = a - v[5];
270
271 return w;
272 }
273
274
275 template <class T>
276 static Shear6<T>
addTuple(Shear6<T> & v,tuple t)277 addTuple(Shear6<T> &v, tuple t)
278 {
279 MATH_EXC_ON;
280 Shear6<T> w;
281
282 if(t.attr("__len__")() == 6){
283 w[0] = v[0] + extract<T>(t[0]);
284 w[1] = v[1] + extract<T>(t[1]);
285 w[2] = v[2] + extract<T>(t[2]);
286 w[3] = v[3] + extract<T>(t[3]);
287 w[4] = v[4] + extract<T>(t[4]);
288 w[5] = v[5] + extract<T>(t[5]);
289 }
290 else
291 throw std::domain_error ("tuple must have length of 6");
292
293 return w;
294 }
295
296 template <class T>
297 static Shear6<T>
addT(Shear6<T> & v,T a)298 addT(Shear6<T> &v, T a)
299 {
300 MATH_EXC_ON;
301 Shear6<T> w;
302
303 w[0] = v[0] + a;
304 w[1] = v[1] + a;
305 w[2] = v[2] + a;
306 w[3] = v[3] + a;
307 w[4] = v[4] + a;
308 w[5] = v[5] + a;
309
310 return w;
311 }
312
313 template <class T>
314 static Shear6<T>
multTuple(Shear6<T> & v,tuple t)315 multTuple(Shear6<T> &v, tuple t)
316 {
317 MATH_EXC_ON;
318 Shear6<T> w;
319
320 if(t.attr("__len__")() == 6){
321 w[0] = v[0] * extract<T>(t[0]);
322 w[1] = v[1] * extract<T>(t[1]);
323 w[2] = v[2] * extract<T>(t[2]);
324 w[3] = v[3] * extract<T>(t[3]);
325 w[4] = v[4] * extract<T>(t[4]);
326 w[5] = v[5] * extract<T>(t[5]);
327 }
328 else
329 throw std::domain_error ("tuple must have length of 6");
330
331 return w;
332 }
333
334 template <class T>
335 static Shear6<T>
rdiv(Shear6<T> & v,T a)336 rdiv(Shear6<T> &v, T a)
337 {
338 MATH_EXC_ON;
339 Shear6<T> w;
340
341 if(v != Shear6<T>()){
342 w[0] = a/v[0];
343 w[1] = a/v[1];
344 w[2] = a/v[2];
345 w[3] = a/v[3];
346 w[4] = a/v[4];
347 w[5] = a/v[5];
348 }
349 else
350 throw std::domain_error ("Division by Zero");
351
352 return w;
353 }
354
355 template <class T>
356 static Shear6<T>
divTuple(Shear6<T> & v,const tuple & t)357 divTuple(Shear6<T> &v, const tuple &t)
358 {
359 MATH_EXC_ON;
360 if(t.attr("__len__")() != 6)
361 throw std::domain_error ("Shear6 expects tuple of length 6");
362
363 Shear6<T> w;
364 for(int i = 0; i < 6; ++i)
365 {
366 T a = extract<T>(t[i]);
367 if(a != T (0))
368 w[i] = v[i] / a;
369 else
370 throw std::domain_error ("Division by Zero");
371 }
372
373 return w;
374 }
375
376 template <class T>
377 static Shear6<T>
rdivTuple(Shear6<T> & v,const tuple & t)378 rdivTuple(Shear6<T> &v, const tuple &t)
379 {
380 MATH_EXC_ON;
381 if(t.attr("__len__")() != 6)
382 throw std::domain_error ("Shear6 expects tuple of length 6");
383
384 Shear6<T> w;
385 for(int i = 0; i < 6; ++i)
386 {
387 T a = extract<T>(t[i]);
388 if(v[i] != T (0))
389 w[i] = a / v[i];
390 else
391 throw std::domain_error ("Division by Zero");
392 }
393
394 return w;
395 }
396
397 template <class T>
398 static bool
lessThan(Shear6<T> & v,const Shear6<T> & w)399 lessThan(Shear6<T> &v, const Shear6<T> &w)
400 {
401 bool isLessThan = (v[0] <= w[0] && v[1] <= w[1] && v[2] <= w[2]
402 && v[3] <= w[3] && v[4] <= w[4] && v[5] <= w[5])
403 && v != w;
404
405 return isLessThan;
406 }
407
408 template <class T>
409 static bool
greaterThan(Shear6<T> & v,const Shear6<T> & w)410 greaterThan(Shear6<T> &v, const Shear6<T> &w)
411 {
412 bool isGreaterThan = (v[0] >= w[0] && v[1] >= w[1] && v[2] >= w[2]
413 && v[3] >= w[3] && v[4] >= w[4] && v[5] >= w[5])
414 && v != w;
415
416 return isGreaterThan;
417 }
418
419 template <class T>
420 static bool
lessThanEqual(Shear6<T> & v,const Shear6<T> & w)421 lessThanEqual(Shear6<T> &v, const Shear6<T> &w)
422 {
423 bool isLessThanEqual = (v[0] <= w[0] && v[1] <= w[1] && v[2] <= w[2]
424 && v[3] <= w[3] && v[4] <= w[4] && v[5] <= w[5]);
425
426 return isLessThanEqual;
427 }
428
429 template <class T>
430 static bool
greaterThanEqual(Shear6<T> & v,const Shear6<T> & w)431 greaterThanEqual(Shear6<T> &v, const Shear6<T> &w)
432 {
433 bool isGreaterThanEqual = (v[0] >= w[0] && v[1] >= w[1] && v[2] >= w[2]
434 && v[3] >= w[3] && v[4] >= w[4] && v[5] >= w[5]);
435
436 return isGreaterThanEqual;
437 }
438
439 template <class T>
440 static T
getitem(Shear6<T> & shear,int i)441 getitem(Shear6<T> &shear, int i)
442 {
443 return shear[i];
444 }
445
446 template <class T>
447 static void
setitem(Shear6<T> & shear,int i,T a)448 setitem(Shear6<T> &shear, int i, T a)
449 {
450 if(i < 0 || i > 5)
451 throw std::domain_error ("Index out of range");
452
453 shear[i] = a;
454 }
455
456 template <class T>
457 static int
len(Shear6<T> & shear)458 len(Shear6<T> &shear)
459 {
460 return 6;
461 }
462
463
464
465 template <class T>
466 class_<Shear6<T> >
register_Shear()467 register_Shear()
468 {
469 const char *name = ShearName<T>::value;
470
471 void (IMATH_NAMESPACE::Shear6<T>::*setValue1)(T,T,T,T,T,T) = &IMATH_NAMESPACE::Shear6<T>::setValue;
472 void (IMATH_NAMESPACE::Shear6<T>::*setValue2)(const Shear6<T> &) = &IMATH_NAMESPACE::Shear6<T>::setValue;
473 void (IMATH_NAMESPACE::Shear6<T>::*getValue1)(Shear6<T> &) const = &IMATH_NAMESPACE::Shear6<T>::getValue;
474
475 class_<Shear6<T> > shear_class(name, name, init<Shear6<T> >("copy construction"));
476 shear_class
477 .def(init<>("default construction: (0 0 0 0 0 0)"))
478 .def(init<T,T,T>("Shear(XY,XZ,YZ) construction: (XY XZ YZ 0 0 0)"))
479 .def(init<const Vec3<float> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
480 .def(init<const Vec3<double> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
481 .def(init<const Vec3<int> &>("Shear(v) construction: (v.x v.y v.z 0 0 0)"))
482 .def(init<T,T,T,T,T,T>("Shear(XY, XZ, YZ, YX, ZX, ZY) construction"))
483 .def("__init__", make_constructor(shearConstructor1<T>))
484 .def("__init__", make_constructor(shearTupleConstructor<T>),"Construction from tuple")
485 .def("__init__", make_constructor(shearConversionConstructor<T,float>))
486 .def("__init__", make_constructor(shearConversionConstructor<T,double>))
487 .def("__init__", make_constructor(shearConversionConstructor<T,int>))
488 .def("__iadd__",&iadd<T>,return_internal_reference<>())
489 .def("__add__",&add<T>)
490 .def("__isub__",&isub<T>,return_internal_reference<>())
491 .def("__sub__",&sub<T>)
492 .def("__neg__",&neg<T>)
493 .def("__imul__",&imul<T>,return_internal_reference<>())
494 .def("__imul__",&imulT<T>,return_internal_reference<>())
495 .def("__mul__",&mul<T>)
496 .def("__mul__",&mulT<T>)
497 .def("__rmul__",&mulT<T>)
498 .def("__idiv__",&idiv<T>,return_internal_reference<>())
499 .def("__idiv__",&idivT<T>,return_internal_reference<>())
500 .def("__itruediv__",&idiv<T>,return_internal_reference<>())
501 .def("__itruediv__",&idivT<T>,return_internal_reference<>())
502 .def("__div__",&div<T>)
503 .def("__div__",&divT<T>)
504 .def("__truediv__",&div<T>)
505 .def("__truediv__",&divT<T>)
506 .def(self == self) // NOSONAR - suppress SonarCloud bug report.
507 .def(self != self) // NOSONAR - suppress SonarCloud bug report.
508 .def("__str__",&Shear_str<T>)
509 .def("__repr__",&Shear_repr<T>)
510 .def("setValue", setValue1)
511 .def("setValue", setValue2)
512 .def("getValue", getValue1)
513 .def("negate", &Shear6<T>::negate, return_internal_reference<>())
514 .def("baseTypeLowest", &Shear6<T>::baseTypeLowest)
515 .staticmethod("baseTypeLowest")
516 .def("baseTypeMax", &Shear6<T>::baseTypeMax)
517 .staticmethod("baseTypeMax")
518 .def("baseTypeSmallest", &Shear6<T>::baseTypeSmallest)
519 .staticmethod("baseTypeSmallest")
520 .def("baseTypeEpsilon", &Shear6<T>::baseTypeEpsilon)
521 .staticmethod("baseTypeEpsilon")
522 .def("equalWithAbsError", &Shear6<T>::equalWithAbsError)
523 .def("equalWithRelError", &Shear6<T>::equalWithRelError)
524 .def("__sub__", &subtract1<T>)
525 .def("__sub__", &subtractT1<T>)
526 .def("__rsub__", &subtract2<T>)
527 .def("__rsub__", &subtractT2<T>)
528 .def("__add__", &addTuple<T>)
529 .def("__add__", &addT<T>)
530 .def("__radd__", &addTuple<T>)
531 .def("__radd__", &addT<T>)
532 .def("__mul__", &multTuple<T>)
533 .def("__rmul__", &multTuple<T>)
534 .def("__div__", &divTuple<T>)
535 .def("__truediv__", &divTuple<T>)
536 .def("__rdiv__", &rdiv<T>)
537 .def("__rdiv__", &rdivTuple<T>)
538 .def("__rtruediv__", &rdiv<T>)
539 .def("__rtruediv__", &rdivTuple<T>)
540 .def("__lt__", &lessThan<T>)
541 .def("__gt__", &greaterThan<T>)
542 .def("__le__", &lessThanEqual<T>)
543 .def("__ge__", &greaterThanEqual<T>)
544 .def("__getitem__", &getitem<T>)
545 .def("__setitem__", &setitem<T>)
546 .def("__len__", &len<T>)
547 ;
548
549 decoratecopy(shear_class);
550
551 return shear_class;
552 }
553
554 template PYIMATH_EXPORT class_<Shear6<float> > register_Shear();
555 template PYIMATH_EXPORT class_<Shear6<double> > register_Shear();
556
557 }//namespace PyIMath
558