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