Tulip  5.6.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 <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  */
161  void initGlParameters();
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  // use computeAdjustSceneToSize instead
197  _DEPRECATED void computeAjustSceneToSize(int width, int height, Coord *center, Coord *eye,
198  float *sceneRadius, float *xWhiteFactor,
199  float *yWhiteFactor,
200  BoundingBox *sceneBoundingBox = nullptr,
201  float *zoomFactor = nullptr) {
202  computeAdjustSceneToSize(width, height, center, eye, sceneRadius, xWhiteFactor, yWhiteFactor,
203  sceneBoundingBox, zoomFactor);
204  }
205 
206  /**
207  * Adjust camera to have entities near borders
208  * @param width requested width
209  * @param height requested height
210  */
211  void adjustSceneToSize(int width, int height);
212 
213  _DEPRECATED inline void ajustSceneToSize(int width, int height) {
214  adjustSceneToSize(width, height);
215  }
216 
217  /**
218  * @brief Zoom by step to given x,y screen coordinates
219  * @param step of zoom
220  */
221  void zoomXY(int step, const int x, const int y);
222 
223  /**
224  * @brief Zoom by factor
225  * @param factor of zoom
226  */
227  void zoomFactor(float factor);
228 
229  /**
230  * @brief Zoom to given world coordinate
231  * \warning factor parameter isn't be used
232  */
233  void zoom(float factor, const Coord &dest);
234 
235  /**
236  * @brief Zoom by step
237  * @param step of zoom
238  */
239  void zoom(int step) {
240  zoomFactor(powf(1.1f, step));
241  }
242 
243  /**
244  * @brief Translate camera by (x,y,z)
245  */
246  void translateCamera(const int x, const int y, const int z);
247 
248  /**
249  * @brief Rotate camera by (x,y,z)
250  * @param x rotation over X axis in degree
251  * @param y rotation over Y axis in degree
252  * @param z rotation over Z axis in degree
253  */
254  void rotateCamera(const int x, const int y, const int z);
255 
256  // use rotateCamera instead
257  _DEPRECATED inline void rotateScene(const int x, const int y, const int z) {
258  rotateCamera(x, y, z);
259  }
260 
261  /**
262  * @brief Select entities in scene
263  * @param type Entities type to select (SelectSimpleEntities,SelectNodes,SelectEdges)
264  * @param x screen coordinates
265  * @param y screen coordinates
266  * @param h height in screen coordinates
267  * @param w width in screen coordinates
268  * @param layer where the selection will be performed
269  * @param selectedEntities the result of the selection is stored on it
270  */
271  bool selectEntities(RenderingEntitiesFlag type, int x, int y, int h, int w, GlLayer *layer,
272  std::vector<SelectedEntity> &selectedEntities);
273 
274  /**
275  * @brief Return the RGB image of GlScene
276  */
277  unsigned char *getImage();
278 
279  /**
280  * @brief Set the viewport of the scene with a vector
281  * The viewport must be in many case the size of the widget containing the scene
282  */
283  void setViewport(Vector<int, 4> &newViewport) {
284  viewport = newViewport;
285  }
286 
287  /**
288  * @brief Set the viewport of the scene with 4 int
289  * The viewport must be in many case the size of the widget containing the scene
290  */
291  void setViewport(int x, int y, int width, int height) {
292  viewport[0] = x;
293  viewport[1] = y;
294  viewport[2] = width;
295  viewport[3] = height;
296  }
297 
298  /**
299  * @brief Get the viewport of the scene
300  * The viewport will be in many case the size of the widget containing the scene
301  */
302  const Vector<int, 4> &getViewport() const {
303  return viewport;
304  }
305 
306  /**
307  * @brief Set the background color of the scene
308  */
309  void setBackgroundColor(const Color &color) {
310  backgroundColor = color;
311  }
312 
313  /**
314  * @brief Get the background color of the scene
315  */
316  Color getBackgroundColor() const {
317  return backgroundColor;
318  }
319 
320  /**
321  * @brief Set if scene is render in orthogonal mode
322  */
323  void setViewOrtho(bool viewOrtho) {
324  this->viewOrtho = viewOrtho;
325  }
326 
327  /**
328  * @brief Scene is render in orthogonal mode ?
329  */
330  bool isViewOrtho() {
331  return viewOrtho;
332  }
333 
334  /**
335  * @brief Create a layer with the given name in the scene
336  * This layer is added to the layers list
337  * Now the scene have the ownership of this GlLayer
338  * so you don't have to delete this GlLayer
339  */
340  GlLayer *createLayer(const std::string &name);
341 
342  /**
343  * @brief Create a layer with the given name in the scene just before layer with given name
344  * This layer is added to the layers list
345  * Return nullptr if the layer with beforeLayerWithName is not find
346  * Now the scene have the ownership of this GlLayer
347  * so you don't have to delete this GlLayer
348  */
349  GlLayer *createLayerBefore(const std::string &layerName, const std::string &beforeLayerWithName);
350 
351  /**
352  * @brief Create a layer with the given name in the scene just after layer with given name
353  * This layer is added to the layers list
354  * Return nullptr if the layer with beforeLayerWithName is not find
355  * Now the scene have the ownership of this GlLayer
356  * so you don't have to delete this GlLayer
357  */
358  GlLayer *createLayerAfter(const std::string &layerName, const std::string &afterLayerWithName);
359 
360  /**
361  * @brief Add an existing layer in the scene
362  * Now the scene have the ownership of this GlLayer
363  * so you don't have to delete this GlLayer
364  */
365  void addExistingLayer(GlLayer *layer);
366 
367  /**
368  * @brief Add an existing layer in the scene just before layer with given name
369  * Return false if the layer with beforeLayerWithName is not find
370  * Now the scene have the ownership of this GlLayer
371  * so you don't have to delete this GlLayer
372  */
373  bool addExistingLayerBefore(GlLayer *layer, const std::string &beforeLayerWithName);
374 
375  /**
376  * @brief Add an existing layer in the scene just after layer with given name
377  * Return false if the layer with beforeLayerWithName is not find
378  * Now the scene have the ownership of this GlLayer
379  * so you don't have to delete this GlLayer
380  */
381  bool addExistingLayerAfter(GlLayer *layer, const std::string &afterLayerWithName);
382 
383  /**
384  * @brief Return the layer with name : name
385  * Return nullptr if the layer doesn't exist in the scene
386  */
387  GlLayer *getLayer(const std::string &name);
388 
389  /**
390  * @brief Remove the layer with name
391  * This GlLayer is automatically deleted
392  * If you want to keep this GlLayer you can put false to deleteLayer parameters
393  * but after that you have the ownership of the GlLayer
394  */
395  void removeLayer(const std::string &name, bool deleteLayer = true);
396 
397  /**
398  * @brief Remove the layer with name
399  * This GlLayer is automatically deleted
400  * If you want to keep this GlLayer you can put false to deleteLayer parameters
401  * but after that you have the ownership of the GlLayer
402  */
403  void removeLayer(GlLayer *layer, bool deleteLayer = true);
404 
405  /**
406  * @brief Return the layer list
407  */
408  const std::vector<std::pair<std::string, GlLayer *>> &getLayersList() {
409  return layersList;
410  }
411 
412  /**
413  * @brief Clear layers list
414  * Layers will not be deleted in this function
415  */
417  for (auto &it : layersList)
418  delete it.second;
419 
420  layersList.clear();
421  }
422 
423  /**
424  * @brief Get XML description of the scene and children and store it in out string
425  */
426  void getXML(std::string &out);
427 
428  /**
429  * @brief Get XML description of cameras of the scene and store it in out string
430  */
431  void getXMLOnlyForCameras(std::string &out);
432 
433  /**
434  * @brief Set scene's data and children with a XML
435  */
436  void setWithXML(std::string &in, Graph *graph);
437 
438  /**
439  * @brief Return lod calculator used to render this scene
440  */
441  GlLODCalculator *getCalculator() {
442  return lodCalculator;
443  }
444 
445  /**
446  * @brief Set a new lod calculator used to render this scene
447  */
448  void setCalculator(GlLODCalculator *calculator) {
449  lodCalculator = calculator;
450  calculator->setScene(*this);
451  }
452 
453  /**
454  * @brief Return the bounding box of the scene (in 3D coordinates)
455  * \warning This bounding box is computed in rendering, so if you add an entity in a layer the
456  * bounding box includes this entity if a draw is called
457  */
458  BoundingBox getBoundingBox();
459 
460  /**
461  * @brief Return the current GlGraphComposite used by the scene
462  */
464  return glGraphComposite;
465  }
466 
467  /**
468  * @brief Return the layer containing the current GlGraphComposite
469  */
471  return graphLayer;
472  }
473 
474  /**
475  * @brief By default the most important layer is the layer where the graph is visualized
476  * This function return the camera of this layer
477  */
479  assert(graphLayer != nullptr);
480  return graphLayer->getCamera();
481  }
482 
483  /**
484  * @brief By default the most important layer is the layer where the graph is visualized
485  * This function set the camera of this layer
486  */
487  void setGraphCamera(Camera *camera) {
488  assert(graphLayer != nullptr);
489  graphLayer->setCamera(camera);
490  }
491 
492  /**
493  * @brief Set if OpenGL buffer will be cleared at draw
494  */
495  void setClearBufferAtDraw(bool clear) {
496  clearBufferAtDraw = clear;
497  }
498 
499  /**
500  * @brief If false, color buffer will not be cleared before drawing the scene.
501  */
502  bool getClearBufferAtDraw() const {
503  return clearBufferAtDraw;
504  }
505 
506  /**
507  * @brief Set if OpenGL depth buffer will be cleared at draw
508  */
509  void setClearDepthBufferAtDraw(bool clear) {
510  clearDepthBufferAtDraw = clear;
511  }
512 
513  /**
514  * @brief If false, depth buffer will not be cleared before drawing the scene.
515  */
517  return clearDepthBufferAtDraw;
518  }
519 
520  /**
521  * @brief Set if OpenGL stencil buffer will be cleared at draw
522  */
523  void setClearStencilBufferAtDraw(bool clear) {
524  clearStencilBufferAtDraw = clear;
525  }
526 
527  /**
528  * @brief If false, color buffer will not be cleared before drawing the scene.
529  */
531  return clearStencilBufferAtDraw;
532  }
533 
534 private:
535  std::vector<std::pair<std::string, GlLayer *>> layersList;
536  GlLODCalculator *lodCalculator;
537  Vector<int, 4> viewport;
538  Color backgroundColor;
539  bool viewOrtho;
540 
541  GlGraphComposite *glGraphComposite;
542  GlLayer *graphLayer;
543 
544  bool clearBufferAtDraw;
545 
546  bool inDraw;
547 
548  bool clearDepthBufferAtDraw;
549 
550  bool clearStencilBufferAtDraw;
551 
552 public:
553  ///@cond DOXYGEN_HIDDEN
554 
555  /**
556  * @brief You don't have to call this function
557  * This function is automatically called when a GlGraphComposite is added in a layer in the scene
558  * You don't have to call this function
559  */
560  void glGraphCompositeAdded(GlLayer *layer, GlGraphComposite *composite);
561 
562  /**
563  * @brief You don't have to call this function
564  * This function is automatically called when a GlGraphComposite is added in a layer in the scene
565  * You don't have to call this function
566  */
567  void glGraphCompositeRemoved(GlLayer *layer, GlGraphComposite *composite);
568 
569  /**
570  * @brief You don't have to call this function
571  * This function is called by GlLayer and GlComposite to send layer modification event
572  */
573  void notifyModifyLayer(const std::string &name, GlLayer *layer);
574 
575  /**
576  * @brief You don't have to call these functions
577  * They are called by GlComposite to send entity modification event
578  */
579  void notifyModifyEntity(GlSimpleEntity *entity);
580  void notifyDeletedEntity(GlSimpleEntity *entity);
581 
582  ///@endcond
583 };
584 } // namespace tlp
585 
586 #endif // Tulip_GLSCENE_H
tlp::SelectedEntity::getEdge
edge getEdge() const
Definition: GlScene.h:97
tlp::GlLayer
A GlLayer is like an 2D drawing software layer system.
Definition: GlLayer.h:54
tlp::GlScene::setCalculator
void setCalculator(GlLODCalculator *calculator)
Set a new lod calculator used to render this scene.
Definition: GlScene.h:448
tlp::GlScene::setGraphCamera
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:487
tlp::GlScene::setBackgroundColor
void setBackgroundColor(const Color &color)
Set the background color of the scene.
Definition: GlScene.h:309
tlp::GlScene::setClearBufferAtDraw
void setClearBufferAtDraw(bool clear)
Set if OpenGL buffer will be cleared at draw.
Definition: GlScene.h:495
tlp::GlScene::isViewOrtho
bool isViewOrtho()
Scene is render in orthogonal mode ?
Definition: GlScene.h:330
tlp::Graph
Definition: Graph.h:234
tlp::GlScene::getViewport
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:302
tlp::GlScene::getClearDepthBufferAtDraw
bool getClearDepthBufferAtDraw() const
If false, depth buffer will not be cleared before drawing the scene.
Definition: GlScene.h:516
tlp::GlScene::getGlGraphComposite
GlGraphComposite * getGlGraphComposite()
Return the current GlGraphComposite used by the scene.
Definition: GlScene.h:463
tlp::GlScene::clearLayersList
void clearLayersList()
Clear layers list Layers will not be deleted in this function.
Definition: GlScene.h:416
tlp::SelectedEntity::getNode
node getNode() const
Definition: GlScene.h:89
tlp::GlScene::setViewOrtho
void setViewOrtho(bool viewOrtho)
Set if scene is render in orthogonal mode.
Definition: GlScene.h:323
tlp::GlScene::getGraphCamera
Camera & getGraphCamera()
By default the most important layer is the layer where the graph is visualized This function return t...
Definition: GlScene.h:478
tlp::GlScene::getBackgroundColor
Color getBackgroundColor() const
Get the background color of the scene.
Definition: GlScene.h:316
tlp::GlSimpleEntity
Base class for all Tulip OpenGL entities.
Definition: GlSimpleEntity.h:62
tlp::GlScene::getGraphLayer
GlLayer * getGraphLayer()
Return the layer containing the current GlGraphComposite.
Definition: GlScene.h:470
tlp::GlScene::getCalculator
GlLODCalculator * getCalculator()
Return lod calculator used to render this scene.
Definition: GlScene.h:441
tlp::SelectedEntity
Structure to store selected entities.
Definition: GlScene.h:50
tlp::GlScene::getClearBufferAtDraw
bool getClearBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:502
tlp::BoundingBox
This class represents the 3D bounding box of an object. It is mostly used to determine whether or not...
Definition: BoundingBox.h:67
tlp::GlScene::setClearStencilBufferAtDraw
void setClearStencilBufferAtDraw(bool clear)
Set if OpenGL stencil buffer will be cleared at draw.
Definition: GlScene.h:523
tlp
Definition: AbstractProperty.h:34
tlp::GlScene::getLayersList
const std::vector< std::pair< std::string, GlLayer * > > & getLayersList()
Return the layer list.
Definition: GlScene.h:408
tlp::GlScene
Tulip scene class.
Definition: GlScene.h:144
tlp::GlScene::setClearDepthBufferAtDraw
void setClearDepthBufferAtDraw(bool clear)
Set if OpenGL depth buffer will be cleared at draw.
Definition: GlScene.h:509
tlp::GlGraphComposite
Class use to visualize graph in OpenGL Tulip engine.
Definition: GlGraphComposite.h:51
tlp::Observable
The Observable class is the base of Tulip's observation system.
Definition: Observable.h:127
tlp::GlScene::getClearStencilBufferAtDraw
bool getClearStencilBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:530
tlp::edge
The edge struct represents an edge in a Graph object.
Definition: Edge.h:40
tlp::node
The node struct represents a node in a Graph object.
Definition: Node.h:40
tlp::Camera
Tulip OpenGL camera object.
Definition: Camera.h:47
tlp::GlScene::zoom
void zoom(int step)
Zoom by step.
Definition: GlScene.h:239
tlp::GlScene::setViewport
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:283
tlp::GlScene::setViewport
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:291