1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME SALOME_PY : binding of VTK graphics and Python
24 // File : SalomePy.cxx
25 // Author : Paul RASCLE, EDF
28 // E.A. : On windows with python 2.6, there is a conflict
29 // E.A. : between pymath.h and Standard_math.h which define
30 // E.A. : some same symbols : acosh, asinh, ...
31 #include <Standard_math.hxx>
36 #include <vtkPythonUtil.h>
38 #include <vtkVersion.h>
39 #include <vtkRenderer.h>
40 #include <vtkRenderWindow.h>
41 #include <vtkRenderWindowInteractor.h>
43 #include <SALOME_Event.h>
45 #include <SUIT_Session.h>
46 #include <LightApp_Application.h>
47 #include <LightApp_Study.h>
49 #include <SVTK_ViewManager.h>
50 #include <SVTK_ViewWindow.h>
52 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
55 \brief Python wrappings for VTK viewer of the SALOME desktop.
57 All methods are implemented using Event mechanism. The module
58 provides the following functions:
61 - getRenderWindowInteractor()
70 renderer = SalomePy.getRenderer() # get VTK renderer
71 window = SalomePy.getRenderWindow() # get render window
74 The methods getRenderer(), getRenderWindow() and getRenderWindowInteractor()
75 open new VTK viewer if there is no one opened.
76 In case of any error these methods return None object to the Python.
79 #define PUBLISH_ENUM(i) \
83 if ( ( w = PyInt_FromLong( i ) ) == NULL ) return; \
84 rc = PyDict_SetItemString( aModuleDict, #i, w ); \
86 if ( rc < 0 ) return; \
89 //! View operation type
91 ViewFront, //!< front view
92 ViewBack, //!< back view
93 ViewTop, //!< top view
94 ViewBottom, //!< bottom view
95 ViewRight, //!< right view
96 ViewLeft //!< left view
100 \brief Get Python class object by name
102 \param theClassName Python class name
103 \return Python class object or None object if class is not found
105 static PyObject* GetPyClass( const char* theClassName )
107 static PyObject* aVTKModule = 0;
108 PyObject* aPyClass = 0;
110 #if VTK_XVERSION < 30000
111 aVTKModule = PyImport_ImportModule( "libVTKGraphicsPython" );
112 #elif VTK_XVERSION < 50700
113 aVTKModule = PyImport_ImportModule( "vtk.libvtkRenderingPython" );
114 #elif VTK_XVERSION < 60000
115 aVTKModule = PyImport_ImportModule( "vtkRenderingPython" );
117 aVTKModule = PyImport_ImportModule( "vtkRenderingCorePython" );
119 if( PyErr_Occurred() ) {
124 PyObject* aVTKDict = PyModule_GetDict( aVTKModule );
125 aPyClass = PyDict_GetItemString(aVTKDict, const_cast<char*>( theClassName ) );
131 \brief VTK window find/create mode
135 __Find, // try to find VTK window; if not found, do nothing
136 __FindOrCreate, // try to find VTK window; if not found, create new one
137 __Create }; // create new VTK window
140 \brief Find or create VTK window.
142 \param toCreate window find/create mode
143 \return VTK window pointer or 0 if it could not be found/created
145 static SVTK_ViewWindow* GetVTKViewWindow( int toCreate = __FindOrCreate ) {
146 SVTK_ViewWindow* aVW = 0;
147 if ( SUIT_Session::session() ) {
149 LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
152 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() );
154 // find or create VTK view manager
155 if ( toCreate == __Create ) {
156 SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->createViewManager( "VTKViewer" ) );
158 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
160 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->createViewWindow() );
161 // VSR : When new view window is created it can be not active yet at this moment,
162 // so the following is a some workaround
163 if ( !aVW && !aVM->getViews().isEmpty() )
164 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
168 SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->getViewManager( "VTKViewer", toCreate == __FindOrCreate ) );
170 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
171 // VSR : When new view window is created it can be not active yet at this moment,
172 // so the following is a some workaround
173 if ( !aVW && !aVM->getViews().isEmpty() )
174 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
184 \fn PyObject* getRenderer( int toCreate = 0 );
185 \brief Get VTK renderer (vtkRenderer).
187 If \a toCreate parameter is 0 (by default) the function tries to find
188 and reuse existing VTK window; if it is not found, the new VTK window
191 If \a toCreate parameter is non-zero, the function always creates
194 If VTK window could not be found and or created, the None Python object
197 \param toCreate window creation mode
198 \return VTK window renderer object
201 class TGetRendererEvent: public SALOME_Event
204 typedef PyObject* TResult;
207 TGetRendererEvent( bool toCreate )
208 : myResult( Py_None ), myCreate( toCreate ) {}
209 virtual void Execute()
211 PyObject* aPyClass = ::GetPyClass( "vtkRenderer" );
212 SVTK_ViewWindow* aVTKViewWindow =
213 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
214 if( aVTKViewWindow && aPyClass ) {
215 vtkRenderer* aVTKObject = aVTKViewWindow->getRenderer();
216 #if VTK_XVERSION < 50700
217 myResult = PyVTKObject_New( aPyClass, aVTKObject );
219 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
225 extern "C" PyObject* libSalomePy_getRenderer( PyObject* self, PyObject* args )
227 PyObject* aResult = Py_None;
229 if ( !PyArg_ParseTuple( args, "|i:getRenderer", &toCreate ) )
232 aResult = ProcessEvent( new TGetRendererEvent( toCreate ) );
237 \fn PyObject* getRenderWindow( int toCreate = 0 );
238 \brief Get VTK render window (vtkRenderWindow).
240 If \a toCreate parameter is 0 (by default) the function tries to find
241 and reuse existing VTK window; if it is not found, the new VTK window
244 If \a toCreate parameter is non-zero, the function always creates
247 If VTK window could not be found and or created, the None Python object
250 \param toCreate window creation mode
251 \return VTK window render window object
254 class TGetRenderWindowEvent: public SALOME_Event
257 typedef PyObject* TResult;
260 TGetRenderWindowEvent( bool toCreate )
261 : myResult( Py_None ), myCreate( toCreate ) {}
262 virtual void Execute()
264 PyObject* aPyClass = ::GetPyClass( "vtkRenderWindow" );
265 SVTK_ViewWindow* aVTKViewWindow =
266 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
267 if( aVTKViewWindow && aPyClass ) {
268 vtkRenderWindow* aVTKObject = aVTKViewWindow->getRenderWindow();
269 #if VTK_XVERSION < 50700
270 myResult = PyVTKObject_New( aPyClass, aVTKObject );
272 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
278 extern "C" PyObject* libSalomePy_getRenderWindow( PyObject* self, PyObject* args )
280 PyObject* aResult = Py_None;
282 if ( !PyArg_ParseTuple( args, "|i:getRenderWindow", &toCreate ) )
285 aResult = ProcessEvent( new TGetRenderWindowEvent( toCreate ) );
290 \fn PyObject* getRenderWindowInteractor( int toCreate = 0 );
291 \brief Get VTK render window interactor (getRenderWindowInteractor).
293 If \a toCreate parameter is 0 (by default) the function tries to find
294 and reuse existing VTK window; if it is not found, the new VTK window
297 If \a toCreate parameter is non-zero, the function always creates
300 If VTK window could not be found and or created, the None Python object
303 \param toCreate window creation mode
304 \return VTK window render window interactor object
307 class TGetRenderWindowInteractorEvent: public SALOME_Event
310 typedef PyObject* TResult;
313 TGetRenderWindowInteractorEvent( bool toCreate )
314 : myResult( Py_None ), myCreate( toCreate ) {}
315 virtual void Execute()
317 PyObject* aPyClass = ::GetPyClass( "vtkRenderWindowInteractor" );
318 SVTK_ViewWindow* aVTKViewWindow =
319 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
320 if( aVTKViewWindow && aPyClass ) {
321 vtkRenderWindowInteractor* aVTKObject = aVTKViewWindow->getInteractor();
322 #if VTK_XVERSION < 50700
323 myResult = PyVTKObject_New( aPyClass, aVTKObject );
325 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
331 extern "C" PyObject* libSalomePy_getRenderWindowInteractor( PyObject* self, PyObject* args )
333 PyObject* aResult = Py_None;
335 if ( !PyArg_ParseTuple( args, "|i:getRenderWindowInteractor", &toCreate ) )
338 aResult = ProcessEvent( new TGetRenderWindowInteractorEvent( toCreate ) );
343 \fn PyObject* showTrihedron( int show );
344 \brief Show/hide trihedron in the current VTK viewer.
346 If there is no active VTK viewer, nothing happens.
348 \param show new trihedron visibility state
349 \return nothing (Py_None)
352 extern "C" PyObject* libSalomePy_showTrihedron( PyObject* self, PyObject* args )
354 class TEvent: public SALOME_Event
360 virtual void Execute()
362 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
363 if ( aVTKViewWindow->isTrihedronDisplayed() != myShow )
364 aVTKViewWindow->onViewTrihedron();
369 PyObject* aResult = Py_None;
371 if ( !PyArg_ParseTuple( args, "i:showTrihedron", &bShow ) )
374 ProcessVoidEvent( new TEvent( bShow ) );
379 \fn PyObject* fitAll();
380 \brief Fit all the contents in the current VTK viewer.
382 If there is no active VTK viewer, nothing happens.
384 \return nothing (Py_None)
387 extern "C" PyObject* libSalomePy_fitAll( PyObject* self, PyObject* args )
389 class TEvent: public SALOME_Event
393 virtual void Execute()
395 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
396 aVTKViewWindow->onFitAll();
401 ProcessVoidEvent( new TEvent() );
406 \fn PyObject* setView( int type );
407 \brief Set view type for the current VTK viewer.
409 If there is no active VTK viewer, nothing happens.
411 \param type view type
412 \return nothing (Py_None)
415 extern "C" PyObject* libSalomePy_setView( PyObject* self, PyObject* args )
417 class TEvent: public SALOME_Event
421 TEvent( long type ) : myType( type) {}
422 virtual void Execute()
424 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
427 aVTKViewWindow->onFrontView(); break;
429 aVTKViewWindow->onBackView(); break;
431 aVTKViewWindow->onTopView(); break;
433 aVTKViewWindow->onBottomView(); break;
435 aVTKViewWindow->onRightView(); break;
437 aVTKViewWindow->onLeftView(); break;
439 PyErr_Format(PyExc_ValueError,"setView%: wrong parameter value; must be between %d and %d", ViewFront, ViewLeft );
447 if ( !PyArg_ParseTuple( args, "l:setView", &type ) )
450 ProcessVoidEvent( new TEvent( type ) );
451 if( PyErr_Occurred() )
458 \fn PyObject* resetView();
459 \brief Reset contents of the current VTK viewer.
461 If there is no active VTK viewer, nothing happens.
463 \return nothing (Py_None)
466 extern "C" PyObject* libSalomePy_resetView( PyObject* self, PyObject* args )
468 class TEvent: public SALOME_Event
472 virtual void Execute()
474 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
475 aVTKViewWindow->onResetView();
480 ProcessVoidEvent( new TEvent() );
484 static PyMethodDef Module_Methods[] =
486 { "getRenderer", libSalomePy_getRenderer, METH_VARARGS },
487 { "getRenderWindow", libSalomePy_getRenderWindow, METH_VARARGS },
488 { "getRenderWindowInteractor", libSalomePy_getRenderWindowInteractor, METH_VARARGS },
489 { "showTrihedron", libSalomePy_showTrihedron, METH_VARARGS },
490 { "fitAll", libSalomePy_fitAll, METH_NOARGS },
491 { "setView", libSalomePy_setView, METH_VARARGS },
492 { "resetView", libSalomePy_resetView, METH_NOARGS },
497 \brief Python module initialization.
500 extern "C" void initlibSalomePy()
502 static char* modulename = (char*)"libSalomePy";
505 PyObject* aModule = Py_InitModule( modulename, Module_Methods );
506 if( PyErr_Occurred() ) {
511 // get module's dictionary
512 PyObject *aModuleDict = PyModule_GetDict( aModule );
513 if ( aModuleDict == NULL )
516 // export View type enumeration
517 PUBLISH_ENUM( ViewFront );
518 PUBLISH_ENUM( ViewBack );
519 PUBLISH_ENUM( ViewTop );
520 PUBLISH_ENUM( ViewBottom );
521 PUBLISH_ENUM( ViewRight );
522 PUBLISH_ENUM( ViewLeft );