Tulip  4.10.0
Better Visualization Through Research
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 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
26 #include <QWindow>
27 #endif
28 
29 #include <tulip/tulipconf.h>
30 #include <tulip/GlScene.h>
31 #include <tulip/Graph.h>
32 
33 class QGLFramebufferObject;
34 
35 namespace tlp {
36 
37 class View;
38 class GlCompositeHierarchyManager;
39 
40 /** @ingroup OpenGL
41  * @brief This widget provide a simple system to visualize data/graph with OpenGL 3D engine
42  *
43  * This widget is an interface between Qt Widget system and tulip OpenGL engine
44  * The central object of GlMainWidget is the GlScene member
45  * @see GlScene
46  *
47  * To use this class you have to :
48  * - create a GlMainWidget
49  * - get the GlScene with getScene() function
50  * - add GlLayer and GlEntity to this scene
51  * - call centerScene() to compute a good GlCamera
52  * - see the result
53  *
54  * @see GlLayer
55  * @see GlSimpleEntity
56  *
57  *
58  * If you only want to visualize a graph, you can call the setGraph function
59  *
60  *
61  * After scene construction you can perform some operation on GlMainWidget :
62  * - Selection with doSelect() and selectGlEntities()
63  * - Image output with getImage(), createPicture(), outputSVG() and outputEPS()
64  * - Texture output with createTexture()
65  * - others operation on GlScene and QGlWidget
66  */
67 class TLP_QT_SCOPE GlMainWidget : public QGLWidget {
68  Q_OBJECT
69 
70 public:
71  /**
72  * @brief Configure the rendering process ( see render function)
73  * @see render
74  **/
76  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. **/
77  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. **/
78  };
79  Q_DECLARE_FLAGS ( RenderingOptions, RenderingOption )
80 
81  /**
82  * @brief Constructor of GlMainWidget
83  *
84  * Create a GlMainWidget with the GlScene associated to it
85  * @param parent Qt Widget parent system
86  * @param view if you want to link this GlMainWidget to a view : use this parameter
87  */
88  GlMainWidget(QWidget *parent=NULL, View *view=NULL);
89  ~GlMainWidget();
90 
91  /**
92  * @brief Get the GlScene of this GlMainWidget
93  * You have to add yours GlLayer and GlEntity to this GlScene
94  * At the construction this GlScene is empty
95  * @see GlScene
96  * @see GlScene::createLayer(const std::string &name)
97  * @see GlLayer::addGlEntity(GlSimpleEntity *entity,const std::string& name)
98  */
99  tlp::GlScene* getScene() {
100  return &scene;
101  }
102 
103  /** @brief Select nodes and edges in a region of the screen
104  *
105  * Select all nodes and edges lying in the area of the screen of given width and height,
106  * and with its upper-left corner at (x,y)
107  * @param selectedNodes filled by the method with the nodes found in the region
108  * @param selectedEdges filled by the method with the edges found in the region
109  * @param layer specify the layer in which to perform the picking
110  * @param pickNodes enable or disable the picking of nodes
111  * @param pickEdges enable or disable the picking of edges
112  */
113  void pickNodesEdges(const int x, const int y,
114  const int width, const int height,
115  std::vector<SelectedEntity> &selectedNodes, std::vector<SelectedEntity> &selectedEdges,
116  tlp::GlLayer* layer=NULL, bool pickNodes=true, bool pickEdges=true);
117 
118  /** @brief Select a node or edge at a screen point
119  * Try to select at point (x,y) a node in the first place then if no result try to select an edge
120  * @param type tells what has been found: NODE, EDGE
121  * @param layer specify the layer in which to perform the picking
122  * @param pickNodes enable or disable the picking of nodes
123  * @param pickEdges enable or disable the picking of edges
124  * @return true if something has been found, false otherwise
125  */
126  bool pickNodesEdges(const int x, const int y,
127  SelectedEntity &selectedEntity,
128  tlp::GlLayer* layer=NULL,
129  bool pickNodes=true, bool pickEdges=true);
130 
131  /**
132  * @deprecated this function should not be used anymore, use pickNodesEdges()
133  */
134  _DEPRECATED void doSelect(const int x, const int y,
135  const int width, const int height,
136  std::vector<tlp::node> &sNode, std::vector<tlp::edge> &sEdge,
137  tlp::GlLayer* layer=NULL);
138 
139  /**
140  * @deprecated this function should not be used anymore, use pickNodesEdges()
141  */
142  _DEPRECATED bool doSelect(const int x, const int y,
143  tlp::ElementType &type,
144  tlp::node &n,tlp::edge &e,
145  tlp::GlLayer* layer=NULL);
146 
147 
148  /**
149  * @brief convert a screen measure into a viewport measure
150  * @param a measure in screen coordinates specified as an integer
151  * @return the converted measure in viewport coordinates as an integer
152  */
153  int screenToViewport(int l) {
154 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
155  return l * windowHandle()->devicePixelRatio();
156 #else
157  return l;
158 #endif
159  }
160 
161  /**
162  * @brief convert a screen measure into a viewport measure
163  * @param a measure in screen coordinates specified as a double
164  * @return the converted measure in viewport coordinates as a double
165  */
166  double screenToViewport(double l) {
167 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
168  return l * windowHandle()->devicePixelRatio();
169 #else
170  return l;
171 #endif
172  }
173 
174  /**
175  * @brief convert a screen point into a viewport point
176  * @param a point in screen coordinates
177  * @return the converted point in viewport coordinates
178  */
179  Coord screenToViewport(Coord point) {
180 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
181  qreal dpr = windowHandle()->devicePixelRatio();
182  point.setX(point.x() * dpr);
183  point.setY(point.y() * dpr);
184 #endif
185  return point;
186  }
187 
188  /**
189  * @brief convert a viewport measure into a screen measure
190  * @param a measure in viewport coordinates specified as a double
191  * @return the converted measure in screen coordinates as a double
192  */
193  double viewportToScreen(double l) {
194 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
195  return l / windowHandle()->devicePixelRatio();
196 #else
197  return l;
198 #endif
199  }
200 
201  /**
202  * @brief convert a viewport point into a screen point
203  * @param a point in viewport coordinates
204  * @return the converted point in screen coordinates
205  */
206  Coord viewportToScreen(Coord point) {
207 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
208  qreal dpr = windowHandle()->devicePixelRatio();
209  point.setX(point.x() / dpr);
210  point.setY(point.y() / dpr);
211 #endif
212  return point;
213  }
214 
215  /**
216  * @brief EPS output of the GlMainWidget
217  */
218  bool outputEPS(int size, int doSort, const char *filename);
219  /**
220  * @brief SVG output of the GlMainWidget
221  */
222  bool outputSVG(int size, const char* filename);
223 
224  /**
225  * @brief Compute texture size in power of two with given height and width
226  * For example if you set width to 94 and height to 256, this function set textureRealWidth to 128 and textureRealHeight to 256
227  */
228  static void getTextureRealSize(int width, int height, int &textureRealWidth, int &textureRealHeight);
229 
230  /**
231  * @brief Take a snapshot of the Widget and put it in an OpenGl texture
232  * @param width power of two number (for example 256)
233  * @param height power of two number (for example 256)
234  * You can use this texture with Tulip texture system
235  * @see GlTextureManager
236  */
237  QGLFramebufferObject *createTexture(const std::string &textureName,int width, int height);
238  /**
239  * @brief Take a snapshot of the Widget and put it in a picture
240  * @param width size
241  * @param height size
242  * @param center if true this function call a centerScene() before picture output
243  */
244  void createPicture(const std::string &pictureName,int width, int height,bool center=true);
245 
246  /**
247  * Take a snapshot of the Widget and return it
248  * @param width size
249  * @param height size
250  * @param center if true this function call a centerScene() before picture output
251  */
252  QImage createPicture(int width, int height, bool center=true);
253 
254  /**
255  * @brief Function to do picking on entities in a screen region
256  * It just calls selectEntities on the GlScene instance.
257  * @param x screen coordinates
258  * @param y screen coordinates
259  * @param width screen size
260  * @param height screen size
261  * @param pickedEntities filled with entity under the selection screen rectangle
262  * @param layer if you want to do the selection only on one GlLayer
263  */
264  bool pickGlEntities(const int x, const int y,
265  const int width, const int height,
266  std::vector<SelectedEntity>
267  &pickedEntities,
268  tlp::GlLayer* layer=NULL);
269  /**
270  * @brief Function to do picking on entities.
271  * It just calls selectEntities on the GlScene instance with a small window of twelve pixels.
272  * @param x screen coordinates
273  * @param y screen coordinates
274  * @param pickedEntities filled with entity under the selection screen rectangle
275  * @param layer if you want to do the selection only on one GlLayer
276  */
277  bool pickGlEntities(const int x, const int y,
278  std::vector<SelectedEntity>
279  &pickedEntities,
280  tlp::GlLayer* layer=NULL);
281 
282  /**
283  * @deprecated this function should not be used anymore, please use pickGlEntities() instead.
284  */
285  _DEPRECATED bool selectGlEntities(const int x, const int y,
286  const int width, const int height,
287  std::vector<GlSimpleEntity*> &pickedEntities,
288  tlp::GlLayer* layer=NULL) {
289  std::vector<SelectedEntity> entities;
290  pickGlEntities(x,y,width,height,entities,layer);
291  bool foundEntity=false;
292 
293  for(std::vector<SelectedEntity>::iterator it=entities.begin(); it!=entities.end(); ++it) {
294  if((*it).getEntityType()==SelectedEntity::SIMPLE_ENTITY_SELECTED) {
295  pickedEntities.push_back((*it).getSimpleEntity());
296  foundEntity=true;
297  }
298  }
299 
300  return foundEntity;
301  }
302 
303  /**
304  * @deprecated this function should not be used anymore, please use pickGlEntities() instead.
305  */
306  _DEPRECATED bool selectGlEntities(const int x, const int y,
307  std::vector<GlSimpleEntity*> &pickedEntities,
308  tlp::GlLayer* layer=NULL) {
309  std::vector<SelectedEntity> entities;
310  pickGlEntities(x,y,entities,layer);
311  bool foundEntity=false;
312 
313  for(std::vector<SelectedEntity>::iterator it=entities.begin(); it!=entities.end(); ++it) {
314  if((*it).getEntityType()==SelectedEntity::SIMPLE_ENTITY_SELECTED) {
315  pickedEntities.push_back((*it).getSimpleEntity());
316  foundEntity=true;
317  }
318  }
319 
320  return foundEntity;
321  }
322 
323  /**
324  * Grab the FrameBuffer of this GlMainWidget
325  * @param withAlpha use alpha chanel
326  */
327  virtual QImage grabFrameBuffer(bool withAlpha = false);
328 
329 
330  /**
331  * Extend makeCurrent function of QGLWidget to inform TextureManager and DisplayListManager of context changement
332  */
333  virtual void makeCurrent();
334 
335  /**
336  * Resize openGL view
337  */
338  void resizeGL(int w, int h);
339 
340  /**
341  * Compute interactors before drawing
342  */
343  void computeInteractors();
344 
345  /**
346  * Draw interactors
347  */
348  void drawInteractors();
349 
350  /**
351  * @brief This function performs all the rendering process of the graph.
352  * Use this function only for advanced purpose, if you want to perform simple rendering use the draw or redraw functions instead.
353  * @param options Configure the rendering process, see the RenderingOption documentation for more information on each rendering option effect.
354  * @see RenderingOption
355  * @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
356  **/
357  void render(RenderingOptions options=RenderingOptions(RenderScene|SwapBuffers), bool checkVisibility=true);
358 
359  /**
360  * @brief Specify if the scene point of view must be kept
361  * when changing between graphs belonging to the same hierarchy
362  */
363  void setKeepScenePointOfViewOnSubgraphChanging(bool);
364  /**
365  * @brief Returns if the scene point of view must be kept
366  * when changing between graphs belonging to the same hierarchy
367  */
368  bool keepScenePointOfViewOnSubgraphChanging() const;
369 
370  /**
371  * @brief Specify if an advanced technique for better scene anti-aliasing has to be activated
372  *
373  * That option allows to obtain a better scene antialiasing through the use of offscreen rendering and sampling.
374  * The result rendering will look better while the performance will be slightly altered.
375  * That option is desactivated by default. Use it with caution as it could cause crashes with some buggy OpenGL drivers.
376  */
377  void setAdvancedAntiAliasing(bool advancedAntiAliasing) {
378  this->advancedAntiAliasing = advancedAntiAliasing;
379  }
380 
381  /**
382  * Returns the advanced anti-aliasing technique state
383  */
385  return advancedAntiAliasing;
386  }
387 
388 private:
389 
390  void setupOpenGlContext();
391  void createRenderingStore(int width, int height);
392  void deleteRenderingStore();
393 
394  tlp::GlScene scene;
395  QRegion _visibleArea;
396  View *view;
397  int widthStored;
398  int heightStored;
399  unsigned char *renderingStore;
400  bool frameBufferStored;
401  bool useFramebufferObject;
402  QGLFramebufferObject *glFrameBuf, *glFrameBuf2;
403  static bool inRendering;
404  bool keepPointOfViewOnSubgraphChanging;
405  bool advancedAntiAliasing;
406 
407 public slots:
408  /**
409  * Draw the GlScene and the interactors
410  */
411  void draw(bool graphChanged=true);
412  /**
413  * This function is given for optimisation purpose only. If the hardware enable it,
414  * it enables to redraw only the Augmented display and the interactors and not the graph
415  * it is really usefull for interactors such as zoom box etc..
416  * Warning, if you change the graph or the porperties of element (Colors, size, etc...)
417  * applying that fonction will not display the change, in that case, use the draw function.
418  */
419  void redraw();
420 
421 
422  void closeEvent(QCloseEvent *e);
423 
424  /**
425  * @brief Convenience function that call center function on the current scene, apply a zoom (if needed) and draw the view.
426  * Same thing than
427  * @code
428  * getScene()->centerScene();
429  * getScene()->zoomFactor();
430  * draw();
431  * @endcode
432  **/
433  void centerScene(bool graphChanged = false, float zoomFactor = 1.0);
434 
435  void emitGraphChanged();
436 
437 protected slots:
438  void paintEvent( QPaintEvent* );
439 
440 signals:
441  /**
442  * This signal is emit when the GlMainWidget will be deleted
443  */
444  void closing(GlMainWidget *, QCloseEvent *);
445 
446  /**
447  * This signal is emit when GlMainWidget::redraw() is call
448  */
449  void viewRedrawn(GlMainWidget *glWidget);
450  /**
451  * This signal is emit when GlMainWidget::draw() is call
452  */
453  void viewDrawn(GlMainWidget *glWidget,bool graphChanged);
454 
455  void glResized(int w,int h);
456 
457  void graphChanged();
458 
459 public :
460 
461  /**
462  * This function return the first QGLWidget created
463  * This function is use to share OpenGL context
464  */
465  static QGLWidget* getFirstQGLWidget();
466 
467  static void clearFirstQGLWidget();
468 
469 private :
470  static QGLWidget *firstQGLWidget;
471 
472 };
473 
474 }
475 
476 
477 #endif
Coord screenToViewport(Coord point)
convert a screen point into a viewport point
Definition: GlMainWidget.h:179
double viewportToScreen(double l)
convert a viewport measure into a screen measure
Definition: GlMainWidget.h:193
bool selectGlEntities(const int x, const int y, std::vector< GlSimpleEntity * > &pickedEntities, tlp::GlLayer *layer=NULL)
Definition: GlMainWidget.h:306
bool advancedAntiAliasingActivated() const
Definition: GlMainWidget.h:384
void setAdvancedAntiAliasing(bool advancedAntiAliasing)
Specify if an advanced technique for better scene anti-aliasing has to be activated.
Definition: GlMainWidget.h:377
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:285
double screenToViewport(double l)
convert a screen measure into a viewport measure
Definition: GlMainWidget.h:166
Coord viewportToScreen(Coord point)
convert a viewport point into a screen point
Definition: GlMainWidget.h:206
View plugins provide a way to dynamically add to a Tulip plateform various ways to visualize a graph...
Definition: View.h:73
int screenToViewport(int l)
convert a screen measure into a viewport measure
Definition: GlMainWidget.h:153
Structure to store selected entities.
Definition: GlScene.h:47
RenderingOption
Configure the rendering process ( see render function)
Definition: GlMainWidget.h:75
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:67