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