Tulip  4.3.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 informations 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 to given x,y screen coordinates
205  * @param step fator of zoom, must be >= 0
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 fator of zoom, must be >= 0
218  */
219  void zoom(int step);
220 
221  /**
222  * @brief Translate camera by (x,y,z)
223  */
224  void translateCamera(const int x, const int y, const int z);
225 
226  /**
227  * @brief Rotate camera by (x,y,z)
228  * @param x rotation over X axis in degree
229  * @param y rotation over Y axis in degree
230  * @param z rotation over Z axis in degree
231  */
232  void rotateScene(const int x, const int y, const int z);
233 
234  /**
235  * @brief Select entities in scene
236  * @param type Entities type to select (SelectSimpleEntities,SelectNodes,SelectEdges)
237  * @param x screen coordinates
238  * @param y screen coordinates
239  * @param h height in screen coordinates
240  * @param w width in screen coordinates
241  * @param layer where the selection will be performed
242  * @param selectedEntities the result of the selection is stored on it
243  */
244  bool selectEntities(RenderingEntitiesFlag type, int x, int y, int h, int w,GlLayer *layer,std::vector<SelectedEntity>& selectedEntities);
245 
246  /**
247  * @brief Output the scene in SVG
248  */
249  void outputSVG(unsigned int size,const std::string& filename);
250 
251  /**
252  * @brief Output the scene in EPS
253  */
254  void outputEPS(unsigned int size,const std::string& filename);
255 
256  /**
257  * @brief Return the RGB image of GlScene
258  */
259  unsigned char * getImage();
260 
261  /**
262  * @brief Set the viewport of the scene with a vector
263  * The viewport must be in many case the size of the widget containing the scene
264  */
265  void setViewport(Vector<int, 4> &newViewport) {
266  viewport=newViewport;
267  }
268 
269  /**
270  * @brief Set the viewport of the scene with 4 int
271  * The viewport must be in many case the size of the widget containing the scene
272  */
273  void setViewport(int x, int y, int width, int height) {
274  viewport[0]=x;
275  viewport[1]=y;
276  viewport[2]=width;
277  viewport[3]=height;
278  }
279 
280  /**
281  * @brief Get the viewport of the scene
282  * The viewport will be in many case the size of the widget containing the scene
283  */
284  Vector<int, 4> getViewport() const {
285  return viewport;
286  }
287 
288  /**
289  * @brief Set the background color of the scene
290  */
291  void setBackgroundColor(const Color& color) {
292  backgroundColor=color;
293  }
294 
295  /**
296  * @brief Get the background color of the scene
297  */
298  Color getBackgroundColor() const {
299  return backgroundColor;
300  }
301 
302  /**
303  * @brief Set if scene is render in orthogonal mode
304  */
305  void setViewOrtho(bool viewOrtho) {
306  this->viewOrtho=viewOrtho;
307  }
308 
309  /**
310  * @brief Scene is render in orthogonal mode ?
311  */
312  bool isViewOrtho() {
313  return viewOrtho;
314  }
315 
316  /**
317  * @brief Create a layer with the given name in the scene
318  * This layer is added to the layers list
319  * Now the scene have the ownership of this GlLayer
320  * so you don't have to delete this GlLayer
321  */
322  GlLayer *createLayer(const std::string &name);
323 
324  /**
325  * @brief Create a layer with the given name in the scene just before layer with given name
326  * This layer is added to the layers list
327  * Return NULL if the layer with beforeLayerWithName is not find
328  * Now the scene have the ownership of this GlLayer
329  * so you don't have to delete this GlLayer
330  */
331  GlLayer *createLayerBefore(const std::string &layerName,const std::string &beforeLayerWithName);
332 
333  /**
334  * @brief Create a layer with the given name in the scene just after layer with given name
335  * This layer is added to the layers list
336  * Return NULL if the layer with beforeLayerWithName is not find
337  * Now the scene have the ownership of this GlLayer
338  * so you don't have to delete this GlLayer
339  */
340  GlLayer *createLayerAfter(const std::string &layerName,const std::string &afterLayerWithName);
341 
342  /**
343  * @brief Add an existing layer in the scene
344  * Now the scene have the ownership of this GlLayer
345  * so you don't have to delete this GlLayer
346  */
347  void addExistingLayer(GlLayer *layer);
348 
349  /**
350  * @brief Add an existing layer in the scene just before layer with given name
351  * Return false if the layer with beforeLayerWithName is not find
352  * Now the scene have the ownership of this GlLayer
353  * so you don't have to delete this GlLayer
354  */
355  bool addExistingLayerBefore(GlLayer *layer, const std::string &beforeLayerWithName);
356 
357  /**
358  * @brief Add an existing layer in the scene just after layer with given name
359  * Return false if the layer with beforeLayerWithName is not find
360  * Now the scene have the ownership of this GlLayer
361  * so you don't have to delete this GlLayer
362  */
363  bool addExistingLayerAfter(GlLayer *layer, const std::string &afterLayerWithName);
364 
365  /**
366  * @brief Return the layer with name : name
367  * Return NULL if the layer doesn't exist in the scene
368  */
369  GlLayer *getLayer(const std::string& name);
370 
371  /**
372  * @brief Remove the layer with name
373  * This GlLayer is automaticaly delete
374  * If you want to keep this GlLayer you can put false to deleteLayer parameters
375  * but after that you have the ownership of the GlLayer
376  */
377  void removeLayer(const std::string& name,bool deleteLayer=true);
378 
379  /**
380  * @brief Remove the layer with name
381  * This GlLayer is automaticaly delete
382  * If you want to keep this GlLayer you can put false to deleteLayer parameters
383  * but after that you have the ownership of the GlLayer
384  */
385  void removeLayer(GlLayer *layer,bool deleteLayer=true);
386 
387  /**
388  * @brief Return the layer list
389  */
390  const std::vector<std::pair<std::string, GlLayer*> > &getLayersList() {
391  return layersList;
392  }
393 
394  /**
395  * @brief Clear layers list
396  * Layers will not be deleted in this function
397  */
399  for(std::vector<std::pair<std::string,GlLayer*> >::iterator it=layersList.begin(); it!=layersList.end(); ++it)
400  delete it->second;
401 
402  layersList.clear();
403  }
404 
405  /**
406  * @brief Get XML description of the scene and children and store it in out string
407  */
408  void getXML(std::string &out);
409 
410  /**
411  * @brief Get XML description of cameras of the scene and store it in out string
412  */
413  void getXMLOnlyForCameras(std::string &out);
414 
415  /**
416  * @brief Set scene's data and children with a XML
417  */
418  void setWithXML(std::string &in,Graph *graph);
419 
420  /**
421  * @brief Return lod calculator used to render this scene
422  */
423  GlLODCalculator *getCalculator() {
424  return lodCalculator;
425  }
426 
427  /**
428  * @brief Set a new lod calculator used to render this scene
429  */
430  void setCalculator(GlLODCalculator *calculator) {
431  lodCalculator=calculator;
432  calculator->setScene(*this);
433  }
434 
435  /**
436  * @brief Return the bouding box of the scene (in 3D coordinates)
437  * \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
438  */
439  BoundingBox getBoundingBox();
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!=NULL);
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!=NULL);
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 private:
488 
489  std::vector<std::pair<std::string,GlLayer *> > layersList;
490  GlLODCalculator *lodCalculator;
491  Vector<int, 4> viewport;
492  Color backgroundColor;
493  bool viewOrtho;
494 
495  GlGraphComposite *glGraphComposite;
496  GlLayer *graphLayer;
497 
498  bool clearBufferAtDraw;
499 
500  bool inDraw;
501 
502 public:
503 
504  ///@cond DOXYGEN_HIDDEN
505 
506  /**
507  * @brief You don't have to call this function
508  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
509  * You don't have to call this function
510  */
511  void glGraphCompositeAdded(GlLayer *layer,GlGraphComposite *composite);
512 
513  /**
514  * @brief You don't have to call this function
515  * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
516  * You don't have to call this function
517  */
518  void glGraphCompositeRemoved(GlLayer *layer,GlGraphComposite *composite);
519 
520  /**
521  * @brief You don't have to call this function
522  * This function is called by GlLayer and GlComposite to send layer modification event
523  */
524  void notifyModifyLayer(const std::string &name,GlLayer *layer);
525 
526  /**
527  * @brief You don't have to call these functions
528  * They are called by GlComposite to send entity modification event
529  */
530  void notifyModifyEntity(GlSimpleEntity *entity);
531  void notifyDeletedEntity(GlSimpleEntity *entity);
532 
533  ///@endcond
534 
535 };
536 
537 }
538 
539 #endif // Tulip_GLSCENE_H