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