Tulip  5.3.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.1, 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 Output the scene in SVG
292  */
293  void outputSVG(unsigned int size, const std::string &filename);
294 
295  /**
296  * @brief Output the scene in EPS
297  */
298  void outputEPS(unsigned int size, const std::string &filename);
299 
300  /**
301  * @brief Return the RGB image of GlScene
302  */
303  unsigned char *getImage();
304 
305  /**
306  * @brief Set the viewport of the scene with a vector
307  * The viewport must be in many case the size of the widget containing the scene
308  */
309  void setViewport(Vector<int, 4> &newViewport) {
310  viewport = newViewport;
311  }
312 
313  /**
314  * @brief Set the viewport of the scene with 4 int
315  * The viewport must be in many case the size of the widget containing the scene
316  */
317  void setViewport(int x, int y, int width, int height) {
318  viewport[0] = x;
319  viewport[1] = y;
320  viewport[2] = width;
321  viewport[3] = height;
322  }
323 
324  /**
325  * @brief Get the viewport of the scene
326  * The viewport will be in many case the size of the widget containing the scene
327  */
328  Vector<int, 4> getViewport() const {
329  return viewport;
330  }
331 
332  /**
333  * @brief Set the background color of the scene
334  */
335  void setBackgroundColor(const Color &color) {
336  backgroundColor = color;
337  }
338 
339  /**
340  * @brief Get the background color of the scene
341  */
342  Color getBackgroundColor() const {
343  return backgroundColor;
344  }
345 
346  /**
347  * @brief Set if scene is render in orthogonal mode
348  */
349  void setViewOrtho(bool viewOrtho) {
350  this->viewOrtho = viewOrtho;
351  }
352 
353  /**
354  * @brief Scene is render in orthogonal mode ?
355  */
356  bool isViewOrtho() {
357  return viewOrtho;
358  }
359 
360  /**
361  * @brief Create a layer with the given name in the scene
362  * This layer is added to the layers list
363  * Now the scene have the ownership of this GlLayer
364  * so you don't have to delete this GlLayer
365  */
366  GlLayer *createLayer(const std::string &name);
367 
368  /**
369  * @brief Create a layer with the given name in the scene just before layer with given name
370  * This layer is added to the layers list
371  * Return nullptr if the layer with beforeLayerWithName is not find
372  * Now the scene have the ownership of this GlLayer
373  * so you don't have to delete this GlLayer
374  */
375  GlLayer *createLayerBefore(const std::string &layerName, const std::string &beforeLayerWithName);
376 
377  /**
378  * @brief Create a layer with the given name in the scene just after layer with given name
379  * This layer is added to the layers list
380  * Return nullptr if the layer with beforeLayerWithName is not find
381  * Now the scene have the ownership of this GlLayer
382  * so you don't have to delete this GlLayer
383  */
384  GlLayer *createLayerAfter(const std::string &layerName, const std::string &afterLayerWithName);
385 
386  /**
387  * @brief Add an existing layer in the scene
388  * Now the scene have the ownership of this GlLayer
389  * so you don't have to delete this GlLayer
390  */
391  void addExistingLayer(GlLayer *layer);
392 
393  /**
394  * @brief Add an existing layer in the scene just before layer with given name
395  * Return false if the layer with beforeLayerWithName is not find
396  * Now the scene have the ownership of this GlLayer
397  * so you don't have to delete this GlLayer
398  */
399  bool addExistingLayerBefore(GlLayer *layer, const std::string &beforeLayerWithName);
400 
401  /**
402  * @brief Add an existing layer in the scene just after layer with given name
403  * Return false if the layer with beforeLayerWithName is not find
404  * Now the scene have the ownership of this GlLayer
405  * so you don't have to delete this GlLayer
406  */
407  bool addExistingLayerAfter(GlLayer *layer, const std::string &afterLayerWithName);
408 
409  /**
410  * @brief Return the layer with name : name
411  * Return nullptr if the layer doesn't exist in the scene
412  */
413  GlLayer *getLayer(const std::string &name);
414 
415  /**
416  * @brief Remove the layer with name
417  * This GlLayer is automaticaly delete
418  * If you want to keep this GlLayer you can put false to deleteLayer parameters
419  * but after that you have the ownership of the GlLayer
420  */
421  void removeLayer(const std::string &name, bool deleteLayer = true);
422 
423  /**
424  * @brief Remove the layer with name
425  * This GlLayer is automaticaly delete
426  * If you want to keep this GlLayer you can put false to deleteLayer parameters
427  * but after that you have the ownership of the GlLayer
428  */
429  void removeLayer(GlLayer *layer, bool deleteLayer = true);
430 
431  /**
432  * @brief Return the layer list
433  */
434  const std::vector<std::pair<std::string, GlLayer *>> &getLayersList() {
435  return layersList;
436  }
437 
438  /**
439  * @brief Clear layers list
440  * Layers will not be deleted in this function
441  */
443  for (std::vector<std::pair<std::string, GlLayer *>>::iterator it = layersList.begin();
444  it != layersList.end(); ++it)
445  delete it->second;
446 
447  layersList.clear();
448  }
449 
450  /**
451  * @brief Get XML description of the scene and children and store it in out string
452  */
453  void getXML(std::string &out);
454 
455  /**
456  * @brief Get XML description of cameras of the scene and store it in out string
457  */
458  void getXMLOnlyForCameras(std::string &out);
459 
460  /**
461  * @brief Set scene's data and children with a XML
462  */
463  void setWithXML(std::string &in, Graph *graph);
464 
465  /**
466  * @brief Return lod calculator used to render this scene
467  */
468  GlLODCalculator *getCalculator() {
469  return lodCalculator;
470  }
471 
472  /**
473  * @brief Set a new lod calculator used to render this scene
474  */
475  void setCalculator(GlLODCalculator *calculator) {
476  lodCalculator = calculator;
477  calculator->setScene(*this);
478  }
479 
480  /**
481  * @brief Return the bouding box of the scene (in 3D coordinates)
482  * \warning This bounding box is compute in rendering, so if you add an entity in a layer the
483  * bounding box include this entity if a draw is call
484  */
485  BoundingBox getBoundingBox();
486 
487  /**
488  * @brief Return the current GlGraphComposite used by the scene
489  */
491  return glGraphComposite;
492  }
493 
494  /**
495  * @brief Return the layer containing the current GlGraphComposite
496  */
498  return graphLayer;
499  }
500 
501  /**
502  * @brief By default the most important layer is the layer where the graph is visualized
503  * This function return the camera of this layer
504  */
506  assert(graphLayer != nullptr);
507  return graphLayer->getCamera();
508  }
509 
510  /**
511  * @brief By default the most important layer is the layer where the graph is visualized
512  * This function set the camera of this layer
513  */
514  void setGraphCamera(Camera *camera) {
515  assert(graphLayer != nullptr);
516  graphLayer->setCamera(camera);
517  }
518 
519  /**
520  * @brief Set if OpenGL buffer will be cleared at draw
521  */
522  void setClearBufferAtDraw(bool clear) {
523  clearBufferAtDraw = clear;
524  }
525 
526  /**
527  * @brief If false, color buffer will not be cleared before drawing the scene.
528  */
529  bool getClearBufferAtDraw() const {
530  return clearBufferAtDraw;
531  }
532 
533  /**
534  * @brief Set if OpenGL depth buffer will be cleared at draw
535  */
536  void setClearDepthBufferAtDraw(bool clear) {
537  clearDepthBufferAtDraw = clear;
538  }
539 
540  /**
541  * @brief If false, depth buffer will not be cleared before drawing the scene.
542  */
544  return clearDepthBufferAtDraw;
545  }
546 
547  /**
548  * @brief Set if OpenGL stencil buffer will be cleared at draw
549  */
550  void setClearStencilBufferAtDraw(bool clear) {
551  clearStencilBufferAtDraw = clear;
552  }
553 
554  /**
555  * @brief If false, color buffer will not be cleared before drawing the scene.
556  */
558  return clearStencilBufferAtDraw;
559  }
560 
561 private:
562  std::vector<std::pair<std::string, GlLayer *>> layersList;
563  GlLODCalculator *lodCalculator;
564  Vector<int, 4> viewport;
565  Color backgroundColor;
566  bool viewOrtho;
567 
568  GlGraphComposite *glGraphComposite;
569  GlLayer *graphLayer;
570 
571  bool clearBufferAtDraw;
572 
573  bool inDraw;
574 
575  bool clearDepthBufferAtDraw;
576 
577  bool clearStencilBufferAtDraw;
578 
579 public:
580  ///@cond DOXYGEN_HIDDEN
581 
582  /**
583  * @brief You don't have to call this function
584  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
585  * You don't have to call this function
586  */
587  void glGraphCompositeAdded(GlLayer *layer, GlGraphComposite *composite);
588 
589  /**
590  * @brief You don't have to call this function
591  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
592  * You don't have to call this function
593  */
594  void glGraphCompositeRemoved(GlLayer *layer, GlGraphComposite *composite);
595 
596  /**
597  * @brief You don't have to call this function
598  * This function is called by GlLayer and GlComposite to send layer modification event
599  */
600  void notifyModifyLayer(const std::string &name, GlLayer *layer);
601 
602  /**
603  * @brief You don't have to call these functions
604  * They are called by GlComposite to send entity modification event
605  */
606  void notifyModifyEntity(GlSimpleEntity *entity);
607  void notifyDeletedEntity(GlSimpleEntity *entity);
608 
609  ///@endcond
610 };
611 } // namespace tlp
612 
613 #endif // Tulip_GLSCENE_H
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:309
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 setGraphCamera(Camera *camera)
By default the most important layer is the layer where the graph is visualized This function set the ...
Definition: GlScene.h:514
void setBackgroundColor(const Color &color)
Set the background color of the scene.
Definition: GlScene.h:335
Base class for all Tulip OpenGL entities.
void clearLayersList()
Clear layers list Layers will not be deleted in this function.
Definition: GlScene.h:442
void setCalculator(GlLODCalculator *calculator)
Set a new lod calculator used to render this scene.
Definition: GlScene.h:475
GlGraphComposite * getGlGraphComposite()
Return the current GlGraphComposite used by the scene.
Definition: GlScene.h:490
bool isViewOrtho()
Scene is render in orthogonal mode ?
Definition: GlScene.h:356
Camera & getGraphCamera()
By default the most important layer is the layer where the graph is visualized This function return t...
Definition: GlScene.h:505
bool getClearDepthBufferAtDraw() const
If false, depth buffer will not be cleared before drawing the scene.
Definition: GlScene.h:543
bool getClearBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:529
Tulip scene class.
Definition: GlScene.h:160
Color getBackgroundColor() const
Get the background color of the scene.
Definition: GlScene.h:342
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:497
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
void setClearDepthBufferAtDraw(bool clear)
Set if OpenGL depth buffer will be cleared at draw.
Definition: GlScene.h:536
void setViewOrtho(bool viewOrtho)
Set if scene is render in orthogonal mode.
Definition: GlScene.h:349
const std::vector< std::pair< std::string, GlLayer * > > & getLayersList()
Return the layer list.
Definition: GlScene.h:434
Class use to visualize graph in OpenGL Tulip engine.
GlLODCalculator * getCalculator()
Return lod calculator used to render this scene.
Definition: GlScene.h:468
void setClearStencilBufferAtDraw(bool clear)
Set if OpenGL stencil buffer will be cleared at draw.
Definition: GlScene.h:550
The Observable class is the base of Tulip&#39;s observation system.
Definition: Observable.h:127
bool getClearStencilBufferAtDraw() const
If false, color buffer will not be cleared before drawing the scene.
Definition: GlScene.h:557
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
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:522
void zoom(int step)
Zoom by step.
Definition: GlScene.h:255
A GlLayer is like an 2D drawing software layer system.
Definition: GlLayer.h:54
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:317
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:328