HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PyImathMatrix.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 // clang-format off
7 
8 #ifndef _PyImathMatrix_h_
9 #define _PyImathMatrix_h_
10 
11 #include <Python.h>
12 #define HBOOST_BIND_GLOBAL_PLACEHOLDERS
13 #include <hboost/python.hpp>
14 #include <ImathMatrix.h>
15 #include <ImathMatrixAlgo.h>
16 #include "PyImath.h"
17 
18 namespace PyImath {
19 
20 template <class T> hboost::python::class_<IMATH_NAMESPACE::Matrix22<T> > register_Matrix22();
21 template <class T> hboost::python::class_<IMATH_NAMESPACE::Matrix33<T> > register_Matrix33();
22 template <class T> hboost::python::class_<IMATH_NAMESPACE::Matrix44<T> > register_Matrix44();
23 template <class T> hboost::python::class_<FixedArray<IMATH_NAMESPACE::Matrix44<T> > > register_M44Array();
24 template <class T> hboost::python::class_<FixedArray<IMATH_NAMESPACE::Matrix33<T> > > register_M33Array();
25 template <class T> hboost::python::class_<FixedArray<IMATH_NAMESPACE::Matrix22<T> > > register_M22Array();
32 
33 //
34 
35 // Other code in the Zeno code base assumes the existance of a class with the
36 // same name as the Imath class, and with static functions wrap() and
37 // convert() to produce a PyImath object from an Imath object and vice-versa,
38 // respectively. The class Boost generates from the Imath class does not
39 // have these properties, so we define a companion class here.
40 // The template argument, T, is the element type (e.g.,float, double).
41 
42 template <class T>
43 class M22 {
44  public:
45  static PyObject * wrap (const IMATH_NAMESPACE::Matrix22<T> &m);
46  static int convert (PyObject *p, IMATH_NAMESPACE::Matrix22<T> *m);
47 };
48 
49 template <class T>
50 class M33 {
51  public:
52  static PyObject * wrap (const IMATH_NAMESPACE::Matrix33<T> &m);
53  static int convert (PyObject *p, IMATH_NAMESPACE::Matrix33<T> *m);
54 };
55 
56 template <class T>
57 class M44 {
58  public:
59  static PyObject * wrap (const IMATH_NAMESPACE::Matrix44<T> &m);
60  static int convert (PyObject *p, IMATH_NAMESPACE::Matrix44<T> *m);
61 };
62 
63 template <class T>
64 PyObject *
65 M22<T>::wrap (const IMATH_NAMESPACE::Matrix22<T> &m)
66 {
67  typename hboost::python::return_by_value::apply < IMATH_NAMESPACE::Matrix22<T> >::type converter;
68  PyObject *p = converter (m);
69  return p;
70 }
71 
72 template <class T>
73 PyObject *
74 M33<T>::wrap (const IMATH_NAMESPACE::Matrix33<T> &m)
75 {
76  typename hboost::python::return_by_value::apply < IMATH_NAMESPACE::Matrix33<T> >::type converter;
77  PyObject *p = converter (m);
78  return p;
79 }
80 
81 template <class T>
82 PyObject *
83 M44<T>::wrap (const IMATH_NAMESPACE::Matrix44<T> &m)
84 {
85  typename hboost::python::return_by_value::apply < IMATH_NAMESPACE::Matrix44<T> >::type converter;
86  PyObject *p = converter (m);
87  return p;
88 }
89 
90 template <class T>
91 int
92 M22<T>::convert (PyObject *p, IMATH_NAMESPACE::Matrix22<T> *m)
93 {
94  hboost::python::extract <IMATH_NAMESPACE::M22f> extractorMf (p);
95  if (extractorMf.check())
96  {
97  IMATH_NAMESPACE::M22f e = extractorMf();
98  m->setValue (e);
99  return 1;
100  }
101 
102  hboost::python::extract <IMATH_NAMESPACE::M22d> extractorMd (p);
103  if (extractorMd.check())
104  {
105  IMATH_NAMESPACE::M22d e = extractorMd();
106  m->setValue (e);
107  return 1;
108  }
109 
110  return 0;
111 }
112 
113 template <class T>
114 int
115 M33<T>::convert (PyObject *p, IMATH_NAMESPACE::Matrix33<T> *m)
116 {
117  hboost::python::extract <IMATH_NAMESPACE::M33f> extractorMf (p);
118  if (extractorMf.check())
119  {
120  IMATH_NAMESPACE::M33f e = extractorMf();
121  m->setValue (e);
122  return 1;
123  }
124 
125  hboost::python::extract <IMATH_NAMESPACE::M33d> extractorMd (p);
126  if (extractorMd.check())
127  {
128  IMATH_NAMESPACE::M33d e = extractorMd();
129  m->setValue (e);
130  return 1;
131  }
132 
133  return 0;
134 }
135 
136 template <class T>
137 int
138 M44<T>::convert (PyObject *p, IMATH_NAMESPACE::Matrix44<T> *m)
139 {
140  hboost::python::extract <IMATH_NAMESPACE::M44f> extractorMf (p);
141  if (extractorMf.check())
142  {
143  IMATH_NAMESPACE::M44f e = extractorMf();
144  m->setValue (e);
145  return 1;
146  }
147 
148  hboost::python::extract <IMATH_NAMESPACE::M44d> extractorMd (p);
149  if (extractorMd.check())
150  {
151  IMATH_NAMESPACE::M44d e = extractorMd();
152  m->setValue (e);
153  return 1;
154  }
155 
156  return 0;
157 }
158 
159 template <class Matrix>
160 hboost::python::tuple
161 jacobiEigensolve(const Matrix& m)
162 {
163  typedef typename Matrix::BaseType T;
164  typedef typename Matrix::BaseVecType Vec;
165 
166  // For the C++ version, we just assume that the passed-in matrix is
167  // symmetric, but we assume that many of our script users are less
168  // sophisticated and might get tripped up by this. Also, the cost
169  // of doing this check is likely miniscule compared to the Pythonic
170  // overhead.
171 
172  // Give a fairly generous tolerance to account for possible epsilon drift:
173  const int d = Matrix::dimensions();
174  const T tol = std::sqrt(std::numeric_limits<T>::epsilon());
175  for (int i = 0; i < d; ++i)
176  {
177  for (int j = i+1; j < d; ++j)
178  {
179  const T Aij = m[i][j],
180  Aji = m[j][i];
181  if (std::abs(Aij - Aji) >= tol){
182  throw std::invalid_argument
183  ("Symmetric eigensolve requires a symmetric matrix (matrix[i][j] == matrix[j][i]).");
184  }
185  }
186  }
187 
188  Matrix tmp = m;
189  Matrix Q;
190  Vec S;
192  return hboost::python::make_tuple (Q, S);
193 }
194 
195 typedef M22<float> M22f;
197 
198 typedef M33<float> M33f;
200 
201 typedef M44<float> M44f;
203 
204 }
205 
206 #endif
Matrix44< float > M44f
4x4 matrix of float
Definition: ImathMatrix.h:1401
M44< double > M44d
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7694
Matrix22< double > M22d
2x2 matrix of double
Definition: ImathMatrix.h:1392
FixedArray< IMATH_NAMESPACE::Matrix44< float > > M44fArray
Definition: PyImathMatrix.h:30
FixedArray< IMATH_NAMESPACE::Matrix22< float > > M22fArray
Definition: PyImathMatrix.h:26
hboost::python::class_< IMATH_NAMESPACE::Matrix33< T > > register_Matrix33()
static int convert(PyObject *p, IMATH_NAMESPACE::Matrix44< T > *m)
static PyObject * wrap(const IMATH_NAMESPACE::Matrix33< T > &m)
Definition: PyImathMatrix.h:74
Matrix33< float > M33f
3x3 matrix of float
Definition: ImathMatrix.h:1395
Matrix44< double > M44d
4x4 matrix of double
Definition: ImathMatrix.h:1404
FixedArray< IMATH_NAMESPACE::Matrix33< float > > M33fArray
Definition: PyImathMatrix.h:28
hboost::python::class_< IMATH_NAMESPACE::Matrix22< T > > register_Matrix22()
Matrix33< double > M33d
3x3 matrix of double
Definition: ImathMatrix.h:1398
M44< float > M44f
hboost::python::tuple jacobiEigensolve(const Matrix &m)
M33< double > M33d
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
FixedArray< IMATH_NAMESPACE::Matrix44< double > > M44dArray
Definition: PyImathMatrix.h:31
hboost::python::class_< FixedArray< IMATH_NAMESPACE::Matrix22< T > > > register_M22Array()
static int convert(PyObject *p, IMATH_NAMESPACE::Matrix33< T > *m)
FixedArray< IMATH_NAMESPACE::Matrix22< double > > M22dArray
Definition: PyImathMatrix.h:27
static PyObject * wrap(const IMATH_NAMESPACE::Matrix22< T > &m)
Definition: PyImathMatrix.h:65
hboost::python::class_< FixedArray< IMATH_NAMESPACE::Matrix44< T > > > register_M44Array()
hboost::python::class_< IMATH_NAMESPACE::Matrix44< T > > register_Matrix44()
GLint j
Definition: glad.h:2733
M33< float > M33f
Matrix22< float > M22f
2x2 matrix of float
Definition: ImathMatrix.h:1389
static PyObject * wrap(const IMATH_NAMESPACE::Matrix44< T > &m)
Definition: PyImathMatrix.h:83
hboost::python::class_< FixedArray< IMATH_NAMESPACE::Matrix33< T > > > register_M33Array()
void jacobiEigenSolver(Matrix33< T > &A, Vec3< T > &S, Matrix33< T > &V, const T tol)
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
M22< double > M22d
M22< float > M22f
static int convert(PyObject *p, IMATH_NAMESPACE::Matrix22< T > *m)
Definition: PyImathMatrix.h:92
FixedArray< IMATH_NAMESPACE::Matrix33< double > > M33dArray
Definition: PyImathMatrix.h:29