Back to index

salome-gui  6.5.0
SalomePy.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library 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 GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SALOME SALOME_PY : binding of VTK graphics and Python
00024 //  File   : SalomePy.cxx
00025 //  Author : Paul RASCLE, EDF
00026 //
00027 #ifdef WNT
00028 // E.A. : On windows with python 2.6, there is a conflict
00029 // E.A. : between pymath.h and Standard_math.h which define
00030 // E.A. : some same symbols : acosh, asinh, ...
00031 #include <Standard_math.hxx>
00032 #include <pymath.h>
00033 #endif
00034 
00035 #include <Python.h>
00036 #include <vtkPythonUtil.h>
00037 
00038 #include <vtkVersion.h>
00039 #include <vtkRenderer.h>
00040 #include <vtkRenderWindow.h>
00041 #include <vtkRenderWindowInteractor.h>
00042 
00043 #include <SALOME_Event.h>
00044 
00045 #include <SUIT_Session.h>
00046 #include <LightApp_Application.h>
00047 #include <LightApp_Study.h>
00048 
00049 #include <SVTK_ViewManager.h>
00050 #include <SVTK_ViewWindow.h>
00051 
00052 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
00053 
00079 #define PUBLISH_ENUM(i)                              \
00080 {                                                    \
00081   PyObject *w;                                       \
00082   int rc;                                            \
00083   if ( ( w = PyInt_FromLong( i ) ) == NULL ) return; \
00084   rc = PyDict_SetItemString( aModuleDict, #i, w );   \
00085   Py_DECREF( w );                                    \
00086   if ( rc < 0 ) return;                              \
00087 }
00088 
00090 enum {
00091   ViewFront,     
00092   ViewBack,      
00093   ViewTop,       
00094   ViewBottom,    
00095   ViewRight,     
00096   ViewLeft       
00097 };
00098 
00105 static PyObject* GetPyClass( const char* theClassName ) 
00106 {
00107   static PyObject* aVTKModule = 0;
00108   PyObject* aPyClass = 0;
00109   if( !aVTKModule ) {
00110 #if VTK_XVERSION < 30000
00111     aVTKModule = PyImport_ImportModule( "libVTKGraphicsPython" ); 
00112 #elif VTK_XVERSION < 50700
00113     aVTKModule = PyImport_ImportModule( "vtk.libvtkRenderingPython" ); 
00114 #else
00115     aVTKModule = PyImport_ImportModule( "vtkRenderingPython" ); 
00116 #endif
00117     if( PyErr_Occurred() ) {
00118       PyErr_Print();
00119     }
00120   }
00121   if ( aVTKModule ) {
00122     PyObject* aVTKDict = PyModule_GetDict( aVTKModule );
00123     aPyClass = PyDict_GetItemString(aVTKDict, const_cast<char*>( theClassName ) );
00124   }
00125   return aPyClass;
00126 }
00127 
00132 enum { 
00133   __Find,          // try to find VTK window; if not found, do nothing
00134   __FindOrCreate,  // try to find VTK window; if not found, create new one
00135   __Create };      // create new VTK window
00136 
00143 static SVTK_ViewWindow* GetVTKViewWindow( int toCreate = __FindOrCreate ) {
00144   SVTK_ViewWindow* aVW = 0;
00145   if ( SUIT_Session::session() ) {
00146     // get application
00147     LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
00148     if ( anApp ) {
00149       // get active study
00150       LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() );
00151       if ( aStudy ) {
00152         // find or create VTK view manager
00153         if ( toCreate == __Create ) {
00154           SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->createViewManager( "VTKViewer" ) );
00155           if ( aVM ) {
00156             aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
00157             if ( !aVW )
00158               aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->createViewWindow() );
00159             // VSR : When new view window is created it can be not active yet at this moment,
00160             // so the following is a some workaround
00161             if ( !aVW && !aVM->getViews().isEmpty() )
00162               aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
00163           }
00164         }
00165         else {
00166           SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->getViewManager( "VTKViewer", toCreate == __FindOrCreate ) );
00167           if ( aVM ) {
00168             aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
00169             // VSR : When new view window is created it can be not active yet at this moment,
00170             // so the following is a some workaround
00171             if ( !aVW && !aVM->getViews().isEmpty() )
00172               aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
00173           }
00174         }
00175       }
00176     }
00177   }
00178   return aVW;
00179 }
00180 
00199 class TGetRendererEvent: public SALOME_Event
00200 {
00201 public:
00202   typedef PyObject* TResult;
00203   TResult myResult;
00204   int     myCreate;
00205   TGetRendererEvent( bool toCreate )
00206     : myResult( Py_None ), myCreate( toCreate ) {}
00207   virtual void Execute()
00208   {
00209     PyObject* aPyClass = ::GetPyClass( "vtkRenderer" );
00210     SVTK_ViewWindow* aVTKViewWindow = 
00211       ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
00212     if( aVTKViewWindow && aPyClass ) {
00213       vtkRenderer* aVTKObject = aVTKViewWindow->getRenderer();
00214 #if VTK_XVERSION < 50700
00215       myResult = PyVTKObject_New( aPyClass, aVTKObject );
00216 #else
00217       myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
00218 #endif
00219     }
00220   }
00221 };
00222 
00223 extern "C" PyObject* libSalomePy_getRenderer( PyObject* self, PyObject* args )
00224 {
00225   PyObject* aResult = Py_None;
00226   int toCreate = 0;
00227   if ( !PyArg_ParseTuple( args, "|i:getRenderer", &toCreate ) )
00228     PyErr_Print();
00229   else
00230     aResult = ProcessEvent( new TGetRendererEvent( toCreate ) );
00231   return aResult;
00232 }
00233 
00252 class TGetRenderWindowEvent: public SALOME_Event
00253 {
00254 public:
00255   typedef PyObject* TResult;
00256   TResult myResult;
00257   int     myCreate;
00258   TGetRenderWindowEvent( bool toCreate )
00259     : myResult( Py_None ), myCreate( toCreate ) {}
00260   virtual void Execute()
00261   {
00262     PyObject* aPyClass = ::GetPyClass( "vtkRenderWindow" );
00263     SVTK_ViewWindow* aVTKViewWindow = 
00264       ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
00265     if( aVTKViewWindow && aPyClass ) {
00266       vtkRenderWindow* aVTKObject = aVTKViewWindow->getRenderWindow();
00267 #if VTK_XVERSION < 50700
00268       myResult = PyVTKObject_New( aPyClass, aVTKObject );
00269 #else
00270       myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
00271 #endif
00272     }
00273   }
00274 };
00275 
00276 extern "C" PyObject* libSalomePy_getRenderWindow( PyObject* self, PyObject* args )
00277 {
00278   PyObject* aResult = Py_None;
00279   int toCreate = 0;
00280   if ( !PyArg_ParseTuple( args, "|i:getRenderWindow", &toCreate ) )
00281     PyErr_Print();
00282   else
00283     aResult = ProcessEvent( new TGetRenderWindowEvent( toCreate ) );
00284   return aResult;
00285 }
00286 
00305 class TGetRenderWindowInteractorEvent: public SALOME_Event
00306 {
00307 public:
00308   typedef PyObject* TResult;
00309   TResult myResult;
00310   int     myCreate;
00311   TGetRenderWindowInteractorEvent( bool toCreate )
00312     : myResult( Py_None ), myCreate( toCreate ) {}
00313   virtual void Execute()
00314   {
00315     PyObject* aPyClass = ::GetPyClass( "vtkRenderWindowInteractor" );
00316     SVTK_ViewWindow* aVTKViewWindow = 
00317       ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
00318     if( aVTKViewWindow && aPyClass ) {
00319       vtkRenderWindowInteractor* aVTKObject = aVTKViewWindow->getInteractor();
00320 #if VTK_XVERSION < 50700
00321       myResult = PyVTKObject_New( aPyClass, aVTKObject );
00322 #else
00323       myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
00324 #endif
00325     }
00326   }
00327 };
00328 
00329 extern "C" PyObject* libSalomePy_getRenderWindowInteractor( PyObject* self, PyObject* args )
00330 {
00331   PyObject* aResult = Py_None;
00332   int toCreate = 0;
00333   if ( !PyArg_ParseTuple( args, "|i:getRenderWindowInteractor", &toCreate ) )
00334     PyErr_Print();
00335   else
00336     aResult = ProcessEvent( new TGetRenderWindowInteractorEvent( toCreate ) );
00337   return aResult;
00338 }
00339 
00350 extern "C" PyObject* libSalomePy_showTrihedron( PyObject* self, PyObject* args )
00351 {
00352   class TEvent: public SALOME_Event
00353   {
00354   public:
00355     int myShow;
00356     TEvent( int bShow )
00357       : myShow( bShow ) {}
00358     virtual void Execute()
00359     {
00360       if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
00361         if ( aVTKViewWindow->isTrihedronDisplayed() != myShow )
00362           aVTKViewWindow->onViewTrihedron();
00363       }
00364     }
00365   };
00366   
00367   PyObject* aResult = Py_None;
00368   int bShow = 0;
00369   if ( !PyArg_ParseTuple( args, "i:showTrihedron", &bShow ) )
00370     PyErr_Print();
00371   else
00372     ProcessVoidEvent( new TEvent( bShow ) );
00373   return aResult;
00374 }
00375 
00385 extern "C" PyObject* libSalomePy_fitAll( PyObject* self, PyObject* args )
00386 {
00387   class TEvent: public SALOME_Event
00388   {
00389   public:
00390     TEvent() {}
00391     virtual void Execute()
00392     {
00393       if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
00394         aVTKViewWindow->onFitAll();
00395       }
00396     }
00397   };
00398   
00399   ProcessVoidEvent( new TEvent() );
00400   return Py_None;
00401 }
00402 
00413 extern "C" PyObject* libSalomePy_setView( PyObject* self, PyObject* args )
00414 {
00415   class TEvent: public SALOME_Event
00416   {
00417   public:
00418     long myType;
00419     TEvent( long type ) : myType( type) {}
00420     virtual void Execute()
00421     {
00422       if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
00423         switch( myType ) {
00424         case ViewFront:
00425           aVTKViewWindow->onFrontView();  break;
00426         case ViewBack:
00427           aVTKViewWindow->onBackView();   break;
00428         case ViewTop:
00429           aVTKViewWindow->onTopView();    break;
00430         case ViewBottom:
00431           aVTKViewWindow->onBottomView(); break;
00432         case ViewRight:
00433           aVTKViewWindow->onRightView();  break;
00434         case ViewLeft:
00435           aVTKViewWindow->onLeftView();   break;
00436         default:
00437           PyErr_Format(PyExc_ValueError,"setView%: wrong parameter value; must be between %d and %d", ViewFront, ViewLeft );
00438           break;
00439         }
00440       }
00441     }
00442   };
00443   
00444   long type = -1;
00445   if ( !PyArg_ParseTuple( args, "l:setView", &type ) )
00446     PyErr_Print();
00447   else {
00448     ProcessVoidEvent( new TEvent( type ) );
00449     if( PyErr_Occurred() )
00450       PyErr_Print();
00451   }
00452   return Py_None;
00453 }
00454 
00464 extern "C" PyObject* libSalomePy_resetView( PyObject* self, PyObject* args )
00465 {
00466   class TEvent: public SALOME_Event
00467   {
00468   public:
00469     TEvent() {}
00470     virtual void Execute()
00471     {
00472       if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
00473         aVTKViewWindow->onResetView();
00474       }
00475     }
00476   };
00477   
00478   ProcessVoidEvent( new TEvent() );
00479   return Py_None;
00480 }
00481 
00482 static PyMethodDef Module_Methods[] = 
00483 {
00484   { "getRenderer",               libSalomePy_getRenderer,               METH_VARARGS },
00485   { "getRenderWindow",           libSalomePy_getRenderWindow,           METH_VARARGS },
00486   { "getRenderWindowInteractor", libSalomePy_getRenderWindowInteractor, METH_VARARGS },
00487   { "showTrihedron",             libSalomePy_showTrihedron,             METH_VARARGS },
00488   { "fitAll",                    libSalomePy_fitAll,                    METH_NOARGS  },
00489   { "setView",                   libSalomePy_setView,                   METH_VARARGS },
00490   { "resetView",                 libSalomePy_resetView,                 METH_NOARGS  },
00491   { NULL, NULL }
00492 };
00493 
00498 extern "C" void initlibSalomePy()
00499 {
00500   static char* modulename = (char*)"libSalomePy";
00501 
00502   // init module
00503   PyObject* aModule = Py_InitModule( modulename, Module_Methods );
00504   if( PyErr_Occurred() ) {
00505     PyErr_Print();
00506     return;
00507   }
00508 
00509   // get module's dictionary
00510   PyObject *aModuleDict = PyModule_GetDict( aModule );
00511   if ( aModuleDict == NULL )
00512     return;
00513 
00514   // export View type enumeration
00515   PUBLISH_ENUM( ViewFront );
00516   PUBLISH_ENUM( ViewBack );
00517   PUBLISH_ENUM( ViewTop );
00518   PUBLISH_ENUM( ViewBottom );
00519   PUBLISH_ENUM( ViewRight );
00520   PUBLISH_ENUM( ViewLeft );
00521 }