Tulip  4.6.0
Better Visualization Through Research
library/tulip-ogl/include/tulip/GlScene.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 
00020 #ifndef Tulip_GLSCENE_H
00021 #define Tulip_GLSCENE_H
00022 
00023 #include <tulip/tulipconf.h>
00024 #include <tulip/GlLODCalculator.h>
00025 #include <tulip/GlLayer.h>
00026 #include <tulip/Color.h>
00027 #include <tulip/Observable.h>
00028 
00029 namespace tlp {
00030 
00031 class GlSimpleEntity;
00032 class Graph;
00033 class GlLODCalculator;
00034 class GlGraphComposite;
00035 
00036 /**
00037  * @ingroup OpenGL
00038  * @brief Structure to store selected entities
00039  *
00040  * After a selection, objects of SelectedEntity is returned
00041  * To use this object the first thing to do is to call getEntity type to know the type of Entity
00042  * After that you can :
00043  *   - Get the GlSimpleEnity pointer (getSimpleEntity())
00044  *   - Get the id of node/edge and the graph associated (getComplexEntityId() and getComplexEntityGraph())
00045  *
00046  */
00047 struct SelectedEntity {
00048 
00049   enum SelectedEntityType {
00050     UNKNOW_SELECTED = 0,
00051     NODE_SELECTED = 1,
00052     EDGE_SELECTED = 2,
00053     SIMPLE_ENTITY_SELECTED = 3
00054   };
00055 
00056   SelectedEntity():simpleEntity(NULL),complexEntityId((unsigned int)(-1)),entityType(UNKNOW_SELECTED),complexEntityGraph(NULL) {}
00057   SelectedEntity(GlSimpleEntity *entity):simpleEntity(entity),complexEntityId((unsigned int)(-1)),entityType(SIMPLE_ENTITY_SELECTED),complexEntityGraph(NULL) {}
00058   SelectedEntity(Graph *graph,unsigned int id,SelectedEntityType type):simpleEntity(NULL),complexEntityId(id),entityType(type),complexEntityGraph(graph) {}
00059 
00060   GlSimpleEntity *getSimpleEntity() const {
00061     assert(simpleEntity!=NULL);
00062     return simpleEntity;
00063   }
00064 
00065   unsigned int getComplexEntityId() const {
00066     assert(complexEntityId!=(unsigned int)(-1));
00067     return complexEntityId;
00068   }
00069 
00070   Graph *getComplexEntityGraph() const {
00071     assert(complexEntityGraph!=NULL);
00072     return complexEntityGraph;
00073   }
00074 
00075   SelectedEntityType getEntityType() const {
00076     return entityType;
00077   }
00078   /**
00079    * @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
00080    * @code
00081    * if(getComplexEntityType()==NODE_SELECTED){
00082    *    return node(getComplexEntityId())
00083    * }
00084    * @endcode
00085    * @return the selected node if the entity type is correct or an invalid node else.
00086    */
00087   node getNode()const {
00088     if(entityType == NODE_SELECTED) {
00089       return node(complexEntityId);
00090     }
00091     else {
00092       return node();
00093     }
00094   }
00095 
00096   /**
00097    * @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
00098    * @code
00099    * if(getComplexEntityType()==EDGE_SELECTED){
00100    *    return edge(getComplexEntityId())
00101    * }
00102    * @endcode
00103    * @return the selected edge if the entity type is correct or an invalid edge else.
00104    */
00105   edge getEdge()const {
00106     if(entityType == EDGE_SELECTED) {
00107       return edge(complexEntityId);
00108     }
00109     else {
00110       return edge();
00111     }
00112   }
00113 
00114 protected :
00115 
00116   GlSimpleEntity *simpleEntity;
00117   unsigned int complexEntityId;
00118   SelectedEntityType entityType;
00119   Graph *complexEntityGraph;
00120 };
00121 
00122 
00123 /**
00124  * @ingroup OpenGL
00125  * @brief Tulip scene class
00126  *
00127  * The GlScene class is the core of the tulip rendering system
00128  * This class is used to render entities and graph in OpenGL
00129  *
00130  * If you want to render entities and graph, you have to use GlLayer system. You just have to create GlLayer and add GlEntity in.
00131  * If you create more than one GlLayer, layers are rendered one after one, so the first GlLayer added is rendered in first.
00132  * @see GlLayer
00133  * @see GlSimpleEntity
00134  *
00135  *
00136  * After adding layers you can do a centerScene() and a draw()
00137  *
00138  * \code
00139  * GlLayer *mainLayer=new GlLayer("Main");
00140  * GlGraphComposite *graphComposite=new GlGraphComposite(graph);
00141  * mainLayer->addGlEntity(graphComposite,"graph");
00142  * GlLayer *otherLayer=new GlLayer("Other");
00143  * GlCircle *circle=new GlCircle();
00144  * otherLayer->addGlEntity(circle,"circle");
00145  * glScene.addLayer(mainLayer);
00146  * glScene.addLayer(otherLayer);
00147  * glScene.centerScene();
00148  * glScene.draw();
00149  * \endcode
00150  *
00151  * If you want to create a widget with a visualisation is better to use GlMainWidget class (this class use a GlScene inside)
00152  */
00153 class TLP_GL_SCOPE GlScene : public Observable {
00154 
00155 public:
00156   /** \brief Constructor
00157    * Default scene is empty
00158    * @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
00159    * Available calculators are : GlCPULODCalculator and GlQuadTreeLODCalculator
00160    */
00161   GlScene(GlLODCalculator *calculator=NULL);
00162 
00163   ~GlScene();
00164 
00165   /**
00166    * @brief Init scene's OpenGL parameters.
00167    * You don't have to call this function, it is call when you do a draw
00168    */
00169   void initGlParameters();
00170 
00171   /**
00172    * @brief Draw the scene
00173    * This function is the most important function of GlScene. If you want to render a scene into an OpenGL widget : call this function
00174    */
00175   void draw();
00176 
00177   /**
00178    * Center scene
00179    * After this function all entities are visible on the screen
00180    */
00181   void centerScene();
00182 
00183   /**
00184    * Compute information for ajustSceneToSize
00185    * \param width : request width
00186    * \param height : request height
00187    * \param center : the result center will be stored in (if center != NULL)
00188    * \param eye : the result eye will be stored in (if eye != NULL)
00189    * \param sceneRadius : the result sceneRadius will be stored in (if sceneRadius != NULL)
00190    * \param xWhiteFactor : xWhiteFactor is the white part on x borders (left and right), the result xWhiteFactor will be stored in (if xWhiteFactor != NULL)
00191    * \param yWhiteFactor : yWhiteFactor is the white part on y borders (top and bottom), the result yWhiteFactor will be stored in (if yWhiteFactor != NULL)
00192    * \param sceneBoundingBox : the result sceneBoundingBox will be stored in (if sceneBoundingBox != NULL)
00193    */
00194   void computeAjustSceneToSize(int width, int height, Coord *center, Coord *eye, float *sceneRadius, float *xWhiteFactor, float *yWhiteFactor,BoundingBox *sceneBoundingBox=NULL,float *zoomFactor=NULL);
00195 
00196   /**
00197    * Ajust camera to have entities near borders
00198    * @param width requested width
00199    * @param height requested height
00200    */
00201   void ajustSceneToSize(int width, int height);
00202 
00203   /**
00204    * @brief Zoom by step to given x,y screen coordinates
00205    * @param step of zoom
00206    */
00207   void zoomXY(int step, const int x, const int y);
00208 
00209   /**
00210    * @brief Zoom to given world coordinate
00211    * \warning factor parameter isn't be used
00212    */
00213   void zoom(float factor,const Coord& dest);
00214 
00215   /**
00216    * @brief Zoom by step
00217    * @param step of zoom
00218    */
00219   void zoom(int step);
00220 
00221   /**
00222    * @brief Zoom by factor
00223    * @param factor of zoom
00224    */
00225   void zoomFactor(float factor);
00226 
00227   /**
00228    * @brief Translate camera by (x,y,z)
00229    */
00230   void translateCamera(const int x, const int y, const int z);
00231 
00232   /**
00233    * @brief Rotate camera by (x,y,z)
00234    * @param x rotation over X axis in degree
00235    * @param y rotation over Y axis in degree
00236    * @param z rotation over Z axis in degree
00237    */
00238   void rotateScene(const int x, const int y, const int z);
00239 
00240   /**
00241    * @brief Select entities in scene
00242    * @param type Entities type to select (SelectSimpleEntities,SelectNodes,SelectEdges)
00243    * @param x screen coordinates
00244    * @param y screen coordinates
00245    * @param h height in screen coordinates
00246    * @param w width in screen coordinates
00247    * @param layer where the selection will be performed
00248    * @param selectedEntities the result of the selection is stored on it
00249    */
00250   bool selectEntities(RenderingEntitiesFlag type, int x, int y, int h, int w,GlLayer *layer,std::vector<SelectedEntity>& selectedEntities);
00251 
00252   /**
00253    * @brief Output the scene in SVG
00254    */
00255   void outputSVG(unsigned int size,const std::string& filename);
00256 
00257   /**
00258    * @brief Output the scene in EPS
00259    */
00260   void outputEPS(unsigned int size,const std::string& filename);
00261 
00262   /**
00263    * @brief Return the RGB image of GlScene
00264    */
00265   unsigned char * getImage();
00266 
00267   /**
00268    * @brief Set the viewport of the scene with a vector
00269    * The viewport must be in many case the size of the widget containing the scene
00270    */
00271   void setViewport(Vector<int, 4> &newViewport) {
00272     viewport=newViewport;
00273   }
00274 
00275   /**
00276    * @brief Set the viewport of the scene with 4 int
00277    * The viewport must be in many case the size of the widget containing the scene
00278    */
00279   void setViewport(int x, int y, int width, int height) {
00280     viewport[0]=x;
00281     viewport[1]=y;
00282     viewport[2]=width;
00283     viewport[3]=height;
00284   }
00285 
00286   /**
00287    * @brief Get the viewport of the scene
00288    * The viewport will be in many case the size of the widget containing the scene
00289    */
00290   Vector<int, 4> getViewport() const {
00291     return viewport;
00292   }
00293 
00294   /**
00295    * @brief Set the background color of the scene
00296    */
00297   void setBackgroundColor(const Color& color) {
00298     backgroundColor=color;
00299   }
00300 
00301   /**
00302    * @brief Get the background color of the scene
00303    */
00304   Color getBackgroundColor() const {
00305     return backgroundColor;
00306   }
00307 
00308   /**
00309    * @brief Set if scene is render in orthogonal mode
00310    */
00311   void setViewOrtho(bool viewOrtho) {
00312     this->viewOrtho=viewOrtho;
00313   }
00314 
00315   /**
00316    * @brief Scene is render in orthogonal mode ?
00317    */
00318   bool isViewOrtho() {
00319     return viewOrtho;
00320   }
00321 
00322   /**
00323    * @brief Create a layer with the given name in the scene
00324    * This layer is added to the layers list
00325    * Now the scene have the ownership of this GlLayer
00326    * so you don't have to delete this GlLayer
00327    */
00328   GlLayer *createLayer(const std::string &name);
00329 
00330   /**
00331    * @brief Create a layer with the given name in the scene just before layer with given name
00332    * This layer is added to the layers list
00333    * Return NULL if the layer with beforeLayerWithName is not find
00334    * Now the scene have the ownership of this GlLayer
00335    * so you don't have to delete this GlLayer
00336    */
00337   GlLayer *createLayerBefore(const std::string &layerName,const std::string &beforeLayerWithName);
00338 
00339   /**
00340    * @brief Create a layer with the given name in the scene just after layer with given name
00341    * This layer is added to the layers list
00342    * Return NULL if the layer with beforeLayerWithName is not find
00343    * Now the scene have the ownership of this GlLayer
00344    * so you don't have to delete this GlLayer
00345    */
00346   GlLayer *createLayerAfter(const std::string &layerName,const std::string &afterLayerWithName);
00347 
00348   /**
00349    * @brief Add an existing layer in the scene
00350    * Now the scene have the ownership of this GlLayer
00351    * so you don't have to delete this GlLayer
00352    */
00353   void addExistingLayer(GlLayer *layer);
00354 
00355   /**
00356    * @brief Add an existing layer in the scene just before layer with given name
00357    * Return false if the layer with beforeLayerWithName is not find
00358    * Now the scene have the ownership of this GlLayer
00359    * so you don't have to delete this GlLayer
00360    */
00361   bool addExistingLayerBefore(GlLayer *layer, const std::string &beforeLayerWithName);
00362 
00363   /**
00364    * @brief Add an existing layer in the scene just after layer with given name
00365    * Return false if the layer with beforeLayerWithName is not find
00366    * Now the scene have the ownership of this GlLayer
00367    * so you don't have to delete this GlLayer
00368    */
00369   bool addExistingLayerAfter(GlLayer *layer, const std::string &afterLayerWithName);
00370 
00371   /**
00372    * @brief Return the layer with name : name
00373    * Return NULL if the layer doesn't exist in the scene
00374    */
00375   GlLayer *getLayer(const std::string& name);
00376 
00377   /**
00378    * @brief Remove the layer with name
00379    * This GlLayer is automaticaly delete
00380    * If you want to keep this GlLayer you can put false to deleteLayer parameters
00381    * but after that you have the ownership of the GlLayer
00382    */
00383   void removeLayer(const std::string& name,bool deleteLayer=true);
00384 
00385   /**
00386    * @brief Remove the layer with name
00387    * This GlLayer is automaticaly delete
00388    * If you want to keep this GlLayer you can put false to deleteLayer parameters
00389    * but after that you have the ownership of the GlLayer
00390    */
00391   void removeLayer(GlLayer *layer,bool deleteLayer=true);
00392 
00393   /**
00394    * @brief Return the layer list
00395    */
00396   const std::vector<std::pair<std::string, GlLayer*> > &getLayersList() {
00397     return layersList;
00398   }
00399 
00400   /**
00401    * @brief Clear layers list
00402    * Layers will not be deleted in this function
00403    */
00404   void clearLayersList() {
00405     for(std::vector<std::pair<std::string,GlLayer*> >::iterator it=layersList.begin(); it!=layersList.end(); ++it)
00406       delete it->second;
00407 
00408     layersList.clear();
00409   }
00410 
00411   /**
00412    * @brief Get XML description of the scene and children and store it in out string
00413    */
00414   void getXML(std::string &out);
00415 
00416   /**
00417    * @brief Get XML description of cameras of the scene and store it in out string
00418    */
00419   void getXMLOnlyForCameras(std::string &out);
00420 
00421   /**
00422    * @brief Set scene's data and children with a XML
00423    */
00424   void setWithXML(std::string &in,Graph *graph);
00425 
00426   /**
00427    * @brief Return lod calculator used to render this scene
00428    */
00429   GlLODCalculator *getCalculator() {
00430     return lodCalculator;
00431   }
00432 
00433   /**
00434    * @brief Set a new lod calculator used to render this scene
00435    */
00436   void setCalculator(GlLODCalculator *calculator) {
00437     lodCalculator=calculator;
00438     calculator->setScene(*this);
00439   }
00440 
00441   /**
00442    * @brief Return the bouding box of the scene (in 3D coordinates)
00443    * \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
00444    */
00445   BoundingBox getBoundingBox();
00446 
00447   /**
00448    * @brief Return the current GlGraphComposite used by the scene
00449    */
00450   GlGraphComposite* getGlGraphComposite() {
00451     return glGraphComposite;
00452   }
00453 
00454   /**
00455    * @brief Return the layer containing the current GlGraphComposite
00456    */
00457   GlLayer* getGraphLayer() {
00458     return graphLayer;
00459   }
00460 
00461   /**
00462    * @brief By default the most important layer is the layer where the graph is visualized
00463    * This function return the camera of this layer
00464    */
00465   Camera& getGraphCamera() {
00466     assert(graphLayer!=NULL);
00467     return graphLayer->getCamera();
00468   }
00469 
00470   /**
00471    * @brief By default the most important layer is the layer where the graph is visualized
00472    * This function set the camera of this layer
00473    */
00474   void setGraphCamera(Camera* camera) {
00475     assert(graphLayer!=NULL);
00476     graphLayer->setCamera(camera);
00477   }
00478 
00479   /**
00480    * @brief Set if OpenGL buffer will be cleared at draw
00481    */
00482   void setClearBufferAtDraw(bool clear) {
00483     clearBufferAtDraw = clear;
00484   }
00485 
00486   /**
00487    * @brief If false, color buffer will not be cleared before drawing the scene.
00488    */
00489   bool getClearBufferAtDraw() const {
00490     return clearBufferAtDraw;
00491   }
00492 
00493 private:
00494 
00495   std::vector<std::pair<std::string,GlLayer *> > layersList;
00496   GlLODCalculator *lodCalculator;
00497   Vector<int, 4> viewport;
00498   Color backgroundColor;
00499   bool viewOrtho;
00500 
00501   GlGraphComposite *glGraphComposite;
00502   GlLayer *graphLayer;
00503 
00504   bool clearBufferAtDraw;
00505 
00506   bool inDraw;
00507 
00508 public:
00509 
00510   ///@cond DOXYGEN_HIDDEN
00511 
00512   /**
00513    * @brief You don't have to call this function
00514    * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
00515    * You don't have to call this function
00516    */
00517   void glGraphCompositeAdded(GlLayer *layer,GlGraphComposite *composite);
00518 
00519   /**
00520    * @brief You don't have to call this function
00521    * This function is automaticaly call when a GlGraphComposite is added in a layer in the scene
00522    * You don't have to call this function
00523    */
00524   void glGraphCompositeRemoved(GlLayer *layer,GlGraphComposite *composite);
00525 
00526   /**
00527    * @brief You don't have to call this function
00528    * This function is called by GlLayer and GlComposite to send layer modification event
00529    */
00530   void notifyModifyLayer(const std::string &name,GlLayer *layer);
00531 
00532   /**
00533    * @brief You don't have to call these functions
00534    * They are called by GlComposite to send entity modification event
00535    */
00536   void notifyModifyEntity(GlSimpleEntity *entity);
00537   void notifyDeletedEntity(GlSimpleEntity *entity);
00538 
00539   ///@endcond
00540 
00541 };
00542 
00543 }
00544 
00545 #endif // Tulip_GLSCENE_H
 All Classes Files Functions Variables Enumerations Enumerator Properties