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