H3D API  2.4.1
PyTypeWrapper.h
Go to the documentation of this file.
1 
3 // Copyright 2004-2019, SenseGraphics AB
4 //
5 // This file is part of H3D API.
6 //
7 // H3D API is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // H3D API is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with H3D API; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //
21 // A commercial license is also available. Please contact us at
22 // www.sensegraphics.com for more information.
23 //
24 //
29 //
31 
32 #ifdef HAVE_PYTHON
33 
34 #if defined(_MSC_VER)
35 // undefine _DEBUG since we want to always link to the release version of
36 // python and pyconfig.h automatically links debug version if _DEBUG is
37 // defined.
38 #if defined _DEBUG && ! defined HAVE_PYTHON_DEBUG_LIBRARY
39 #define _DEBUG_UNDEFED
40 #undef _DEBUG
41 #endif
42 
43 #include <pyconfig.h>
44 
45 // define HAVE_ROUND if not defined
46 #if _MSC_VER >= 1800
47 #ifndef HAVE_ROUND
48 #define HAVE_ROUND 1
49 #endif
50 #endif // _MSC_VER >= 1800
51 
52 #endif
53 #if defined(__APPLE__) && defined(__MACH__) && defined( HAVE_PYTHON_OSX_FRAMEWORK )
54 #include <Python/Python.h>
55 #else
56 #include <Python.h>
57 #endif
58 #if defined(_MSC_VER)
59 // redefine _DEBUG if it was undefed
60 #ifdef _DEBUG_UNDEFED
61 #define _DEBUG
62 #endif
63 #endif
64 
65 namespace H3D {
66 
71  struct PyType {
72  PyObject_HEAD
73  };
74 
86  template< class Type,
87  PyTypeObject *TypeObject,
88  string ( *NameFunc ) (),
89  bool ( *CheckFunc )( PyObject * ),
90  Type (*ValueFunc)( PyObject *),
91  PyObject *(*NewFunc)( const Type &) >
92  struct PyTypeWrapper: public PyType, Type {
93 
96  static void installType( PyObject* _H3D_module ) {
97  if (PyType_Ready( TypeObject ) < 0 )
98  return; // THROW ERROR!?
99 
100  Py_INCREF( TypeObject );
101  PyModule_AddObject( _H3D_module,
102  (char *)NameFunc().c_str(),
103  (PyObject *)TypeObject );
104  }
105 
109  static PyObject* create() {
110  return PyType_GenericAlloc( TypeObject, 1 );
111  }
112 
114  static void dealloc( PyObject *self ) {
115  self->ob_type->tp_free( self );
116  }
117 
119  static PyObject* repr( PyObject *myself, PyObject * /*args*/ ) {
120  if( CheckFunc( myself ) ) {
121  ostringstream s;
122  s << ValueFunc( myself );
123  return PyString_FromString( s.str().c_str() );
124  } else {
125  ostringstream s;
126  s << "PyObject * is not a " << NameFunc() << "*";
127  throw Exception::H3DAPIException( s.str(),
129  }
130  }
131 
132 
134  static int compare( PyObject *veca, PyObject *vecb ) {
135  if( CheckFunc( veca ) && CheckFunc( vecb ) ){
136  Type a = ValueFunc( veca );
137  Type b = ValueFunc( vecb );
138  return a != b;
139  } else {
140  ostringstream s;
141  s << "PyObject * is not a " << NameFunc() << "*";
142  throw Exception::H3DAPIException( s.str(),
144  }
145  }
146 #if PY_MAJOR_VERSION >= 3
147  static PyObject* richCompare( PyObject *lhs, PyObject *rhs, int operation ) {
148  switch( operation ) {
149  case Py_EQ:
150  case Py_NE: // For equals and not equals we use the same code but invert the result
151  if( !compare( lhs, rhs ) ) {
152  if( operation == Py_EQ ) {
153  Py_RETURN_TRUE;
154  } else {
155  Py_RETURN_FALSE;
156  }
157  } else {
158  if( operation == Py_EQ ) {
159  Py_RETURN_FALSE;
160  } else {
161  Py_RETURN_TRUE;
162  }
163  }
164  break;
165  default:
166  Py_RETURN_NOTIMPLEMENTED;
167  break;
168  }
169  }
170 #endif
171  };
172 
173 
187  template< class Type,
188  PyTypeObject *TypeObject,
189  string ( *NameFunc ) (),
190  bool ( *CheckFunc )( PyObject * ),
191  Type (*ValueFunc)( PyObject *),
192  PyObject *(*NewFunc)( const Type &) >
194  public PyTypeWrapper< Type,
195  TypeObject,
196  NameFunc,
197  CheckFunc,
198  ValueFunc,
199  NewFunc > {
200 
202  static PyObject* add( PyObject *veca, PyObject *vecb ) {
203  if( CheckFunc( veca ) && CheckFunc( vecb ) ){
204  Type c = ValueFunc( veca ) + ValueFunc( vecb );
205  return NewFunc( c );
206  }
207  Py_INCREF( Py_NotImplemented );
208  return Py_NotImplemented;
209  }
210 
212  static PyObject* sub( PyObject *veca, PyObject *vecb ) {
213  if( CheckFunc( veca ) && CheckFunc( vecb ) ){
214  Type c = ValueFunc( veca ) - ValueFunc( vecb );
215  return NewFunc( c );
216  }
217  Py_INCREF( Py_NotImplemented );
218  return Py_NotImplemented;
219  }
222  static PyObject* mul( PyObject *veca, PyObject *vecb ) {
223  if( CheckFunc( veca ) ) {
224  Type a = ValueFunc( veca );
225  if( PyFloat_Check( vecb ) ) {
226  Type c = a * PyFloat_AsDouble( vecb );
227  return NewFunc( c );
228  // int type
229  } else if( PyInt_Check( vecb ) ) {
230  Type c = a * PyInt_AsLong( vecb );
231  return NewFunc( c );
232  // long type
233  } else if( PyLong_Check( vecb ) ) {
234  Type c = a * PyLong_AsLong( vecb );
235  return NewFunc( c );
236  }
237  } else if( CheckFunc( vecb ) ) {
238  Type b = ValueFunc( vecb );
239  // float type
240  if( PyFloat_Check( veca ) ) {
241  Type c = PyFloat_AsDouble( veca ) * b;
242  return NewFunc( c );
243  // int type
244  } else if( PyInt_Check( veca ) ) {
245  Type c = PyInt_AsLong( veca ) * b;
246  return NewFunc( c );
247  // long type
248  } else if( PyLong_Check( veca ) ) {
249  Type c = PyLong_AsLong( veca ) * b;
250  return NewFunc( c );
251  }
252  }
253  Py_INCREF( Py_NotImplemented );
254  return Py_NotImplemented;
255  }
256 
258  static PyObject* div( PyObject *veca, PyObject *floatb ) {
259  if( CheckFunc( veca ) ) {
260  Type a = ValueFunc( veca );
261  // float type
262  if( PyFloat_Check( floatb ) ) {
263  Type c = a / PyFloat_AsDouble( floatb );
264  return NewFunc( c );
265  // int type
266  } else if( PyInt_Check( floatb ) ) {
267  Type c = a / PyInt_AsLong( floatb );
268  return NewFunc( c );
269  // long type
270  } else if( PyLong_Check( floatb ) ) {
271  Type c = a / PyLong_AsLong( floatb );
272  return NewFunc( c );
273  }
274  }
275  Py_INCREF( Py_NotImplemented );
276  return Py_NotImplemented;
277  }
278 
280  static PyObject* neg( PyObject *vec ) {
281  if( CheckFunc( vec ) ){
282  Type c = -ValueFunc( vec );
283  return NewFunc( c );
284  }
285  Py_INCREF( Py_NotImplemented );
286  return Py_NotImplemented;
287  }
288 
289  };
290 
303  template< class Type,
304  PyTypeObject *TypeObject,
305  string ( *NameFunc ) (),
306  bool ( *CheckFunc )( PyObject * ),
307  Type (*ValueFunc)( PyObject *),
308  PyObject *(*NewFunc)( const Type &) >
310  public PyNumberTypeWrapperBase< Type,
311  TypeObject,
312  NameFunc,
313  CheckFunc,
314  ValueFunc,
315  NewFunc > {
317  static PyObject* mul( PyObject *veca, PyObject *vecb ) {
318  if( CheckFunc( veca ) && CheckFunc( vecb ) ) {
319  Type a = ValueFunc( veca );
320  Type b = ValueFunc( vecb );
321  return PyFloat_FromDouble( a * b );
322  } else {
323  return PyNumberTypeWrapperBase< Type,
324  TypeObject,
325  NameFunc,
326  CheckFunc,
327  ValueFunc,
328  NewFunc >::mul( veca, vecb );
329  }
330  }
331  };
332 
345  template< class Type,
346  PyTypeObject *TypeObject,
347  string ( *NameFunc ) (),
348  bool ( *CheckFunc )( PyObject * ),
349  Type (*ValueFunc)( PyObject *),
350  PyObject *(*NewFunc)( const Type &) >
352  public PyNumberTypeWrapperBase< Type,
353  TypeObject,
354  NameFunc,
355  CheckFunc,
356  ValueFunc,
357  NewFunc > {
359  static PyObject* mul( PyObject *veca, PyObject *vecb ) {
360  if( CheckFunc( veca ) && CheckFunc( vecb ) ) {
361  Type a = ValueFunc( veca );
362  Type b = ValueFunc( vecb );
363  return NewFunc( a * b );
364  } else {
365  return PyNumberTypeWrapperBase< Type,
366  TypeObject,
367  NameFunc,
368  CheckFunc,
369  ValueFunc,
370  NewFunc >::mul( veca, vecb );
371  }
372  }
373  };
374 
375 }
376 
377 #endif // HAVE_PYTHON
#define H3D_FULL_LOCATION
H3D API namespace.
Definition: Anchor.h:38
PyNumberTypeWrapperBase is a template wrapper class to create new Python types from types already exi...
Definition: PyTypeWrapper.h:199
static PyObject * sub(PyObject *veca, PyObject *vecb)
Performs subtraction between two instances.
Definition: PyTypeWrapper.h:212
static PyObject * neg(PyObject *vec)
Negation.
Definition: PyTypeWrapper.h:280
static PyObject * div(PyObject *veca, PyObject *floatb)
Performs division with a float, long or int instance.
Definition: PyTypeWrapper.h:258
static PyObject * mul(PyObject *veca, PyObject *vecb)
Performs multiplication between a instance of the type and a float, long or int.
Definition: PyTypeWrapper.h:222
static PyObject * add(PyObject *veca, PyObject *vecb)
Performs addition between two instances.
Definition: PyTypeWrapper.h:202
PyNumberTypeWrapper is the same as PyNumberTypeWrapperBase with the difference that its mul function ...
Definition: PyTypeWrapper.h:357
static PyObject * mul(PyObject *veca, PyObject *vecb)
Performs multiplacation.
Definition: PyTypeWrapper.h:359
PyTypeWrapper is a template wrapper class to create new Python types from types already existing in t...
Definition: PyTypeWrapper.h:92
static PyObject * repr(PyObject *myself, PyObject *)
Converts to a char* string.
Definition: PyTypeWrapper.h:119
static void dealloc(PyObject *self)
Python type deallocation.
Definition: PyTypeWrapper.h:114
static PyObject * create()
create() a new instance of Type using Python to allocate the memory and initialise the PyObject heade...
Definition: PyTypeWrapper.h:109
static int compare(PyObject *veca, PyObject *vecb)
Test if two PyTypes are equal or not.
Definition: PyTypeWrapper.h:134
static void installType(PyObject *_H3D_module)
Install type in the given python module.
Definition: PyTypeWrapper.h:96
Base class for all Python C type wrappers.
Definition: PyTypeWrapper.h:71
PyVecTypeWrapper is the same as PyNumberTypeWrapperBase with the difference that its mul function als...
Definition: PyTypeWrapper.h:315
static PyObject * mul(PyObject *veca, PyObject *vecb)
Performs vector dot product of two vector instances.
Definition: PyTypeWrapper.h:317