LCOV - code coverage report
Current view: top level - ugbase/lib_grid/grid - grid_connection_managment.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 15.8 % 1136 180
Test Date: 2025-09-21 23:31:46 Functions: 26.8 % 56 15

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : ////////////////////////////////////////////////////////////////////////
      34              : ////////////////////////////////////////////////////////////////////////
      35              : /*
      36              :  * In this file the the grids connectivity-management is implemented.
      37              :  * The methods change_vertex_options(...), change_edge_options, ...
      38              :  * attach and detach Containers to vertices, edges, ... in order to
      39              :  * store associated elements, as specified in the passed options.
      40              :  * The generated data can be accessed through Grids
      41              :  * get_associated_edges, get_associated_faces, ... methods later on.
      42              :  *
      43              :  * New edges, faces and volumes have to be registered with other objects
      44              :  * directly after creation. For this task the methods
      45              :  * register_edge, register_face, ... are supplied.
      46              :  * On the other hand Grid has to update connectivity information, as
      47              :  * soon as grid-elements are removed. for these tasks the methods
      48              :  * unregister_edge, unregister_face, ... are supplied.
      49              :  */
      50              : ////////////////////////////////////////////////////////////////////////
      51              : ////////////////////////////////////////////////////////////////////////
      52              : 
      53              : 
      54              : #include <algorithm>
      55              : #include "grid.h"
      56              : #include "grid_util.h"
      57              : #include "common/common.h"
      58              : #include "common/profiler/profiler.h"
      59              : 
      60              : using namespace std;
      61              : 
      62              : ////////////////////////////////////////////////////////////////////////
      63              : //define PROFILE_GRID_CONNECTION_MANAGMENT if you want to profile
      64              : //the code below.
      65              : //#define PROFILE_GRID_CONNECTION_MANAGMENT
      66              : #ifdef PROFILE_GRID_CONNECTION_MANAGMENT
      67              :         #define GCM_PROFILE_FUNC()      PROFILE_FUNC()
      68              :         #define GCM_PROFILE(name)       PROFILE_BEGIN(name)
      69              :         #define GCM_PROFILE_END()       PROFILE_END()
      70              : #else
      71              :         #define GCM_PROFILE_FUNC()
      72              :         #define GCM_PROFILE(name)
      73              :         #define GCM_PROFILE_END()
      74              : #endif
      75              : 
      76              : 
      77              : ////////////////////////////////////////////////////////////////////////
      78              : ///     this macro helps calling callbacks of different observers.
      79              : /**
      80              :  * Be sure that callback is a complete function call - including parameters.
      81              :  */
      82              : #define NOTIFY_OBSERVERS(observerContainer, callback)   {for(Grid::ObserverContainer::iterator iter = observerContainer.begin(); iter != observerContainer.end(); iter++) (*iter)->callback;}
      83              : #define NOTIFY_OBSERVERS_REVERSE(observerContainer, callback)   {for(Grid::ObserverContainer::reverse_iterator iter = observerContainer.rbegin(); iter != observerContainer.rend(); iter++) (*iter)->callback;}
      84              : 
      85              : ////////////////////////////////////////////////////////////////////////
      86              : ///     a useful macro that checks if a set of options contains the specified option.
      87              : #define OPTIONS_CONTAIN_OPTION(options, option) (((options) & (option)) == (option))
      88              : 
      89              : 
      90              : namespace ug
      91              : {
      92              : 
      93              : ////////////////////////////////////////////////////////////////////////
      94              : ////////////////////////////////////////////////////////////////////////
      95              : //      VERTICES
      96              : ///     creates and removes connectivity data, as specified in optsNew.
      97            3 : void Grid::register_vertex(Vertex* v, GridObject* pParent)
      98              : {
      99              :         GCM_PROFILE_FUNC();
     100              : 
     101              : //      store the element and register it at the pipe.
     102            3 :         m_vertexElementStorage.m_attachmentPipe.register_element(v);
     103            3 :         m_vertexElementStorage.m_sectionContainer.insert(v, v->container_section());
     104              : 
     105              : //      assign the hash-value
     106              :         assign_hash_value(v);
     107              : 
     108              :         GCM_PROFILE(GCM_notify_vertex_observers);
     109              : //      inform observers about the creation
     110            3 :         NOTIFY_OBSERVERS(m_vertexObservers, vertex_created(this, v, pParent));
     111              :         GCM_PROFILE_END();
     112            3 : }
     113              : 
     114            0 : void Grid::register_and_replace_element(Vertex* v, Vertex* pReplaceMe)
     115              : {
     116            0 :         m_vertexElementStorage.m_attachmentPipe.register_element(v);
     117            0 :         m_vertexElementStorage.m_sectionContainer.insert(v, v->container_section());
     118              : 
     119              : //      assign the hash-value
     120              :         assign_hash_value(v);
     121              : 
     122              : //      pass on values
     123            0 :         pass_on_values(pReplaceMe, v);
     124              : 
     125              : //      inform observers about the creation
     126            0 :         NOTIFY_OBSERVERS(m_vertexObservers, vertex_created(this, v, pReplaceMe, true));
     127              : //      inform observers about the deletion
     128            0 :         NOTIFY_OBSERVERS_REVERSE(m_vertexObservers,
     129              :                                                          vertex_to_be_erased(this, pReplaceMe, v));
     130              : 
     131              : //      all edges, faces and volumes associated with pReplaceMe have to be updated.
     132              : //      the options in GRIDOPT_VERTEXCENTRIC_INTERCONNECTION have to be enabled.
     133              : //      we do this per element only, to avoid unnecessary memory overhead.
     134              : 
     135              : //      update edges
     136            0 :         if(num_edges()){
     137            0 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES)){
     138              :                         LOG("WARNING in Grid::register_and_replace_element(...) - Vertex: autoenabling grid-option VRTOPT_STORE_ASSOCIATED_EDGES.");
     139            0 :                         enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
     140              :                 }
     141              : 
     142            0 :                 for(AssociatedEdgeIterator iter = associated_edges_begin(pReplaceMe);
     143            0 :                         iter != associated_edges_end(pReplaceMe); ++iter)
     144              :                 {
     145            0 :                         Edge* e = *iter;
     146              :                 //      replace the vertex and push e into v's associated edges.
     147            0 :                         for(uint i = 0; i < 2; ++i)
     148              :                         {
     149            0 :                                 if(e->vertex(i) == pReplaceMe)
     150              :                                         e->set_vertex(i, v);
     151              :                         }
     152              : 
     153            0 :                         m_aaEdgeContainerVERTEX[v].push_back(e);
     154              :                 }
     155              :         }
     156              : 
     157              : //      update faces
     158            0 :         if(num_faces()){
     159            0 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES)){
     160              :                         LOG("WARNING in Grid::register_and_replace_element(...) - Vertex: autoenabling grid-option VRTOPT_STORE_ASSOCIATED_FACES.");
     161            0 :                         enable_options(VRTOPT_STORE_ASSOCIATED_FACES);
     162              :                 }
     163              : 
     164            0 :                 for(AssociatedFaceIterator iter = associated_faces_begin(pReplaceMe);
     165            0 :                         iter != associated_faces_end(pReplaceMe); ++iter)
     166              :                 {
     167            0 :                         Face* f = *iter;
     168              :                 //      replace the vertex and push f into v's associated faces.
     169            0 :                         uint numVrts = f->num_vertices();
     170            0 :                         Face::ConstVertexArray vrts = f->vertices();
     171            0 :                         for(uint i = 0; i < numVrts; ++i)
     172              :                         {
     173            0 :                                 if(vrts[i] == pReplaceMe)
     174            0 :                                         f->set_vertex(i, v);
     175              :                         }
     176              : 
     177            0 :                         m_aaFaceContainerVERTEX[v].push_back(f);
     178              :                 }
     179              :         }
     180              : 
     181              : //      update volumes
     182            0 :         if(num_volumes()){
     183            0 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES)){
     184              :                         LOG("WARNING in Grid::register_and_replace_element(...) - Vertex: autoenabling grid-option VRTOPT_STORE_ASSOCIATED_VOLUMES.");
     185            0 :                         enable_options(VRTOPT_STORE_ASSOCIATED_VOLUMES);
     186              :                 }
     187              : 
     188            0 :                 for(AssociatedVolumeIterator iter = associated_volumes_begin(pReplaceMe);
     189            0 :                         iter != associated_volumes_end(pReplaceMe); ++iter)
     190              :                 {
     191            0 :                         Volume* vol = *iter;
     192              :                 //      replace the vertex and push vol into v's associated volumes.
     193            0 :                         uint numVrts = vol->num_vertices();
     194            0 :                         Volume::ConstVertexArray vrts = vol->vertices();
     195            0 :                         for(uint i = 0; i < numVrts; ++i)
     196              :                         {
     197            0 :                                 if(vrts[i] == pReplaceMe)
     198            0 :                                         vol->set_vertex(i, v);
     199              :                         }
     200              : 
     201            0 :                         m_aaVolumeContainerVERTEX[v].push_back(vol);
     202              :                 }
     203              :         }
     204              : 
     205              : //      clear the containers of pReplaceMe
     206            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     207              :                 m_aaEdgeContainerVERTEX[pReplaceMe].clear();
     208            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     209              :                 m_aaFaceContainerVERTEX[pReplaceMe].clear();
     210            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     211              :                 m_aaVolumeContainerVERTEX[pReplaceMe].clear();
     212              : 
     213              : //      remove pReplaceMe
     214            0 :         m_vertexElementStorage.m_attachmentPipe.unregister_element(pReplaceMe);
     215            0 :         m_vertexElementStorage.m_sectionContainer.erase(get_iterator(pReplaceMe), pReplaceMe->container_section());
     216            0 :         delete pReplaceMe;
     217            0 : }
     218              : 
     219            3 : void Grid::unregister_vertex(Vertex* v)
     220              : {
     221              : //      notify observers that the vertex is being erased
     222            3 :         NOTIFY_OBSERVERS_REVERSE(m_vertexObservers, vertex_to_be_erased(this, v));
     223              : 
     224              : //      perform some checks in order to assert grid consistency.
     225              : //      all edges, faces and volume referencing this vertex have to be erased.
     226              : 
     227            3 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     228              :         {
     229              :         //      if there are edges this option has to be enabled!
     230            3 :                 if(num_edges() > 0)
     231              :                 {
     232              :                         LOG("WARNING in Grid::unregister_vertex(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << std::endl);
     233            0 :                         vertex_store_associated_edges(true);
     234              :                 }
     235              :         }
     236              : 
     237            3 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     238              :         {
     239              :         //      if there are faces we have to consider the following
     240            3 :                 if(num_faces() > 0)
     241              :                 {
     242              :                 //      if edges store associated faces and if faces auto-generate edges, then
     243              :                 //      nothing has to be performed here.
     244            0 :                         if(!(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES)
     245            0 :                                  &&     option_is_enabled(FACEOPT_AUTOGENERATE_EDGES)))
     246              :                         {
     247              :                         //      since adjacent faces have to be removed, we have to enable VRTOPT_STORE_ASSOCIATED_FACES
     248              :                                 LOG("WARNING in Grid::unregister_vertex(...): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << std::endl);
     249            0 :                                 vertex_store_associated_faces(true);
     250              :                         }
     251              :                 }
     252              :         }
     253              : 
     254            3 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     255              :         {
     256              :         //      if there are volumes we have to consider the following
     257            3 :                 if(num_volumes() > 0)
     258              :                 {
     259              :                 //      if edges store associated volumes and volumes auto-generate edges or
     260              :                 //      if faces store associated volumes and volumes auto-generate faces then
     261              :                 //      nothing has to be performed here.
     262            0 :                         bool cond1 =    option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES) &&
     263            0 :                                                         option_is_enabled(VOLOPT_AUTOGENERATE_EDGES);
     264            0 :                         bool cond2 =    option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES) &&
     265            0 :                                                         option_is_enabled(VOLOPT_AUTOGENERATE_FACES);
     266              : 
     267            0 :                         if(!(cond1 || cond2))
     268              :                         {
     269              :                         //      since we have to remove adjacent volumes we have to enable VRTOPT_STORE_ASSOCIATED_VOLUMES
     270              :                                 LOG("WARNING in Grid::unregister_vertex(...): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << std::endl);
     271            0 :                                 vertex_store_associated_volumes(true);
     272              :                         }
     273              :                 }
     274              :         }
     275              : 
     276              : //      remove associated volumes
     277            3 :         if(num_volumes() > 0)
     278              :         {
     279            0 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     280              :                 {
     281              :                 //      remove associated volumes. Make sure that there are no problems
     282              :                 //      when volumes try to unregister from the vertex.
     283              :                         VolumeContainer vols;
     284            0 :                         vols.swap(m_aaVolumeContainerVERTEX[v]);
     285              : 
     286            0 :                         for(VolumeContainer::iterator iter = vols.begin(); iter != vols.end();)
     287              :                         {
     288            0 :                                 Volume* eraseVol = *iter;
     289              :                                 ++iter;
     290            0 :                                 erase(eraseVol);
     291              :                         }
     292            0 :                 }
     293              :         }
     294              : 
     295              : //      remove associated faces
     296            3 :         if(num_faces() > 0)
     297              :         {
     298            0 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     299              :                 {
     300              :                 //      remove all associated faces. Make sure that there are no problems
     301              :                 //      when faces try to unregister from the vertex.
     302              :                         FaceContainer faces;
     303            0 :                         faces.swap(m_aaFaceContainerVERTEX[v]);
     304            0 :                         for(FaceContainer::iterator iter = faces.begin(); iter != faces.end();)
     305              :                         {
     306            0 :                                 Face* eraseFace = *iter;
     307              :                                 ++iter;
     308            0 :                                 erase(eraseFace);
     309              :                         }
     310            0 :                 }
     311              :         }
     312              : 
     313              : //      remove associated edges
     314            3 :         if(num_edges() > 0)
     315              :         {
     316              :                 assert(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES) && "unexpected internal error in Grid::unregister_vertex - rae.");
     317              :         //      remove all associated edges. Make sure that there are no problems
     318              :         //      when edges try to unregister from the vertex.
     319              :                 EdgeContainer edges;
     320            0 :                 edges.swap(m_aaEdgeContainerVERTEX[v]);
     321            0 :                 for(EdgeContainer::iterator iter = edges.begin(); iter != edges.end();)
     322              :                 {
     323            0 :                         Edge* eraseEdge = *iter;
     324              :                         ++iter;
     325            0 :                         erase(eraseEdge);
     326              :                 }
     327            0 :         }
     328              : 
     329              : //      remove the element from the storage
     330            3 :         m_vertexElementStorage.m_sectionContainer.erase(get_iterator(v), v->container_section());
     331            3 :         m_vertexElementStorage.m_attachmentPipe.unregister_element(v);
     332            3 : }
     333              : 
     334            3 : void Grid::change_vertex_options(uint optsNew)
     335              : {
     336              : //      check if associated edge information has to be created or removed.
     337            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VRTOPT_STORE_ASSOCIATED_EDGES))
     338              :         {
     339            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES)){
     340            2 :                         vertex_store_associated_edges(true);
     341              :                 }
     342              :         }
     343              :         else
     344              :         {
     345            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES)){
     346            1 :                         vertex_store_associated_edges(false);
     347              :                 }
     348              :         }
     349              : 
     350              : //      check if associated face information has to be created or removed.
     351            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VRTOPT_STORE_ASSOCIATED_FACES))
     352              :         {
     353            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     354            2 :                         vertex_store_associated_faces(true);
     355              :         }
     356              :         else
     357              :         {
     358            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     359            1 :                         vertex_store_associated_faces(false);
     360              :         }
     361              : 
     362              : //      check if associated volume information has to be created or removed.
     363            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VRTOPT_STORE_ASSOCIATED_VOLUMES))
     364              :         {
     365            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     366            2 :                         vertex_store_associated_volumes(true);
     367              :         }
     368              :         else
     369              :         {
     370            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     371            1 :                         vertex_store_associated_volumes(false);
     372              :         }
     373            3 : }
     374              : 
     375            3 : void Grid::vertex_store_associated_edges(bool bStoreIt)
     376              : {
     377            3 :         if(bStoreIt)
     378              :         {
     379            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     380              :                 {
     381              :                 //      store associated edges
     382            2 :                         attach_to_vertices(m_aEdgeContainer);
     383            2 :                         m_aaEdgeContainerVERTEX.access(*this, m_aEdgeContainer);
     384              : 
     385              :                 //      iterate through all edges and store them in the associated vertices
     386            2 :                         for(EdgeIterator iter = this->edges_begin(); iter != this->edges_end(); iter++)
     387              :                         {
     388            0 :                                 Edge* e = *iter;
     389            0 :                                 m_aaEdgeContainerVERTEX[e->vertex(0)].push_back(e);
     390            0 :                                 m_aaEdgeContainerVERTEX[e->vertex(1)].push_back(e);
     391              :                         }
     392              : 
     393            2 :                         m_options |= VRTOPT_STORE_ASSOCIATED_EDGES;
     394              :                 }
     395              :         }
     396              :         else
     397              :         {
     398            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     399              :                 {
     400            1 :                         detach_from_vertices(m_aEdgeContainer);
     401            1 :                         m_options &= (~VRTOPT_STORE_ASSOCIATED_EDGES);
     402              :                 }
     403              :         }
     404            3 : }
     405              : 
     406            3 : void Grid::vertex_store_associated_faces(bool bStoreIt)
     407              : {
     408            3 :         if(bStoreIt)
     409              :         {
     410            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     411              :                 {
     412              :                 //      store associated faces
     413            2 :                         attach_to_vertices(m_aFaceContainer);
     414            2 :                         m_aaFaceContainerVERTEX.access(*this, m_aFaceContainer);
     415              : 
     416              :                 //      iterator through all faces and store them in the referenced vertices
     417            2 :                         for(FaceIterator iter = this->faces_begin(); iter != this->faces_end(); iter++)
     418              :                         {
     419            0 :                                 Face* f = *iter;
     420            0 :                                 int numVrts = f->num_vertices();
     421            0 :                                 Face::ConstVertexArray vrts = f->vertices();
     422            0 :                                 for(int i = 0; i < numVrts; i++)
     423            0 :                                         m_aaFaceContainerVERTEX[vrts[i]].push_back(f);
     424              :                         }
     425              : 
     426              :                 //      store the option
     427            2 :                         m_options |= VRTOPT_STORE_ASSOCIATED_FACES;
     428              :                 }
     429              :         }
     430              :         else
     431              :         {
     432            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     433              :                 {
     434            1 :                         detach_from_vertices(m_aFaceContainer);
     435            1 :                         m_options &= (~VRTOPT_STORE_ASSOCIATED_FACES);
     436              :                 }
     437              :         }
     438            3 : }
     439              : 
     440            3 : void Grid::vertex_store_associated_volumes(bool bStoreIt)
     441              : {
     442            3 :         if(bStoreIt)
     443              :         {
     444            2 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     445              :                 {
     446              :                 //      store associated volumes
     447            2 :                         attach_to_vertices(m_aVolumeContainer);
     448            2 :                         m_aaVolumeContainerVERTEX.access(*this, m_aVolumeContainer);
     449              : 
     450              :                 //      iterator through all faces and store them in the referenced vertices
     451            2 :                         for(VolumeIterator iter = this->volumes_begin(); iter != this->volumes_end(); iter++)
     452              :                         {
     453            0 :                                 Volume* v = *iter;
     454            0 :                                 int numVrts = v->num_vertices();
     455            0 :                                 Volume::ConstVertexArray vrts = v->vertices();
     456            0 :                                 for(int i = 0; i < numVrts; i++)
     457            0 :                                         m_aaVolumeContainerVERTEX[vrts[i]].push_back(v);
     458              :                         }
     459              : 
     460              :                 //      store the option
     461            2 :                         m_options |= VRTOPT_STORE_ASSOCIATED_VOLUMES;
     462              :                 }
     463              :         }
     464              :         else
     465              :         {
     466            1 :                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     467              :                 {
     468            1 :                         detach_from_vertices(m_aVolumeContainer);
     469            1 :                         m_options &= (~VRTOPT_STORE_ASSOCIATED_VOLUMES);
     470              :                 }
     471              :         }
     472            3 : }
     473              : 
     474              : ////////////////////////////////////////////////////////////////////////
     475              : ////////////////////////////////////////////////////////////////////////
     476              : //      EDGES
     477              : ///     creates and removes connectivity data, as specified in optsNew.
     478            3 : void Grid::register_edge(Edge* e, GridObject* pParent,
     479              :                                                  Face* createdByFace, Volume* createdByVol)
     480              : {
     481              :         GCM_PROFILE_FUNC();
     482              : 
     483              : //      store the element and register it at the pipe.
     484            3 :         m_edgeElementStorage.m_attachmentPipe.register_element(e);
     485            3 :         m_edgeElementStorage.m_sectionContainer.insert(e, e->container_section());
     486              : 
     487              : //      register edge at vertices, faces and volumes, if the according options are enabled.
     488            3 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     489              :         {
     490            3 :                 m_aaEdgeContainerVERTEX[e->vertex(0)].push_back(e);
     491            3 :                 m_aaEdgeContainerVERTEX[e->vertex(1)].push_back(e);
     492              :         }
     493              : 
     494              : //      register edges at faces and vice versa
     495              : //      this is only necessary, if faces do not autogenerate edges
     496            3 :         if(createdByFace != NULL){
     497              :         //      e has been autogenerated by f. We thus have don't have to check
     498              :         //      for other faces. e is already contained in f's edge-container.
     499            3 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     500            0 :                         m_aaFaceContainerEDGE[e].push_back(createdByFace);
     501              :         }
     502              :         else
     503              :         {
     504            0 :                 if(!option_is_enabled(FACEOPT_AUTOGENERATE_EDGES)){
     505              :                         GCM_PROFILE(GCM_reg_edge_processing_faces);
     506              :                         int switchVar = 0;      // this var will be used to determine what to register where.
     507            0 :                         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     508              :                                 switchVar = 1;
     509            0 :                         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
     510            0 :                                 switchVar += 2;
     511              : 
     512            0 :                         if(switchVar > 0)
     513              :                         {
     514              :                         //      find the faces that contain the edge. search the associated vertices for connected faces.
     515            0 :                                 AssociatedFaceIterator iterStart = associated_faces_begin(e->vertex(0));
     516            0 :                                 AssociatedFaceIterator iterEnd = associated_faces_end(e->vertex(0));
     517              : 
     518            0 :                                 EdgeDescriptor ed;
     519            0 :                                 for(AssociatedFaceIterator iter = iterStart; iter != iterEnd; iter++)
     520              :                                 {
     521            0 :                                         Face* f = *iter;
     522              :                                         uint numEdges = f->num_edges();
     523            0 :                                         for(uint i = 0; i < numEdges; ++i)
     524              :                                         {
     525            0 :                                                 f->edge_desc(i, ed);
     526            0 :                                                 if(CompareVertices(e, &ed))
     527              :                                                 {
     528              :                                                 //      f contains e
     529            0 :                                                         switch(switchVar)
     530              :                                                         {
     531            0 :                                                                 case 1: m_aaFaceContainerEDGE[e].push_back(f);
     532              :                                                                                 break;
     533            0 :                                                                 case 2: m_aaEdgeContainerFACE[f].push_back(e);
     534              :                                                                                 break;
     535            0 :                                                                 case 3: m_aaFaceContainerEDGE[e].push_back(f);
     536            0 :                                                                                 m_aaEdgeContainerFACE[f].push_back(e);
     537              :                                                                                 break;
     538              :                                                         }
     539              :                                                 }
     540              :                                         }
     541              :                                 }
     542              :                         }
     543              :                 }
     544              :         }
     545              : 
     546              : //      register edges at volumes and vice versa
     547            3 :         if(createdByVol != NULL){
     548              :         //      e was at least indirectly created by a volume.
     549              :         //      We thus do not have to check for other volumes.
     550              :         //      e is already registered in v's edge-container.
     551            0 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     552            0 :                         m_aaVolumeContainerEDGE[e].push_back(createdByVol);
     553              :         }
     554              :         else
     555              :         {
     556            3 :                 bool ignoreVolumes = option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)
     557            3 :                                                 || (option_is_enabled(VOLOPT_AUTOGENERATE_FACES)
     558            3 :                                                         && option_is_enabled(FACEOPT_AUTOGENERATE_EDGES));
     559              : 
     560              :                 if(!ignoreVolumes){
     561              :                         GCM_PROFILE(GCM_reg_edge_processing_volumes);
     562              :                         int switchVar = 0;      // this var will be used to determine what to register where.
     563            0 :                         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     564              :                                 switchVar = 1;
     565            0 :                         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
     566            0 :                                 switchVar += 2;
     567              : 
     568            0 :                         if(switchVar > 0)
     569              :                         {
     570              :                         //      find the volumes that contain the edge.
     571            0 :                                 AssociatedVolumeIterator iterStart = associated_volumes_begin(e->vertex(0));
     572            0 :                                 AssociatedVolumeIterator iterEnd = associated_volumes_end(e->vertex(0));
     573              : 
     574            0 :                                 for(AssociatedVolumeIterator iter = iterStart; iter != iterEnd; iter++)
     575              :                                 {
     576            0 :                                         Volume* v = *iter;
     577            0 :                                         uint numEdges = v->num_edges();
     578            0 :                                         for(uint i = 0; i < numEdges; ++i)
     579              :                                         {
     580            0 :                                                 EdgeDescriptor ed;
     581            0 :                                                 v->edge_desc(i, ed);
     582            0 :                                                 if(CompareVertices(e, &ed))
     583              :                                                 {
     584              :                                                 //      f contains e
     585            0 :                                                         switch(switchVar)
     586              :                                                         {
     587            0 :                                                                 case 1: m_aaVolumeContainerEDGE[e].push_back(v);
     588              :                                                                                 break;
     589            0 :                                                                 case 2: m_aaEdgeContainerVOLUME[v].push_back(e);
     590              :                                                                                 break;
     591            0 :                                                                 case 3: m_aaVolumeContainerEDGE[e].push_back(v);
     592            0 :                                                                                 m_aaEdgeContainerVOLUME[v].push_back(e);
     593              :                                                                                 break;
     594              :                                                         }
     595              :                                                 }
     596              :                                         }
     597              :                                 }
     598              :                         }
     599              :                 }
     600              :         }
     601              : 
     602              :         GCM_PROFILE(GCM_notify_edge_observers);
     603              : //      inform observers about the creation
     604            3 :         NOTIFY_OBSERVERS(m_edgeObservers, edge_created(this, e, pParent));
     605              :         GCM_PROFILE_END();
     606            3 : }
     607              : 
     608            0 : void Grid::register_and_replace_element(Edge* e, Edge* pReplaceMe)
     609              : {
     610              : //      store the element and register it at the pipe.
     611            0 :         m_edgeElementStorage.m_attachmentPipe.register_element(e);
     612            0 :         m_edgeElementStorage.m_sectionContainer.insert(e, e->container_section());
     613              : 
     614            0 :         pass_on_values(pReplaceMe, e);
     615              : 
     616              : //      assign vertices
     617            0 :         e->set_vertex(0, pReplaceMe->vertex(0));
     618            0 :         e->set_vertex(1, pReplaceMe->vertex(1));
     619              : 
     620              : //      inform observers about the creation
     621            0 :         NOTIFY_OBSERVERS(m_edgeObservers, edge_created(this, e, pReplaceMe, true));
     622              : //      inform observers about the deletion
     623            0 :         NOTIFY_OBSERVERS_REVERSE(m_edgeObservers, edge_to_be_erased(this, pReplaceMe, e));
     624              : 
     625              : //      check if vertices, faces and volumes reference pReplaceMe.
     626              : //      if so, correct those references.
     627            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     628              :         {
     629            0 :                 for(uint i = 0; i < 2; ++i)
     630            0 :                         replace(associated_edges_begin(e->vertex(i)),
     631            0 :                                         associated_edges_end(e->vertex(i)),
     632              :                                         pReplaceMe, e);
     633              :         }
     634              : 
     635            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
     636              :         {
     637              :         //      collect all faces that are associated with pReplaceMe
     638              :                 vector<Face*> vFaces;
     639            0 :                 CollectFaces(vFaces, *this, pReplaceMe);
     640            0 :                 for(uint i = 0; i < vFaces.size(); ++i)
     641            0 :                         replace(associated_edges_begin(vFaces[i]),
     642              :                                         associated_edges_end(vFaces[i]),
     643              :                                         pReplaceMe, e);
     644            0 :         }
     645              : 
     646            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
     647              :         {
     648              :         //      collect all volumes that are associated with pReplaceMe
     649              :                 vector<Volume*> vVolumes;
     650            0 :                 CollectVolumes(vVolumes, *this, pReplaceMe);
     651            0 :                 for(uint i = 0; i < vVolumes.size(); ++i)
     652            0 :                         replace(associated_edges_begin(vVolumes[i]),
     653              :                                         associated_edges_end(vVolumes[i]),
     654              :                                         pReplaceMe, e);
     655            0 :         }
     656              : 
     657              : //      now we have to copy all associated elements of pReplaceMe to e
     658            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     659              :         {
     660            0 :                 m_aaFaceContainerEDGE[e].assign(associated_faces_begin(pReplaceMe),
     661              :                                                                                 associated_faces_end(pReplaceMe));
     662              :                 m_aaFaceContainerEDGE[pReplaceMe].clear();
     663              :         }
     664              : 
     665            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     666              :         {
     667            0 :                 m_aaVolumeContainerEDGE[e].assign(associated_volumes_begin(pReplaceMe),
     668              :                                                                                 associated_volumes_end(pReplaceMe));
     669              :                 m_aaVolumeContainerEDGE[pReplaceMe].clear();
     670              :         }
     671              : 
     672              : //      remove the element from the storage and delete it.
     673            0 :         m_edgeElementStorage.m_sectionContainer.erase(get_iterator(pReplaceMe), pReplaceMe->container_section());
     674            0 :         m_edgeElementStorage.m_attachmentPipe.unregister_element(pReplaceMe);
     675            0 :         delete pReplaceMe;
     676            0 : }
     677              : 
     678            3 : void Grid::unregister_edge(Edge* e)
     679              : {
     680              : //      notify observers that the edge is being erased
     681            3 :         NOTIFY_OBSERVERS_REVERSE(m_edgeObservers, edge_to_be_erased(this, e));
     682              : 
     683              : //      delete associated faces or unregister from associated faces
     684            3 :         if(num_volumes() > 0)
     685              :         {
     686            0 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES) ||
     687            0 :                         option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
     688              :                 {
     689              :                 //      check if anything has to be performed at all.
     690            0 :                         if(!(option_is_enabled(VOLOPT_AUTOGENERATE_FACES) &&
     691            0 :                                  option_is_enabled(FACEOPT_AUTOGENERATE_EDGES) &&
     692            0 :                                  option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES) &&
     693            0 :                                  option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES)))
     694              :                         {
     695              :                         //      we have to perform something...
     696              :                                 vector<Volume*> vVolumes;
     697            0 :                                 CollectVolumes(vVolumes, *this, e);
     698              :                                 vector<Volume*>::iterator vIter = vVolumes.begin();
     699              : 
     700            0 :                                 if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
     701              :                                 {
     702            0 :                                         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     703            0 :                                                 m_aaVolumeContainerEDGE[e].clear();
     704              : 
     705              :                                 //      erase the collected volumes
     706            0 :                                         while(vIter != vVolumes.end())
     707              :                                         {
     708            0 :                                                 Volume* eraseVol = *vIter;
     709              :                                                 ++vIter;
     710            0 :                                                 erase(eraseVol);
     711              :                                         }
     712              :                                 }
     713              :                                 else
     714              :                                 {
     715              :                                 //      unlink from the collected volumes
     716            0 :                                         for(; vIter != vVolumes.end(); ++vIter)
     717              :                                         {
     718            0 :                                                 Volume* v = *vIter;
     719              :                                         //      find the edge and remove the corresponding entry
     720            0 :                                                 EdgeContainer::iterator iter = find(m_aaEdgeContainerVOLUME[v].begin(),
     721              :                                                                                                                         m_aaEdgeContainerVOLUME[v].end(), e);
     722            0 :                                                 if(iter != m_aaEdgeContainerVOLUME[v].end())
     723              :                                                         m_aaEdgeContainerVOLUME[v].erase(iter);
     724              :                                         }
     725              :                                 }
     726            0 :                         }
     727              :                 }
     728              :         }
     729              : 
     730              : //      delete associated faces or unregister from associated faces
     731            3 :         if(num_faces() > 0)
     732              :         {
     733            0 :                 if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES) ||
     734            0 :                         option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
     735              :                 {
     736              :                         vector<Face*> vFaces;
     737            0 :                         CollectFaces(vFaces, *this, e);
     738              :                         vector<Face*>::iterator fIter = vFaces.begin();
     739              : 
     740            0 :                         if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
     741              :                         {
     742            0 :                                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     743            0 :                                         m_aaFaceContainerEDGE[e].clear();
     744              : 
     745              :                         //      erase the collected faces.
     746            0 :                                 while(fIter != vFaces.end())
     747              :                                 {
     748            0 :                                         Face* eraseFace = *fIter;
     749              :                                         ++fIter;
     750            0 :                                         erase(eraseFace);
     751              :                                 }
     752              :                         }
     753              :                         else
     754              :                         {
     755              :                         //      unlink
     756            0 :                                 for(; fIter != vFaces.end(); ++fIter)
     757              :                                 {
     758            0 :                                         Face* f = *fIter;
     759              :                                 //      find the matching entry and remove it
     760            0 :                                         EdgeContainer::iterator iter = find(m_aaEdgeContainerFACE[f].begin(),
     761              :                                                                                                                 m_aaEdgeContainerFACE[f].end(), e);
     762            0 :                                         if(iter != m_aaEdgeContainerFACE[f].end())
     763              :                                                 m_aaEdgeContainerFACE[f].erase(iter);
     764              :                                 }
     765              :                         }
     766            0 :                 }
     767              :         }
     768              : 
     769              : //      unregister from vertices
     770            3 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     771              :         {
     772              :         //      iterate through the associated vertices and remove the edge from their edge-list.
     773            0 :                 for(int i = 0; i < 2; ++i)
     774              :                 {
     775            0 :                         Vertex* vrt = e->vertex(i);
     776            0 :                         EdgeContainer::iterator iter = find(m_aaEdgeContainerVERTEX[vrt].begin(),
     777              :                                                                                                 m_aaEdgeContainerVERTEX[vrt].end(), e);
     778            0 :                         if(iter != m_aaEdgeContainerVERTEX[vrt].end())
     779            0 :                                 m_aaEdgeContainerVERTEX[e->vertex(i)].erase(iter);
     780              :                 }
     781              :         }
     782              : 
     783              : //      remove the element from the storage
     784            3 :         m_edgeElementStorage.m_sectionContainer.erase(get_iterator(e), e->container_section());
     785            3 :         m_edgeElementStorage.m_attachmentPipe.unregister_element(e);
     786            3 : }
     787              : 
     788            3 : void Grid::change_edge_options(uint optsNew)
     789              : {
     790              : //      check if associated face information has to be created or removed.
     791            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, EDGEOPT_STORE_ASSOCIATED_FACES))
     792              :         {
     793            0 :                 if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     794            0 :                         edge_store_associated_faces(true);
     795              :         }
     796              :         else
     797              :         {
     798            3 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     799            0 :                         edge_store_associated_faces(false);
     800              :         }
     801              : 
     802              : //      check if associated volume information has to be created or removed.
     803            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     804              :         {
     805            0 :                 if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     806            0 :                         edge_store_associated_volumes(true);
     807              :         }
     808              :         else
     809              :         {
     810            3 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     811            0 :                         edge_store_associated_volumes(false);
     812              :         }
     813            3 : }
     814              : 
     815            0 : void Grid::edge_store_associated_faces(bool bStoreIt)
     816              : {
     817            0 :         if(bStoreIt)
     818              :         {
     819            0 :                 if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     820              :                 {
     821              :                 //      store associated faces
     822            0 :                         attach_to_edges(m_aFaceContainer);
     823            0 :                         m_aaFaceContainerEDGE.access(*this, m_aFaceContainer);
     824              : 
     825              :                 //      iterate through the faces and store them at each of their edges.
     826              :                 //      in order to perform this task at acceptable speed,
     827              :                 //      the option VRTOPT_STORE_ASSOCIATED_EDGES has to be enabled.
     828              :                 //      (This is due to the use of GetEdge(...))
     829              :                 //      if it is disabled here, we'll enable it.
     830            0 :                         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     831              :                         {
     832              :                                 LOG("WARNING in edge_store_associated_faces(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
     833            0 :                                 vertex_store_associated_edges(true);
     834              :                         }
     835              : 
     836            0 :                         for(FaceIterator iter = faces_begin(); iter != faces_end(); iter++)
     837              :                         {
     838            0 :                                 Face* f = *iter;
     839              :                         //      iterate through the edges of the face
     840            0 :                                 int numEdges = f->num_edges();
     841            0 :                                 for(int i = 0; i < numEdges; ++i)
     842              :                                 {
     843              :                                 //      get the i-th edge
     844            0 :                                         Edge* e = get_edge(f, i);
     845            0 :                                         if(e != NULL)
     846            0 :                                                 m_aaFaceContainerEDGE[e].push_back(f);
     847              :                                 }
     848              :                         }
     849              :                 //      store the option
     850            0 :                         m_options |= EDGEOPT_STORE_ASSOCIATED_FACES;
     851              :                 }
     852              :         }
     853              :         else
     854              :         {
     855            0 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     856              :                 {
     857              :                 //      detach edge-face connections
     858            0 :                         detach_from_edges(m_aFaceContainer);
     859            0 :                         m_options &= (~EDGEOPT_STORE_ASSOCIATED_FACES);
     860              :                 }
     861              :         }
     862            0 : }
     863              : 
     864            0 : void Grid::edge_store_associated_volumes(bool bStoreIt)
     865              : {
     866            0 :         if(bStoreIt)
     867              :         {
     868            0 :                 if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     869              :                 {
     870              :                 //      store associated faces
     871            0 :                         attach_to_edges(m_aVolumeContainer);
     872            0 :                         m_aaVolumeContainerEDGE.access(*this, m_aVolumeContainer);
     873              : 
     874              :                 //      iterate through the volumes and store them at each of their edges.
     875              :                 //      in order to perform this task at acceptable speed,
     876              :                 //      the option VRTOPT_STORE_ASSOCIATED_VOLUMES has to be enabled.
     877              :                 //      (This is due to the use of GetEdge(...))
     878              :                 //      if it is disabled here, we'll enable it.
     879            0 :                         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
     880              :                         {
     881              :                                 LOG("WARNING in Grid::edge_store_associated_volumes(...): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
     882            0 :                                 vertex_store_associated_volumes(true);
     883              :                         }
     884              : 
     885            0 :                         for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
     886              :                         {
     887            0 :                                 Volume* v = *iter;
     888              :                         //      iterate through the edges of the volume
     889            0 :                                 int numEdges = v->num_edges();
     890            0 :                                 for(int i = 0; i < numEdges; ++i)
     891              :                                 {
     892              :                                 //      get the edge-descriptor
     893            0 :                                         EdgeDescriptor ed;
     894            0 :                                         v->edge_desc(i, ed);
     895              :                                 //      get the edge that is described by the EdgeDescriptor - if it exists at all.
     896            0 :                                         Edge* e = get_edge(ed);
     897            0 :                                         if(e != NULL)
     898            0 :                                                 m_aaVolumeContainerEDGE[e].push_back(v);
     899              :                                 }
     900              :                         }
     901              : 
     902              :                 //      store the option
     903            0 :                         m_options |= EDGEOPT_STORE_ASSOCIATED_VOLUMES;
     904              :                 }
     905              :         }
     906              :         else
     907              :         {
     908            0 :                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
     909              :                 {
     910              :                 //      detach edge-volume connections
     911            0 :                         detach_from_edges(m_aVolumeContainer);
     912            0 :                         m_options &= (~EDGEOPT_STORE_ASSOCIATED_VOLUMES);
     913              :                 }
     914              :         }
     915            0 : }
     916              : 
     917              : 
     918              : ////////////////////////////////////////////////////////////////////////////////
     919              : ////////////////////////////////////////////////////////////////////////////////
     920              : //      FACES
     921              : ///     creates and removes connectivity data, as specified in optsNew.
     922            1 : void Grid::register_face(Face* f, GridObject* pParent, Volume* createdByVol)
     923              : {
     924              :         GCM_PROFILE_FUNC();
     925              : 
     926              : //      store the element and register it at the pipe.
     927            1 :         m_faceElementStorage.m_attachmentPipe.register_element(f);
     928            1 :         m_faceElementStorage.m_sectionContainer.insert(f, f->container_section());
     929              : 
     930              : //      register face at vertices
     931            1 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     932              :         {
     933            1 :                 uint numVrts = f->num_vertices();
     934            1 :                 Face::ConstVertexArray vrts = f->vertices();
     935            4 :                 for(uint i = 0; i < numVrts; ++i)
     936            3 :                         m_aaFaceContainerVERTEX[vrts[i]].push_back(f);
     937              :         }
     938              : 
     939            1 :         bool createEdges = option_is_enabled(FACEOPT_AUTOGENERATE_EDGES);;
     940            1 :         const bool edgesStoreFaces = option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES);
     941            1 :         const bool facesStoreEdges = option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES);
     942              : 
     943              : //      make sure that the edge container is big enough to hold all edges
     944            1 :         if(facesStoreEdges)
     945            0 :                 m_aaEdgeContainerFACE[f].reserve(f->num_edges());
     946              : 
     947              : //      create edges if FACEOPT_AUTOGENERATE_EDGES is enabled.
     948              : //      register face at associated vertices and edges if the according options are set.
     949            1 :         if(createEdges
     950            1 :                 || edgesStoreFaces
     951            0 :                 || facesStoreEdges)
     952              :         {
     953              :                 GCM_PROFILE(GCM_reg_face_processing_edges);
     954              :         //      loop through the edges of the face and check if they already exist in the grid.
     955            1 :                 int numEdges = f->num_edges();
     956            1 :                 EdgeDescriptor ed;
     957            4 :                 for(int i = 0; i < numEdges; ++i)
     958              :                 {
     959            3 :                         f->edge_desc(i, ed);
     960            3 :                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
     961              : 
     962            3 :                         if(e == NULL)
     963              :                         {
     964            3 :                                 if(createEdges)
     965              :                                 {
     966              :                                 //      create the edge - regard the parent of f as the parent of the new edge, too.
     967            3 :                                         e = f->create_edge(i);
     968              : 
     969            3 :                                         if(facesStoreEdges)
     970            0 :                                                 m_aaEdgeContainerFACE[f].push_back(e);
     971              : 
     972              :                                 //      register the edge
     973            3 :                                         register_edge(e, pParent, f, createdByVol);
     974              :                                 }
     975              :                         }
     976              :                         else
     977              :                         {
     978              :                         //      register the face at the edge
     979            0 :                                 if(edgesStoreFaces)
     980            0 :                                         m_aaFaceContainerEDGE[e].push_back(f);
     981              :                         //      register the edge at the face.
     982            0 :                                 if(facesStoreEdges)
     983            0 :                                         m_aaEdgeContainerFACE[f].push_back(e);
     984              :                         }
     985              :                 }
     986              :         }
     987              : 
     988              : //      register face at existing volumes. find all volumes that contain face
     989              : //      if the option VOLOPT_AUTOGENERATE_FACES is enabled, we can ignore volumes
     990              : //      here anyways, since they would be associated with volumes in register_volume
     991            1 :         if(createdByVol != NULL){
     992              :         //      This means that the face was autogenerated by a volume.
     993              :         //      In this case the face is already registered in the volumes container.
     994            0 :                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
     995            0 :                         m_aaVolumeContainerFACE[f].push_back(createdByVol);
     996              :         }
     997              :         else
     998              :         {
     999            1 :                 if(!option_is_enabled(VOLOPT_AUTOGENERATE_FACES)){
    1000              :                         GCM_PROFILE(GCM_reg_face_processing_volumes);
    1001              : 
    1002              :                         int switchVar = 0;
    1003            0 :                         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1004              :                                 switchVar = 1;
    1005            0 :                         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1006            0 :                                 switchVar += 2;
    1007              : 
    1008            0 :                         if(switchVar > 0)
    1009              :                         {
    1010              :                         //      find associated volumes of f. Don't use get_associated, since it
    1011              :                         //      may lookup m_aaVolumeContainerFACE, which we just want to update...
    1012              :                                 vector<Volume*> vVols;
    1013            0 :                                 vVols.reserve(2);
    1014              : 
    1015            0 :                                 CollectVolumes(vVols, *this, f, false, true);
    1016              : 
    1017              : 
    1018              : 
    1019            0 :                                 for(vector<Volume*>::iterator iter = vVols.begin(); iter != vVols.end(); ++iter)
    1020              :                                 {
    1021            0 :                                         Volume* v = *iter;
    1022              :                                 //      v contains f
    1023            0 :                                         switch(switchVar)
    1024              :                                         {
    1025            0 :                                                 case 1: m_aaVolumeContainerFACE[f].push_back(v);
    1026              :                                                                 break;
    1027            0 :                                                 case 2: m_aaFaceContainerVOLUME[v].push_back(f);
    1028              :                                                                 break;
    1029            0 :                                                 case 3: m_aaVolumeContainerFACE[f].push_back(v);
    1030            0 :                                                                 m_aaFaceContainerVOLUME[v].push_back(f);
    1031              :                                                                 break;
    1032              :                                         }
    1033              :                                 }
    1034            0 :                         }
    1035              :                 }
    1036              :         }
    1037              : 
    1038              :         GCM_PROFILE(GCM_notify_face_observers);
    1039              : //      inform observers about the creation
    1040            1 :         NOTIFY_OBSERVERS(m_faceObservers, face_created(this, f, pParent));
    1041              :         GCM_PROFILE_END();
    1042            1 : }
    1043              : 
    1044            0 : void Grid::register_and_replace_element(Face* f, Face* pReplaceMe)
    1045              : {
    1046              : //      check that f and pReplaceMe have the same amount of vertices.
    1047            0 :         if(f->num_vertices() != pReplaceMe->num_vertices())
    1048              :         {
    1049              :                 LOG("WARNING in Grid::register_and_replace_element(Face* f, Face* pReplaceMe): f and pReplaceMe have different numbers of vertices.");
    1050              :                 LOG("  f has not been registered. pReplaceMe has not been replaced.");
    1051              :                 assert(!"ERROR in Grid::register_and_replace_element(Face* f, Face* pReplaceMe): f and pReplaceMe have different numbers of vertices.");
    1052            0 :                 return;
    1053              :         }
    1054              : 
    1055              : //      store the element and register it at the pipe.
    1056            0 :         m_faceElementStorage.m_attachmentPipe.register_element(f);
    1057            0 :         m_faceElementStorage.m_sectionContainer.insert(f, f->container_section());
    1058              : 
    1059            0 :         pass_on_values(pReplaceMe, f);
    1060              : 
    1061            0 :         Face::ConstVertexArray vrts = pReplaceMe->vertices();
    1062              : 
    1063              : //      assign vertices
    1064            0 :         uint numVrts = f->num_vertices();
    1065              :         {
    1066            0 :                 for(uint i = 0; i < numVrts; ++i)
    1067            0 :                         f->set_vertex(i, vrts[i]);
    1068              :         }
    1069              : 
    1070              : //      inform observers about the creation
    1071            0 :         NOTIFY_OBSERVERS(m_faceObservers, face_created(this, f, pReplaceMe, true));
    1072              : //      inform observers about the deletion
    1073            0 :         NOTIFY_OBSERVERS_REVERSE(m_faceObservers, face_to_be_erased(this, pReplaceMe, f));
    1074              : 
    1075              : //      check if vertices, edges and volumes reference pReplaceMe.
    1076              : //      if so, correct those references.
    1077            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
    1078              :         {
    1079            0 :                 for(uint i = 0; i < numVrts; ++i)
    1080            0 :                         replace(associated_faces_begin(vrts[i]),
    1081            0 :                                         associated_faces_end(vrts[i]),
    1082              :                                         pReplaceMe, f);
    1083              :         }
    1084              : 
    1085            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
    1086              :         {
    1087              :         //      collect all edges that are associated with pReplaceMe
    1088              :                 vector<Edge*> vEdges;
    1089            0 :                 CollectEdges(vEdges, *this, pReplaceMe);
    1090            0 :                 for(uint i = 0; i < vEdges.size(); ++i)
    1091            0 :                         replace(associated_faces_begin(vEdges[i]),
    1092              :                                         associated_faces_end(vEdges[i]),
    1093              :                                         pReplaceMe, f);
    1094            0 :         }
    1095              : 
    1096            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1097              :         {
    1098              :         //      collect all volumes that are associated with pReplaceMe
    1099              :                 vector<Volume*> vVolumes;
    1100            0 :                 CollectVolumes(vVolumes, *this, pReplaceMe);
    1101            0 :                 for(uint i = 0; i < vVolumes.size(); ++i)
    1102            0 :                         replace(associated_faces_begin(vVolumes[i]),
    1103              :                                         associated_faces_end(vVolumes[i]),
    1104              :                                         pReplaceMe, f);
    1105            0 :         }
    1106              : 
    1107              : //      now we have to copy all associated elements of pReplaceMe to f
    1108            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1109              :         {
    1110            0 :                 m_aaEdgeContainerFACE[f].assign(associated_edges_begin(pReplaceMe),
    1111              :                                                                                 associated_edges_end(pReplaceMe));
    1112              :                 m_aaEdgeContainerFACE[pReplaceMe].clear();
    1113              :         }
    1114              : 
    1115            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1116              :         {
    1117            0 :                 m_aaVolumeContainerFACE[f].assign(associated_volumes_begin(pReplaceMe),
    1118              :                                                                                         associated_volumes_end(pReplaceMe));
    1119              :                 m_aaVolumeContainerFACE[pReplaceMe].clear();
    1120              :         }
    1121              : 
    1122              : //      remove the element from the storage and delete it.
    1123            0 :         m_faceElementStorage.m_sectionContainer.erase(get_iterator(pReplaceMe), pReplaceMe->container_section());
    1124            0 :         m_faceElementStorage.m_attachmentPipe.unregister_element(pReplaceMe);
    1125            0 :         delete pReplaceMe;
    1126              : }
    1127              : 
    1128            1 : void Grid::unregister_face(Face* f)
    1129              : {
    1130              : //      notify observers that the face is being erased
    1131            1 :         NOTIFY_OBSERVERS_REVERSE(m_faceObservers, face_to_be_erased(this, f));
    1132              : 
    1133              : //      remove or disconnect from volumes
    1134            1 :         if(num_volumes() > 0)
    1135              :         {
    1136            0 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES) ||
    1137            0 :                         option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1138              :                 {
    1139              :                         vector<Volume*> vVolumes;
    1140            0 :                         CollectVolumes(vVolumes, *this, f, true);
    1141              :                         vector<Volume*>::iterator vIter= vVolumes.begin();
    1142              : 
    1143            0 :                         if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
    1144              :                         {
    1145            0 :                                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1146            0 :                                         m_aaVolumeContainerFACE[f].clear();
    1147              : 
    1148              :                         //      delete the collected volumes
    1149            0 :                                 while(vIter != vVolumes.end())
    1150              :                                 {
    1151            0 :                                         Volume* eraseVol = *vIter;
    1152              :                                         ++vIter;
    1153            0 :                                         erase(eraseVol);
    1154              :                                 }
    1155              :                         }
    1156              :                         else
    1157              :                         {
    1158              :                         //      unregister from the collected volumes.
    1159            0 :                                 for(;vIter != vVolumes.end(); ++vIter)
    1160              :                                 {
    1161            0 :                                         Volume* vol = *vIter;
    1162            0 :                                         FaceContainer::iterator iter = find(m_aaFaceContainerVOLUME[vol].begin(),
    1163              :                                                                                                                 m_aaFaceContainerVOLUME[vol].end(), f);
    1164            0 :                                         if(iter != m_aaFaceContainerVOLUME[vol].end())
    1165              :                                                 m_aaFaceContainerVOLUME[vol].erase(iter);
    1166              :                                 }
    1167              :                         }
    1168            0 :                 }
    1169              :         }
    1170              : 
    1171              : //      disconnect from edges
    1172            1 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
    1173              :         {
    1174              :         //      iterate through all edges of the face
    1175            0 :                 uint numEdges = f->num_edges();
    1176            0 :                 for(uint i = 0; i < numEdges; ++i)
    1177              :                 {
    1178            0 :                         Edge* e = get_edge(f, i);
    1179            0 :                         if(e != NULL)
    1180              :                         {
    1181            0 :                                 FaceContainer::iterator iter = find(m_aaFaceContainerEDGE[e].begin(),
    1182              :                                                                                                         m_aaFaceContainerEDGE[e].end(), f);
    1183            0 :                                 if(iter != m_aaFaceContainerEDGE[e].end())
    1184              :                                         m_aaFaceContainerEDGE[e].erase(iter);
    1185              :                         }
    1186              :                 }
    1187              :         }
    1188              : 
    1189              : //      disconnect from vertices
    1190            1 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
    1191              :         {
    1192            0 :                 size_t numVrts = f->num_vertices();
    1193            0 :                 Face::ConstVertexArray vrts = f->vertices();
    1194            0 :                 for(uint i = 0; i < numVrts; ++i)
    1195              :                 {
    1196            0 :                         Vertex* vrt = vrts[i];
    1197            0 :                         FaceContainer::iterator iter = find(m_aaFaceContainerVERTEX[vrt].begin(),
    1198              :                                                                                                 m_aaFaceContainerVERTEX[vrt].end(), f);
    1199            0 :                         if(iter != m_aaFaceContainerVERTEX[vrt].end())
    1200              :                                 m_aaFaceContainerVERTEX[vrt].erase(iter);
    1201              :                 }
    1202              :         }
    1203              : 
    1204              : //      remove the element from the storage
    1205            1 :         m_faceElementStorage.m_sectionContainer.erase(get_iterator(f), f->container_section());
    1206            1 :         m_faceElementStorage.m_attachmentPipe.unregister_element(f);
    1207            1 : }
    1208              : 
    1209            3 : void Grid::change_face_options(uint optsNew)
    1210              : {
    1211              : //      check if associated edge information has to be created or removed.
    1212            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, FACEOPT_STORE_ASSOCIATED_EDGES))
    1213              :         {
    1214            0 :                 if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1215            0 :                         face_store_associated_edges(true);
    1216              :         }
    1217              :         else
    1218              :         {
    1219            3 :                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1220            0 :                         face_store_associated_edges(false);
    1221              :         }
    1222              : 
    1223              : //      check if associated volume information has to be created or removed.
    1224            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1225              :         {
    1226            0 :                 if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1227            0 :                         face_store_associated_volumes(true);
    1228              :         }
    1229              :         else
    1230              :         {
    1231            3 :                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1232            0 :                         face_store_associated_volumes(false);
    1233              :         }
    1234              : 
    1235              : //      turn auto-generation of edges on and of
    1236            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, FACEOPT_AUTOGENERATE_EDGES))
    1237              :         {
    1238            2 :                 if(!option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
    1239            2 :                         face_autogenerate_edges(true);
    1240              :         }
    1241              :         else
    1242              :         {
    1243            1 :                 if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
    1244            1 :                         face_autogenerate_edges(false);
    1245              :         }
    1246            3 : }
    1247              : 
    1248            0 : void Grid::face_store_associated_edges(bool bStoreIt)
    1249              : {
    1250            0 :         if(bStoreIt)
    1251              :         {
    1252            0 :                 if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1253              :                 {
    1254              :                 //      store associated edges
    1255            0 :                         attach_to_faces(m_aEdgeContainer);
    1256            0 :                         m_aaEdgeContainerFACE.access(*this, m_aEdgeContainer);
    1257              : 
    1258            0 :                         bool createEdges = option_is_enabled(FACEOPT_AUTOGENERATE_EDGES);
    1259              : 
    1260              :                 //      if EDGEOPT_STORE_ASSOCIATED_FACES is enabled, this is as simple
    1261              :                 //      as to iterate through all edges and store them at their
    1262              :                 //      associated faces.
    1263              :                 //      if not we have to iterate through the faces and store
    1264              :                 //      each of their edges..
    1265              :                 //      If createEdges == true, we want to store the edges sorted.
    1266              :                 //      The else branch thus has to be executed.
    1267              :                         if(!createEdges
    1268            0 :                                 && option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
    1269              :                         {
    1270              :                         //      iterate through the edges
    1271            0 :                                 for(EdgeIterator iter = edges_begin(); iter != edges_end(); iter++)
    1272              :                                 {
    1273            0 :                                         Edge* e = *iter;
    1274              :                                 //      iterate through the edges associated faces
    1275            0 :                                         for(AssociatedFaceIterator fIter = associated_faces_begin(e);
    1276            0 :                                                 fIter != associated_faces_end(e); fIter++)
    1277              :                                         {
    1278            0 :                                                 m_aaEdgeContainerFACE[*fIter].push_back(e);
    1279              :                                         }
    1280              :                                 }
    1281              :                         }
    1282              :                         else
    1283              :                         {
    1284              :                         //      we have to find the edges by hand using GetEdge(...)
    1285            0 :                                 for(FaceIterator iter = faces_begin(); iter != faces_end(); iter++)
    1286              :                                 {
    1287              :                                         Face* f = *iter;
    1288              :                                         uint numEdges = f->num_edges();
    1289              : 
    1290            0 :                                         if(createEdges){
    1291            0 :                                                 m_aaEdgeContainerFACE[f].resize(numEdges);
    1292            0 :                                                 for(uint i = 0; i < numEdges; ++i)
    1293            0 :                                                         m_aaEdgeContainerFACE[f][i] = get_edge(f, i);
    1294              :                                         }
    1295              :                                         else{
    1296            0 :                                                 for(uint i = 0; i < numEdges; ++i)
    1297              :                                                 {
    1298              :                                                 //      get the i-th edge that is described by the EdgeDescriptor - if it exists at all.
    1299            0 :                                                         Edge* e = get_edge(f, i);
    1300            0 :                                                         if(e != NULL)
    1301            0 :                                                                 m_aaEdgeContainerFACE[f].push_back(e);
    1302              :                                                 }
    1303              :                                         }
    1304              :                                 }
    1305              :                         }
    1306              : 
    1307              :                 //      store the options
    1308            0 :                         m_options |= FACEOPT_STORE_ASSOCIATED_EDGES;
    1309              :                 }
    1310              :         }
    1311              :         else
    1312              :         {
    1313            0 :                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1314              :                 {
    1315              :                 //      remove face-edge connections
    1316            0 :                         detach_from_faces(m_aEdgeContainer);
    1317            0 :                         m_options &= (~FACEOPT_STORE_ASSOCIATED_EDGES);
    1318              :                 }
    1319              :         }
    1320            0 : }
    1321              : 
    1322            0 : void Grid::face_store_associated_volumes(bool bStoreIt)
    1323              : {
    1324            0 :         if(bStoreIt)
    1325              :         {
    1326            0 :                 if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1327              :                 {
    1328              :                 //      store associated faces
    1329            0 :                         attach_to_faces(m_aVolumeContainer);
    1330            0 :                         m_aaVolumeContainerFACE.access(*this, m_aVolumeContainer);
    1331              : 
    1332              :                 //      iterate through the volumes and store each of their faces...
    1333            0 :                         for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    1334              :                         {
    1335            0 :                                 Volume* v = *iter;
    1336              : 
    1337              :                         //      if faces are already stored at their associated volumes, we iterate over them.
    1338            0 :                                 if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1339              :                                 {
    1340            0 :                                         AssociatedFaceIterator iterEnd = associated_faces_end(v);
    1341            0 :                                         for(AssociatedFaceIterator iter = associated_faces_begin(v); iter != iterEnd; iter++)
    1342            0 :                                                 m_aaVolumeContainerFACE[*iter].push_back(v);
    1343              :                                 }
    1344              :                                 else
    1345              :                                 {
    1346            0 :                                         uint numFaces = v->num_faces();
    1347            0 :                                         for(uint i = 0; i < numFaces; ++i)
    1348              :                                         {
    1349            0 :                                                 Face* f = get_face(v, i);
    1350              : 
    1351            0 :                                                 if(f)
    1352            0 :                                                         m_aaVolumeContainerFACE[f].push_back(v);
    1353              :                                         }
    1354              :                                 }
    1355              :                         }
    1356              : 
    1357              :                 //      store options
    1358            0 :                         m_options |= FACEOPT_STORE_ASSOCIATED_VOLUMES;
    1359              :                 }
    1360              :         }
    1361              :         else
    1362              :         {
    1363            0 :                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1364              :                 {
    1365              :                 //      remove face-edge connections
    1366            0 :                         detach_from_faces(m_aVolumeContainer);
    1367            0 :                         m_options &= (~FACEOPT_STORE_ASSOCIATED_VOLUMES);
    1368              :                 }
    1369              :         }
    1370            0 : }
    1371              : 
    1372            3 : void Grid::face_autogenerate_edges(bool bAutogen)
    1373              : {
    1374            3 :         if(bAutogen)
    1375              :         {
    1376            2 :                 if(!option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
    1377              :                 {
    1378            2 :                         bool storeEdges = option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES);
    1379            2 :                         EdgeDescriptor ed;
    1380              : 
    1381              :                 //      generate all missing edges now!
    1382            2 :                         for(FaceIterator iter = faces_begin(); iter != faces_end(); iter++)
    1383              :                         {
    1384              :                                 Face* f = *iter;
    1385              :                         //      check for each edge of the face if it exists. if not create it and link it to the face.
    1386              :                                 uint numEdges = f->num_edges();
    1387              : 
    1388              :                         //      reserve memory for neighbors
    1389            0 :                                 if(storeEdges){
    1390              :                                         m_aaEdgeContainerFACE[f].clear();
    1391            0 :                                         m_aaEdgeContainerFACE[f].reserve(numEdges);
    1392              :                                 }
    1393              : 
    1394            0 :                                 for(uint i = 0; i < numEdges; ++i)
    1395              :                                 {
    1396              :                                 //      we can't use get_edge here, since we're manipulating m_aaEdgeContainerFACE on the fly.
    1397            0 :                                         f->edge_desc(i, ed);
    1398            0 :                                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
    1399              : 
    1400            0 :                                         if(e == NULL)
    1401              :                                         {
    1402              :                                         //      create the edge
    1403            0 :                                                 e = f->create_edge(i);
    1404            0 :                                                 if(storeEdges)
    1405            0 :                                                         m_aaEdgeContainerFACE[f].push_back(e);
    1406            0 :                                                 register_edge(e, f, f, NULL);
    1407              :                                         }
    1408            0 :                                         else if(storeEdges)
    1409            0 :                                                 m_aaEdgeContainerFACE[f].push_back(e);
    1410              :                                 }
    1411              :                         }
    1412              : 
    1413              :                 //      store the option
    1414            2 :                         m_options |= FACEOPT_AUTOGENERATE_EDGES;
    1415              : 
    1416              :                 //      if VOLOPT_AUTOGENERATE_FACES is active, too, then all volume-edges exist.
    1417              :                 //      Now, if VOLOPT_STORE_ASSOCIATED_EDGES is active but
    1418              :                 //      VOLOPT_AUTOGENERATE_EDGES is inactive, then we'll sort the associated-edges
    1419              :                 //      of volumes.
    1420            2 :                         if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES)
    1421            0 :                            && option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)
    1422            2 :                            && (!option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)))
    1423              :                         {
    1424            0 :                                 volume_sort_associated_edge_container();
    1425              :                         }
    1426              :                 }
    1427              :         }
    1428              :         else
    1429              :         {
    1430              :         //      stop auto-generation
    1431            1 :                 m_options &= (~FACEOPT_AUTOGENERATE_EDGES);
    1432              :         }
    1433            3 : }
    1434              : 
    1435              : 
    1436              : ////////////////////////////////////////////////////////////////////////////////////////////////
    1437              : ////////////////////////////////////////////////////////////////////////////////////////////////
    1438              : //      VOLUMES
    1439              : ///     creates and removes connectivity data, as specified in optsNew.
    1440            0 : void Grid::register_volume(Volume* v, GridObject* pParent)
    1441              : {
    1442              :         GCM_PROFILE_FUNC();
    1443              : 
    1444              : //      store the element and register it at the pipe.
    1445            0 :         m_volumeElementStorage.m_attachmentPipe.register_element(v);
    1446            0 :         m_volumeElementStorage.m_sectionContainer.insert(v, v->container_section());
    1447              : 
    1448              : //      create edges and faces if the according options are enabled.
    1449              : //      register the volume at the associated vertices, edges and faces, if the according options are enabled.
    1450              : 
    1451              : //      register volume at vertices
    1452            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    1453              :         {
    1454            0 :                 uint numVrts = v->num_vertices();
    1455            0 :                 Volume::ConstVertexArray vrts = v->vertices();
    1456            0 :                 for(uint i = 0; i < numVrts; ++i)
    1457            0 :                         m_aaVolumeContainerVERTEX[vrts[i]].push_back(v);
    1458              :         }
    1459              : 
    1460            0 :         const bool createEdges = option_is_enabled(VOLOPT_AUTOGENERATE_EDGES);
    1461            0 :         const bool createFaces = option_is_enabled(VOLOPT_AUTOGENERATE_FACES);
    1462            0 :         const bool createEdgesIndirect = option_is_enabled(VOLOPT_AUTOGENERATE_FACES
    1463              :                                                                                                            | FACEOPT_AUTOGENERATE_EDGES);
    1464              : 
    1465            0 :         const bool edgesStoreVols = option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES);
    1466            0 :         const bool volsStoreEdges = option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES);
    1467              : 
    1468            0 :         const bool facesStoreVols = option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES);
    1469            0 :         const bool volsStoreFaces = option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES);
    1470              : 
    1471              : 
    1472              : //      if elements are automatically created, then we can directly reserve memory
    1473              : //      to store neighborhood relations
    1474            0 :         if(volsStoreEdges && (createEdges || createEdgesIndirect))
    1475            0 :                 m_aaEdgeContainerVOLUME[v].reserve(v->num_edges());
    1476            0 :         if(volsStoreFaces && createFaces)
    1477            0 :                 m_aaFaceContainerVOLUME[v].reserve(v->num_faces());
    1478              : 
    1479              : //      create faces first. This makes sense, since faces thus get a chance to
    1480              : //      generate associated edges. This has the benefit, that the option
    1481              : //      VOLOPT_AUTOGENERATE_EDGES has no effect in this case.
    1482              : 
    1483              : //      register with faces. autogenerate them if they do not already exist.
    1484            0 :         if(createFaces
    1485            0 :                 || facesStoreVols
    1486            0 :                 || volsStoreFaces)
    1487              :         {
    1488              :                 GCM_PROFILE(GCM_vol_handle_faces);
    1489              :         //      iterate through the faces of the volume. create them if demanded.
    1490              :         //      register faces at the volume and vice versa.
    1491            0 :                 uint numFaces = v->num_faces();
    1492            0 :                 FaceDescriptor fd;
    1493            0 :                 for(uint i = 0; i < numFaces; ++i)
    1494              :                 {
    1495            0 :                         v->face_desc(i, fd);
    1496            0 :                         Face* f = find_face_in_associated_faces(fd.vertex(0), fd);
    1497              : 
    1498            0 :                         if(f == NULL)
    1499              :                         {
    1500            0 :                                 if(createFaces)
    1501              :                                 {
    1502            0 :                                         f = v->create_face(i);
    1503              : 
    1504            0 :                                         if(volsStoreFaces)
    1505            0 :                                                 m_aaFaceContainerVOLUME[v].push_back(f);
    1506              : 
    1507              :                                 //      register the face. By passing v, we speed up the process.
    1508            0 :                                         register_face(f, pParent, v);
    1509              :                                 }
    1510              :                         }
    1511              :                         else
    1512              :                         {
    1513            0 :                                 if(facesStoreVols)
    1514            0 :                                         m_aaVolumeContainerFACE[f].push_back(v);
    1515              : 
    1516            0 :                                 if(volsStoreFaces)
    1517            0 :                                         m_aaFaceContainerVOLUME[v].push_back(f);
    1518              :                         }
    1519              :                 }
    1520              :         }
    1521              : 
    1522              : //      register with edges. autogenerate missing edges if option is set
    1523            0 :         if(createEdges
    1524            0 :                 || edgesStoreVols
    1525            0 :                 || volsStoreEdges)
    1526              :         {
    1527              :                 GCM_PROFILE(GCM_vol_handle_edges);
    1528              :         //      loop through all edges of the volume. check if we have to create it.
    1529              :         //      register the volume with the edges and vice versa after that.
    1530            0 :                 uint numEdges = v->num_edges();
    1531            0 :                 EdgeDescriptor ed;
    1532            0 :                 for(uint i = 0; i < numEdges; ++i)
    1533              :                 {
    1534            0 :                         v->edge_desc(i, ed);
    1535            0 :                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
    1536              : 
    1537            0 :                         if(e == NULL)
    1538              :                         {
    1539            0 :                                 if(createEdges)
    1540              :                                 {
    1541              :                                 //      create the edge
    1542            0 :                                         e = v->create_edge(i);
    1543              : 
    1544              :                                 //      store a reference to the edge, if required
    1545            0 :                                         if(volsStoreEdges)
    1546            0 :                                                 m_aaEdgeContainerVOLUME[v].push_back(e);
    1547              : 
    1548              :                                 //      register the edge.
    1549            0 :                                         register_edge(e, pParent, NULL, v);
    1550              :                                 }
    1551              :                         }
    1552              :                         else
    1553              :                         {
    1554            0 :                                 if(edgesStoreVols){
    1555              :                                 //      if the edge was indirectly created during creation of
    1556              :                                 //      a side-face above, it already has v in its associated-
    1557              :                                 //      volume container. v is the first element in this container
    1558              :                                 //      in that case and doesn't have to be added again.
    1559              :                                         VolumeContainer& assVols = m_aaVolumeContainerEDGE[e];
    1560            0 :                                         if((assVols.size() == 0) || (assVols.front() != v))
    1561            0 :                                                 assVols.push_back(v);
    1562              :                                 }
    1563              : 
    1564            0 :                                 if(volsStoreEdges)
    1565            0 :                                         m_aaEdgeContainerVOLUME[v].push_back(e);
    1566              :                         }
    1567              :                 }
    1568              :         }
    1569              : 
    1570              :         GCM_PROFILE(GCM_notify_volume_observers);
    1571              : //      inform observers about the creation
    1572            0 :         NOTIFY_OBSERVERS(m_volumeObservers, volume_created(this, v, pParent));
    1573              :         GCM_PROFILE_END();
    1574            0 : }
    1575              : 
    1576            0 : void Grid::register_and_replace_element(Volume* v, Volume* pReplaceMe)
    1577              : {
    1578              : //      check that v and pReplaceMe have the same number of vertices.
    1579            0 :         if(v->num_vertices() != pReplaceMe->num_vertices())
    1580              :         {
    1581              :                 LOG("WARNING in Grid::register_and_replace_element(Volume* v, Volume* pReplaceMe): v and pReplaceMe have different numbers of vertices.");
    1582              :                 LOG("  v has not been registered. pReplaceMe has not been replaced.");
    1583              :                 assert(!"ERROR in Grid::register_and_replace_element(Volume* v, Volume* pReplaceMe): v and pReplaceMe have different numbers of vertices.");
    1584            0 :                 return;
    1585              :         }
    1586              : 
    1587              : //      store the element and register it at the pipe.
    1588            0 :         m_volumeElementStorage.m_attachmentPipe.register_element(v);
    1589            0 :         m_volumeElementStorage.m_sectionContainer.insert(v, v->container_section());
    1590              : 
    1591            0 :         pass_on_values(pReplaceMe, v);
    1592              : 
    1593              : //      assign vertices
    1594            0 :         uint numVrts = v->num_vertices();
    1595            0 :         Volume::ConstVertexArray vrts = pReplaceMe->vertices();
    1596            0 :         for(uint i = 0; i < numVrts; ++i)
    1597            0 :                 v->set_vertex(i, vrts[i]);
    1598              : 
    1599              : //      inform observers about the creation
    1600            0 :         NOTIFY_OBSERVERS(m_volumeObservers, volume_created(this, v, pReplaceMe, true));
    1601              : //      inform observers about the deletion
    1602            0 :         NOTIFY_OBSERVERS_REVERSE(m_volumeObservers, volume_to_be_erased(this, pReplaceMe, v));
    1603              : 
    1604              : //      check if vertices, edges and faces reference pReplaceMe.
    1605              : //      if so, correct those references.
    1606            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    1607              :         {
    1608            0 :                 for(uint i = 0; i < numVrts; ++i)
    1609            0 :                         replace(associated_volumes_begin(vrts[i]),
    1610            0 :                                         associated_volumes_end(vrts[i]),
    1611              :                                         pReplaceMe, v);
    1612              :         }
    1613              : 
    1614            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    1615              :         {
    1616              :         //      collect all edges that are associated with pReplaceMe
    1617              :                 vector<Edge*> vEdges;
    1618            0 :                 CollectEdges(vEdges, *this, pReplaceMe);
    1619            0 :                 for(uint i = 0; i < vEdges.size(); ++i)
    1620            0 :                         replace(associated_volumes_begin(vEdges[i]),
    1621              :                                         associated_volumes_end(vEdges[i]),
    1622              :                                         pReplaceMe, v);
    1623            0 :         }
    1624              : 
    1625            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1626              :         {
    1627              :         //      collect all faces that are associated with pReplaceMe
    1628              :                 vector<Face*> vFaces;
    1629            0 :                 CollectFaces(vFaces, *this, pReplaceMe);
    1630            0 :                 for(uint i = 0; i < vFaces.size(); ++i)
    1631            0 :                         replace(associated_volumes_begin(vFaces[i]),
    1632              :                                         associated_volumes_end(vFaces[i]),
    1633              :                                         pReplaceMe, v);
    1634            0 :         }
    1635              : 
    1636              : //      now we have to copy all associated elements of pReplaceMe to v
    1637            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1638              :         {
    1639            0 :                 m_aaEdgeContainerVOLUME[v].assign(associated_edges_begin(pReplaceMe),
    1640              :                                                                                         associated_edges_end(pReplaceMe));
    1641              :                 m_aaEdgeContainerVOLUME[pReplaceMe].clear();
    1642              :         }
    1643              : 
    1644            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1645              :         {
    1646            0 :                 m_aaFaceContainerVOLUME[v].assign(associated_faces_begin(pReplaceMe),
    1647              :                                                                                         associated_faces_end(pReplaceMe));
    1648              :                 m_aaFaceContainerVOLUME[pReplaceMe].clear();
    1649              :         }
    1650              : 
    1651              : //      remove the element from the storage and delete it.
    1652            0 :         m_volumeElementStorage.m_sectionContainer.erase(get_iterator(pReplaceMe), pReplaceMe->container_section());
    1653            0 :         m_volumeElementStorage.m_attachmentPipe.unregister_element(pReplaceMe);
    1654            0 :         delete pReplaceMe;
    1655              : }
    1656              : 
    1657            0 : void Grid::unregister_volume(Volume* v)
    1658              : {
    1659              : //      notify observers that the face is being erased
    1660            0 :         NOTIFY_OBSERVERS_REVERSE(m_volumeObservers, volume_to_be_erased(this, v));
    1661              : 
    1662              : //      disconnect from faces
    1663            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1664              :         {
    1665            0 :                 uint numFaces = v->num_faces();
    1666              :                 vector<Face*> vFaces;
    1667            0 :                 vFaces.reserve(numFaces);
    1668            0 :                 CollectFaces(vFaces, *this, v, false);
    1669            0 :                 numFaces = vFaces.size();
    1670            0 :                 for(uint i = 0; i < numFaces; ++i)
    1671              :                 {
    1672            0 :                         Face* f = vFaces[i];
    1673              : 
    1674            0 :                         if(f != NULL)
    1675              :                         {
    1676            0 :                                 VolumeContainer::iterator iter = find(m_aaVolumeContainerFACE[f].begin(),
    1677              :                                                                                                                 m_aaVolumeContainerFACE[f].end(), v);
    1678            0 :                                 if(iter != m_aaVolumeContainerFACE[f].end())
    1679              :                                         m_aaVolumeContainerFACE[f].erase(iter);
    1680              :                         }
    1681              :                 }
    1682            0 :         }
    1683              : 
    1684              : //      disconnect from edges
    1685            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    1686              :         {
    1687            0 :                 uint numEdges = v->num_edges();
    1688            0 :                 for(uint i = 0; i < numEdges; ++i)
    1689              :                 {
    1690              :                 //      find the correct entry
    1691            0 :                         Edge* e = get_edge(v, i);
    1692            0 :                         if(e != NULL)
    1693              :                         {
    1694            0 :                                 VolumeContainer::iterator iter = find(m_aaVolumeContainerEDGE[e].begin(),
    1695              :                                                                                                                 m_aaVolumeContainerEDGE[e].end(), v);
    1696            0 :                                 if(iter != m_aaVolumeContainerEDGE[e].end())
    1697              :                                         m_aaVolumeContainerEDGE[e].erase(iter);
    1698              :                         }
    1699              :                 }
    1700              :         }
    1701              : 
    1702              : //      disconnect from vertices
    1703            0 :         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    1704              :         {
    1705              :         //      iterate through all associated vertices and update their connection-info
    1706            0 :                 uint numVertices = v->num_vertices();
    1707            0 :                 Volume::ConstVertexArray vrts = v->vertices();
    1708            0 :                 for(uint i = 0; i < numVertices; ++i)
    1709              :                 {
    1710              :                 //      find the correct entry
    1711            0 :                         Vertex* vrt = vrts[i];
    1712            0 :                         VolumeContainer::iterator iter = find(m_aaVolumeContainerVERTEX[vrt].begin(),
    1713              :                                                                                                         m_aaVolumeContainerVERTEX[vrt].end(), v);
    1714            0 :                         if(iter != m_aaVolumeContainerVERTEX[vrt].end())
    1715              :                                 m_aaVolumeContainerVERTEX[vrt].erase(iter);
    1716              :                 }
    1717              :         }
    1718              : 
    1719              : //      remove the element from the storage
    1720            0 :         m_volumeElementStorage.m_sectionContainer.erase(get_iterator(v), v->container_section());
    1721            0 :         m_volumeElementStorage.m_attachmentPipe.unregister_element(v);
    1722            0 : }
    1723              : 
    1724            3 : void Grid::change_volume_options(uint optsNew)
    1725              : {
    1726              : //      check if associated edge information has to be created or removed.
    1727            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VOLOPT_STORE_ASSOCIATED_EDGES))
    1728              :         {
    1729            0 :                 if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1730            0 :                         volume_store_associated_edges(true);
    1731              :         }
    1732              :         else
    1733              :         {
    1734            3 :                 if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1735            0 :                         volume_store_associated_edges(false);
    1736              :         }
    1737              : 
    1738              : //      check if associated face information has to be created or removed.
    1739            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VOLOPT_STORE_ASSOCIATED_FACES))
    1740              :         {
    1741            0 :                 if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1742            0 :                         volume_store_associated_faces(true);
    1743              :         }
    1744              :         else
    1745              :         {
    1746            3 :                 if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1747            0 :                         volume_store_associated_faces(false);
    1748              :         }
    1749              : 
    1750              : //      enable or disable edge-auto-generation
    1751            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VOLOPT_AUTOGENERATE_EDGES))
    1752              :         {
    1753            0 :                 if(!option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
    1754            0 :                         volume_autogenerate_edges(true);
    1755              :         }
    1756              :         else
    1757              :         {
    1758            3 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
    1759            0 :                         volume_autogenerate_edges(false);
    1760              :         }
    1761              : 
    1762              : //      enable or disable face-auto-generation
    1763            3 :         if(OPTIONS_CONTAIN_OPTION(optsNew, VOLOPT_AUTOGENERATE_FACES))
    1764              :         {
    1765            2 :                 if(!option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
    1766            2 :                         volume_autogenerate_faces(true);
    1767              :         }
    1768              :         else
    1769              :         {
    1770            1 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
    1771            1 :                         volume_autogenerate_faces(false);
    1772              :         }
    1773            3 : }
    1774              : 
    1775            0 : void Grid::volume_store_associated_edges(bool bStoreIt)
    1776              : {
    1777            0 :         if(bStoreIt)
    1778              :         {
    1779            0 :                 if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1780              :                 {
    1781              :                 //      store associated edges
    1782            0 :                         attach_to_volumes(m_aEdgeContainer);
    1783            0 :                         m_aaEdgeContainerVOLUME.access(*this, m_aEdgeContainer);
    1784              : 
    1785            0 :                         bool createEdges = option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)
    1786            0 :                                                                 || option_is_enabled(GRIDOPT_AUTOGENERATE_SIDES);
    1787              :                 //      if EDGEOPT_STORE_ASSOCIATED_VOLUMES is enabled, this is as simple
    1788              :                 //      as to iterate through all edges and store them at their
    1789              :                 //      associated volumes.
    1790              :                 //      if not we have to iterate through the volumes and store
    1791              :                 //      each of their edges..
    1792              :                 //      If createEdges == true, we want to store the edges sorted.
    1793              :                 //      The else branch thus has to be executed.
    1794              :                         if(!createEdges
    1795            0 :                                 && option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    1796              :                         {
    1797              :                         //      iterate through the edges
    1798            0 :                                 for(EdgeIterator iter = edges_begin(); iter != edges_end(); iter++)
    1799              :                                 {
    1800            0 :                                         Edge* e = *iter;
    1801              :                                 //      iterate through the edges associated faces
    1802            0 :                                         for(AssociatedVolumeIterator vIter = associated_volumes_begin(e);
    1803            0 :                                                 vIter != associated_volumes_end(e); vIter++)
    1804              :                                         {
    1805            0 :                                                 m_aaEdgeContainerVOLUME[*vIter].push_back(e);
    1806              :                                         }
    1807              :                                 }
    1808              :                         }
    1809              :                         else
    1810              :                         {
    1811              :                         //      we have to find the edges by hand using GetEdge(...)
    1812            0 :                                 for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    1813              :                                 {
    1814              :                                         Volume* v = *iter;
    1815            0 :                                         int numEdges = v->num_edges();
    1816              : 
    1817            0 :                                         if(createEdges){
    1818              :                                         //      all edges exist. We can insert them sorted.
    1819            0 :                                                 m_aaEdgeContainerVOLUME[v].resize(numEdges);
    1820            0 :                                                 for(int i = 0; i < numEdges; ++i)
    1821            0 :                                                         m_aaEdgeContainerVOLUME[v][i] = get_edge(v, i);
    1822              :                                         }
    1823              :                                         else{
    1824              :                                         //      iterate through the edges of the volume
    1825            0 :                                                 for(int i = 0; i < numEdges; ++i)
    1826              :                                                 {
    1827              :                                                 //      get the edge-descriptor
    1828            0 :                                                         Edge* e = get_edge(v, i);
    1829            0 :                                                         if(e != NULL)
    1830            0 :                                                                 m_aaEdgeContainerVOLUME[v].push_back(e);
    1831              :                                                 }
    1832              :                                         }
    1833              :                                 }
    1834              :                         }
    1835              : 
    1836              :                 //      store the option
    1837            0 :                         m_options |= VOLOPT_STORE_ASSOCIATED_EDGES;
    1838              :                 }
    1839              :         }
    1840              :         else
    1841              :         {
    1842            0 :                 if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1843              :                 {
    1844              :                         //      remove vol-edge connection
    1845            0 :                         detach_from_volumes(m_aEdgeContainer);
    1846            0 :                         m_options &= (~VOLOPT_STORE_ASSOCIATED_EDGES);
    1847              :                 }
    1848              :         }
    1849            0 : }
    1850              : 
    1851            0 : void Grid::volume_store_associated_faces(bool bStoreIt)
    1852              : {
    1853            0 :         if(bStoreIt)
    1854              :         {
    1855            0 :                 if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1856              :                 {
    1857              :                 //      store associated faces
    1858            0 :                         attach_to_volumes(m_aFaceContainer);
    1859            0 :                         m_aaFaceContainerVOLUME.access(*this, m_aFaceContainer);
    1860              : 
    1861            0 :                         bool createFaces = option_is_enabled(VOLOPT_AUTOGENERATE_FACES);
    1862              : 
    1863              :                 //      if FACEOPT_STORE_ASSOCIATED_VOLUMES is enabled, this is as simple
    1864              :                 //      as to iterate through all faces and store them at their
    1865              :                 //      associated volumes.
    1866              :                 //      if not we have to iterate through the volumes and store
    1867              :                 //      each of their faces..
    1868              :                 //      if createFaces == true then we want to store the faces sorted.
    1869              :                         if(!createFaces
    1870            0 :                                 && option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1871              :                         {
    1872              :                         //      iterate through the edges
    1873            0 :                                 for(FaceIterator iter = faces_begin(); iter != faces_end(); iter++)
    1874              :                                 {
    1875            0 :                                         Face* f = *iter;
    1876              :                                 //      iterate through the faces associated volumes
    1877            0 :                                         for(AssociatedVolumeIterator vIter = associated_volumes_begin(f);
    1878            0 :                                                 vIter != associated_volumes_end(f); vIter++)
    1879              :                                         {
    1880            0 :                                                 m_aaFaceContainerVOLUME[*vIter].push_back(f);
    1881              :                                         }
    1882              :                                 }
    1883              :                         }
    1884              :                         else
    1885              :                         {
    1886              :                         //      we have to find the edges by hand using GetEdge(...)
    1887            0 :                                 FaceDescriptor fd;
    1888              : 
    1889            0 :                                 for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    1890              :                                 {
    1891              :                                         Volume* v = *iter;
    1892              :                                 //      iterate through the faces of the volume and get the corresponding face from the grid.
    1893            0 :                                         int numFaces = v->num_faces();
    1894              : 
    1895            0 :                                         if(createFaces){
    1896            0 :                                                 m_aaFaceContainerVOLUME[v].resize(numFaces);
    1897            0 :                                                 for(int i = 0; i < numFaces; ++i)
    1898            0 :                                                         m_aaFaceContainerVOLUME[v][i] = get_face(v, i);
    1899              : 
    1900              :                                         }
    1901              :                                         else{
    1902            0 :                                                 for(int i = 0; i < numFaces; ++i)
    1903              :                                                 {
    1904            0 :                                                         v->face_desc(i, fd);
    1905            0 :                                                         Face* f = find_face_in_associated_faces(fd.vertex(0), fd);
    1906              : 
    1907            0 :                                                         if(f)
    1908            0 :                                                                 m_aaFaceContainerVOLUME[v].push_back(f);
    1909              :                                                 }
    1910              :                                         }
    1911              :                                 }
    1912              :                         }
    1913              : 
    1914              :                 //      store options
    1915            0 :                         m_options |= VOLOPT_STORE_ASSOCIATED_FACES;
    1916              :                 }
    1917              :         }
    1918              :         else
    1919              :         {
    1920            0 :                 if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1921              :                 {
    1922              :                         //      remove vol-edge connection
    1923            0 :                         detach_from_volumes(m_aFaceContainer);
    1924            0 :                         m_options &= (~VOLOPT_STORE_ASSOCIATED_FACES);
    1925              :                 }
    1926              :         }
    1927            0 : }
    1928              : 
    1929            0 : void Grid::volume_autogenerate_edges(bool bAutogen)
    1930              : {
    1931            0 :         if(bAutogen)
    1932              :         {
    1933            0 :                 if(!option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
    1934              :                 {
    1935            0 :                         bool volsStoreEdges = option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES);
    1936            0 :                         EdgeDescriptor ed;
    1937              : 
    1938              :                 //      generate all missing edges now!
    1939            0 :                         for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    1940              :                         {
    1941              :                                 Volume* v = *iter;
    1942              : 
    1943              :                         //      check for each edge of the volume if it exists. if not create it and link it to the edge.
    1944            0 :                                 uint numEdges = v->num_edges();
    1945              : 
    1946              :                         //      reserve memory for neighbors
    1947            0 :                                 if(volsStoreEdges){
    1948              :                                         m_aaEdgeContainerVOLUME[v].clear();
    1949            0 :                                         m_aaEdgeContainerVOLUME[v].reserve(numEdges);
    1950              :                                 }
    1951              : 
    1952            0 :                                 for(uint i = 0; i < numEdges; ++i)
    1953              :                                 {
    1954              :                                 //      we can't use get_edge here, since we modify m_aaEdgeContainerVOLUME on the fly.
    1955            0 :                                         v->edge_desc(i, ed);
    1956            0 :                                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
    1957              : 
    1958            0 :                                         if(e == NULL)
    1959              :                                         {
    1960              :                                         //      create the edge
    1961            0 :                                                 e = v->create_edge(i);
    1962            0 :                                                 if(volsStoreEdges) // has to be performed before register_edge
    1963            0 :                                                         m_aaEdgeContainerVOLUME[v].push_back(e);
    1964            0 :                                                 register_edge(e, v, NULL, v);
    1965              :                                         }
    1966            0 :                                         else if(volsStoreEdges)
    1967            0 :                                                 m_aaEdgeContainerVOLUME[v].push_back(e);
    1968              :                                 }
    1969              :                         }
    1970              : 
    1971              :                 //      store the option
    1972            0 :                         m_options |= VOLOPT_AUTOGENERATE_EDGES;
    1973              :                 }
    1974              :         }
    1975              :         else
    1976              :         {
    1977              :         //      stop auto-generation
    1978            0 :                 m_options &= (~VOLOPT_AUTOGENERATE_EDGES);
    1979              :         }
    1980            0 : }
    1981              : 
    1982            3 : void Grid::volume_autogenerate_faces(bool bAutogen)
    1983              : {
    1984            3 :         if(bAutogen)
    1985              :         {
    1986            2 :                 if(!option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
    1987              :                 {
    1988            2 :                         bool volsStoreFaces = option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES);
    1989            2 :                         FaceDescriptor fd;
    1990              : 
    1991              :                 //      generate all missing faces now!
    1992            2 :                         for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    1993              :                         {
    1994              :                                 Volume* v = *iter;
    1995              :                         //      check for each face of the volume if it exists. if not create it and link it to the face.
    1996            0 :                                 uint numFaces = v->num_faces();
    1997              : 
    1998              :                         //      reserve memory for neighbors
    1999            0 :                                 if(volsStoreFaces){
    2000              :                                         m_aaFaceContainerVOLUME[v].clear();
    2001            0 :                                         m_aaFaceContainerVOLUME[v].reserve(numFaces);
    2002              :                                 }
    2003              : 
    2004            0 :                                 for(uint i = 0; i < numFaces; ++i)
    2005              :                                 {
    2006              :                                 //      we can't use get_face here, since we modify m_aaEdgeContainerVOLUME on the fly.
    2007            0 :                                         v->face_desc(i, fd);
    2008            0 :                                         Face* f = find_face_in_associated_faces(fd.vertex(0), fd);
    2009              : 
    2010            0 :                                         if(f == NULL)
    2011              :                                         {
    2012              :                                         //      create the face
    2013            0 :                                                 f = v->create_face(i);
    2014            0 :                                                 if(volsStoreFaces) // has to be performed before register_face
    2015            0 :                                                         m_aaFaceContainerVOLUME[v].push_back(f);
    2016            0 :                                                 register_face(f, v, v);
    2017              :                                         }
    2018            0 :                                         else if(volsStoreFaces)
    2019            0 :                                                 m_aaFaceContainerVOLUME[v].push_back(f);
    2020              :                                 }
    2021              :                         }
    2022              : 
    2023              :                 //      store the option
    2024            2 :                         m_options |= VOLOPT_AUTOGENERATE_FACES;
    2025              : 
    2026              :                 //      if FACEOPT_AUTOGENERATE_EDGES is active, too, then all volume-edges exist.
    2027              :                 //      Now, if VOLOPT_STORE_ASSOCIATED_EDGES is active but
    2028              :                 //      VOLOPT_AUTOGENERATE_EDGES is inactive, then we'll sort the associated-edges
    2029              :                 //      of volumes.
    2030            2 :                         if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES)
    2031            2 :                            && option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)
    2032            2 :                            && (!option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)))
    2033              :                         {
    2034            0 :                                 volume_sort_associated_edge_container();
    2035              :                         }
    2036              :                 }
    2037              :         }
    2038              :         else
    2039              :         {
    2040              :         //      stop auto-generation
    2041            1 :                 m_options &= (~VOLOPT_AUTOGENERATE_FACES);
    2042              :         }
    2043            3 : }
    2044              : 
    2045              : 
    2046            0 : void Grid::volume_sort_associated_edge_container()
    2047              : {
    2048            0 :         if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    2049            0 :                 return;
    2050              : 
    2051              :         EdgeContainer tmpCon;
    2052            0 :         for(VolumeIterator iter = volumes_begin(); iter != volumes_end(); iter++)
    2053              :         {
    2054              :                 Volume* v = *iter;
    2055            0 :                 uint numEdges = v->num_edges();
    2056              : 
    2057              :         //      since we already have a container of associated edges, we will search it
    2058              :         //      for matching edges...
    2059              :         //      to reduce memory allocation, we'll first copy the values to tmpCon
    2060              :                 EdgeContainer& edges = m_aaEdgeContainerVOLUME[v];
    2061              :                 tmpCon.clear();
    2062            0 :                 for(size_t i = 0; i < edges.size(); ++i)
    2063            0 :                         tmpCon.push_back(edges[i]);
    2064              : 
    2065              :                 edges.clear();
    2066              : 
    2067              :         //      check for each edge-desc, whether a matching edge is contained in edges.
    2068              :         //      if so push it back to edgesSorted.
    2069            0 :                 EdgeDescriptor ed;
    2070            0 :                 for(uint i = 0; i < numEdges; ++i){
    2071            0 :                         v->edge_desc(i, ed);
    2072            0 :                         for(size_t j = 0; j < tmpCon.size(); ++j){
    2073            0 :                                 if(tmpCon[j] && CompareVertices(&ed, tmpCon[j])){
    2074            0 :                                         edges.push_back(tmpCon[j]);
    2075            0 :                                         tmpCon[j] = NULL;
    2076            0 :                                         break;
    2077              :                                 }
    2078              :                         }
    2079              :                 }
    2080              :         }
    2081            0 : }
    2082              : 
    2083              : ////////////////////////////////////////////////////////////////////////
    2084              : ////////////////////////////////////////////////////////////////////////
    2085              : //      replace_vertex
    2086            0 : bool Grid::replace_vertex(Vertex* vrtOld, Vertex* vrtNew)
    2087              : {
    2088              : //      this bool should be a parameter. However one first would have
    2089              : //      to add connectivity updates for double-elements in this method,
    2090              : //      to handle the case when eraseDoubleElements is set to false.
    2091              :         bool eraseDoubleElements = true;
    2092              : 
    2093              : //      iterate through associated objects of vrtOld.
    2094              : //      replace in each vrtOld by vrtNew.
    2095              : //      Delete objects that would be doubled if eraseDoubleElements is set to true.
    2096              : //      Update connectivity information.
    2097              : //      erase vrtOld
    2098              : //      all elements that will be erased, during this method will be
    2099              : //      unregistered manually on the fly.
    2100              : 
    2101              : //      containers for object collection
    2102              :         vector<Edge*> vEdges;
    2103              :         vector<Face*> vFaces;
    2104              :         vector<Volume*> vVolumes;
    2105              : 
    2106            0 :         EdgeDescriptor ed;
    2107            0 :         FaceDescriptor fd;
    2108            0 :         VolumeDescriptor vd;
    2109              : 
    2110              : //      since vrtOld will be erased, we will notify all observers
    2111            0 :         NOTIFY_OBSERVERS_REVERSE(m_vertexObservers, vertex_to_be_erased(this, vrtOld));
    2112              : 
    2113              : //      EDGES
    2114            0 :         if(num_edges() > 0)
    2115              :         {
    2116            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_EDGES,
    2117              :                                                 "Grid::replace_vertex(...)",
    2118              :                                                 "VRTOPT_STORE_ASSOCIATED_EDGES");
    2119              : 
    2120            0 :                 AssociatedEdgeIterator iter = associated_edges_begin(vrtOld);
    2121            0 :                 AssociatedEdgeIterator iterEnd = associated_edges_end(vrtOld);
    2122            0 :                 while(iter != iterEnd)
    2123              :                 {
    2124            0 :                         Edge* e = *iter;
    2125              :                         ++iter;
    2126              : 
    2127              :                 //      if eraseDoubleElementes is enabled and the new edge would
    2128              :                 //      already exist, we wont replace the vertex in it.
    2129              :                         bool bReplaceVertex = true;
    2130              : 
    2131              :                         if(eraseDoubleElements)
    2132              :                         {
    2133              :                         //      create an edge-descriptor of the edge that will be created.
    2134            0 :                                 if(e->vertex(0) == vrtOld)
    2135            0 :                                         ed.set_vertices(e->vertex(1), vrtNew);
    2136              :                                 else
    2137            0 :                                         ed.set_vertices(e->vertex(0), vrtNew);
    2138              : 
    2139              :                         //      check if this edge already exists.
    2140            0 :                                 Edge* eNew = get_edge(ed);
    2141            0 :                                 if(eNew)
    2142              :                                 {
    2143              :                                 //      The edge will be removed. Notify observers.
    2144            0 :                                         NOTIFY_OBSERVERS_REVERSE(m_edgeObservers, edge_to_be_erased(this, e));
    2145              : 
    2146              :                                 //      Since we want to avoid deletion of associated elements
    2147              :                                 //      we have to handle the erasure of e by our self.
    2148              :                                         bReplaceVertex = false;
    2149              : 
    2150              :                                 //      before the removal we will replace its entry in associated-
    2151              :                                 //      element-lists with the pointer to the existing edge.
    2152            0 :                                         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
    2153              :                                         {
    2154              :                                         //      unregister e from the vertex with which e connects vrtOld.
    2155              :                                                 EdgeContainer& ec = m_aaEdgeContainerVERTEX[ed.vertex(0)];
    2156            0 :                                                 EdgeContainer::iterator tmpI = find(ec.begin(), ec.end(), e);
    2157            0 :                                                 if(tmpI != ec.end())
    2158              :                                                         ec.erase(tmpI);
    2159              :                                         }
    2160              : 
    2161            0 :                                         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES)
    2162            0 :                                                         && num_faces() > 0)
    2163              :                                         {
    2164              :                                         //      unregister the edge from all adjacent faces
    2165            0 :                                                 CollectFaces(vFaces, *this, e);
    2166            0 :                                                 for(uint i = 0; i < vFaces.size(); ++i)
    2167              :                                                 {
    2168            0 :                                                         Face* f = vFaces[i];
    2169            0 :                                                         replace(associated_edges_begin(f),
    2170              :                                                                         associated_edges_end(f), e, eNew);
    2171              :                                                 }
    2172              :                                         }
    2173              : 
    2174            0 :                                         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)
    2175            0 :                                                         && num_volumes() > 0)
    2176              :                                         {
    2177              :                                         //      unregister the edge from all adjacent volumes
    2178            0 :                                                 CollectVolumes(vVolumes, *this, e);
    2179            0 :                                                 for(uint i = 0; i < vVolumes.size(); ++i)
    2180              :                                                 {
    2181            0 :                                                         Volume* v = vVolumes[i];
    2182            0 :                                                         replace(associated_edges_begin(v),
    2183              :                                                                         associated_edges_end(v), e, eNew);
    2184              :                                                 }
    2185              :                                         }
    2186              : 
    2187              :                                 //      we can now remove e from the storage.
    2188            0 :                                         m_edgeElementStorage.m_sectionContainer.erase(get_iterator(e), e->container_section());
    2189            0 :                                         m_edgeElementStorage.m_attachmentPipe.unregister_element(e);
    2190            0 :                                         delete e;
    2191              :                                 }
    2192              :                         }
    2193              : 
    2194              :                 //      perform the replace
    2195              :                         if(bReplaceVertex)
    2196              :                         {
    2197              :                         //      replace the vertex
    2198            0 :                                 if(e->vertex(0) == vrtOld)
    2199            0 :                                         e->set_vertex(0, vrtNew);
    2200              :                                 else
    2201            0 :                                         e->set_vertex(1, vrtNew);
    2202              : 
    2203              :                         //      register e at vrtNew
    2204            0 :                                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
    2205              :                                 {
    2206            0 :                                         m_aaEdgeContainerVERTEX[vrtNew].push_back(e);
    2207              :                                 }
    2208              :                         }
    2209              :                 }
    2210              : 
    2211              :         //      we will now clear the associated edges array of vrtOld.
    2212              :                 m_aaEdgeContainerVERTEX[vrtOld].clear();
    2213              :         }
    2214              : 
    2215              : //      FACES
    2216            0 :         if(num_faces() > 0)
    2217              :         {
    2218            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_FACES,
    2219              :                                                 "Grid::replace_vertex(...)",
    2220              :                                                 "VRTOPT_STORE_ASSOCIATED_FACES");
    2221              : 
    2222            0 :                 AssociatedFaceIterator iter = associated_faces_begin(vrtOld);
    2223            0 :                 AssociatedFaceIterator iterEnd = associated_faces_end(vrtOld);
    2224            0 :                 while(iter != iterEnd)
    2225              :                 {
    2226            0 :                         Face* f = *iter;
    2227            0 :                         uint numVrts = f->num_vertices();
    2228            0 :                         Face::ConstVertexArray vrts = f->vertices();
    2229              : 
    2230              :                         ++iter;
    2231              : 
    2232              :                 //      if eraseDoubleElementes is enabled and the new face would
    2233              :                 //      already exist, we wont replace the vertex in it.
    2234              :                         bool bReplaceVertex = true;
    2235              : 
    2236              :                         if(eraseDoubleElements)
    2237              :                         {
    2238              :                         //      create a face-descriptor of the face that will be created.
    2239              :                                 fd.set_num_vertices(numVrts);
    2240            0 :                                 for(uint i = 0; i < numVrts; ++i)
    2241              :                                 {
    2242            0 :                                         if(vrts[i] == vrtOld)
    2243              :                                                 fd.set_vertex(i, vrtNew);
    2244              :                                         else
    2245              :                                                 fd.set_vertex(i, vrts[i]);
    2246              :                                 }
    2247              : 
    2248              :                         //      check if this face already exists.
    2249            0 :                                 Face* fNew = get_face(fd);
    2250            0 :                                 if(fNew)
    2251              :                                 {
    2252              :                                 //      The face will be removed. Notify observers.
    2253            0 :                                         NOTIFY_OBSERVERS_REVERSE(m_faceObservers, face_to_be_erased(this, f));
    2254              : 
    2255              :                                 //      Since we want to avoid deletion of associated elements
    2256              :                                 //      we have to handle the erasure of f by our self.
    2257              :                                         bReplaceVertex = false;
    2258              : 
    2259              :                                 //      before the removal we will replace its entry in associated-
    2260              :                                 //      element-lists with the pointer to the existing face.
    2261            0 :                                         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
    2262              :                                         {
    2263              :                                         //      unregister f from the vertices with which f connects vrtOld.
    2264            0 :                                                 for(uint i = 0; i < numVrts; ++i)
    2265              :                                                 {
    2266            0 :                                                         if(vrts[i] != vrtOld)
    2267              :                                                         {
    2268              :                                                                 FaceContainer& fc = m_aaFaceContainerVERTEX[vrts[i]];
    2269            0 :                                                                 FaceContainer::iterator tmpI = find(fc.begin(), fc.end(), f);
    2270            0 :                                                                 if(tmpI != fc.end())
    2271              :                                                                         fc.erase(tmpI);
    2272              :                                                         }
    2273              :                                                 }
    2274              :                                         }
    2275              : 
    2276            0 :                                         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES)
    2277            0 :                                                 && num_edges() > 0)
    2278              :                                         {
    2279              :                                         //      unregister f from adjacent edges.
    2280            0 :                                                 CollectEdges(vEdges, *this, f);
    2281            0 :                                                 for(uint i = 0; i < vEdges.size(); ++i)
    2282              :                                                 {
    2283            0 :                                                         FaceContainer& fc = m_aaFaceContainerEDGE[vEdges[i]];
    2284            0 :                                                         FaceContainer::iterator tmpI = find(fc.begin(), fc.end(), f);
    2285            0 :                                                         if(tmpI != fc.end())
    2286              :                                                                 fc.erase(tmpI);
    2287              :                                                 }
    2288              :                                         }
    2289              : 
    2290            0 :                                         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES)
    2291            0 :                                                         && num_volumes() > 0)
    2292              :                                         {
    2293              :                                         //      unregister the face from all adjacent volumes
    2294            0 :                                                 CollectVolumes(vVolumes, *this, f);
    2295            0 :                                                 for(uint i = 0; i < vVolumes.size(); ++i)
    2296              :                                                 {
    2297            0 :                                                         Volume* v = vVolumes[i];
    2298            0 :                                                         replace(associated_faces_begin(v),
    2299              :                                                                         associated_faces_end(v), f, fNew);
    2300              :                                                 }
    2301              :                                         }
    2302              : 
    2303              :                                 //      we can now remove f from the storage.
    2304            0 :                                         m_faceElementStorage.m_sectionContainer.erase(get_iterator(f), f->container_section());
    2305            0 :                                         m_faceElementStorage.m_attachmentPipe.unregister_element(f);
    2306            0 :                                         delete f;
    2307              :                                 }
    2308              :                         }
    2309              : 
    2310              :                 //      perform the replace
    2311              :                         if(bReplaceVertex)
    2312              :                         {
    2313              :                         //      replace the vertex
    2314            0 :                                 uint numVrts = f->num_vertices();
    2315            0 :                                 for(uint i = 0; i < numVrts; ++i)
    2316              :                                 {
    2317            0 :                                         if(vrts[i] == vrtOld)
    2318            0 :                                                 f->set_vertex(i, vrtNew);
    2319              :                                 }
    2320              : 
    2321              :                         //      register f at vrtNew
    2322            0 :                                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
    2323              :                                 {
    2324            0 :                                         m_aaFaceContainerVERTEX[vrtNew].push_back(f);
    2325              :                                 }
    2326              : 
    2327              :                         //      register f at existing edges
    2328            0 :                                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
    2329              :                                 {
    2330              :                                 //      only edges which contain vrtNew are relevant.
    2331            0 :                                         uint numEdges = f->num_edges();
    2332            0 :                                         for(uint i = 0; i < numEdges; ++i)
    2333              :                                         {
    2334            0 :                                                 f->edge_desc(i, ed);
    2335            0 :                                                 if(ed.vertex(0) == vrtNew || ed.vertex(1) == vrtNew)
    2336              :                                                 {
    2337            0 :                                                         Edge* tEdge = get_edge(ed);
    2338            0 :                                                         if(tEdge)
    2339              :                                                         {
    2340              :                                                                 FaceContainer& fc = m_aaFaceContainerEDGE[tEdge];
    2341            0 :                                                                 FaceContainer::iterator tmpI = find(fc.begin(), fc.end(), f);
    2342            0 :                                                                 if(tmpI == fc.end())
    2343            0 :                                                                         fc.push_back(f);
    2344              :                                                         }
    2345              :                                                 }
    2346              :                                         }
    2347              :                                 }
    2348              :                         }
    2349              :                 }
    2350              :         //      clear associated faces list of vrtOld
    2351              :                 m_aaFaceContainerVERTEX[vrtOld].clear();
    2352              :         }
    2353              : 
    2354              : //      VOLUMES
    2355            0 :         if(num_volumes() > 0)
    2356              :         {
    2357            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_VOLUMES,
    2358              :                                                 "Grid::replace_vertex(...)",
    2359              :                                                 "VRTOPT_STORE_ASSOCIATED_VOLUMES");
    2360              : 
    2361            0 :                 AssociatedVolumeIterator iter = associated_volumes_begin(vrtOld);
    2362            0 :                 AssociatedVolumeIterator iterEnd = associated_volumes_end(vrtOld);
    2363            0 :                 while(iter != iterEnd)
    2364              :                 {
    2365            0 :                         Volume* v = *iter;
    2366            0 :                         uint numVrts = v->num_vertices();
    2367            0 :                         Volume::ConstVertexArray vrts = v->vertices();
    2368              :                         ++iter;
    2369              : 
    2370              :                 //      if eraseDoubleElementes is enabled and the new face would
    2371              :                 //      already exist, we wont replace the vertex in it.
    2372              :                         bool bReplaceVertex = true;
    2373              : 
    2374              :                         if(eraseDoubleElements)
    2375              :                         {
    2376              :                         //      create a volume-descriptor of the volume that will be created.
    2377              :                                 vd.set_num_vertices(numVrts);
    2378              : 
    2379            0 :                                 for(uint i = 0; i < numVrts; ++i)
    2380              :                                 {
    2381            0 :                                         if(vrts[i] == vrtOld)
    2382              :                                                 vd.set_vertex(i, vrtNew);
    2383              :                                         else
    2384              :                                                 vd.set_vertex(i, vrts[i]);
    2385              :                                 }
    2386              : 
    2387              :                         //      check if this volume already exists.
    2388            0 :                                 Volume* vNew = get_volume(vd);
    2389            0 :                                 if(vNew)
    2390              :                                 {
    2391              :                                 //      The volume will be removed. Notify observers.
    2392            0 :                                         NOTIFY_OBSERVERS_REVERSE(m_volumeObservers, volume_to_be_erased(this, v));
    2393              : 
    2394              :                                 //      Since we want to avoid deletion of associated elements
    2395              :                                 //      we have to handle the erasure of v by our self.
    2396              :                                         bReplaceVertex = false;
    2397              : 
    2398              :                                 //      before the removal we will replace its entry in associated-
    2399              :                                 //      element-lists with the pointer to the existing volume.
    2400            0 :                                         if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    2401              :                                         {
    2402              :                                         //      unregister v from the vertices with which v connects vrtOld.
    2403            0 :                                                 for(uint i = 0; i < numVrts; ++i)
    2404              :                                                 {
    2405            0 :                                                         if(vrts[i] != vrtOld)
    2406              :                                                         {
    2407              :                                                                 VolumeContainer& vc = m_aaVolumeContainerVERTEX[vrts[i]];
    2408            0 :                                                                 VolumeContainer::iterator tmpI = find(vc.begin(), vc.end(), v);
    2409            0 :                                                                 if(tmpI != vc.end())
    2410              :                                                                         vc.erase(tmpI);
    2411              :                                                         }
    2412              :                                                 }
    2413              :                                         }
    2414              : 
    2415            0 :                                         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES)
    2416            0 :                                                 && num_edges() > 0)
    2417              :                                         {
    2418              :                                         //      unregister v from adjacent edges.
    2419            0 :                                                 CollectEdges(vEdges, *this, v);
    2420            0 :                                                 for(uint i = 0; i < vEdges.size(); ++i)
    2421              :                                                 {
    2422            0 :                                                         VolumeContainer& vc = m_aaVolumeContainerEDGE[vEdges[i]];
    2423            0 :                                                         VolumeContainer::iterator tmpI = find(vc.begin(), vc.end(), v);
    2424            0 :                                                         if(tmpI != vc.end())
    2425              :                                                                 vc.erase(tmpI);
    2426              :                                                 }
    2427              :                                         }
    2428              : 
    2429            0 :                                         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES)
    2430            0 :                                                 && num_faces() > 0)
    2431              :                                         {
    2432              :                                         //      unregister v from adjacent faces.
    2433            0 :                                                 CollectFaces(vFaces, *this, v);
    2434            0 :                                                 for(uint i = 0; i < vFaces.size(); ++i)
    2435              :                                                 {
    2436            0 :                                                         VolumeContainer& vc = m_aaVolumeContainerFACE[vFaces[i]];
    2437            0 :                                                         VolumeContainer::iterator tmpI = find(vc.begin(), vc.end(), v);
    2438            0 :                                                         if(tmpI != vc.end())
    2439              :                                                                 vc.erase(tmpI);
    2440              :                                                 }
    2441              :                                         }
    2442              : 
    2443              : 
    2444              :                                 //      we can now remove v from the storage.
    2445            0 :                                         m_volumeElementStorage.m_sectionContainer.erase(get_iterator(v), v->container_section());
    2446            0 :                                         m_volumeElementStorage.m_attachmentPipe.unregister_element(v);
    2447            0 :                                         delete v;
    2448              :                                 }
    2449              :                         }
    2450              : 
    2451              :                 //      perform the replace
    2452              :                         if(bReplaceVertex)
    2453              :                         {
    2454              :                         //      replace the vertex
    2455            0 :                                 uint numVrts = v->num_vertices();
    2456            0 :                                 for(uint i = 0; i < numVrts; ++i)
    2457              :                                 {
    2458            0 :                                         if(vrts[i] == vrtOld)
    2459            0 :                                                 v->set_vertex(i, vrtNew);
    2460              :                                 }
    2461              : 
    2462              :                         //      register v at vrtNew
    2463            0 :                                 if(option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    2464              :                                 {
    2465            0 :                                         m_aaVolumeContainerVERTEX[vrtNew].push_back(v);
    2466              :                                 }
    2467              : 
    2468              :                         //      register v at existing edges
    2469            0 :                                 if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    2470              :                                 {
    2471              :                                 //      only edges which contain vrtNew are relevant.
    2472            0 :                                         uint numEdges = v->num_edges();
    2473            0 :                                         for(uint i = 0; i < numEdges; ++i)
    2474              :                                         {
    2475            0 :                                                 v->edge_desc(i, ed);
    2476            0 :                                                 if(ed.vertex(0) == vrtNew || ed.vertex(1) == vrtNew)
    2477              :                                                 {
    2478            0 :                                                         Edge* tEdge = get_edge(ed);
    2479            0 :                                                         if(tEdge)
    2480              :                                                         {
    2481              :                                                                 VolumeContainer& vc = m_aaVolumeContainerEDGE[tEdge];
    2482            0 :                                                                 VolumeContainer::iterator tmpI = find(vc.begin(), vc.end(), v);
    2483            0 :                                                                 if(tmpI == vc.end())
    2484            0 :                                                                         vc.push_back(v);
    2485              :                                                         }
    2486              :                                                 }
    2487              :                                         }
    2488              :                                 }
    2489              : 
    2490              :                         //      register v at existing faces
    2491            0 :                                 if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    2492              :                                 {
    2493              :                                 //      only faces which contain vrtNew are relevant.
    2494            0 :                                         uint numFaces = v->num_faces();
    2495            0 :                                         for(uint i = 0; i < numFaces; ++i)
    2496              :                                         {
    2497            0 :                                                 v->face_desc(i, fd);
    2498              :                                         //      check whether fd contains vrtNew
    2499              :                                                 bool bContainsVrtNew = false;
    2500              :                                                 size_t numFaceVrts = fd.num_vertices();
    2501              :                                                 Face::ConstVertexArray fvrts = fd.vertices();
    2502            0 :                                                 for(uint j = 0; j < numFaceVrts; ++j)
    2503              :                                                 {
    2504            0 :                                                         if(fvrts[j] == vrtNew)
    2505              :                                                         {
    2506              :                                                                 bContainsVrtNew = true;
    2507              :                                                                 break;
    2508              :                                                         }
    2509              :                                                 }
    2510              : 
    2511            0 :                                                 if(bContainsVrtNew)
    2512              :                                                 {
    2513            0 :                                                         Face* tFace = get_face(fd);
    2514            0 :                                                         if(tFace)
    2515              :                                                         {
    2516              :                                                                 VolumeContainer& vc = m_aaVolumeContainerFACE[tFace];
    2517            0 :                                                                 VolumeContainer::iterator tmpI = find(vc.begin(), vc.end(), v);
    2518            0 :                                                                 if(tmpI == vc.end())
    2519            0 :                                                                         vc.push_back(v);
    2520              :                                                         }
    2521              :                                                 }
    2522              :                                         }
    2523              :                                 }
    2524              :                         }
    2525              :                 }
    2526              :         }
    2527              : 
    2528              : //      finally erase vrtOld.
    2529            0 :         m_vertexElementStorage.m_sectionContainer.erase(get_iterator(vrtOld), vrtOld->container_section());
    2530            0 :         m_vertexElementStorage.m_attachmentPipe.unregister_element(vrtOld);
    2531            0 :         delete vrtOld;
    2532              : 
    2533            0 :         return true;
    2534            0 : }
    2535              : 
    2536              : ////////////////////////////////////////////////////////////////////////
    2537              : //      replace_vertex_is_valid
    2538            0 : bool Grid::replace_vertex_is_valid(Vertex* vrtOld, Vertex* vrtNew)
    2539              : {
    2540              : //      iterate through all geometric objects connected to vrtOld and check
    2541              : //      if they contain vrtNew too. If not return true, else return false.
    2542              : 
    2543              : //      check edges
    2544            0 :         if(num_edges() > 0)
    2545              :         {
    2546              :         //      we need vertex-edge connectivity
    2547            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_EDGES,
    2548              :                                                 "Grid::replace_vertex_is_valid(...)",
    2549              :                                                 "VRTOPT_STORE_ASSOCIATED_EDGES");
    2550              : 
    2551            0 :                 AssociatedEdgeIterator iterEnd = associated_edges_end(vrtOld);
    2552            0 :                 for(AssociatedEdgeIterator iter = associated_edges_begin(vrtOld);
    2553            0 :                         iter != iterEnd; ++iter)
    2554              :                 {
    2555              :                 //      check whether vrtNew is contained in the edge.
    2556            0 :                         if((*iter)->vertex(0) == vrtNew)
    2557              :                                 return false;
    2558            0 :                         if((*iter)->vertex(1) == vrtNew)
    2559              :                                 return false;
    2560              :                 }
    2561              :         }
    2562              : 
    2563              : //      check faces
    2564            0 :         if(num_faces() > 0)
    2565              :         {
    2566              :         //      we need vertex-face connectivity
    2567            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_FACES,
    2568              :                                                 "Grid::replace_vertex_is_valid(...)",
    2569              :                                                 "VRTOPT_STORE_ASSOCIATED_FACES");
    2570              : 
    2571            0 :                 AssociatedFaceIterator iterEnd = associated_faces_end(vrtOld);
    2572            0 :                 for(AssociatedFaceIterator iter = associated_faces_begin(vrtOld);
    2573            0 :                         iter != iterEnd; ++iter)
    2574              :                 {
    2575            0 :                         if(FaceContains(*iter, vrtNew))
    2576              :                                 return false;
    2577              :                 }
    2578              :         }
    2579              : 
    2580              : //      check volumes
    2581            0 :         if(num_volumes() > 0)
    2582              :         {
    2583              :         //      we need vertex-face connectivity
    2584            0 :                 autoenable_option(VRTOPT_STORE_ASSOCIATED_VOLUMES,
    2585              :                                                 "Grid::replace_vertex_is_valid(...)",
    2586              :                                                 "VRTOPT_STORE_ASSOCIATED_VOLUMES");
    2587              : 
    2588            0 :                 AssociatedVolumeIterator iterEnd = associated_volumes_end(vrtOld);
    2589            0 :                 for(AssociatedVolumeIterator iter = associated_volumes_begin(vrtOld);
    2590            0 :                         iter != iterEnd; ++iter)
    2591              :                 {
    2592            0 :                         if(VolumeContains(*iter, vrtNew))
    2593              :                                 return false;
    2594              :                 }
    2595              :         }
    2596              : 
    2597              :         return true;
    2598              : }
    2599              : 
    2600              : 
    2601              : 
    2602              : ////////////////////////////////////////////////////////////////////////////////
    2603              : //      ASSOCIATED ELEMENTS
    2604              : ////////////////////////////////////////////////////////////////////////////////
    2605              : 
    2606              : ////////////////////////////////////////////////////////////////////////////////
    2607              : //      ASSOCIATED VERTICES
    2608            0 : void Grid::get_associated(SecureVertexContainer& vrts, Edge* e)
    2609              : {
    2610            0 :         vrts.set_external_array(e->vertices(), e->num_vertices());
    2611            0 : }
    2612              : 
    2613            0 : void Grid::get_associated(SecureVertexContainer& vrts, Face* f)
    2614              : {
    2615            0 :         vrts.set_external_array(f->vertices(), f->num_vertices());
    2616            0 : }
    2617              : 
    2618            0 : void Grid::get_associated(SecureVertexContainer& vrts, Volume* v)
    2619              : {
    2620            0 :         vrts.set_external_array(v->vertices(), v->num_vertices());
    2621            0 : }
    2622              : 
    2623              : 
    2624              : ////////////////////////////////////////////////////////////////////////////////
    2625              : //      ASSOCIATED EDGES
    2626            0 : void Grid::get_associated(SecureEdgeContainer& edges, Vertex* v)
    2627              : {
    2628              : //      Without the VRTOPT_STORE_ASSOCIATED_... option, this operation would have
    2629              : //      complexity O(n). This has to be avoided! We thus simply enable the option.
    2630              : //      This takes some time, however, later queries will greatly benefit.
    2631            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES)){
    2632              :         //      only enable the option if edges exist at all
    2633            0 :                 if(num<Edge>() == 0){
    2634              :                         edges.clear();
    2635            0 :                         return;
    2636              :                 }
    2637              : 
    2638              :                 LOG("WARNING in get_associated(edges, vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
    2639            0 :                 vertex_store_associated_edges(true);
    2640              :         }
    2641              : 
    2642              :         EdgeContainer& assEdges = m_aaEdgeContainerVERTEX[v];
    2643            0 :         if(assEdges.empty())
    2644              :                 edges.clear();
    2645              :         else
    2646            0 :                 edges.set_external_array(&assEdges.front(), assEdges.size());
    2647              : }
    2648              : 
    2649            0 : void Grid::get_associated(SecureEdgeContainer& edges, Face* f)
    2650              : {
    2651              : //      to improve performance, we first check the grid options.
    2652            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    2653              :         {
    2654              :         //      we can output the associated array directly
    2655              :                 EdgeContainer& assEdges = m_aaEdgeContainerFACE[f];
    2656            0 :                 if(assEdges.empty())
    2657              :                         edges.clear();
    2658              :                 else
    2659            0 :                         edges.set_external_array(&assEdges.front(), assEdges.size());
    2660              :         }
    2661              :         else{
    2662              :         //      clear the container
    2663              :                 edges.clear();
    2664              : 
    2665              :         //      if no edges are present, we can leave immediately
    2666            0 :                 if(num<Edge>() == 0)
    2667              :                         return;
    2668              : 
    2669              :         //      get the edges one by one
    2670              :                 uint numEdges = f->num_edges();
    2671            0 :                 for(uint i = 0; i < numEdges; ++i){
    2672            0 :                         Edge* e = get_edge(f, i);
    2673            0 :                         if(e != NULL)
    2674            0 :                                 edges.push_back(e);
    2675              :                 }
    2676              :         }
    2677              : }
    2678              : 
    2679            0 : void Grid::get_associated(SecureEdgeContainer& edges, Volume* v)
    2680              : {
    2681              : //      to improve performance, we first check the grid options.
    2682            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    2683              :         {
    2684              :         //      we can output the associated array directly
    2685              :                 EdgeContainer& assEdges = m_aaEdgeContainerVOLUME[v];
    2686            0 :                 if(assEdges.empty())
    2687              :                         edges.clear();
    2688              :                 else
    2689            0 :                         edges.set_external_array(&assEdges.front(), assEdges.size());
    2690              :         }
    2691              :         else{
    2692              :         //      clear the container
    2693              :                 edges.clear();
    2694              : 
    2695              :         //      if no edges are present, we can leave immediately
    2696            0 :                 if(num<Edge>() == 0)
    2697              :                         return;
    2698              : 
    2699              :         //      get the edges one by one
    2700            0 :                 uint numEdges = v->num_edges();
    2701            0 :                 for(uint i = 0; i < numEdges; ++i){
    2702            0 :                         Edge* e = get_edge(v, i);
    2703            0 :                         if(e != NULL)
    2704            0 :                                 edges.push_back(e);
    2705              :                 }
    2706              :         }
    2707              : }
    2708              : 
    2709              : 
    2710              : ////////////////////////////////////////////////////////////////////////////////
    2711              : //      ASSOCIATED FACES
    2712            0 : void Grid::get_associated(SecureFaceContainer& faces, Vertex* v)
    2713              : {
    2714              : //      Without the VRTOPT_STORE_ASSOCIATED_... option, this operation would have
    2715              : //      complexity O(n). This has to be avoided! We thus simply enable the option.
    2716              : //      This takes some time, however, later queries will greatly benefit.
    2717            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES)){
    2718              :         //      only enable the option if faces exist at all
    2719            0 :                 if(num<Face>() == 0){
    2720              :                         faces.clear();
    2721            0 :                         return;
    2722              :                 }
    2723              : 
    2724              :                 LOG("WARNING in get_associated(faces, vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
    2725            0 :                 vertex_store_associated_faces(true);
    2726              :         }
    2727              : 
    2728              :         FaceContainer& assFaces = m_aaFaceContainerVERTEX[v];
    2729            0 :         if(assFaces.empty())
    2730              :                 faces.clear();
    2731              :         else
    2732            0 :                 faces.set_external_array(&assFaces.front(), assFaces.size());
    2733              : }
    2734              : 
    2735            0 : void Grid::get_associated(SecureFaceContainer& faces, Edge* e)
    2736              : {
    2737              : //      best option: EDGEOPT_STORE_ASSOCIATED_FACES
    2738            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES)){
    2739              :         //      we can output the associated array directly
    2740              :                 FaceContainer& assFaces = m_aaFaceContainerEDGE[e];
    2741            0 :                 if(assFaces.empty())
    2742              :                         faces.clear();
    2743              :                 else
    2744            0 :                         faces.set_external_array(&assFaces.front(), assFaces.size());
    2745              :         }
    2746              :         else{
    2747              :         //      second best: iterate through all faces associated with the first end-point of e
    2748              :         //      and check for each if it contains e. If so push it into the container.
    2749              :         //      VRTOPT_STORE_ASSOCIATED_FACES has to be enabled for this. Only continue,
    2750              :         //      if faces exist at all
    2751              :                 faces.clear();
    2752            0 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES)){
    2753              :                 //      only enable the option if faces exist at all
    2754            0 :                         if(num<Face>() == 0){
    2755              :                                 return;
    2756              :                         }
    2757              : 
    2758              :                         LOG("WARNING in get_associated(faces, edge): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
    2759            0 :                         vertex_store_associated_faces(true);
    2760              :                 }
    2761              : 
    2762              :         //      check as few faces as possible
    2763            0 :                 Vertex* vrt = e->vertex(0);
    2764              : /*      //      This check could be beneficial - however, it probably introduces unnecessary overhead.
    2765              :                 if(m_aaFaceContainerVERTEX[vrt].size() >
    2766              :                         m_aaFaceContainerVERTEX[e->vertex(1)].size())
    2767              :                 {
    2768              :                         vrt = e->vertex(1);
    2769              :                 }
    2770              : */
    2771              : 
    2772              :                 FaceContainer& assFaces = m_aaFaceContainerVERTEX[vrt];
    2773            0 :                 for(size_t i = 0; i < assFaces.size(); ++i){
    2774            0 :                         if(FaceContains(assFaces[i], e))
    2775            0 :                                 faces.push_back(assFaces[i]);
    2776              :                 }
    2777              :         }
    2778              : }
    2779              : 
    2780            0 : void Grid::get_associated(SecureFaceContainer& faces, Volume* v)
    2781              : {
    2782              : //      to improve performance, we first check the grid options.
    2783            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    2784              :         {
    2785              :         //      we can output the associated array directly
    2786              :                 FaceContainer& assFaces = m_aaFaceContainerVOLUME[v];
    2787            0 :                 if(assFaces.empty())
    2788              :                         faces.clear();
    2789              :                 else
    2790            0 :                         faces.set_external_array(&assFaces.front(), assFaces.size());
    2791              :         }
    2792              :         else{
    2793              :         //      clear the container
    2794              :                 faces.clear();
    2795              : 
    2796              :         //      if no faces are present, we can leave immediately
    2797            0 :                 if(num<Face>() == 0)
    2798              :                         return;
    2799              : 
    2800              :         //      get the faces one by one
    2801            0 :                 uint numFaces = v->num_faces();
    2802            0 :                 for(uint i = 0; i < numFaces; ++i){
    2803            0 :                         Face* f = get_face(v, i);
    2804            0 :                         if(f != NULL)
    2805            0 :                                 faces.push_back(f);
    2806              :                 }
    2807              :         }
    2808              : }
    2809              : 
    2810              : 
    2811              : ////////////////////////////////////////////////////////////////////////////////
    2812              : //      ASSOCIATED VOLUMES
    2813            0 : void Grid::get_associated(SecureVolumeContainer& vols, Vertex* v)
    2814              : {
    2815              : //      Without the VRTOPT_STORE_ASSOCIATED_... option, this operation would have
    2816              : //      complexity O(n). This has to be avoided! We thus simply enable the option.
    2817              : //      This takes some time, however, later queries will greatly benefit.
    2818            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES)){
    2819              :         //      only enable the option if volumes exist at all
    2820            0 :                 if(num<Volume>() == 0){
    2821              :                         vols.clear();
    2822            0 :                         return;
    2823              :                 }
    2824              : 
    2825              :                 LOG("WARNING in get_associated(volumes, vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    2826            0 :                 vertex_store_associated_volumes(true);
    2827              :         }
    2828              : 
    2829              :         VolumeContainer& assVols = m_aaVolumeContainerVERTEX[v];
    2830            0 :         if(assVols.empty())
    2831              :                 vols.clear();
    2832              :         else
    2833            0 :                 vols.set_external_array(&assVols.front(), assVols.size());
    2834              : }
    2835              : 
    2836            0 : void Grid::get_associated(SecureVolumeContainer& vols, Edge* e)
    2837              : {
    2838              : //      best option: EDGEOPT_STORE_ASSOCIATED_VOLUMES
    2839            0 :         if(option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES)){
    2840              :         //      we can output the associated array directly
    2841              :                 VolumeContainer& assVols = m_aaVolumeContainerEDGE[e];
    2842            0 :                 if(assVols.empty())
    2843              :                         vols.clear();
    2844              :                 else
    2845            0 :                         vols.set_external_array(&assVols.front(), assVols.size());
    2846              :         }
    2847              :         else{
    2848              :         //      second best: iterate through all volumes associated with the first end-point of e
    2849              :         //      and check for each if it contains e. If so push it into the container.
    2850              :         //      VRTOPT_STORE_ASSOCIATED_VOLUMES has to be enabled for this. Only continue,
    2851              :         //      if volumes exist at all
    2852              :                 vols.clear();
    2853            0 :                 if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES)){
    2854              :                 //      only enable the option if volumes exist at all
    2855            0 :                         if(num<Volume>() == 0){
    2856              :                                 return;
    2857              :                         }
    2858              : 
    2859              :                         LOG("WARNING in get_associated(volumes, edge): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    2860            0 :                         vertex_store_associated_volumes(true);
    2861              :                 }
    2862              : 
    2863              :         //      check as few faces as possible
    2864            0 :                 Vertex* vrt = e->vertex(0);
    2865              : /*      //      This check could be beneficial - however, it probably introduces unnecessary overhead.
    2866              :                 if(m_aaVolumeContainerVERTEX[vrt].size() >
    2867              :                         m_aaVolumeContainerVERTEX[e->vertex(1)].size())
    2868              :                 {
    2869              :                         vrt = e->vertex(1);
    2870              :                 }
    2871              : */
    2872              : 
    2873              :                 VolumeContainer& assVols = m_aaVolumeContainerVERTEX[vrt];
    2874            0 :                 for(size_t i = 0; i < assVols.size(); ++i){
    2875            0 :                         if(VolumeContains(assVols[i], e))
    2876            0 :                                 vols.push_back(assVols[i]);
    2877              :                 }
    2878              :         }
    2879              : }
    2880              : 
    2881            0 : void Grid::get_associated(SecureVolumeContainer& vols, Face* f)
    2882              : {
    2883              : //      best option: FACEOPT_STORE_ASSOCIATED_VOLUMES
    2884            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES)){
    2885              :         //      we can output the associated array directly
    2886              :                 VolumeContainer& assVols = m_aaVolumeContainerFACE[f];
    2887            0 :                 if(assVols.empty())
    2888              :                         vols.clear();
    2889              :                 else
    2890            0 :                         vols.set_external_array(&assVols.front(), assVols.size());
    2891              :         }
    2892              :         else
    2893            0 :                 get_associated_vols_raw(vols, f);
    2894            0 : }
    2895              : 
    2896            0 : void Grid::get_associated_vols_raw(SecureVolumeContainer& vols, Face* f)
    2897              : {
    2898              : 
    2899              : //      iterate through all volumes associated with the first corner of f
    2900              : //      and check for each if it contains f. If so push it into the container.
    2901              : //      VRTOPT_STORE_ASSOCIATED_VOLUMES has to be enabled for this. Only continue,
    2902              : //      if volumes exist at all
    2903              :         vols.clear();
    2904            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES)){
    2905              :         //      only enable the option if volumes exist at all
    2906            0 :                 if(num<Volume>() == 0){
    2907              :                         return;
    2908              :                 }
    2909              : 
    2910              :                 LOG("WARNING in get_associated_vols_raw(volumes, face): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    2911            0 :                 vertex_store_associated_volumes(true);
    2912              :         }
    2913              : 
    2914              : //      check as few faces as possible
    2915            0 :         Vertex* vrt = f->vertex(0);
    2916              : 
    2917              :         VolumeContainer& assVols = m_aaVolumeContainerVERTEX[vrt];
    2918            0 :         for(size_t i = 0; i < assVols.size(); ++i){
    2919            0 :                 Volume* v = assVols[i];
    2920            0 :                 if(VolumeContains(v, f->vertex(1))){
    2921            0 :                         if(VolumeContains(v, f->vertex(2))){
    2922            0 :                                 if(VolumeContains(v, f))
    2923            0 :                                         vols.push_back(v);
    2924              :                         }
    2925              :                 }
    2926              :         }
    2927              : }
    2928              : 
    2929              : 
    2930              : ////////////////////////////////////////////////////////////////////////////////
    2931              : //      ASSOCIATED SORTED
    2932            0 : void Grid::get_associated_sorted(SecureVertexContainer& vrts, Edge* e) const
    2933              : {
    2934            0 :         vrts.set_external_array(e->vertices(), e->num_vertices());
    2935            0 : }
    2936              : 
    2937            0 : void Grid::get_associated_sorted(SecureVertexContainer& vrts, Face* f) const
    2938              : {
    2939            0 :         vrts.set_external_array(f->vertices(), f->num_vertices());
    2940            0 : }
    2941              : 
    2942            0 : void Grid::get_associated_sorted(SecureVertexContainer& vrts, Volume* v) const
    2943              : {
    2944            0 :         vrts.set_external_array(v->vertices(), v->num_vertices());
    2945            0 : }
    2946              : 
    2947              : 
    2948            0 : void Grid::get_associated_sorted(SecureEdgeContainer& edges, Vertex*)
    2949              : {
    2950            0 :         edges.set_external_array(NULL, 0);
    2951            0 : }
    2952              : 
    2953            0 : void Grid::get_associated_sorted(SecureEdgeContainer& edges, Face* f)
    2954              : {
    2955              : //      to improve performance, we first check the grid options.
    2956            0 :         if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES
    2957              :                                            | FACEOPT_STORE_ASSOCIATED_EDGES))
    2958              :         {
    2959              :         //      we can output the associated array directly
    2960              :                 EdgeContainer& assEdges = m_aaEdgeContainerFACE[f];
    2961            0 :                 edges.set_external_array(&assEdges.front(), assEdges.size());
    2962              :         }
    2963              :         else{
    2964              :         //      clear the container
    2965              :                 edges.clear();
    2966              : 
    2967              :         //      if no edges are present, we can leave immediately
    2968            0 :                 if(num<Edge>() == 0)
    2969              :                         return;
    2970              : 
    2971              :         //      get the edges one by one
    2972              :                 uint numEdges = f->num_edges();
    2973            0 :                 for(uint i = 0; i < numEdges; ++i){
    2974            0 :                         Edge* e = get_edge(f, i);
    2975            0 :                         if(e != NULL)
    2976            0 :                                 edges.push_back(e);
    2977              :                 }
    2978              :         }
    2979              : }
    2980              : 
    2981            0 : void Grid::get_associated_sorted(SecureEdgeContainer& edges, Volume* v)
    2982              : {
    2983              : //      to improve performance, we first check the grid options.
    2984            0 :         if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES
    2985              :                                                         | VOLOPT_STORE_ASSOCIATED_EDGES)
    2986            0 :                 || option_is_enabled(VOLOPT_AUTOGENERATE_FACES
    2987              :                                                         | FACEOPT_AUTOGENERATE_EDGES
    2988              :                                                         | VOLOPT_STORE_ASSOCIATED_EDGES))
    2989              :         {
    2990              :         //      we can output the associated array directly
    2991              :                 EdgeContainer& assEdges = m_aaEdgeContainerVOLUME[v];
    2992            0 :                 edges.set_external_array(&assEdges.front(), assEdges.size());
    2993              :         }
    2994              :         else{
    2995              :         //      clear the container
    2996              :                 edges.clear();
    2997              : 
    2998              :         //      if no edges are present, we can leave immediately
    2999            0 :                 if(num<Edge>() == 0)
    3000              :                         return;
    3001              : 
    3002              :         //      get the edges one by one
    3003            0 :                 uint numEdges = v->num_edges();
    3004            0 :                 for(uint i = 0; i < numEdges; ++i){
    3005            0 :                         Edge* e = get_edge(v, i);
    3006            0 :                         if(e != NULL)
    3007            0 :                                 edges.push_back(e);
    3008              :                 }
    3009              :         }
    3010              : }
    3011              : 
    3012            0 : void Grid::get_associated_sorted(SecureFaceContainer& faces, Vertex*)
    3013              : {
    3014            0 :         faces.set_external_array(NULL, 0);
    3015            0 : }
    3016              : 
    3017            0 : void Grid::get_associated_sorted(SecureFaceContainer& faces, Edge*)
    3018              : {
    3019            0 :         faces.set_external_array(NULL, 0);
    3020            0 : }
    3021              : 
    3022            0 : void Grid::get_associated_sorted(SecureFaceContainer& faces, Volume* v)
    3023              : {
    3024              : //      to improve performance, we first check the grid options.
    3025            0 :         if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES
    3026              :                                            | VOLOPT_STORE_ASSOCIATED_FACES))
    3027              :         {
    3028              :         //      we can output the associated array directly
    3029              :                 FaceContainer& assFaces = m_aaFaceContainerVOLUME[v];
    3030            0 :                 faces.set_external_array(&assFaces.front(), assFaces.size());
    3031              :         }
    3032              :         else{
    3033              :         //      clear the container
    3034              :                 faces.clear();
    3035              : 
    3036              :         //      if no edges are present, we can leave immediately
    3037            0 :                 if(num<Face>() == 0)
    3038              :                         return;
    3039              : 
    3040              :         //      get the edges one by one
    3041            0 :                 uint numFaces = v->num_faces();
    3042            0 :                 for(uint i = 0; i < numFaces; ++i){
    3043            0 :                         Face* f = get_face(v, i);
    3044            0 :                         if(f != NULL)
    3045            0 :                                 faces.push_back(f);
    3046              :                 }
    3047              :         }
    3048              : }
    3049              : 
    3050            0 : void Grid::get_associated_sorted(SecureVolumeContainer& vols, Vertex*)
    3051              : {
    3052            0 :         vols.set_external_array(NULL, 0);
    3053            0 : }
    3054              : 
    3055            0 : void Grid::get_associated_sorted(SecureVolumeContainer& vols, Edge*)
    3056              : {
    3057            0 :         vols.set_external_array(NULL, 0);
    3058            0 : }
    3059              : 
    3060            0 : void Grid::get_associated_sorted(SecureVolumeContainer& vols, Face*)
    3061              : {
    3062            0 :         vols.set_external_array(NULL, 0);
    3063            0 : }
    3064              : 
    3065              : }       //      end of namespace
        

Generated by: LCOV version 2.0-1