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" );
115 aVTKModule = PyImport_ImportModule( "vtkRenderingPython" );
117 if( PyErr_Occurred() ) {
122 PyObject* aVTKDict = PyModule_GetDict( aVTKModule );
123 aPyClass = PyDict_GetItemString(aVTKDict, const_cast<char*>( theClassName ) );
129 \brief VTK window find/create mode
133 __Find, // try to find VTK window; if not found, do nothing
134 __FindOrCreate, // try to find VTK window; if not found, create new one
135 __Create }; // create new VTK window
138 \brief Find or create VTK window.
140 \param toCreate window find/create mode
141 \return VTK window pointer or 0 if it could not be found/created
143 static SVTK_ViewWindow* GetVTKViewWindow( int toCreate = __FindOrCreate ) {
144 SVTK_ViewWindow* aVW = 0;
145 if ( SUIT_Session::session() ) {
147 LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
150 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() );
152 // find or create VTK view manager
153 if ( toCreate == __Create ) {
154 SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->createViewManager( "VTKViewer" ) );
156 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
158 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->createViewWindow() );
159 // VSR : When new view window is created it can be not active yet at this moment,
160 // so the following is a some workaround
161 if ( !aVW && !aVM->getViews().isEmpty() )
162 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
166 SVTK_ViewManager* aVM = dynamic_cast<SVTK_ViewManager*>( anApp->getViewManager( "VTKViewer", toCreate == __FindOrCreate ) );
168 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getActiveView() );
169 // VSR : When new view window is created it can be not active yet at this moment,
170 // so the following is a some workaround
171 if ( !aVW && !aVM->getViews().isEmpty() )
172 aVW = dynamic_cast<SVTK_ViewWindow*>( aVM->getViews()[0] );
182 \fn PyObject* getRenderer( int toCreate = 0 );
183 \brief Get VTK renderer (vtkRenderer).
185 If \a toCreate parameter is 0 (by default) the function tries to find
186 and reuse existing VTK window; if it is not found, the new VTK window
189 If \a toCreate parameter is non-zero, the function always creates
192 If VTK window could not be found and or created, the None Python object
195 \param toCreate window creation mode
196 \return VTK window renderer object
199 class TGetRendererEvent: public SALOME_Event
202 typedef PyObject* TResult;
205 TGetRendererEvent( bool toCreate )
206 : myResult( Py_None ), myCreate( toCreate ) {}
207 virtual void Execute()
209 PyObject* aPyClass = ::GetPyClass( "vtkRenderer" );
210 SVTK_ViewWindow* aVTKViewWindow =
211 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
212 if( aVTKViewWindow && aPyClass ) {
213 vtkRenderer* aVTKObject = aVTKViewWindow->getRenderer();
214 #if VTK_XVERSION < 50700
215 myResult = PyVTKObject_New( aPyClass, aVTKObject );
217 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
223 extern "C" PyObject* libSalomePy_getRenderer( PyObject* self, PyObject* args )
225 PyObject* aResult = Py_None;
227 if ( !PyArg_ParseTuple( args, "|i:getRenderer", &toCreate ) )
230 aResult = ProcessEvent( new TGetRendererEvent( toCreate ) );
235 \fn PyObject* getRenderWindow( int toCreate = 0 );
236 \brief Get VTK render window (vtkRenderWindow).
238 If \a toCreate parameter is 0 (by default) the function tries to find
239 and reuse existing VTK window; if it is not found, the new VTK window
242 If \a toCreate parameter is non-zero, the function always creates
245 If VTK window could not be found and or created, the None Python object
248 \param toCreate window creation mode
249 \return VTK window render window object
252 class TGetRenderWindowEvent: public SALOME_Event
255 typedef PyObject* TResult;
258 TGetRenderWindowEvent( bool toCreate )
259 : myResult( Py_None ), myCreate( toCreate ) {}
260 virtual void Execute()
262 PyObject* aPyClass = ::GetPyClass( "vtkRenderWindow" );
263 SVTK_ViewWindow* aVTKViewWindow =
264 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
265 if( aVTKViewWindow && aPyClass ) {
266 vtkRenderWindow* aVTKObject = aVTKViewWindow->getRenderWindow();
267 #if VTK_XVERSION < 50700
268 myResult = PyVTKObject_New( aPyClass, aVTKObject );
270 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
276 extern "C" PyObject* libSalomePy_getRenderWindow( PyObject* self, PyObject* args )
278 PyObject* aResult = Py_None;
280 if ( !PyArg_ParseTuple( args, "|i:getRenderWindow", &toCreate ) )
283 aResult = ProcessEvent( new TGetRenderWindowEvent( toCreate ) );
288 \fn PyObject* getRenderWindowInteractor( int toCreate = 0 );
289 \brief Get VTK render window interactor (getRenderWindowInteractor).
291 If \a toCreate parameter is 0 (by default) the function tries to find
292 and reuse existing VTK window; if it is not found, the new VTK window
295 If \a toCreate parameter is non-zero, the function always creates
298 If VTK window could not be found and or created, the None Python object
301 \param toCreate window creation mode
302 \return VTK window render window interactor object
305 class TGetRenderWindowInteractorEvent: public SALOME_Event
308 typedef PyObject* TResult;
311 TGetRenderWindowInteractorEvent( bool toCreate )
312 : myResult( Py_None ), myCreate( toCreate ) {}
313 virtual void Execute()
315 PyObject* aPyClass = ::GetPyClass( "vtkRenderWindowInteractor" );
316 SVTK_ViewWindow* aVTKViewWindow =
317 ::GetVTKViewWindow( myCreate ? __Create : __FindOrCreate );
318 if( aVTKViewWindow && aPyClass ) {
319 vtkRenderWindowInteractor* aVTKObject = aVTKViewWindow->getInteractor();
320 #if VTK_XVERSION < 50700
321 myResult = PyVTKObject_New( aPyClass, aVTKObject );
323 myResult = PyVTKObject_New( aPyClass, NULL, aVTKObject );
329 extern "C" PyObject* libSalomePy_getRenderWindowInteractor( PyObject* self, PyObject* args )
331 PyObject* aResult = Py_None;
333 if ( !PyArg_ParseTuple( args, "|i:getRenderWindowInteractor", &toCreate ) )
336 aResult = ProcessEvent( new TGetRenderWindowInteractorEvent( toCreate ) );
341 \fn PyObject* showTrihedron( int show );
342 \brief Show/hide trihedron in the current VTK viewer.
344 If there is no active VTK viewer, nothing happens.
346 \param show new trihedron visibility state
347 \return nothing (Py_None)
350 extern "C" PyObject* libSalomePy_showTrihedron( PyObject* self, PyObject* args )
352 class TEvent: public SALOME_Event
358 virtual void Execute()
360 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
361 if ( aVTKViewWindow->isTrihedronDisplayed() != myShow )
362 aVTKViewWindow->onViewTrihedron();
367 PyObject* aResult = Py_None;
369 if ( !PyArg_ParseTuple( args, "i:showTrihedron", &bShow ) )
372 ProcessVoidEvent( new TEvent( bShow ) );
377 \fn PyObject* fitAll();
378 \brief Fit all the contents in the current VTK viewer.
380 If there is no active VTK viewer, nothing happens.
382 \return nothing (Py_None)
385 extern "C" PyObject* libSalomePy_fitAll( PyObject* self, PyObject* args )
387 class TEvent: public SALOME_Event
391 virtual void Execute()
393 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
394 aVTKViewWindow->onFitAll();
399 ProcessVoidEvent( new TEvent() );
404 \fn PyObject* setView( int type );
405 \brief Set view type for the current VTK viewer.
407 If there is no active VTK viewer, nothing happens.
409 \param type view type
410 \return nothing (Py_None)
413 extern "C" PyObject* libSalomePy_setView( PyObject* self, PyObject* args )
415 class TEvent: public SALOME_Event
419 TEvent( long type ) : myType( type) {}
420 virtual void Execute()
422 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
425 aVTKViewWindow->onFrontView(); break;
427 aVTKViewWindow->onBackView(); break;
429 aVTKViewWindow->onTopView(); break;
431 aVTKViewWindow->onBottomView(); break;
433 aVTKViewWindow->onRightView(); break;
435 aVTKViewWindow->onLeftView(); break;
437 PyErr_Format(PyExc_ValueError,"setView%: wrong parameter value; must be between %d and %d", ViewFront, ViewLeft );
445 if ( !PyArg_ParseTuple( args, "l:setView", &type ) )
448 ProcessVoidEvent( new TEvent( type ) );
449 if( PyErr_Occurred() )
456 \fn PyObject* resetView();
457 \brief Reset contents of the current VTK viewer.
459 If there is no active VTK viewer, nothing happens.
461 \return nothing (Py_None)
464 extern "C" PyObject* libSalomePy_resetView( PyObject* self, PyObject* args )
466 class TEvent: public SALOME_Event
470 virtual void Execute()
472 if( SVTK_ViewWindow* aVTKViewWindow = GetVTKViewWindow( __Find ) ) {
473 aVTKViewWindow->onResetView();
478 ProcessVoidEvent( new TEvent() );
482 static PyMethodDef Module_Methods[] =
484 { "getRenderer", libSalomePy_getRenderer, METH_VARARGS },
485 { "getRenderWindow", libSalomePy_getRenderWindow, METH_VARARGS },
486 { "getRenderWindowInteractor", libSalomePy_getRenderWindowInteractor, METH_VARARGS },
487 { "showTrihedron", libSalomePy_showTrihedron, METH_VARARGS },
488 { "fitAll", libSalomePy_fitAll, METH_NOARGS },
489 { "setView", libSalomePy_setView, METH_VARARGS },
490 { "resetView", libSalomePy_resetView, METH_NOARGS },
495 \brief Python module initialization.
498 extern "C" void initlibSalomePy()
500 static char* modulename = (char*)"libSalomePy";
503 PyObject* aModule = Py_InitModule( modulename, Module_Methods );
504 if( PyErr_Occurred() ) {
509 // get module's dictionary
510 PyObject *aModuleDict = PyModule_GetDict( aModule );
511 if ( aModuleDict == NULL )
514 // export View type enumeration
515 PUBLISH_ENUM( ViewFront );
516 PUBLISH_ENUM( ViewBack );
517 PUBLISH_ENUM( ViewTop );
518 PUBLISH_ENUM( ViewBottom );
519 PUBLISH_ENUM( ViewRight );
520 PUBLISH_ENUM( ViewLeft );