]> SALOME platform Git repositories - modules/paravis.git/blob - doc/dev/index.rst
Salome HOME
Update documentation: PARAVIS_OPTIONS environment variable was removed to PARAVIEW_OP...
[modules/paravis.git] / doc / dev / index.rst
1
2 PARAVIS Module - Architecture and conception
3 ############################################
4
5 *This documentation is intended for SALOME's developpers or anyone wishing to modify the module itself.
6 If you are looking for user documentation, please launch SALOME, activate the PARAVIS module, and refer 
7 to the Help menu there.*
8
9 PARAVIS is the visualization module of SALOME. The module is a tight integration of the functionalities
10 offered by ParaView in the SALOME architecture.
11 The architecture of the PARAVIS module has been revised end of 2014 to offer a smoother integration with ParaView.
12
13 If you are looking for the Doxygen of the C++ code, it can be found here: `Doxygen documentation <api/index.html>`_
14
15 Overview - Executive summary
16 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
17
18 The PARAVIS module represents the integration of ParaView inside SALOME.
19
20 SALOME uses by default the *detached* server mode of ParaView: the ``pvserver`` is launched outside the main Salome process
21 and the ParaVis module, or the PVViewer view (Window -> ParaView view) connects to it.
22
23 Following this logic, the PVSERVER CORBA service has a very restrained role. Its only purpose is to:
24
25 * control the start and stop of the pvserver process
26 * provide the URL of the pvserver, so that a client can connect to it.
27
28 Hence, we emphazise the fact that the CORBA engine does *not* provide any access to the objects or the visualisation 
29 results themselves. It only serves to establish the link with the ``pvserver``. The latter can then be queried (with 
30 the standard ParaView mechanisms) to retrieve those objects.   
31
32 A typical session looks like this:
33
34 * start SALOME's GUI
35 * request activation of PARAVIS (or request activation of a *Paraview's View*)
36         * activation of the PVSERVER CORBA service
37         * invokation of the method ``FindOrStartPVServer()``: launches the pvserver process and returns its URL
38           (in the standard ParaView's format, e.g. ``cs://localhost:11111``)
39         * invokation of the standard ParaView's API to connect to the pvserver (e.g. ``Connect()`` method in the 
40           Python module ``paraview.simple``)
41 * use the standard ParaView's API to interact with the server (either from the C++ side, within SALOME's GUI
42   or from a Python script, using for example the methods provided in the Python module ``pvsimple``). 
43
44 The picture below summarizes the architecture:
45
46 .. image:: images/archi.jpg
47         :scale: 70
48
49 In terms of code structure, the main, all the initialization logic of ParaView is attached to the ``PVViewer``
50 (ParaView's viewer) located in the GUI module in the **src/PVViewer** folder. 
51 The CORBA engine and the graphical interface of the ParaVis module are located in the ParaVis module of SALOME.
52
53 Functionalities
54 %%%%%%%%%%%%%%%
55
56 The following functionalities are offered by the PVSERVER and the ParaVis module:
57
58 * full embedding of ParaView's functionalities inside SALOME environment
59 * manage ParaVis GUI and ParaView server data from Python scripts in synchronized mode.
60 * compatibility of the Python scripting interface with the ``paraview.simple`` and the ``paraview.servermanager`` 
61   modules.
62
63 Folder structure
64 %%%%%%%%%%%%%%%%
65
66 ParaVis module
67 ==============
68
69 In the ParaVis module, here is the list of code folders:
70
71 * **idl**: contains the IDL for the PVSERVER CORBA service
72 * **src/ENGINE**: implementation of the IDL's functionalities in Python. Mainly deal with the start/stop of the pvserver
73 * **src/Plugins**: SALOME's specific plugins for ParaView: MEDReader, etc ...
74 * **src/PVGUI**: graphical elements constituing the ParaVis client in the SALOME GUI. Management of the menus, the toolbars,
75   etc ... seen in PARAVIS interface.
76 * **src/PV_SWIG**: Python modules to be able to invoke visualization functionalities from a script
77
78 At the time of writing the PVSERVER CORBA service is sitll hosted by the ParaVis module, but it should move to GUI
79 to be able to compile GUI without any dependency to PARAVIS. At present, this is only a weak dependency in the sense
80 that nothing is needed at link time, but only at run-time. 
81
82 GUI module
83 ==========
84
85 One can request a ParaView view without activating the ParaVis module itself. For example the MED module now integrates
86 a control visualization which is in fact a ParaView view.
87
88 To make this work, a specific type of viewer (*PVViewer*, short for ParaView viewer) has been created in the GUI module itself.
89 The code is located in **src/PVViewer**. 
90
91 This folder contains the following classes:
92
93 * ``PVViewer_Behaviors``: re-instanciates the desired ParaView behaviors (a behavior defines for example the fact that ParaView
94   should automatically reconnect to the server if a disconnection occurs) 
95 * ``PVViewer_EngineWrapper``: encapsulates the calls to the PVSERVER CORBA service in a dynamic fashion, so that GUI can be
96   compiled without having a link dependency to the ParaVis module 
97 * ``PVViewer_GUIElements``: see :ref:`view_part`
98 * ``PVViewer_LogWindowAdapter``: an adapter to redirect VTK and ParaView's output messages to the SALOME's message 
99   window (not working?)
100
101 The folder also contain the adaptor classes needed to make the ParaView 
102 native 3D view (a ``pqTabbedMultiViewWidget``) fit into the *SUIT*
103 model (i.e. the model imposed by SALOME's GUI architecture to define a new type of view):
104
105 * ``PVViewer_ViewManager``: this class centralizes all the initialization logic (see method ``ParaviewInitApp``) of the
106   ParaView application (``pqCoreApplication``).
107 * ``PVViewer_ViewModel``
108 * ``PVViewer_ViewWindow``
109  
110
111 Reminder about ParaView's architecture
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113
114 ParaView works in a client/server mode. In two words, a server part (the ``pvserver``) takes care of the 'intensive' 
115 computations (filter, etc ...) and a client part serves to control this server, and obviously visualize the final rendering.  
116
117 The ``pvserver`` represents the main visualisation server, and can be either:
118
119 * *built-in*, in which case, launching ParaView suffices to activate it automatically; 
120 * *detached*, in which case, one has to launch the server first (possibly on another host) and then connect
121   to it from a client.
122
123 The various types of clients are:
124
125 * either the standard ParaView GUI (where the name and type of the current server can be 
126   seen by looking at the top element in the pipeline widget)
127 * or a Python script, using for example the module ``paraview.simple`` and the ``Connect()`` method. 
128
129 Historically the pvserver was not able to receive the connections from multiple clients, but this has been changed from 
130 ParaView 4.0 (or was it 3.98?). Salome now exploits this feature.
131
132 .. _view_part:
133
134 Viewer part (in GUI module)
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%
136
137 In the GUI module of SALOME, the folder **src/PVViewer** contains all the code needed to activate a minimal ParaView
138 3D view, without activating the ParaVis module itself. 
139 This folder hence deals with:
140
141 * the initialization of the ParaView application (``pqApplicationCore``)
142 * the initialization of ParaView's desired behaviors (class ``PVViewer_GUIElements``)
143 * the initialization of all the GUI elements needed for a later activation of the ParaVis interface: at the time of 
144   writing the pipeline, some menus, and other elements are very hard to connect *after* having set up a 3D view. They are
145   however not wanted when the user just requested a 3D view, outside the ParaVis interface. We hence create those elements
146   any way, but hide them, so that we can later show them again, once the ParaVis module is activated.
147   The class ``PVViewer_GUIElements`` is in charge of this.
148
149 The PVViewer follows otherwise the standard structure of a Salome's view (SUIT model).
150
151 A special trick is used to make ``PVGUI_ViewWindow`` the parent of the ``pqViewManager`` widget. 
152 It is created initally by ``pqMainWindowCore`` 
153 with the desktop as a parent, so when it is shown, a ``PVGUI_ViewWindow`` instance is passed to its ``setParent()`` method. 
154 In the destructor ``PVGUI_ViewWindow::~PVGUI_ViewWindow()``the parent is nullified to avoid deletion
155 of the ``pqViewManager`` widget (that would break the ``pqMainWindowCore`` class).
156
157
158 ParaVis graphical interface
159 %%%%%%%%%%%%%%%%%%%%%%%%%%%
160
161 The initialization of the viewer (see previous section) takes part of instantiating the most important widgets, notably:
162
163 * the pipeline
164 * the dynamic menus (filters and sources)
165 * the macros
166 * the Properties panel
167 * and finally the toolbars
168
169 All those menus are dynamic in the sense that they are automatically populated when a plugin/a configuration is loaded
170 (this is also they need to be connected so early by the ``PVViewer_GUIElements`` class seen before).
171
172 In the ParaVis module, the class ``PVGUI_Module`` represents the GUI client compliant with the usual architecture of
173 a SALOME GUI module. The implementation is split in three ``cxx`` files:
174
175 * ``PVGUI_Module.cxx``: core stuff: module initialization and activation, management of the Python trace, etc ...
176 * ``PVGUI_Module_actions.cxx``: creation of the Qt actions and menus
177 * ``PVGUI_Module_widgets.cxx``: hide/show various widgets and save/restore their positions in the main window. 
178
179 Embedded Python interpreter - Multi-threading
180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181
182 ParaView is a mono-threaded application. It also provides an embedded Python interpreter to make the Python shell work.
183 SALOME on the other hand is multi-threaded, and also provides an embedded Python's interpreter.
184
185 Making the two work together has often been (and still is) a painful job! 
186 If you run into this sort of problems, take a look at what the GIL is: 
187 `Global Interpreter Lock <https://wiki.python.org/moin/GlobalInterpreterLock>`_  
188
189 In Salome, the current setup is to:
190
191 * patch ParaView itself so that all calls to the Python C API are GIL safe (using ``PyGILState_Ensure``, ``PyGILState_Release``)
192 * have Salome's embedded Python console work in mono-threaded mode (although it is fully capable of being asynchronous).
193   This is achieved in ``src/PyConsole/PyConsole_Editor.cxx`` and the initialization of the ``myIsSync`` boolean member to ``True``. 
194
195 **The last point is of crucial importance**: it basically means that all the GUI events are in a single thread.
196 Even without considering 
197
198 All the calls to the Python API in the rest of SALOME are (should be!) GIL safe.
199
200 The ParaView Python's trace mechanism has long been a problem, but has fortunately been rationalized thanks to the API of
201 ParaView providing clear methods to control the start/stop (and other options of the trace). 
202 This is grouped in the ``ParaViewCore/ServerManager/Core/vtkSMTrace`` class and used in the 
203 method ``PVGUI_Module::startTrace()``.
204
205 Python modules
206 %%%%%%%%%%%%%%
207 The modules found in **src/PV_SWIG** are mostly simple namespace forwards from the original ParaView's modules (i.e. they
208 redirect to the original modules):
209
210 * ``pvsimple`` is a forward of ``paraview.simple`` with little extra functionalities to make sure:
211         * the connection to the correct PVSERVER is automatically established
212         * that a ParaView's view is available when importing the module from the embedded Python console.  
213 * ``paravisSM`` is a forward of ``paraview.servermanager``. It is left mostly for backward compatibility (it used to be
214   full of nasty overrides).  
215
216 Those forward/similarities are naturally intended so that a script written for pure ParaView can easily be ported 
217 to ParaVis. The conversion boils down to replacing ``import paraview.simple`` by ``impory pvsimple`` (with a few other
218 extra details of lesser importance).
219
220 Updating to a newer ParaView version
221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222
223 The following items should be revised each time an upgrade to a newer ParaView version is done.
224 They are often a copy/paste of ParaView's source code with a slight amendment to fit SALOME's requirements.
225
226 * *initialization sequence*: currently located in GUI module, ``PVViewer_ViewManager::ParaViewInitApp()``: the following
227   classes should be inspected, and compared with their equivalent in ParaView source code to see if an update is necessary:
228         * ``PVViewer_ViewManager`` (GUI module): method ``ParaviewInitApp()``, ``ParaviewInitBehaviors()``, ``ParaviewLoadConfigurations()``
229           and finally ``ConnectToExternalPVServer()`` should be re-read. Their precise ordering is used in ``PVGUI_Module::initialize()``
230           and the whole sequence should be compared with what can be found in:
231                 * ``Applications/ParaView/ParaViewMainWindow.cxx``
232                 * ``CMake/branded_paraview_initializer.cxx.in``, and the method ``Initialize()``
233         * ``PVViewer_Behaviors`` (GUI module): compare with ``Qt/ApplicationComponents/pqParaViewBehaviors.cxx``
234 * *menus and actions*: ``PVGUI_Module_widgets.cxx`` (ParaVis module) should be compared with ``Applications/ParaView/ParaViewMainWindow.cxx``
235 * *toolbars*: ``PVViewer_GUIElements::myBuildToolbars()`` (GUI module): compare with ``pqParaViewMenuBuilders::buildToolbars()``
236 * *dock widgets placement*: ``PVGUI_Module::setupDockWidgets()`` (ParaVis module): compare with ``Application/Paraview/ParaviewMainWindow.ui``
237 * *settings dialog box*: ``PVGUI_ParaViewSettingsPane`` (ParaVis module) should be compared with ``Qt/Components/pqSettingsDialog.h``
238 * *trace mechanism*: method ``PVGUI_Module::startTrace()`` should be compared with ``pqTraceReaction::start()`` in file 
239   ``Qt/ApplicationComponents/pqTraceReaction.h``
240
241 Miscellaneous
242 %%%%%%%%%%%%%
243
244 **Trace management**
245
246 Contrary to ParaView, which can start/stop its trace at any moment, in PARAVIS the trace is activated
247 or deactivated for the whole session.
248
249 The trace functionality can be switched on/off in SALOME preferences dialog box, in the PARAVIS tab (main menu | Preferences...).
250 It contains a check box “Deactivate Trace”. By default the trace is activated. 
251 Change of check box state makes effect only for next session.
252
253 Also, the trace is used for the "Dump Study" functionality. But if the tracing is switched off then the "Dump Study" 
254 doesn't save PARAVIS module trace.
255
256 **Application options**
257
258 If it is necessary to define a spcific command line parameter for ParaView application,
259 then it can be defined with the help of the PARAVIEW_OPTIONS environment variable. For example: ::
260
261         export PARAVIEW_OPTIONS=--server=myServer
262
263 If it is necessary to define several command line parameters, these parameters have to be separated by the “:” character.
264
265
266 Various TODO
267 %%%%%%%%%%%%
268
269 * make the PVSERVER a true CORBA service not linked to the PARAVIS module
270 * the PARAVIS module should be a *light* module (TODO check again why this is blocking). 
271
272 Doxygen documentation
273 %%%%%%%%%%%%%%%%%%%%%
274
275 If you are looking for the Doxygen of the C++ code, it can be found here: `Doxygen documentation <api/index.html>`_