Tulip  5.2.0
Large graphs analysis and drawing
GlScene.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
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_GLSCENE_H
21 #define Tulip_GLSCENE_H
22 
23 #include <tulip/tulipconf.h>
24 #include <tulip/GlLODCalculator.h>
25 #include <tulip/GlLayer.h>
26 #include <tulip/Color.h>
27 #include <tulip/Observable.h>
28 
29 namespace tlp {
30 
31 class GlSimpleEntity;
32 class Graph;
33 class GlLODCalculator;
34 class GlGraphComposite;
35 
36 /**
37  * @ingroup OpenGL
38  * @brief Structure to store selected entities
39  *
40  * After a selection, objects of SelectedEntity is returned
41  * To use this object the first thing to do is to call getEntity type to know the type of Entity
42  * After that you can :
43  * - Get the GlSimpleEnity pointer (getSimpleEntity())
44  * - Get the id of node/edge and the graph associated (getComplexEntityId() and
45  * getComplexEntityGraph())
46  *
47  */
49 
50  enum SelectedEntityType {
51  UNKNOW_SELECTED = 0,
52  NODE_SELECTED = 1,
53  EDGE_SELECTED = 2,
54  SIMPLE_ENTITY_SELECTED = 3
55  };
56 
58  : simpleEntity(nullptr), complexEntityId(uint(-1)), entityType(UNKNOW_SELECTED),
59  complexEntityGraph(nullptr) {}
61  : simpleEntity(entity), complexEntityId(uint(-1)), entityType(SIMPLE_ENTITY_SELECTED),
62  complexEntityGraph(nullptr) {}
63  SelectedEntity(Graph *graph, unsigned int id, SelectedEntityType type)
64  : simpleEntity(nullptr), complexEntityId(id), entityType(type), complexEntityGraph(graph) {}
65 
66  GlSimpleEntity *getSimpleEntity() const {
67  assert(simpleEntity != nullptr);
68  return simpleEntity;
69  }
70 
71  unsigned int getComplexEntityId() const {
72  assert(complexEntityId != uint(-1));
73  return complexEntityId;
74  }
75 
76  Graph *getComplexEntityGraph() const {
77  assert(complexEntityGraph != nullptr);
78  return complexEntityGraph;
79  }
80 
81  SelectedEntityType getEntityType() const {
82  return entityType;
83  }
84  /**
85  * @brief getNode is a convenience method to perform the check on the selected element type and
86  * return the corresponding node object. It's equivalent to
87  * @code
88  * if(getComplexEntityType()==NODE_SELECTED){
89  * return node(getComplexEntityId())
90  * }
91  * @endcode
92  * @return the selected node if the entity type is correct or an invalid node else.
93  */
94  node getNode() const {
95  if (entityType == NODE_SELECTED) {
96  return node(complexEntityId);
97  } else {
98  return node();
99  }
100  }
101 
102  /**
103  * @brief getEdge is a convenience method to perform the check on the selected element type and
104  * return the corresponding edge object. It's equivalent to
105  * @code
106  * if(getComplexEntityType()==EDGE_SELECTED){
107  * return edge(getComplexEntityId())
108  * }
109  * @endcode
110  * @return the selected edge if the entity type is correct or an invalid edge else.
111  */
112  edge getEdge() const {
113  if (entityType == EDGE_SELECTED) {
114  return edge(complexEntityId);
115  } else {
116  return edge();
117  }
118  }
119 
120 protected:
121  GlSimpleEntity *simpleEntity;
122  unsigned int complexEntityId;
123  SelectedEntityType entityType;
124  Graph *complexEntityGraph;
125 };
126 
127 /**
128  * @ingroup OpenGL
129  * @brief Tulip scene class
130  *
131  * The GlScene class is the core of the tulip rendering system
132  * This class is used to render entities and graph in OpenGL
133  *
134  * If you want to render entities and graph, you have to use GlLayer system. You just have to create
135  * GlLayer and add GlEntity in.
136  * If you create more than one GlLayer, layers are rendered one after one, so the first GlLayer
137  * added is rendered in first.
138  * @see GlLayer
139  * @see GlSimpleEntity
140  *
141  *
142  * After adding layers you can do a centerScene() and a draw()
143  *
144  * \code
145  * GlLayer *mainLayer=new GlLayer("Main");
146  * GlGraphComposite *graphComposite=new GlGraphComposite(graph);
147  * mainLayer->addGlEntity(graphComposite,"graph");
148  * GlLayer *otherLayer=new GlLayer("Other");
149  * GlCircle *circle=new GlCircle();
150  * otherLayer->addGlEntity(circle,"circle");
151  * glScene.addLayer(mainLayer);
152  * glScene.addLayer(otherLayer);
153  * glScene.centerScene();
154  * glScene.draw();
155  * \endcode
156  *
157  * If you want to create a widget with a visualisation is better to use GlMainWidget class (this
158  * class use a GlScene inside)
159  */
160 class TLP_GL_SCOPE GlScene : public Observable {
161 
162 public:
163  /** \brief Constructor
164  * Default scene is empty
165  * @param calculator By default GlScene use a GlCPULODCalculator to compute LOD but you can change
166  * this default lod calculator, to do that : put your calculator in constructor parameters
167  * Available calculators are : GlCPULODCalculator and GlQuadTreeLODCalculator
168  */
169  GlScene(GlLODCalculator *calculator = nullptr);
170 
171  ~GlScene() override;
172 
173  /**
174  * @brief Init scene's OpenGL parameters.
175  * You don't have to call this function, it is call when you do a draw
176  */
177  void initGlParameters();
178 
179  /**
180  * @brief Draw the scene
181  * This function is the most important function of GlScene. If you want to render a scene into an
182  * OpenGL widget : call this function
183  */
184  void draw();
185 
186  /**
187  * Center scene
188  * After this function all entities are visible on the screen
189  */
190  void centerScene();
191 
192  /**
193  * Compute information for ajustSceneToSize
194  * \param width : request width
195  * \param height : request height
196  * \param center : the result center will be stored in (if center != nullptr)
197  * \param eye : the result eye will be stored in (if eye != nullptr)
198  * \param sceneRadius : the result sceneRadius will be stored in (if sceneRadius != nullptr)
199  * \param xWhiteFactor : xWhiteFactor is the white part on x borders (left and right), the result
200  * xWhiteFactor will be stored in (if xWhiteFactor != nullptr)
201  * \param yWhiteFactor : yWhiteFactor is the white part on y borders (top and bottom), the result
202  * yWhiteFactor will be stored in (if yWhiteFactor != nullptr)
203  * \param sceneBoundingBox : the result sceneBoundingBox will be stored in (if sceneBoundingBox !=
204  * nullptr)
205  */
206  void computeAjustSceneToSize(int width, int height, Coord *center, Coord *eye, float *sceneRadius,
207  float *xWhiteFactor, float *yWhiteFactor,
208  BoundingBox *sceneBoundingBox = nullptr,
209  float *zoomFactor = nullptr);
210 
211  /**
212  * Ajust camera to have entities near borders
213  * @param width requested width
214  * @param height requested height
215  */
216  void ajustSceneToSize(int width, int height);
217 
218  /**
219  * @brief Zoom by step to given x,y screen coordinates
220  * @param step of zoom
221  */
222  void zoomXY(int step, const int x, const int y);
223 
224  /**
225  * @brief Zoom to given world coordinate
226  * \warning factor parameter isn't be used
227  */
228  void zoom(float factor, const Coord &dest);
229 
230  /**
231  * @brief Zoom by step
232  * @param step of zoom
233  */
234  void zoom(int step);
235 
236  /**
237  * @brief Zoom by factor
238  * @param factor of zoom
239  */
240  void zoomFactor(float factor);
241 
242  /**
243  * @brief Translate camera by (x,y,z)
244  */
245  void translateCamera(const int x, const int y, const int z);
246 
247  /**
248  * @brief Rotate camera by (x,y,z)
249  * @param x rotation over X axis in degree
250  * @param y rotation over Y axis in degree
251  * @param z rotation over Z axis in degree
252  */
253  void rotateScene(const int x, const int y, const int z);
254 
255  /**
256  * @brief Select entities in scene
257  * @param type Entities type to select (SelectSimpleEntities,SelectNodes,SelectEdges)
258  * @param x screen coordinates
259  * @param y screen coordinates
260  * @param h height in screen coordinates
261  * @param w width in screen coordinates
262  * @param layer where the selection will be performed
263  * @param selectedEntities the result of the selection is stored on it
264  */
265  bool selectEntities(RenderingEntitiesFlag type, int x, int y, int h, int w, GlLayer *layer,
266  std::vector<SelectedEntity> &selectedEntities);
267 
268  /**
269  * @brief Output the scene in SVG
270  */
271  void outputSVG(unsigned int size, const std::string &filename);
272 
273  /**
274  * @brief Output the scene in EPS
275  */
276  void outputEPS(unsigned int size, const std::string &filename);
277 
278  /**
279  * @brief Return the RGB image of GlScene
280  */
281  unsigned char *getImage();
282 
283  /**
284  * @brief Set the viewport of the scene with a vector
285  * The viewport must be in many case the size of the widget containing the scene
286  */
287  void setViewport(Vector<int, 4> &newViewport) {
288  viewport = newViewport;
289  }
290 
291  /**
292  * @brief Set the viewport of the scene with 4 int
293  * The viewport must be in many case the size of the widget containing the scene
294  */
295  void setViewport(int x, int y, int width, int height) {
296  viewport[0] = x;
297  viewport[1] = y;
298  viewport[2] = width;
299  viewport[3] = height;
300  }
301 
302  /**
303  * @brief Get the viewport of the scene
304  * The viewport will be in many case the size of the widget containing the scene
305  */
306  Vector<int, 4> getViewport() const {
307  return viewport;
308  }
309 
310  /**
311  * @brief Set the background color of the scene
312  */
313  void setBackgroundColor(const Color &color) {
314  backgroundColor = color;
315  }
316 
317  /**
318  * @brief Get the background color of the scene
319  */
320  Color getBackgroundColor() const {
321  return backgroundColor;
322  }
323 
324  /**
325  * @brief Set if scene is render in orthogonal mode
326  */
327  void setViewOrtho(bool viewOrtho) {
328  this->viewOrtho = viewOrtho;
329  }
330 
331  /**
332  * @brief Scene is render in orthogonal mode ?
333  */
334  bool isViewOrtho() {
335  return viewOrtho;
336  }
337 
338  /**
339  * @brief Create a layer with the given name in the scene
340  * This layer is added to the layers list
341  * Now the scene have the ownership of this GlLayer
342  * so you don't have to delete this GlLayer
343  */
344  GlLayer *createLayer(const std::string &name);
345 
346  /**
347  * @brief Create a layer with the given name in the scene just before layer with given name
348  * This layer is added to the layers list
349  * Return nullptr if the layer with beforeLayerWithName is not find
350  * Now the scene have the ownership of this GlLayer
351  * so you don't have to delete this GlLayer
352  */
353  GlLayer *createLayerBefore(const std::string &layerName, const std::string &beforeLayerWithName);
354 
355  /**
356  * @brief Create a layer with the given name in the scene just after layer with given name
357  * This layer is added to the layers list
358  * Return nullptr if the layer with beforeLayerWithName is not find
359  * Now the scene have the ownership of this GlLayer
360  * so you don't have to delete this GlLayer
361  */
362  GlLayer *createLayerAfter(const std::string &layerName, const std::string &afterLayerWithName);
363 
364  /**
365  * @brief Add an existing layer in the scene
366  * Now the scene have the ownership of this GlLayer
367  * so you don't have to delete this GlLayer
368  */
369  void addExistingLayer(GlLayer *layer);
370 
371  /**
372  * @brief Add an existing layer in the scene just before layer with given name
373  * Return false if the layer with beforeLayerWithName is not find
374  * Now the scene have the ownership of this GlLayer
375  * so you don't have to delete this GlLayer
376  */
377  bool addExistingLayerBefore(GlLayer *layer, const std::string &beforeLayerWithName);
378 
379  /**
380  * @brief Add an existing layer in the scene just after layer with given name
381  * Return false if the layer with beforeLayerWithName is not find
382  * Now the scene have the ownership of this GlLayer
383  * so you don't have to delete this GlLayer
384  */
385  bool addExistingLayerAfter(GlLayer *layer, const std::string &afterLayerWithName);
386 
387  /**
388  * @brief Return the layer with name : name
389  * Return nullptr if the layer doesn't exist in the scene
390  */
391  GlLayer *getLayer(const std::string &name);
392 
393  /**
394  * @brief Remove the layer with name
395  * This GlLayer is automaticaly delete
396  * If you want to keep this GlLayer you can put false to deleteLayer parameters
397  * but after that you have the ownership of the GlLayer
398  */
399  void removeLayer(const std::string &name, bool deleteLayer = true);
400 
401  /**
402  * @brief Remove the layer with name
403  * This GlLayer is automaticaly delete
404  * If you want to keep this GlLayer you can put false to deleteLayer parameters
405  * but after that you have the ownership of the GlLayer
406  */
407  void removeLayer(GlLayer *layer, bool deleteLayer = true);
408 
409  /**
410  * @brief Return the layer list
411  */
412  const std::vector<std::pair<std::string, GlLayer *>> &getLayersList() {
413  return layersList;
414  }
415 
416  /**
417  * @brief Clear layers list
418  * Layers will not be deleted in this function
419  */
421  for (std::vector<std::pair<std::string, GlLayer *>>::iterator it = layersList.begin();
422  it != layersList.end(); ++it)
423  delete it->second;
424 
425  layersList.clear();
426  }
427 
428  /**
429  * @brief Get XML description of the scene and children and store it in out string
430  */
431  void getXML(std::string &out);
432 
433  /**
434  * @brief Get XML description of cameras of the scene and store it in out string
435  */
436  void getXMLOnlyForCameras(std::string &out);
437 
438  /**
439  * @brief Set scene's data and children with a XML
440  */
441  void setWithXML(std::string &in, Graph *graph);
442 
443  /**
444  * @brief Return lod calculator used to render this scene
445  */
446  GlLODCalculator *getCalculator() {
447  return lodCalculator;
448  }
449 
450  /**
451  * @brief Set a new lod calculator used to render this scene
452  */
453  void setCalculator(GlLODCalculator *calculator) {
454  lodCalculator = calculator;
455  calculator->setScene(*this);
456  }
457 
458  /**
459  * @brief Return the bouding box of the scene (in 3D coordinates)
460  * \warning This bounding box is compute in rendering, so if you add an entity in a layer the
461  * bounding box include this entity if a draw is call
462  */
463  BoundingBox getBoundingBox();
464 
465  /**
466  * @brief Return the current GlGraphComposite used by the scene
467  */
469  return glGraphComposite;
470  }
471 
472  /**
473  * @brief Return the layer containing the current GlGraphComposite
474  */
476  return graphLayer;
477  }
478 
479  /**
480  * @brief By default the most important layer is the layer where the graph is visualized
481  * This function return the camera of this layer
482  */
484  assert(graphLayer != nullptr);
485  return graphLayer->getCamera();
486  }
487 
488  /**
489  * @brief By default the most important layer is the layer where the graph is visualized
490  * This function set the camera of this layer
491  */
492  void setGraphCamera(Camera *camera) {
493  assert(graphLayer != nullptr);
494  graphLayer->setCamera(camera);
495  }
496 
497  /**
498  * @brief Set if OpenGL buffer will be cleared at draw
499  */
500  void setClearBufferAtDraw(bool clear) {
501  clearBufferAtDraw = clear;
502  }
503 
504  /**
505  * @brief If false, color buffer will not be cleared before drawing the scene.
506  */
507  bool getClearBufferAtDraw() const {
508  return clearBufferAtDraw;
509  }
510 
511  /**
512  * @brief Set if OpenGL depth buffer will be cleared at draw
513  */
514  void setClearDepthBufferAtDraw(bool clear) {
515  clearDepthBufferAtDraw = clear;
516  }
517 
518  /**
519  * @brief If false, depth buffer will not be cleared before drawing the scene.
520  */
522  return clearDepthBufferAtDraw;
523  }
524 
525  /**
526  * @brief Set if OpenGL stencil buffer will be cleared at draw
527  */
528  void setClearStencilBufferAtDraw(bool clear) {
529  clearStencilBufferAtDraw = clear;
530  }
531 
532  /**
533  * @brief If false, color buffer will not be cleared before drawing the scene.
534  */
536  return clearStencilBufferAtDraw;
537  }
538 
539 private:
540  std::vector<std::pair<std::string, GlLayer *>> layersList;
541  GlLODCalculator *lodCalculator;
542  Vector<int, 4> viewport;
543  Color backgroundColor;
544  bool viewOrtho;
545 
546  GlGraphComposite *glGraphComposite;
547  GlLayer *graphLayer;
548 
549  bool clearBufferAtDraw;
550 
551  bool inDraw;
552 
553  bool clearDepthBufferAtDraw;
554 
555  bool clearStencilBufferAtDraw;
556 
557 public:
558  ///@cond DOXYGEN_HIDDEN
559 
560  /**
561  * @brief You don't have to call this function
562  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
563  * You don't have to call this function
564  */
565  void glGraphCompositeAdded(GlLayer *layer, GlGraphComposite *composite);
566 
567  /**
568  * @brief You don't have to call this function
569  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
570  * You don't have to call this function
571  */
572  void glGraphCompositeRemoved(GlLayer *layer, GlGraphComposite *composite);
573 
574  /**
575  * @brief You don't have to call this function
576  * This function is called by GlLayer and GlComposite to send layer modification event
577  */
578  void notifyModifyLayer(const std::string &name, GlLayer *layer);
579 
580  /**
581  * @brief You don't have to call these functions
582  * They are called by GlComposite to send entity modification event
583  */
584  void notifyModifyEntity(GlSimpleEntity *entity);
585  void notifyDeletedEntity(GlSimpleEntity *entity);
586 
587  ///@endcond
588 };
589 }
590 
591 #endif // Tulip_GLSCENE_H
bool getClearBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:507
void setViewport(Vector< int, 4 > &newViewport)
Set the viewport of the scene with a vector The viewport must be in many case the size of the widget ...
Definition: GlScene.h:287
void setGraphCamera(Camera *camera)
By default the most important layer is the layer where the graph is visualized This function set the ...
Definition: GlScene.h:492
void setBackgroundColor(const Color &color)
Set the background color of the scene.
Definition: GlScene.h:313
Base class for all Tulip OpenGL entities.
void clearLayersList()
Clear layers list Layers will not be deleted in this function.
Definition: GlScene.h:420
void setCalculator(GlLODCalculator *calculator)
Set a new lod calculator used to render this scene.
Definition: GlScene.h:453
bool getClearStencilBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:535
GlGraphComposite * getGlGraphComposite()
Return the current GlGraphComposite used by the scene.
Definition: GlScene.h:468
node getNode() const
getNode is a convenience method to perform the check on the selected element type and return the corr...
Definition: GlScene.h:94
bool isViewOrtho()
Scene is render in orthogonal mode ?
Definition: GlScene.h:334
Camera & getGraphCamera()
By default the most important layer is the layer where the graph is visualized This function return t...
Definition: GlScene.h:483
Vector< int, 4 > getViewport() const
Get the viewport of the scene The viewport will be in many case the size of the widget containing the...
Definition: GlScene.h:306
Tulip scene class.
Definition: GlScene.h:160
The edge struct represents an edge in a Graph object.
Definition: Edge.h:40
The node struct represents a node in a Graph object.
Definition: Node.h:40
GlLayer * getGraphLayer()
Return the layer containing the current GlGraphComposite.
Definition: GlScene.h:475
This class represents the 3D bounding box of an object. It is mostly used to determine whether or not...
Definition: BoundingBox.h:66
Tulip OpenGL camera object.
Definition: Camera.h:47
Color getBackgroundColor() const
Get the background color of the scene.
Definition: GlScene.h:320
edge getEdge() const
getEdge is a convenience method to perform the check on the selected element type and return the corr...
Definition: GlScene.h:112
void setClearDepthBufferAtDraw(bool clear)
Set if OpenGL depth buffer will be cleared at draw.
Definition: GlScene.h:514
void setViewOrtho(bool viewOrtho)
Set if scene is render in orthogonal mode.
Definition: GlScene.h:327
const std::vector< std::pair< std::string, GlLayer * > > & getLayersList()
Return the layer list.
Definition: GlScene.h:412
Class use to visualize graph in OpenGL Tulip engine.
GlLODCalculator * getCalculator()
Return lod calculator used to render this scene.
Definition: GlScene.h:446
void setClearStencilBufferAtDraw(bool clear)
Set if OpenGL stencil buffer will be cleared at draw.
Definition: GlScene.h:528
The Observable class is the base of Tulip&#39;s observation system.
Definition: Observable.h:141
Structure to store selected entities.
Definition: GlScene.h:48
void setClearBufferAtDraw(bool clear)
Set if OpenGL buffer will be cleared at draw.
Definition: GlScene.h:500
A GlLayer is like an 2D drawing software layer system.
Definition: GlLayer.h:54
bool getClearDepthBufferAtDraw() const
If false, depth buffer will not be cleared before drawing the scene.
Definition: GlScene.h:521
void setViewport(int x, int y, int width, int height)
Set the viewport of the scene with 4 int The viewport must be in many case the size of the widget con...
Definition: GlScene.h:295