Tulip
4.6.0
Better Visualization Through Research
|
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