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