Tulip  4.7.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
GlMainWidget.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef Tulip_GLMAINWIDGET_H
21 #define Tulip_GLMAINWIDGET_H
22 
23 
24 #include <QGLWidget>
25 
26 #include <tulip/tulipconf.h>
27 #include <tulip/GlScene.h>
28 #include <tulip/Graph.h>
29 
30 class QGLFramebufferObject;
31 
32 namespace tlp {
33 
34 class View;
35 class GlCompositeHierarchyManager;
36 
37 /** @ingroup OpenGL
38  * @brief This widget provide a simple system to visualize data/graph with OpenGL 3D engine
39  *
40  * This widget is an interface between Qt Widget system and tulip OpenGL engine
41  * The central object of GlMainWidget is the GlScene member
42  * @see GlScene
43  *
44  * To use this class you have to :
45  * - create a GlMainWidget
46  * - get the GlScene with getScene() function
47  * - add GlLayer and GlEntity to this scene
48  * - call centerScene() to compute a good GlCamera
49  * - see the result
50  *
51  * @see GlLayer
52  * @see GlSimpleEntity
53  *
54  *
55  * If you only want to visualize a graph, you can call the setGraph function
56  *
57  *
58  * After scene construction you can perform some operation on GlMainWidget :
59  * - Selection with doSelect() and selectGlEntities()
60  * - Image output with getImage(), createPicture(), outputSVG() and outputEPS()
61  * - Texture output with createTexture()
62  * - others operation on GlScene and QGlWidget
63  */
64 class TLP_QT_SCOPE GlMainWidget : public QGLWidget {
65  Q_OBJECT
66 
67 public:
68  /**
69  * @brief Configure the rendering process ( see render function)
70  * @see render
71  **/
73  RenderScene=0x1, /** Force to render the graph even if there is a previous buffered render. You need to call this option if the graph is updated to regenerate the buffer. If not set try to use the last buffered graph render, if there is no valid buffer this flag is forced. **/
74  SwapBuffers=0x2 /** Call the swapBuffer functions at the end of the rendering process. If the disabled it's up to you to call the swapBuffer function. **/
75  };
76  Q_DECLARE_FLAGS ( RenderingOptions, RenderingOption )
77 
78  /**
79  * @brief Constructor of GlMainWidget
80  *
81  * Create a GlMainWidget with the GlScene associated to it
82  * @param parent Qt Widget parent system
83  * @param view if you want to link this GlMainWidget to a view : use this parameter
84  */
85  GlMainWidget(QWidget *parent=NULL, View *view=NULL);
86  ~GlMainWidget();
87 
88  /**
89  * @brief Get the GlScene of this GlMainWidget
90  * You have to add yours GlLayer and GlEntity to this GlScene
91  * At the construction this GlScene is empty
92  * @see GlScene
93  * @see GlScene::createLayer(const std::string &name)
94  * @see GlLayer::addGlEntity(GlSimpleEntity *entity,const std::string& name)
95  */
96  tlp::GlScene* getScene() {
97  return &scene;
98  }
99 
100  /** @brief Select nodes and edges in a region of the screen
101  *
102  * Select all nodes and edges lying in the area of the screen of given width and height,
103  * and with its upper-left corner at (x,y)
104  * @param selectedNodes filled by the method with the nodes found in the region
105  * @param selectedEdges filled by the method with the edges found in the region
106  * @param layer specify the layer in which to perform the picking
107  * @param pickNodes enable or disable the picking of nodes
108  * @param pickEdges enable or disable the picking of edges
109  */
110  void pickNodesEdges(const int x, const int y,
111  const int width, const int height,
112  std::vector<SelectedEntity> &selectedNodes, std::vector<SelectedEntity> &selectedEdges,
113  tlp::GlLayer* layer=NULL, bool pickNodes=true, bool pickEdges=true);
114 
115  /** @brief Select a node or edge at a point
116  * Try to select at point (x,y) a node in the first place then if no result try to select an edge
117  * @param type tells what has been found: NODE, EDGE
118  * @param layer specify the layer in which to perform the picking
119  * @param pickNodes enable or disable the picking of nodes
120  * @param pickEdges enable or disable the picking of edges
121  * @return true if something has been found, false otherwise
122  */
123  bool pickNodesEdges(const int x, const int y,
124  SelectedEntity &selectedEntity,
125  tlp::GlLayer* layer=NULL,
126  bool pickNodes=true, bool pickEdges=true);
127 
128  /**
129  * @deprecated this function should not be used anymore, use pickNodesEdges()
130  */
131  _DEPRECATED void doSelect(const int x, const int y,
132  const int width, const int height,
133  std::vector<tlp::node> &sNode, std::vector<tlp::edge> &sEdge,
134  tlp::GlLayer* layer=NULL);
135 
136  /**
137  * @deprecated this function should not be used anymore, use pickNodesEdges()
138  */
139  _DEPRECATED bool doSelect(const int x, const int y,
140  tlp::ElementType &type,
141  tlp::node &n,tlp::edge &e,
142  tlp::GlLayer* layer=NULL);
143 
144  /**
145  * @brief EPS output of the GlMainWidget
146  */
147  bool outputEPS(int size, int doSort, const char *filename);
148  /**
149  * @brief SVG output of the GlMainWidget
150  */
151  bool outputSVG(int size, const char* filename);
152 
153  /**
154  * @brief Compute texture size in power of two with given height and width
155  * For example if you set width to 94 and height to 256, this function set textureRealWidth to 128 and textureRealHeight to 256
156  */
157  static void getTextureRealSize(int width, int height, int &textureRealWidth, int &textureRealHeight);
158 
159  /**
160  * @brief Take a snapshot of the Widget and put it in an OpenGl texture
161  * @param width power of two number (for example 256)
162  * @param height power of two number (for example 256)
163  * You can use this texture with Tulip texture system
164  * @see GlTextureManager
165  */
166  QGLFramebufferObject *createTexture(const std::string &textureName,int width, int height);
167  /**
168  * @brief Take a snapshot of the Widget and put it in a picture
169  * @param width size
170  * @param height size
171  * @param center if true this function call a centerScene() before picture output
172  */
173  void createPicture(const std::string &pictureName,int width, int height,bool center=true);
174 
175  /**
176  * Take a snapshot of the Widget and return it
177  * @param width size
178  * @param height size
179  * @param center if true this function call a centerScene() before picture output
180  */
181  QImage createPicture(int width, int height, bool center=true);
182 
183  /**
184  * @brief Function to do picking on entities.
185  * It just calls selectEntities on the GlScene instance.
186  * @param x screen coordinates
187  * @param y screen coordinates
188  * @param width screen size
189  * @param height screen size
190  * @param pickedEntities filled with entity under the selection screen rectangle
191  * @param layer if you want to do the selection only on one GlLayer
192  */
193  bool pickGlEntities(const int x, const int y,
194  const int width, const int height,
195  std::vector<SelectedEntity>
196  &pickedEntities,
197  tlp::GlLayer* layer=NULL);
198  /**
199  * @brief Function to do picking on entities.
200  * It just calls selectEntities on the GlScene instance with a small window of twelve pixels.
201  * @param x screen coordinates
202  * @param y screen coordinates
203  * @param pickedEntities filled with entity under the selection screen rectangle
204  * @param layer if you want to do the selection only on one GlLayer
205  */
206  bool pickGlEntities(const int x, const int y,
207  std::vector<SelectedEntity>
208  &pickedEntities,
209  tlp::GlLayer* layer=NULL);
210 
211  /**
212  * @deprecated this function should not be used anymore, please use pickGlEntities() instead.
213  */
214  _DEPRECATED bool selectGlEntities(const int x, const int y,
215  const int width, const int height,
216  std::vector<GlSimpleEntity*> &pickedEntities,
217  tlp::GlLayer* layer=NULL) {
218  std::vector<SelectedEntity> entities;
219  pickGlEntities(x,y,width,height,entities,layer);
220  bool foundEntity=false;
221 
222  for(std::vector<SelectedEntity>::iterator it=entities.begin(); it!=entities.end(); ++it) {
223  if((*it).getEntityType()==SelectedEntity::SIMPLE_ENTITY_SELECTED) {
224  pickedEntities.push_back((*it).getSimpleEntity());
225  foundEntity=true;
226  }
227  }
228 
229  return foundEntity;
230  }
231 
232  /**
233  * @deprecated this function should not be used anymore, please use pickGlEntities() instead.
234  */
235  _DEPRECATED bool selectGlEntities(const int x, const int y,
236  std::vector<GlSimpleEntity*> &pickedEntities,
237  tlp::GlLayer* layer=NULL) {
238  std::vector<SelectedEntity> entities;
239  pickGlEntities(x,y,entities,layer);
240  bool foundEntity=false;
241 
242  for(std::vector<SelectedEntity>::iterator it=entities.begin(); it!=entities.end(); ++it) {
243  if((*it).getEntityType()==SelectedEntity::SIMPLE_ENTITY_SELECTED) {
244  pickedEntities.push_back((*it).getSimpleEntity());
245  foundEntity=true;
246  }
247  }
248 
249  return foundEntity;
250  }
251 
252  /**
253  * Grab the FrameBuffer of this GlMainWidget
254  * @param withAlpha use alpha chanel
255  */
256  virtual QImage grabFrameBuffer(bool withAlpha = false);
257 
258 
259  /**
260  * Extend makeCurrent function of QGLWidget to inform TextureManager and DisplayListManager of context changement
261  */
262  virtual void makeCurrent();
263 
264  /**
265  * Resize openGL view
266  */
267  void resizeGL(int w, int h);
268 
269  /**
270  * Compute interactors before drawing
271  */
272  void computeInteractors();
273 
274  /**
275  * Draw interactors
276  */
277  void drawInteractors();
278 
279  /**
280  * @brief This function performs all the rendering process of the graph.
281  * Use this function only for advanced purpose, if you want to perform simple rendering use the draw or redraw functions instead.
282  * @param options Configure the rendering process, see the RenderingOption documentation for more information on each rendering option effect.
283  * @see RenderingOption
284  * @param checkVisibility If check visibility is set as true : the engine check if GlMainWidget QWidget is visible. If set at false : the engine render the scene in all cases
285  **/
286  void render(RenderingOptions options=RenderingOptions(RenderScene|SwapBuffers), bool checkVisibility=true);
287 
288  /**
289  * @brief Specify if the scene point of view must be kept
290  * when changing between graphs belonging to the same hierarchy
291  */
292  void setKeepScenePointOfViewOnSubgraphChanging(bool);
293  /**
294  * @brief Returns if the scene point of view must be kept
295  * when changing between graphs belonging to the same hierarchy
296  */
297  bool keepScenePointOfViewOnSubgraphChanging() const;
298 
299  /**
300  * @brief Specify if an advanced technique for better scene anti-aliasing has to be activated
301  *
302  * That option allows to obtain a better scene antialiasing through the use of offscreen rendering and sampling.
303  * The result rendering will look better while the performance will be slightly altered.
304  * That option is desactivated by default. Use it with caution as it could cause crashes with some buggy OpenGL drivers.
305  */
306  void setAdvancedAntiAliasing(bool advancedAntiAliasing) {
307  this->advancedAntiAliasing = advancedAntiAliasing;
308  }
309 
310  /**
311  * Returns the advanced anti-aliasing technique state
312  */
314  return advancedAntiAliasing;
315  }
316 
317 private:
318 
319  void setupOpenGlContext();
320  void createRenderingStore(int width, int height);
321  void deleteRenderingStore();
322 
323  tlp::GlScene scene;
324  QRegion _visibleArea;
325  View *view;
326  int widthStored;
327  int heightStored;
328  unsigned char *renderingStore;
329  bool frameBufferStored;
330  bool useFramebufferObject;
331  QGLFramebufferObject *glFrameBuf, *glFrameBuf2;
332  static bool inRendering;
333  bool keepPointOfViewOnSubgraphChanging;
334  bool advancedAntiAliasing;
335 
336 public slots:
337  /**
338  * Draw the GlScene and the interactors
339  */
340  void draw(bool graphChanged=true);
341  /**
342  * This function is given for optimisation purpose only. If the hardware enable it,
343  * it enables to redraw only the Augmented display and the interactors and not the graph
344  * it is really usefull for interactors such as zoom box etc..
345  * Warning, if you change the graph or the porperties of element (Colors, size, etc...)
346  * applying that fonction will not display the change, in that case, use the draw function.
347  */
348  void redraw();
349 
350 
351  void closeEvent(QCloseEvent *e);
352 
353  /**
354  * @brief Convenience function that call center function on the current scene, apply a zoom (if needed) and draw the view.
355  * Same thing than
356  * @code
357  * getScene()->centerScene();
358  * getScene()->zoomFactor();
359  * draw();
360  * @endcode
361  **/
362  void centerScene(bool graphChanged = false, float zoomFactor = 1.0);
363 
364  void emitGraphChanged();
365 
366 protected slots:
367  void paintEvent( QPaintEvent* );
368 
369 signals:
370  /**
371  * This signal is emit when the GlMainWidget will be deleted
372  */
373  void closing(GlMainWidget *, QCloseEvent *);
374 
375  /**
376  * This signal is emit when GlMainWidget::redraw() is call
377  */
378  void viewRedrawn(GlMainWidget *glWidget);
379  /**
380  * This signal is emit when GlMainWidget::draw() is call
381  */
382  void viewDrawn(GlMainWidget *glWidget,bool graphChanged);
383 
384  void glResized(int w,int h);
385 
386  void graphChanged();
387 
388 public :
389 
390  /**
391  * This function return the first QGLWidget created
392  * This function is use to share OpenGL context
393  */
394  static QGLWidget* getFirstQGLWidget();
395 
396  static void clearFirstQGLWidget();
397 
398 private :
399  static QGLWidget *firstQGLWidget;
400 
401 };
402 
403 }
404 
405 
406 #endif
bool selectGlEntities(const int x, const int y, std::vector< GlSimpleEntity * > &pickedEntities, tlp::GlLayer *layer=NULL)
Definition: GlMainWidget.h:235
bool advancedAntiAliasingActivated() const
Definition: GlMainWidget.h:313
void setAdvancedAntiAliasing(bool advancedAntiAliasing)
Specify if an advanced technique for better scene anti-aliasing has to be activated.
Definition: GlMainWidget.h:306
ElementType
Definition: Graph.h:46
Tulip scene class.
Definition: GlScene.h:153
The edge struct represents an edge in a Graph object.
Definition: Edge.h:39
The node struct represents a node in a Graph object.
Definition: Node.h:39
bool selectGlEntities(const int x, const int y, const int width, const int height, std::vector< GlSimpleEntity * > &pickedEntities, tlp::GlLayer *layer=NULL)
Definition: GlMainWidget.h:214
View plugins provide a way to dynamically add to a Tulip plateform various ways to visualize a graph...
Definition: View.h:73
Structure to store selected entities.
Definition: GlScene.h:47
RenderingOption
Configure the rendering process ( see render function)
Definition: GlMainWidget.h:72
A GlLayer is like an 2D drawing software layer system.
Definition: GlLayer.h:51
This widget provide a simple system to visualize data/graph with OpenGL 3D engine.
Definition: GlMainWidget.h:64