PythonMethods.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
00022 //
00023 //
00028 //
00030 #ifndef __PYTHONMETHODS_H__
00031 #define __PYTHONMETHODS_H__
00032 #include "Field.h"
00033 #include "X3DTypes.h"
00034 #include "X3DFieldConversion.h"
00035 #include "X3DTypeFunctions.h"
00036 
00037 #ifdef HAVE_PYTHON
00038 #if defined(_MSC_VER)
00039 // undefine _DEBUG since we want to always link to the release version of
00040 // python and pyconfig.h automatically links debug version if _DEBUG is
00041 // defined.
00042 #ifdef _DEBUG
00043 #define _DEBUG_UNDEFED
00044 #undef _DEBUG
00045 #endif
00046 #endif
00047 #if defined(__APPLE__) && defined(__MACH__)
00048 #include <Python/Python.h>
00049 #else
00050 #include <Python.h>
00051 #endif
00052 #if defined(_MSC_VER)
00053 // redefine _DEBUG if it was undefed
00054 #ifdef _DEBUG_UNDEFED
00055 #define _DEBUG
00056 #endif
00057 #endif
00058 
00059 namespace H3D {
00060   namespace PythonInternals {
00061     PyMODINIT_FUNC initH3D();
00062     
00063     double pyObjectToDouble( PyObject *v );
00064 
00065     void fieldDestructor( void *f );
00066 
00067     PyObject *fieldAsPythonObject( Field * f, bool destruct=false );
00068 
00069     PyObject *pythonCreateField( PyObject *self, PyObject *args );
00070     
00071     PyObject *pythonSetFieldValueFromObject( Field *field_ptr, PyObject *v );
00072 
00073     PyObject *pythonSetFieldValue( PyObject *self, PyObject *args );
00074 
00075     PyObject *pythonGetFieldValue( PyObject *self, PyObject *arg );
00076 
00077     PyObject *pythonRouteField( PyObject *self, PyObject *args );
00078 
00079     PyObject *pythonRouteFieldNoEvent( PyObject *self, PyObject *args );
00080 
00081     PyObject *pythonUnrouteField( PyObject *self, PyObject *args );
00082 
00083     PyObject *pythonGetCPtr( PyObject *self, PyObject *arg  );
00084 
00085     PyObject* pythonCreateX3DFromURL( PyObject *self, PyObject *arg );
00086 
00087     PyObject* pythonCreateX3DFromString( PyObject *self, PyObject *arg );
00088 
00089     PyObject* pythonCreateX3DNodeFromURL( PyObject *self, PyObject *arg );
00090 
00091     PyObject* pythonCreateX3DNodeFromString( PyObject *self, PyObject *arg );
00092 
00093     PyObject* pythonCreateVRMLFromURL( PyObject *self, PyObject *arg );
00094 
00095     PyObject* pythonCreateVRMLFromString( PyObject *self, PyObject *arg );
00096 
00097     PyObject* pythonCreateVRMLNodeFromURL( PyObject *self, PyObject *arg );
00098 
00099     PyObject* pythonCreateVRMLNodeFromString( PyObject *self, PyObject *arg );
00100 
00101     PyObject* pythonGetRoutesIn( PyObject *self, PyObject *arg );
00102 
00103     PyObject* pythonGetRoutesOut( PyObject *self, PyObject *arg );
00104 
00105     PyObject* pythonGetCurrentScenes( PyObject *self, PyObject *arg );
00106 
00107 #ifdef USE_HAPTICS
00108     PyObject* pythonGetActiveDeviceInfo( PyObject *self, PyObject *arg );
00109 #endif
00110 
00111     PyObject* pythonGetActiveViewpoint( PyObject *self, PyObject *arg );
00112 
00113     PyObject* pythonGetActiveNavigationInfo( PyObject *self, PyObject *arg );
00114 
00115     PyObject* pythonGetActiveStereoInfo( PyObject *self, PyObject *arg );
00116 
00117     PyObject* pythonGetActiveBackground( PyObject *self, PyObject *arg );
00118 
00119     PyObject* pythonEraseElementFromMField( PyObject *self, PyObject *arg );
00120 
00121     PyObject* pythonPushBackElementInMField( PyObject *self, PyObject *arg );
00122 
00123     PyObject* pythonMFieldClear( PyObject *self, PyObject *arg );
00124 
00125     PyObject* pythonMFieldBack( PyObject *self, PyObject *arg );
00126 
00127     PyObject* pythonMFieldFront( PyObject *self, PyObject *arg );
00128 
00129     PyObject* pythonMFieldEmpty( PyObject *self, PyObject *arg );
00130 
00131     PyObject* pythonMFieldPopBack( PyObject *self, PyObject *arg );
00132 
00133     PyObject* pythonTouchField( PyObject *self, PyObject *arg );
00134 
00135     PyObject* pythonResolveURLAsFile( PyObject *self, PyObject *arg );
00136     
00137   }
00138 
00139     
00144   H3D_VALUE_EXCEPTION( string, PythonInvalidFieldType );
00145 
00146   struct PythonFieldBase {
00147     PythonFieldBase( void *_python_field ) :
00148       python_field( _python_field ),
00149       python_update( 0 ),
00150       python_typeinfo( 0 ),
00151       python_opttypeinfo( 0 ){}
00152     
00153     void *python_field;
00154     void *python_update;
00155     void *python_typeinfo;
00156     void *python_opttypeinfo;
00157   };
00158   
00159   template< class F >
00160   struct PythonField : public F, PythonFieldBase {
00161     
00162     PythonField( void *_python_field ) : 
00163       PythonFieldBase( _python_field ) {
00164     }
00165     virtual void update() {
00166       if ( python_update ) {
00167         PyErr_Clear();
00168         PyObject *args = PyTuple_New(1);
00169         PyObject *f = PythonInternals::fieldAsPythonObject( this->event.ptr, false );
00170         PyTuple_SetItem( args, 0, f );
00171         PyObject *r = PyEval_CallObject( static_cast< PyObject * >(python_update), 
00172                                          args );
00174         Py_DECREF( args );
00175         if( r == Py_None ) {
00176           Console(3) << "Warning: update()-function for Python defined field of type " 
00177                      << this->getFullName() << " does not return a value. "<< endl;
00178           Py_DECREF( r );
00179         } else if ( r ) {
00180           if( !PythonInternals::pythonSetFieldValueFromObject( this, r ) ) {
00181             Console(3) << "Warning: invalid return value from update()-function"
00182                        << " for Python defined field of type " 
00183                        << this->getFullName() << endl;
00184           }
00185           Py_DECREF( r );
00186         } else {
00187           PyErr_Print();
00188         }        
00189       } else {
00190         F::update();
00191       }
00192     }
00193     
00201     void checkFieldType( Field *f, int index ) {
00202       if( python_typeinfo == 0 && python_opttypeinfo == 0 ) {
00203         F::checkFieldType( f, index );
00204         return;
00205       }
00206       int arg_size = -1;      
00207       if( python_typeinfo )
00208         arg_size = PyTuple_Size( static_cast< PyObject * >(python_typeinfo) );
00209 
00210       if ( index >= arg_size ) {
00211         int opt_arg_size = -1;
00212         if( python_opttypeinfo )
00213           opt_arg_size = PyTuple_Size( static_cast< PyObject * >(python_opttypeinfo) );
00214         if( opt_arg_size > 0 ) {
00215           PyObject *type_info = 
00216             PyTuple_GetItem( static_cast< PyObject * >(python_opttypeinfo),
00217                              0 );
00218           PyObject *type_id = PyObject_GetAttrString( type_info, "type" );
00219           int type_int = PyInt_AsLong( type_id );
00220           if ( f->getTypeName().compare( 
00221            X3DTypes::typeToString( (X3DTypes::X3DType)type_int ) ) != 0 ) {
00222             ostringstream err;
00223             err << "Bad input, expected " 
00224                 << X3DTypes::typeToString( (X3DTypes::X3DType)type_int )  
00225                 << " got " << f->getTypeName() << " for route" << index;
00226             throw H3D::PythonInvalidFieldType( err.str(), "", 
00227                                                H3D_FULL_LOCATION );
00228       }
00229         } else {
00230           ostringstream err;
00231           err << "Too many inputs, expected " << arg_size+1;
00232           throw H3D::PythonInvalidFieldType( err.str(), "", 
00233                                              H3D_FULL_LOCATION );
00234         }
00235       } else {
00236       PyObject *type_info = 
00237         PyTuple_GetItem( static_cast< PyObject * >(python_typeinfo),
00238                          index );
00239       PyObject *type_id = PyObject_GetAttrString( type_info, "type" );
00240       int type_int = PyInt_AsLong( type_id );
00241       //if( ! t || ! PyInt_Check( t ) )
00242       if ( f->getTypeName().compare( 
00243            X3DTypes::typeToString( (X3DTypes::X3DType)type_int ) ) != 0 ) {
00244         ostringstream err;
00245         err << "Bad input, expected " 
00246             << X3DTypes::typeToString( (X3DTypes::X3DType)type_int )  
00247             << " got " << f->getTypeName() << " for route" << index;
00248         throw H3D::PythonInvalidFieldType( err.str(), "", 
00249                                            H3D_FULL_LOCATION );
00250       }
00251       }
00252     }
00253   };
00254 }
00255 
00256 #endif // HAVE_PYTHON
00257 #endif

Generated on Thu Aug 24 12:38:33 2006 for H3D API by  doxygen 1.4.5