LCOV - code coverage report
Current view: top level - ugbase/lib_grid/algorithms - selection_util.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 386 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 45 0

            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              : #include <vector>
      34              : #include <stack>
      35              : #include <queue>
      36              : #include "lib_grid/selector.h"
      37              : #include "selection_util.h"
      38              : #include "geom_obj_util/geom_obj_util.h"
      39              : #include "lib_grid/grid/grid_util.h"
      40              : 
      41              : using namespace std;
      42              : 
      43              : namespace ug
      44              : {
      45              : ////////////////////////////////////////////////////////////////////////
      46              : //      instatiate template specializations
      47              : template void SelectInnerSelectionVertices<Selector>(Selector&);
      48              : template void SelectInnerSelectionVertices<MGSelector>(MGSelector&);
      49              : 
      50              : template void SelectInnerSelectionEdges<Selector>(Selector&);
      51              : template void SelectInnerSelectionEdges<MGSelector>(MGSelector&);
      52              : 
      53              : template void SelectInnerSelectionFaces<Selector>(Selector&);
      54              : template void SelectInnerSelectionFaces<MGSelector>(MGSelector&);
      55              : 
      56              : ////////////////////////////////////////////////////////////////////////
      57              : template void DeselectBoundarySelectionVertices<Selector>(Selector&);
      58              : template void DeselectBoundarySelectionVertices<MGSelector>(MGSelector&);
      59              : 
      60              : template void DeselectBoundarySelectionEdges<Selector>(Selector&);
      61              : template void DeselectBoundarySelectionEdges<MGSelector>(MGSelector&);
      62              : 
      63              : template void DeselectBoundarySelectionFaces<Selector>(Selector&);
      64              : template void DeselectBoundarySelectionFaces<MGSelector>(MGSelector&);
      65              : 
      66              : ////////////////////////////////////////////////////////////////////////
      67              : template void EraseSelectedObjects<Selector>(Selector&);
      68              : template void EraseSelectedObjects<MGSelector>(MGSelector&);
      69              : 
      70              : ////////////////////////////////////////////////////////////////////////
      71              : template void InvertSelection<Selector>(Selector&);
      72              : template void InvertSelection<MGSelector>(MGSelector&);
      73              : 
      74              : 
      75              : ////////////////////////////////////////////////////////////////////////
      76              : ////////////////////////////////////////////////////////////////////////
      77            0 : size_t CollectVerticesTouchingSelection(std::vector<Vertex*>& vrtsOut,
      78              :                                                                                 ISelector& sel)
      79              : {
      80              :         vrtsOut.clear();
      81              :         Grid* pGrid = sel.grid();
      82            0 :         if(!pGrid)
      83              :                 return 0;
      84              : 
      85              :         Grid& grid = *pGrid;
      86              : 
      87            0 :         grid.begin_marking();
      88              : 
      89              : //      get the goc and iterate over all elements
      90            0 :         GridObjectCollection goc = sel.get_grid_objects();
      91            0 :         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
      92              :                 for(VertexIterator iter = goc.begin<Vertex>(lvl);
      93            0 :                         iter != goc.end<Vertex>(lvl); ++iter)
      94              :                 {
      95            0 :                         if(!grid.is_marked(*iter)){
      96              :                                 grid.mark(*iter);
      97            0 :                                 vrtsOut.push_back(*iter);
      98              :                         }
      99              :                 }
     100              : 
     101              :                 for(EdgeIterator iter = goc.begin<Edge>(lvl);
     102            0 :                         iter != goc.end<Edge>(lvl); ++iter)
     103              :                 {
     104            0 :                         for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     105            0 :                                 Vertex* vrt = (*iter)->vertex(i);
     106            0 :                                 if(!grid.is_marked(vrt)){
     107              :                                         grid.mark(vrt);
     108            0 :                                         vrtsOut.push_back(vrt);
     109              :                                 }
     110              :                         }
     111              :                 }
     112              : 
     113              :                 for(FaceIterator iter = goc.begin<Face>(lvl);
     114            0 :                         iter != goc.end<Face>(lvl); ++iter)
     115              :                 {
     116            0 :                         for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     117            0 :                                 Vertex* vrt = (*iter)->vertex(i);
     118            0 :                                 if(!grid.is_marked(vrt)){
     119              :                                         grid.mark(vrt);
     120            0 :                                         vrtsOut.push_back(vrt);
     121              :                                 }
     122              :                         }
     123              :                 }
     124              : 
     125              :                 for(VolumeIterator iter = goc.begin<Volume>(lvl);
     126            0 :                         iter != goc.end<Volume>(lvl); ++iter)
     127              :                 {
     128            0 :                         for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     129            0 :                                 Vertex* vrt = (*iter)->vertex(i);
     130            0 :                                 if(!grid.is_marked(vrt)){
     131              :                                         grid.mark(vrt);
     132            0 :                                         vrtsOut.push_back(vrt);
     133              :                                 }
     134              :                         }
     135              :                 }
     136              :         }
     137              : 
     138            0 :         grid.end_marking();
     139              : 
     140              :         return vrtsOut.size();
     141              : }
     142              : 
     143              : ////////////////////////////////////////////////////////////////////////
     144              : template <class TSelector>
     145            0 : void EraseSelectedObjects(TSelector& sel)
     146              : {
     147            0 :         if(!sel.grid())
     148              :                 return;
     149              :         
     150              :         Grid& grid = *sel.grid();
     151              :         
     152            0 :         for(size_t i = 0; i < sel.num_levels(); ++i)
     153              :         {
     154            0 :                 EraseElements<Vertex>(grid, sel.template begin<Vertex>(i),
     155              :                                                                   sel.template end<Vertex>(i));
     156            0 :                 EraseElements<Edge>(grid, sel.template begin<Edge>(i),
     157              :                                                                 sel.template end<Edge>(i));
     158            0 :                 EraseElements<Face>(grid, sel.template begin<Face>(i),
     159              :                                                         sel.template end<Face>(i));
     160            0 :                 EraseElements<Volume>(grid, sel.template begin<Volume>(i),
     161              :                                                           sel.template end<Volume>(i));
     162              :         }
     163              : }
     164              : 
     165              : ////////////////////////////////////////////////////////////////////////
     166              : template <class TSelector>
     167            0 : void InvertSelection(TSelector& sel)
     168              : {
     169            0 :         if(!sel.grid())
     170              :                 return;
     171              :         
     172              :         Grid& grid = *sel.grid();
     173              :         
     174            0 :         InvertSelection(sel, grid.begin<Vertex>(),
     175              :                                         grid.end<Vertex>());
     176            0 :         InvertSelection(sel, grid.begin<Edge>(),
     177              :                                         grid.end<Edge>());
     178            0 :         InvertSelection(sel, grid.begin<Face>(),
     179              :                                         grid.end<Face>());
     180            0 :         InvertSelection(sel, grid.begin<Volume>(),
     181              :                                         grid.end<Volume>());
     182              : }
     183              : 
     184              : //////////////////////////////////////////////////////////////////////////
     185              : ////    SelectAssociatedGridObjects
     186              : //void SelectAssociatedGridObjects(Selector& sel, ISelector::status_t status)
     187              : //{
     188              : //      if(!sel.grid()){
     189              : //              UG_LOG("ERROR in SelectAssociatedGridObjects: Selector has to be assigned to a grid.\n");
     190              : //              return;
     191              : //      }
     192              : //
     193              : //      Grid& grid = *sel.grid();
     194              : //
     195              : ////    select associated elements of selected elements
     196              : //      SelectAssociatedFaces(sel, sel.begin<Volume>(),
     197              : //                                                sel.end<Volume>(), status);
     198              : //      if(!grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES)){
     199              : //      //      if faces are not automatically generated, there may be edges connected
     200              : //      //      to the volume, which are not connected to a face. Same goes for vertices.
     201              : //              SelectAssociatedEdges(sel, sel.begin<Volume>(),
     202              : //                                                        sel.end<Volume>(), status);
     203              : //              if(!grid.option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
     204              : //                      SelectAssociatedVertices(sel, sel.begin<Volume>(),
     205              : //                                                                       sel.end<Volume>(), status);
     206              : //      }
     207              : //
     208              : //      SelectAssociatedEdges(sel, sel.begin<Face>(), sel.end<Face>(), status);
     209              : //      if(!grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
     210              : //              SelectAssociatedVertices(sel, sel.begin<Face>(),
     211              : //                                                               sel.end<Face>(), status);
     212              : //
     213              : //      SelectAssociatedVertices(sel, sel.begin<Edge>(),
     214              : //                                                       sel.end<Edge>(), status);
     215              : //}
     216              : 
     217              : 
     218              : ////////////////////////////////////////////////////////////////////////
     219              : //      SelectAssociatedGridObjects
     220              : template <class TSelector>
     221            0 : void SelectAssociatedGridObjects(TSelector& sel, ISelector::status_t status)
     222              : {
     223            0 :         if(!sel.grid()){
     224              :                 UG_LOG("ERROR in SelectAssociatedGridObjects: Selector has to be assigned to a grid.\n");
     225            0 :                 return;
     226              :         }
     227              :         
     228              :         Grid& grid = *sel.grid();
     229              :         
     230              : //      select associated elements of selected elements on each level
     231            0 :         for(size_t i = 0; i < sel.num_levels(); ++i)
     232              :         {
     233            0 :                 SelectAssociatedFaces(sel, sel.template begin<Volume>(i),
     234              :                                                           sel.template end<Volume>(i), status);
     235            0 :                 if(!grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES)){
     236            0 :                         SelectAssociatedEdges(sel, sel.template begin<Volume>(i),
     237              :                                                                   sel.template end<Volume>(i), status);
     238            0 :                         if(!grid.option_is_enabled(VOLOPT_AUTOGENERATE_EDGES))
     239            0 :                                 SelectAssociatedVertices(sel, sel.template begin<Volume>(i),
     240              :                                                                                  sel.template end<Volume>(i), status);
     241              :                 }
     242              :                 
     243            0 :                 SelectAssociatedEdges(sel, sel.template begin<Face>(i),
     244              :                                                           sel.template end<Face>(i), status);
     245            0 :                 if(!grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
     246            0 :                         SelectAssociatedVertices(sel, sel.template begin<Face>(i),
     247              :                                                                          sel.template end<Face>(i), status);
     248              :                         
     249            0 :                 SelectAssociatedVertices(sel, sel.template begin<Edge>(i),
     250              :                                                                  sel.template end<Edge>(i), status);
     251              :         }
     252              : }
     253              : 
     254              : template void SelectAssociatedGridObjects<Selector>(Selector& sel,
     255              :                                                                                                         ISelector::status_t status);
     256              : template void SelectAssociatedGridObjects<MGSelector>(MGSelector& sel,
     257              :                                                                                                         ISelector::status_t status);
     258              : 
     259              : 
     260              : ////////////////////////////////////////////////////////////////////////
     261              : template <class TSelector>
     262            0 : void CloseSelection (TSelector& sel)
     263              : {
     264            0 :         SelectAssociatedFaces(sel, sel.template begin<Volume>(), sel.template end<Volume>());
     265            0 :         SelectAssociatedEdges(sel, sel.template begin<Face>(), sel.template end<Face>());
     266            0 :         SelectAssociatedVertices(sel, sel.template begin<Edge>(), sel.template end<Edge>());
     267            0 : }
     268              : 
     269              : template void CloseSelection<Selector>(Selector& sel);
     270              : template void CloseSelection<MGSelector>(MGSelector& sel);
     271              : 
     272              : 
     273              : ////////////////////////////////////////////////////////////////////////
     274              : //      SelectParents
     275              : ///     helper for SelectAssociatedGenealogy.
     276              : template <class TIterator>
     277            0 : static void SelectParents(MultiGrid& mg, MGSelector& msel,
     278              :                                                   TIterator iterBegin, TIterator iterEnd)
     279              : {
     280            0 :         while(iterBegin != iterEnd)
     281              :         {
     282              :         //      if the object has a parent, then select it.
     283              :                 GridObject* parent = mg.get_parent(*iterBegin);
     284            0 :                 if(parent)
     285            0 :                         msel.select(parent);
     286              : 
     287              :                 iterBegin++;
     288              :         }
     289            0 : }
     290              : 
     291              : ////////////////////////////////////////////////////////////////////////
     292              : //      ExtendSelection
     293              : template <class TSelector>
     294            0 : void ExtendSelection(TSelector& sel, size_t extSize, ISelector::status_t status)
     295              : {
     296            0 :         if(!sel.grid()){
     297              :                 UG_LOG("ERROR in ExtendSelection: Selector has to be assigned to a grid.\n");
     298            0 :                 return;
     299              :         }
     300              :         
     301              :         Grid& grid = *sel.grid();
     302              :         
     303              : //      first select associated elements of volumes, faces and edges.
     304              : //      then select associated elements of selected vertices.
     305              : //      do this extSize times.
     306              : //      elements that have already been processed are marked.
     307              :         
     308            0 :         grid.begin_marking();
     309              :         
     310              : //      perform iteration
     311            0 :         for(size_t extIters = 0; extIters < extSize; ++extIters)
     312              :         {
     313              : //TODO: speed-up by only calling SelectAssociatedGridObjects once before the loop.
     314              : //              During the loop only newly selected elements should be checked for associated elements.
     315              : 
     316              :         //      select associated elements
     317            0 :                 SelectAssociatedGridObjects(sel, status);
     318              : 
     319              :         //      iterate over all selected vertices.
     320            0 :                 for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl){
     321            0 :                         for(VertexIterator iter = sel.template begin<Vertex>(lvl);
     322            0 :                                 iter != sel.template end<Vertex>(lvl); ++iter)
     323              :                         {
     324              :                                 Vertex* vrt = *iter;
     325              :                         //      all marked vertices have already been processed.
     326            0 :                                 if(!grid.is_marked(vrt)){
     327              :                                         grid.mark(vrt);
     328              : 
     329              :                                 //      select associated volumes, faces and edges.
     330            0 :                                         for(Grid::AssociatedEdgeIterator asIter = grid.associated_edges_begin(vrt);
     331            0 :                                                 asIter != grid.associated_edges_end(vrt); ++asIter)
     332              :                                         {
     333            0 :                                                 sel.select(*asIter, status);
     334              :                                         }
     335              : 
     336            0 :                                         for(Grid::AssociatedFaceIterator asIter = grid.associated_faces_begin(vrt);
     337            0 :                                                 asIter != grid.associated_faces_end(vrt); ++asIter)
     338              :                                         {
     339            0 :                                                 sel.select(*asIter, status);
     340              :                                         }
     341              : 
     342            0 :                                         for(Grid::AssociatedVolumeIterator asIter = grid.associated_volumes_begin(vrt);
     343            0 :                                                 asIter != grid.associated_volumes_end(vrt); ++asIter)
     344              :                                         {
     345            0 :                                                 sel.select(*asIter, status);
     346              :                                         }
     347              :                                 }
     348              :                         }
     349              :                 }
     350              :         }
     351              :         
     352            0 :         grid.end_marking();
     353              : }
     354              : 
     355              : template void ExtendSelection<Selector>(Selector& sel, size_t extSize,
     356              :                                                                                 ISelector::status_t status);
     357              : template void ExtendSelection<MGSelector>(MGSelector& sel, size_t extSize,
     358              :                                                                                   ISelector::status_t status);
     359              : 
     360              : 
     361              : 
     362              : template <class TGeomObj>
     363            0 : void SelectionFill(Selector& sel,
     364              :                                    typename Grid::traits<typename TGeomObj::side>::callback cbRegionBoundary)
     365              : {
     366              :         typedef typename geometry_traits<TGeomObj>::iterator GeomObjIter;
     367              :         typedef typename TGeomObj::lower_dim_base_object Side;
     368              : 
     369            0 :         if(sel.grid() == 0){
     370              :                 UG_LOG("WARNING in SelectionFill: A grid has to be assigned! Aborting.\n");
     371            0 :                 return;
     372              :         }
     373              : 
     374              :         Grid& grid = *sel.grid();
     375              : 
     376              :         vector<Side*> sides;
     377              :         vector<TGeomObj*> objs;
     378              :         queue<TGeomObj*> qCandidates;
     379              : 
     380              : //      all initially selected objects are candidates
     381              :         for(GeomObjIter iter = sel.begin<TGeomObj>();
     382            0 :                 iter != sel.end<TGeomObj>(); ++iter)
     383              :         {
     384            0 :                 qCandidates.push(*iter);
     385              :         }
     386              : 
     387              : //      while there are candidates left
     388            0 :         while(!qCandidates.empty())
     389              :         {
     390              :         //      get the candidate
     391            0 :                 TGeomObj* o = qCandidates.front();
     392              :                 qCandidates.pop();
     393              : 
     394              :         //      collect all sides in a vector
     395              :                 CollectAssociated(sides, grid, o);
     396            0 :                 for(size_t i = 0; i < sides.size(); ++i){
     397              :                 //      if the side is a region boundary, we don't have to process it
     398            0 :                         if(cbRegionBoundary(sides[i]))
     399            0 :                                 continue;
     400              : 
     401              :                 //      all associated unselected geom-objs have to be selected
     402              :                 //      and are new candidates
     403            0 :                         CollectAssociated(objs, grid, sides[i]);
     404            0 :                         for(size_t j = 0; j < objs.size(); ++j){
     405            0 :                                 if(!sel.is_selected(objs[j])){
     406            0 :                                         sel.select(objs[j]);
     407              :                                         qCandidates.push(objs[j]);
     408              :                                 }
     409              :                         }
     410              :                 }
     411              :         }
     412            0 : }
     413              : 
     414              : //      Only those template specializations make sense.
     415              : template void SelectionFill<Edge>(Selector&, Grid::vertex_traits::callback);
     416              : template void SelectionFill<Face>(Selector&, Grid::edge_traits::callback);
     417              : template void SelectionFill<Volume>(Selector&, Grid::face_traits::callback);
     418              : 
     419              : 
     420              : ////////////////////////////////////////////////////////////////////////
     421              : //      SelectAssociatedGenealogy
     422            0 : void SelectAssociatedGenealogy(MGSelector& msel, bool selectAssociatedElements)
     423              : {
     424              :         MultiGrid* mg = msel.multi_grid();
     425            0 :         if(!mg)
     426              :                 return;
     427              : 
     428              : //      we'll iterate through the levels from top to bottom.
     429              : //      in each level we'll select the parents of all selected elements.
     430            0 :         for(int i = (int)msel.num_levels() - 1; i >= 0; --i)
     431              :         {
     432            0 :                 if(selectAssociatedElements)
     433              :                 {
     434            0 :                         SelectAssociatedVertices(msel, msel.begin<Edge>(i), msel.end<Edge>(i));
     435            0 :                         SelectAssociatedVertices(msel, msel.begin<Face>(i), msel.end<Face>(i));
     436            0 :                         SelectAssociatedVertices(msel, msel.begin<Volume>(i), msel.end<Volume>(i));
     437              :                         
     438            0 :                         SelectAssociatedEdges(msel, msel.begin<Face>(i), msel.end<Face>(i));
     439            0 :                         SelectAssociatedEdges(msel, msel.begin<Volume>(i), msel.end<Volume>(i));
     440              :                         
     441            0 :                         SelectAssociatedFaces(msel, msel.begin<Volume>(i), msel.end<Volume>(i));
     442              :                 }
     443            0 :                 if(i > 0)
     444              :                 {
     445            0 :                         SelectParents(*mg, msel, msel.vertices_begin(i), msel.vertices_end(i));
     446            0 :                         SelectParents(*mg, msel, msel.edges_begin(i), msel.edges_end(i));
     447            0 :                         SelectParents(*mg, msel, msel.faces_begin(i), msel.faces_end(i));
     448            0 :                         SelectParents(*mg, msel, msel.volumes_begin(i), msel.volumes_end(i));
     449              :                 }
     450              :         }
     451              : 
     452              : //      thats it. done!
     453              : }
     454              : 
     455              : ////////////////////////////////////////////////////////////////////////
     456              : //      SelectSmoothEdgePath
     457            0 : void SelectSmoothEdgePath(Selector& sel, number thresholdDegree, number normalWeight,
     458              :                                                         bool stopAtSelVrts, APosition& aPos)
     459              : {
     460              :         bool bMinimalNormalDeviation = true;
     461              :         
     462              :         normalWeight = clip<number>(normalWeight, 0, 1);
     463            0 :         number dirWeight = 1. - normalWeight;
     464              : 
     465            0 :         if(!sel.grid())
     466            0 :                 return;
     467              :         
     468              :         Grid& grid = *sel.grid();
     469              :         
     470              : //      access the position attachment
     471              :         assert(grid.has_vertex_attachment(aPos) &&
     472              :                         "INFO in SelectSmoothEdgePath: missing position attachment.");
     473              :         
     474              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
     475              :         
     476              : //      make sure that associated edges can be easily accessed.
     477            0 :         if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES)){
     478              :                 UG_LOG("  INFO in SelectSmoothEdgePath: auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES.\n");
     479            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
     480              :         }
     481              :         
     482              : //      convert the thresholdDegree to thresholdDot
     483            0 :         number thresholdDot = cos(deg_to_rad(thresholdDegree));
     484              :         
     485              : //      here we'll store candidates.
     486              :         stack<Vertex*>    m_candidates;
     487              :         
     488              : //      initially mark all vertices of selected edges as candidates
     489              :         for(EdgeIterator iter = sel.begin<Edge>();
     490            0 :                 iter != sel.end<Edge>(); ++iter)
     491              :         {
     492              :         //      we don't care if vertices are pushed twice.
     493              :         //      if a vertex is selected and stopAtSelVrts is true,
     494              :         //      then we don't need to push them on the stack.
     495            0 :                 for(size_t i = 0; i < 2; ++i){
     496            0 :                         if(!(stopAtSelVrts && sel.is_selected((*iter)->vertex(i))))
     497            0 :                                 m_candidates.push((*iter)->vertex(i));
     498              :                 }
     499              :         }
     500              :                 
     501              : //      while there are candidates left
     502            0 :         while(!m_candidates.empty())
     503              :         {
     504            0 :                 Vertex* srcVrt = m_candidates.top();
     505              :                 m_candidates.pop();
     506              : 
     507              :         //      search for associated selected edges (there has to be at last one!)
     508              :                 Edge* lastEdge = NULL;
     509              :                 int counter = 0;
     510              :                 
     511            0 :                 for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(srcVrt);
     512            0 :                         iter != grid.associated_edges_end(srcVrt); ++iter)
     513              :                 {
     514            0 :                         Edge* e = *iter;
     515            0 :                         if(sel.is_selected(e)){
     516              :                                 lastEdge = e;
     517            0 :                                 ++counter;
     518              :                         }
     519              :                 }
     520              :                 
     521              :                 assert(lastEdge && "there has to be at least one selected associated edge!");
     522              :                 
     523              :         //      if more than one associated selected edge have been found,
     524              :         //      then the vertex has already been completly handled.
     525            0 :                 if(counter > 1)
     526            0 :                         continue;
     527              :                         
     528              :         //      the direction of the last edge
     529              :                 vector3 lastDir;
     530            0 :                 VecSubtract(lastDir, aaPos[GetConnectedVertex(lastEdge, srcVrt)],
     531              :                                         aaPos[srcVrt]);
     532            0 :                 VecNormalize(lastDir, lastDir);
     533              :                 
     534              :                 vector3 lastNormal;
     535            0 :                 int numInvolvedFaces = CalculateNormal(lastNormal, grid, lastEdge, aaPos);
     536            0 :                 bool bLastNormalValid = (numInvolvedFaces > 0 && numInvolvedFaces < 3);
     537              :                 
     538              :         //      follow the smooth path
     539            0 :                 while(srcVrt)
     540              :                 {
     541              :                 //      check smoothness for each connected unselected edge
     542              :                         Edge* bestEdge = NULL;
     543              :                         number bestDot = -1.1;
     544              :                         number bestNormalDot = -1.1;
     545              :                         vector3 bestDir(0, 0, 0);
     546              :                         vector3 bestNormal(0, 0, 0);
     547              :                         bool bBestNormalValid = false;
     548              :                 
     549              :                 //      if invalid normals are involved we have to skip further normal
     550              :                 //      tests for this edge-set.
     551              :                         bool ignoreNormalChecks = false;
     552              :                         
     553              :                         int counter = 0;
     554            0 :                         Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(srcVrt);
     555            0 :                         for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(srcVrt);
     556            0 :                                 iter != iterEnd; ++iter)
     557              :                         {
     558            0 :                                 Edge* e = *iter;
     559            0 :                                 if(!sel.is_selected(e)){
     560              :                                 //      check smoothness
     561              :                                         vector3 dir;
     562              :                                         VecSubtract(dir, aaPos[srcVrt],
     563            0 :                                                                 aaPos[GetConnectedVertex(e, srcVrt)]);
     564            0 :                                         VecNormalize(dir, dir);
     565              :                                         
     566              :                                         number d = VecDot(lastDir, dir);
     567            0 :                                         if(d > thresholdDot){
     568              :                                                 bool moreChecks = true;
     569              :                                                 bool bNormalValid = false;
     570              :                                                 vector3 n(0, 0, 0);
     571              :                                         //      if minimal normal deviation is activated, then first try do perform
     572              :                                         //      the following checks. Take into account, that edges can be connected
     573              :                                         //      to an arbitrary amount of faces.
     574              :                                                 if(bMinimalNormalDeviation){
     575            0 :                                                         int numAdjacentFaces = CalculateNormal(n, grid, e, aaPos);
     576            0 :                                                         bNormalValid = (numAdjacentFaces > 0 && numAdjacentFaces < 3);
     577              :                                                         
     578            0 :                                                         if(bLastNormalValid && bNormalValid && (!ignoreNormalChecks)){
     579              :                                                                 moreChecks = false;
     580              :                                                         //      check whether the normal dot is better than the last one.
     581              :                                                                 number nd = VecDot(lastNormal, n);
     582              :                                                         //      weight the dots to ensure that the better edge is found even
     583              :                                                         //      for equal normal-dots.
     584            0 :                                                                 if((normalWeight*nd + dirWeight*d) > (normalWeight*bestNormalDot + dirWeight*bestDot)){
     585              :                                                                         bestEdge = e;
     586              :                                                                         bestDot = d;
     587              :                                                                         bestDir = dir;
     588              :                                                                         bestNormal = n;
     589              :                                                                         bestNormalDot = nd;
     590              :                                                                         bBestNormalValid = true;
     591              :                                                                 }
     592              :                                                         }
     593              :                                                 }
     594              :                                                 
     595              :                                         //      either bMinimalNormalDeviation was false, or a normal of one
     596              :                                         //      of the edges was not valid.
     597            0 :                                                 if(moreChecks){
     598            0 :                                                         if(d > bestDot){
     599              :                                                                 bestEdge = e;
     600              :                                                                 bestDot = d;
     601              :                                                                 bestDir = dir;
     602              : 
     603              :                                                                 if(bMinimalNormalDeviation){
     604              :                                                                         bestNormal = n;
     605              :                                                                         bBestNormalValid = bNormalValid;
     606              :                                                                         ignoreNormalChecks = true;
     607              :                                                                 }
     608              :                                                         }
     609              :                                                 }
     610              :                                         }
     611              :                                 }
     612              :                                 else {
     613            0 :                                         counter++;
     614              :                                 }
     615              : 
     616              :                         }
     617              :                         
     618            0 :                         if((bestEdge != NULL) && (counter < 2)){
     619            0 :                                 sel.select(bestEdge);
     620              :                         //      the next vertex has to be checked
     621            0 :                                 srcVrt = GetConnectedVertex(bestEdge, srcVrt);
     622              :                         //      make sure that we stop at selected vertices - if desired
     623            0 :                                 if(stopAtSelVrts && sel.is_selected(srcVrt))
     624              :                                         srcVrt = NULL;
     625              :                                         
     626              :                                 // lastEdge = bestEdge;  // never used
     627              :                                 lastDir = bestDir;
     628              :                                 bLastNormalValid = bBestNormalValid;
     629              :                                 lastNormal = bestNormal;
     630              :                         }
     631              :                         else{
     632              :                                 srcVrt = NULL;
     633              :                         }
     634              :                 }
     635              :         }
     636              : }
     637              : 
     638              : ////////////////////////////////////////////////////////////////////////
     639              : //      SelectInnerSelectionVertices
     640              : template <class TSelector>
     641            0 : void SelectInnerSelectionVertices(TSelector& sel)
     642              : {
     643            0 :         if(!sel.grid())
     644            0 :                 return;
     645              :         
     646              :         Grid& grid = *sel.grid();
     647              :         
     648            0 :         grid.begin_marking();
     649              :         
     650              : //      we'll first collect all vertices that we want to check
     651              :         vector<Vertex*> vrts;
     652              :         
     653              : //      iterate over all levels
     654            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
     655              :         {
     656            0 :                 for(VolumeIterator iter = sel.template begin<Volume>(lvl);
     657            0 :                         iter != sel.template end<Volume>(lvl); ++iter)
     658              :                 {
     659              :                         Volume* vol = *iter;
     660            0 :                         for(size_t i = 0; i < vol->num_vertices(); ++i){
     661            0 :                                 Vertex* v = vol->vertex(i);
     662            0 :                                 if(!grid.is_marked(v)){
     663              :                                         grid.mark(v);
     664            0 :                                         vrts.push_back(v);
     665              :                                 }
     666              :                         }
     667              :                 }
     668              : 
     669            0 :                 for(FaceIterator iter = sel.template begin<Face>(lvl);
     670            0 :                         iter != sel.template end<Face>(lvl); ++iter)
     671              :                 {
     672              :                         Face* f = *iter;
     673            0 :                         for(size_t i = 0; i < f->num_vertices(); ++i){
     674            0 :                                 Vertex* v = f->vertex(i);
     675            0 :                                 if(!grid.is_marked(v)){
     676              :                                         grid.mark(v);
     677            0 :                                         vrts.push_back(v);
     678              :                                 }
     679              :                         }
     680              :                 }
     681              : 
     682            0 :                 for(EdgeIterator iter = sel.template begin<Edge>(lvl);
     683            0 :                         iter != sel.template end<Edge>(lvl); ++iter)
     684              :                 {
     685              :                         Edge* e = *iter;
     686            0 :                         for(size_t i = 0; i < 2; ++i){
     687            0 :                                 Vertex* v = e->vertex(i);
     688            0 :                                 if(!grid.is_marked(v)){
     689              :                                         grid.mark(v);
     690            0 :                                         vrts.push_back(v);
     691              :                                 }
     692              :                         }
     693              :                 }
     694              :         }
     695            0 :         grid.end_marking();
     696              : 
     697              : 
     698              : //      now check for each vertex if an unselected element is associated
     699            0 :         for(size_t i = 0; i < vrts.size(); ++i)
     700              :         {
     701            0 :                 Vertex* v = vrts[i];
     702              :         
     703              :         //      check whether all associated elements are selected
     704              :                 bool foundUnselected = false;
     705              :                 
     706              :         //      volumes
     707            0 :                 for(Grid::AssociatedVolumeIterator aIter = grid.associated_volumes_begin(v);
     708            0 :                         aIter != grid.associated_volumes_end(v); ++ aIter)
     709              :                 {
     710            0 :                         if(!sel.is_selected(*aIter)){
     711              :                                 foundUnselected = true;
     712              :                                 break;
     713              :                         }
     714              :                 }
     715              : 
     716              :         //      face            
     717            0 :                 if(!foundUnselected){
     718            0 :                         for(Grid::AssociatedFaceIterator aIter = grid.associated_faces_begin(v);
     719            0 :                                 aIter != grid.associated_faces_end(v); ++ aIter)
     720              :                         {
     721            0 :                                 if(!sel.is_selected(*aIter)){
     722              :                                         foundUnselected = true;
     723              :                                         break;
     724              :                                 }
     725              :                         }
     726              :                 }
     727              :         
     728              :         //      edge            
     729            0 :                 if(!foundUnselected){
     730            0 :                         for(Grid::AssociatedEdgeIterator aIter = grid.associated_edges_begin(v);
     731            0 :                                 aIter != grid.associated_edges_end(v); ++ aIter)
     732              :                         {
     733            0 :                                 if(!sel.is_selected(*aIter)){
     734              :                                         foundUnselected = true;
     735              :                                         break;
     736              :                                 }
     737              :                         }
     738              :                 }
     739              : 
     740            0 :                 if(!foundUnselected)
     741            0 :                         sel.select(v);
     742              :         }
     743            0 : }
     744              : 
     745              : ////////////////////////////////////////////////////////////////////////
     746              : //      SelectInnerSelectionEdges
     747              : template <class TSelector>
     748            0 : void SelectInnerSelectionEdges(TSelector& sel)
     749              : {
     750            0 :         if(!sel.grid())
     751            0 :                 return;
     752              :         
     753              :         Grid& grid = *sel.grid();
     754              :         
     755            0 :         grid.begin_marking();
     756              :         
     757              : //      we'll first collect all edges that we want to check
     758              :         vector<Edge*> edges;
     759              :         vector<Edge*> vAssEdges;
     760              :         
     761              : //      iterate over all levels
     762            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
     763              :         {
     764            0 :                 for(VolumeIterator iter = sel.template begin<Volume>(lvl);
     765            0 :                         iter != sel.template end<Volume>(lvl); ++iter)
     766              :                 {
     767            0 :                         CollectEdges(vAssEdges, grid, *iter);
     768            0 :                         for(size_t i = 0; i < vAssEdges.size(); ++i){
     769            0 :                                 Edge* e = vAssEdges[i];
     770            0 :                                 if(!grid.is_marked(e)){
     771              :                                         grid.mark(e);
     772            0 :                                         edges.push_back(e);
     773              :                                 }
     774              :                         }
     775              :                 }
     776              : 
     777            0 :                 for(FaceIterator iter = sel.template begin<Face>(lvl);
     778            0 :                         iter != sel.template end<Face>(lvl); ++iter)
     779              :                 {
     780            0 :                         CollectEdges(vAssEdges, grid, *iter);
     781            0 :                         for(size_t i = 0; i < vAssEdges.size(); ++i){
     782            0 :                                 Edge* e = vAssEdges[i];
     783            0 :                                 if(!grid.is_marked(e)){
     784              :                                         grid.mark(e);
     785            0 :                                         edges.push_back(e);
     786              :                                 }
     787              :                         }
     788              :                 }
     789              :         }
     790            0 :         grid.end_marking();
     791              : 
     792              : 
     793              : //      now check for each edge if an unselected element is associated
     794              :         vector<Face*> vAssFaces;
     795              :         vector<Volume*> vAssVols;
     796              :         
     797            0 :         for(size_t i = 0; i < edges.size(); ++i)
     798              :         {
     799            0 :                 Edge* e = edges[i];
     800              :         
     801              :         //      check whether all associated elements are selected
     802              :                 bool foundUnselected = false;
     803              :                 
     804              :         //      volumes
     805            0 :                 CollectVolumes(vAssVols, grid, e);
     806            0 :                 for(size_t j = 0; j < vAssVols.size(); ++j)
     807              :                 {
     808            0 :                         if(!sel.is_selected(vAssVols[j])){
     809              :                                 foundUnselected = true;
     810              :                                 break;
     811              :                         }
     812              :                 }
     813              : 
     814              :         //      face            
     815            0 :                 if(!foundUnselected){
     816            0 :                         CollectFaces(vAssFaces, grid, e);
     817            0 :                         for(size_t j = 0; j < vAssFaces.size(); ++j)
     818              :                         {
     819            0 :                                 if(!sel.is_selected(vAssFaces[j])){
     820              :                                         foundUnselected = true;
     821              :                                         break;
     822              :                                 }
     823              :                         }
     824              :                 }
     825              : 
     826            0 :                 if(!foundUnselected)
     827            0 :                         sel.select(e);
     828              :         }
     829            0 : }
     830              : 
     831              : 
     832              : ////////////////////////////////////////////////////////////////////////
     833              : //      SelectInnerSelectionFaces
     834              : template <class TSelector>
     835            0 : void SelectInnerSelectionFaces(TSelector& sel)
     836              : {
     837            0 :         if(!sel.grid())
     838            0 :                 return;
     839              :         
     840              :         Grid& grid = *sel.grid();
     841              :         
     842            0 :         grid.begin_marking();
     843              :         
     844              : //      iterate through selected volumes and check for each side
     845              : //      whether it is connected to any unselected volumes.
     846              :         vector<Face*> vAssFaces;
     847              :         vector<Volume*> vAssVols;
     848              :         
     849              : //      iterate over all levels
     850            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
     851              :         {
     852            0 :                 for(VolumeIterator iter = sel.template begin<Volume>(lvl);
     853            0 :                         iter != sel.template end<Volume>(lvl); ++iter)
     854              :                 {
     855            0 :                         CollectFaces(vAssFaces, grid, *iter);
     856            0 :                         for(size_t i = 0; i < vAssFaces.size(); ++i){
     857            0 :                                 Face* f = vAssFaces[i];
     858            0 :                                 if(!grid.is_marked(f)){
     859              :                                         grid.mark(f);
     860            0 :                                         CollectVolumes(vAssVols, grid, f);
     861              :                                         bool foundUnselected = false;
     862            0 :                                         for(size_t j = 0; j < vAssVols.size(); ++j){
     863            0 :                                                 if(!sel.is_selected(vAssVols[j])){
     864              :                                                         foundUnselected = true;
     865              :                                                         break;
     866              :                                                 }
     867              :                                         }
     868              :                                         
     869            0 :                                         if(!foundUnselected)
     870            0 :                                                 sel.select(f);
     871              :                                 }
     872              :                         }
     873              :                 }
     874              :         }
     875              :         
     876            0 :         grid.end_marking();
     877            0 : }
     878              : 
     879              : 
     880              : 
     881              : 
     882              : ////////////////////////////////////////////////////////////////////////
     883              : //      DeselectBoundarySelectionVertices
     884              : template <class TSelector>
     885            0 : void DeselectBoundarySelectionVertices(TSelector& sel)
     886              : {
     887            0 :         if(!sel.grid())
     888              :                 return;
     889              :         
     890              :         Grid& grid = *sel.grid();
     891              : 
     892              : //      check each selected vertex of each level
     893            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
     894              :         {
     895            0 :                 for(VertexIterator iter = sel.template begin<Vertex>(lvl);
     896            0 :                         iter != sel.template end<Vertex>(lvl);)
     897              :                 {
     898              :                         Vertex* v = *iter;
     899              :                 //      increase iterator here, since v may get deselected.
     900              :                         ++iter;
     901              :                         
     902              :                 //      check whether there is an unselected associated element
     903              :                         bool foundUnselected = false;
     904              :                         
     905              :                 //      volumes
     906            0 :                         for(Grid::AssociatedVolumeIterator aIter = grid.associated_volumes_begin(v);
     907            0 :                                 aIter != grid.associated_volumes_end(v); ++ aIter)
     908              :                         {
     909            0 :                                 if(!sel.is_selected(*aIter)){
     910              :                                         foundUnselected = true;
     911              :                                         break;
     912              :                                 }
     913              :                         }
     914              : 
     915              :                 //      face            
     916            0 :                         if(!foundUnselected){
     917            0 :                                 for(Grid::AssociatedFaceIterator aIter = grid.associated_faces_begin(v);
     918            0 :                                         aIter != grid.associated_faces_end(v); ++ aIter)
     919              :                                 {
     920            0 :                                         if(!sel.is_selected(*aIter)){
     921              :                                                 foundUnselected = true;
     922              :                                                 break;
     923              :                                         }
     924              :                                 }
     925              :                         }
     926              :                 
     927              :                 //      edge            
     928            0 :                         if(!foundUnselected){
     929            0 :                                 for(Grid::AssociatedEdgeIterator aIter = grid.associated_edges_begin(v);
     930            0 :                                         aIter != grid.associated_edges_end(v); ++ aIter)
     931              :                                 {
     932            0 :                                         if(!sel.is_selected(*aIter)){
     933              :                                                 foundUnselected = true;
     934              :                                                 break;
     935              :                                         }
     936              :                                 }
     937              :                         }
     938              : 
     939            0 :                         if(foundUnselected)
     940            0 :                                 sel.deselect(v);
     941              :                 }
     942              :         }
     943              : }
     944              : 
     945              : ////////////////////////////////////////////////////////////////////////
     946              : //      DeselectBoundarySelectionEdges
     947              : template <class TSelector>
     948            0 : void DeselectBoundarySelectionEdges(TSelector& sel)
     949              : {
     950            0 :         if(!sel.grid())
     951            0 :                 return;
     952              :         
     953              :         Grid& grid = *sel.grid();
     954              : 
     955              :         vector<Face*> vAssFaces;
     956              :         vector<Volume*> vAssVols;
     957              : 
     958              : //      check each selected vertex of each level
     959            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
     960              :         {
     961            0 :                 for(EdgeIterator iter = sel.template begin<Edge>(lvl);
     962            0 :                         iter != sel.template end<Edge>(lvl);)
     963              :                 {
     964              :                         Edge* e = *iter;
     965              :                 //      increase iterator here, since e may get deselected.
     966              :                         ++iter;
     967              :                         
     968              :                 //      check whether there is an unselected associated element
     969              :                         bool foundUnselected = false;
     970              :                         
     971              :                 //      volumes
     972            0 :                         CollectVolumes(vAssVols, grid, e);
     973            0 :                         for(size_t j = 0; j < vAssVols.size(); ++j)
     974              :                         {
     975            0 :                                 if(!sel.is_selected(vAssVols[j])){
     976              :                                         foundUnselected = true;
     977              :                                         break;
     978              :                                 }
     979              :                         }
     980              : 
     981              :                 //      face            
     982            0 :                         if(!foundUnselected){
     983            0 :                                 CollectFaces(vAssFaces, grid, e);
     984            0 :                                 for(size_t j = 0; j < vAssFaces.size(); ++j)
     985              :                                 {
     986            0 :                                         if(!sel.is_selected(vAssFaces[j])){
     987              :                                                 foundUnselected = true;
     988              :                                                 break;
     989              :                                         }
     990              :                                 }
     991              :                         }
     992              :                         
     993            0 :                         if(foundUnselected)
     994            0 :                                 sel.deselect(e);
     995              :                 }
     996              :         }
     997            0 : }
     998              : 
     999              : 
    1000              : ////////////////////////////////////////////////////////////////////////
    1001              : //      DeselectBoundarySelectionFaces
    1002              : template <class TSelector>
    1003            0 : void DeselectBoundarySelectionFaces(TSelector& sel)
    1004              : {
    1005            0 :         if(!sel.grid())
    1006            0 :                 return;
    1007              :         
    1008              :         Grid& grid = *sel.grid();
    1009              :         
    1010              :         vector<Volume*> vAssVols;
    1011              :         
    1012              : //      iterate over all levels
    1013            0 :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl)
    1014              :         {
    1015            0 :                 for(FaceIterator iter = sel.template begin<Face>(lvl);
    1016            0 :                         iter != sel.template end<Face>(lvl);)
    1017              :                 {
    1018              :                         Face* f = *iter;
    1019              :                 //      increase iterator here, since f may get deselected.
    1020              :                         ++iter;
    1021              :                         
    1022            0 :                         CollectVolumes(vAssVols, grid, f);
    1023            0 :                         for(size_t i = 0; i < vAssVols.size(); ++i){
    1024            0 :                                 if(!sel.is_selected(vAssVols[i])){
    1025            0 :                                         sel.deselect(f);
    1026              :                                         break;
    1027              :                                 }
    1028              :                         }
    1029              :                 }
    1030              :         }
    1031            0 : }
    1032              : 
    1033              : 
    1034              : ////////////////////////////////////////////////////////////////////////
    1035              : // SelectLinkedFlatFaces
    1036            0 : void SelectLinkedFlatFaces(Selector& sel, number maxDeviationAngle,
    1037              :                                                    bool ignoreOrientation, bool stopAtSelectedEdges,
    1038              :                                                    APosition& aPos)
    1039              : {
    1040            0 :         if(!sel.grid())
    1041            0 :                 return;
    1042              :         
    1043              :         Grid& grid = *sel.grid();
    1044              :         
    1045            0 :         if(!grid.has_vertex_attachment(aPosition))
    1046              :                 return;
    1047              :                 
    1048              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPosition);
    1049              :         
    1050              : //      convert the thresholdDegree to thresholdDot
    1051            0 :         number thresholdDot = cos(deg_to_rad(maxDeviationAngle));
    1052              :         
    1053              : //      all initially selected faces are candidates
    1054              :         queue<Face*> qCandidates;
    1055            0 :         for(FaceIterator iter = sel.begin<Face>(); iter != sel.end<Face>(); ++iter)
    1056            0 :                 qCandidates.push(*iter);
    1057              :         
    1058              : //      we'll collect neighbours in this vector
    1059              :         vector<Face*> vNeighbours;
    1060              :         vector<Edge*> edges;
    1061              :         
    1062              : //      while there are candidates left
    1063            0 :         while(!qCandidates.empty())
    1064              :         {
    1065            0 :                 Face* f = qCandidates.front();
    1066              :                 qCandidates.pop();
    1067              :                 
    1068              :         //      calculate the normal
    1069              :                 vector3 n;
    1070            0 :                 CalculateNormal(n, f, aaPos);
    1071              :                 
    1072              :                 //CollectNeighbors(vNeighbours, f, grid);
    1073              :         //      collect associated edges
    1074              :                 CollectAssociated(edges, grid, f);
    1075              :                 
    1076              :         //      iterate through all neighbours
    1077            0 :                 for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge)
    1078              :                 {
    1079            0 :                         Edge* e = edges[i_edge];
    1080            0 :                         if(stopAtSelectedEdges && sel.is_selected(e))
    1081            0 :                                 continue;
    1082              : 
    1083              :                         CollectAssociated(vNeighbours, grid, e);
    1084            0 :                         for(size_t i = 0; i < vNeighbours.size(); ++i){
    1085            0 :                                 Face* nbr = vNeighbours[i];
    1086            0 :                                 if(nbr == f)
    1087            0 :                                         continue;
    1088              :                                 
    1089            0 :                                 if(!sel.is_selected(nbr)){
    1090              :                                 //      compare normals
    1091              :                                         vector3 nNbr;
    1092            0 :                                         CalculateNormal(nNbr, nbr, aaPos);
    1093              : 
    1094              :                                 //      check dots
    1095              :                                         number d = VecDot(n, nNbr);
    1096            0 :                                         if(ignoreOrientation)
    1097            0 :                                                 d = fabs(d);
    1098              : 
    1099            0 :                                         if(d >= thresholdDot){
    1100              :                                         //      nbr is a linked flat face
    1101            0 :                                                 sel.select(nbr);
    1102              :                                                 qCandidates.push(nbr);
    1103              :                                         }
    1104              :                                 }
    1105              :                         }
    1106              :                 }
    1107              :         }
    1108            0 : }
    1109              : 
    1110              : 
    1111            0 : void SelectLinkedFlatAndDegeneratedFaces(Selector& sel,
    1112              :                                                                                  number maxDeviationAngle,
    1113              :                                                                                  bool ignoreOrientation,
    1114              :                                                                                  bool stopAtSelectedEdges,
    1115              :                                                                                  number degThreshold,
    1116              :                                                                              APosition& aPos)
    1117              : {
    1118            0 :         if(!sel.grid())
    1119            0 :                 return;
    1120              : 
    1121              :         Grid& grid = *sel.grid();
    1122              : 
    1123            0 :         if(!grid.has_vertex_attachment(aPosition))
    1124              :                 return;
    1125              : 
    1126              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPosition);
    1127              : 
    1128              : //      convert the thresholdDegree to thresholdDot
    1129            0 :         number thresholdDot = cos(deg_to_rad(maxDeviationAngle));
    1130            0 :         number degThresholdSq = degThreshold * degThreshold;
    1131              : 
    1132              : //      all initially selected faces are candidates
    1133              : //      with each candidate we'll also store its normal (this is
    1134              : //      required since we'll traverse degenerated faces)
    1135              :         queue<Face*>      qCandidates;
    1136              :         queue<vector3>    qNormals;
    1137            0 :         for(FaceIterator iter = sel.begin<Face>(); iter != sel.end<Face>(); ++iter){
    1138            0 :                 qCandidates.push(*iter);
    1139              :         //      calculate the normal
    1140              :                 vector3 n;
    1141            0 :                 CalculateNormal(n, *iter, aaPos);
    1142              :                 qNormals.push(n);
    1143              :         }
    1144              : 
    1145              : //      temporary vectors for edges and faces
    1146              :         vector<Edge*> edges;
    1147              :         vector<Face*> faces;
    1148              : 
    1149              : //      while there are candidates left
    1150            0 :         while(!qCandidates.empty())
    1151              :         {
    1152            0 :                 Face* f = qCandidates.front();
    1153              :                 qCandidates.pop();
    1154              : 
    1155              :         //      calculate the normal
    1156              :                 vector3 n = qNormals.front();
    1157              :                 qNormals.pop();
    1158              : 
    1159              :         //      get associated edges
    1160              :                 CollectAssociated(edges, grid, f);
    1161              : 
    1162              :         //      iterate through all edges
    1163            0 :                 for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge)
    1164              :                 {
    1165            0 :                         Edge* e = edges[i_edge];
    1166              : 
    1167              :                 //      only proceed if the edge is not degenerated
    1168            0 :                         if(EdgeLengthSq(e, aaPos) <= degThresholdSq)
    1169            0 :                                 continue;
    1170              : 
    1171              :                 //      if the edge is selected we might have to ignore it
    1172            0 :                         if(stopAtSelectedEdges && sel.is_selected(e))
    1173            0 :                                 continue;
    1174              : 
    1175              :                 //      check associated faces
    1176              :                         CollectAssociated(faces, grid, e);
    1177            0 :                         for(size_t i_face = 0; i_face < faces.size(); ++i_face){
    1178            0 :                                 Face* nbr = faces[i_face];
    1179            0 :                                 if(!sel.is_selected(nbr)){
    1180              :                                 //      if the neighbor is degenerated, we can immediately select it.
    1181            0 :                                         if(IsDegenerated(nbr, aaPos, degThreshold)){
    1182            0 :                                                 sel.select(nbr);
    1183              :                                                 qCandidates.push(nbr);
    1184              :                                         //      use the normal from the face from which the degenerated
    1185              :                                         //      face was encountered
    1186              :                                                 qNormals.push(n);
    1187              :                                         }
    1188              :                                         else{
    1189              :                                         //      compare normals
    1190              :                                                 vector3 nNbr;
    1191            0 :                                                 CalculateNormal(nNbr, nbr, aaPos);
    1192              : 
    1193              :                                         //      check dots
    1194              :                                                 number d = VecDot(n, nNbr);
    1195            0 :                                                 if(ignoreOrientation)
    1196            0 :                                                         d = fabs(d);
    1197              : 
    1198            0 :                                                 if(d >= thresholdDot){
    1199              :                                                 //      nbr is a linked flat face
    1200            0 :                                                         sel.select(nbr);
    1201              :                                                         qCandidates.push(nbr);
    1202              :                                                         qNormals.push(nNbr);
    1203              :                                                 }
    1204              :                                         }
    1205              :                                 }
    1206              :                         }
    1207              :                 }
    1208              :         }
    1209            0 : }
    1210              : 
    1211              : 
    1212              : template <class elem_t>
    1213            0 : void GetSelectedElementIndices (const ISelector& sel, std::vector<size_t>& indsOut)
    1214              : {
    1215            0 :         UG_COND_THROW(!sel.grid(), "The specified selector has to operate on a grid!");
    1216              :         
    1217              :         Grid& g = *sel.grid();
    1218              :         indsOut.clear();
    1219              : 
    1220              : //      NOTE:   We have to keep the order in which the elements were selected.
    1221              : //                      That's why an index attachment is required here.
    1222              :         AInt aIndex;
    1223            0 :         g.attach_to<elem_t>(aIndex);
    1224              :         Grid::AttachmentAccessor<elem_t, AInt>    aaIndex (g, aIndex);
    1225              :         AssignIndices (g.begin<elem_t>(), g.end<elem_t>(), aaIndex);
    1226              : 
    1227            0 :         GridObjectCollection goc = sel.get_grid_objects ();
    1228              :         typedef typename GridObjectCollection::traits<elem_t>::iterator iter_t;
    1229            0 :         for(size_t ilvl = 0; ilvl < goc.num_levels(); ++ilvl){
    1230            0 :                 for(iter_t ielem = goc.begin<elem_t>(ilvl); ielem != goc.end<elem_t>(ilvl); ++ielem)
    1231              :                 {
    1232            0 :                         indsOut.push_back(aaIndex[*ielem]);
    1233              :                 }
    1234              :         }
    1235              :         g.detach_from<elem_t>(aIndex);
    1236            0 : }
    1237              : 
    1238              : 
    1239            0 : void GetSelectedElementIndices (const ISelector& sel,
    1240              :                                 std::vector<size_t>& vrtIndsOut,
    1241              :                                 std::vector<size_t>& edgeIndsOut,
    1242              :                                 std::vector<size_t>& faceIndsOut,
    1243              :                                 std::vector<size_t>& volIndsOut)
    1244              : {
    1245            0 :         GetSelectedElementIndices<Vertex> (sel, vrtIndsOut);
    1246            0 :         GetSelectedElementIndices<Edge> (sel, edgeIndsOut);
    1247            0 :         GetSelectedElementIndices<Face> (sel, faceIndsOut);
    1248            0 :         GetSelectedElementIndices<Volume> (sel, volIndsOut);
    1249            0 : }
    1250              : 
    1251              : 
    1252              : template <class elem_t>
    1253            0 : void SelectElementsByIndex (ISelector& sel, const std::vector<size_t>& inds)
    1254              : {
    1255              : //      NOTE:   If we could hope that 'inds' is always sorted, this could be
    1256              : //                      implemented in a more efficient way. However, 'inds' is not sorted
    1257              : //                      generally. Since we have to maintain the order of indices (important!)
    1258              : //                      the present implementation should be the fastest one in worst
    1259              : //                      case scenarios.
    1260            0 :         UG_COND_THROW(!sel.grid(), "The specified selector has to operate on a grid!");
    1261              :         
    1262              :         Grid& g = *sel.grid();
    1263              : 
    1264              :         typedef typename Grid::traits<elem_t>::iterator iter_t;
    1265              : 
    1266              :         const size_t numElems = g.num<elem_t>();
    1267            0 :         if(numElems == 0)
    1268            0 :                 return;
    1269              : 
    1270              :         vector<elem_t*>   elems;
    1271            0 :         elems.reserve(numElems);
    1272            0 :         for(iter_t ielem = g.begin<elem_t>(); ielem != g.end<elem_t>(); ++ielem)
    1273            0 :                 elems.push_back(*ielem);
    1274              : 
    1275            0 :         for(size_t iind = 0; iind < inds.size(); ++iind) {
    1276            0 :                 const size_t ind = inds[iind];
    1277            0 :                 UG_COND_THROW (ind >= numElems, "Invalid element index encountered: "
    1278              :                                << ind << "! (max is " << numElems - 1 << ")");
    1279              : 
    1280            0 :                 sel.select(elems[ind]);
    1281              :         }
    1282            0 : }
    1283              : 
    1284              : 
    1285            0 : void SelectElementsByIndex (ISelector& sel,
    1286              :                             const std::vector<size_t>& vrtInds,
    1287              :                             const std::vector<size_t>& edgeInds,
    1288              :                             const std::vector<size_t>& faceInds,
    1289              :                             const std::vector<size_t>& volInds)
    1290              : {
    1291            0 :         SelectElementsByIndex<Vertex> (sel, vrtInds);
    1292            0 :         SelectElementsByIndex<Edge> (sel, edgeInds);
    1293            0 :         SelectElementsByIndex<Face> (sel, faceInds);
    1294            0 :         SelectElementsByIndex<Volume> (sel, volInds);
    1295            0 : }
    1296              : 
    1297            0 : void SelectSubset(ISelector& sel,
    1298              :                                   const ISubsetHandler& sh,
    1299              :                                   int si,
    1300              :                                   ISelector::status_t status)
    1301              : {
    1302            0 :         GridObjectCollection goc = sh.get_grid_objects_in_subset(si);
    1303            0 :         for (size_t lvl = 0; lvl < goc.num_levels(); ++lvl) {
    1304            0 :                 for (VertexIterator iter = goc.begin<Vertex>(lvl); iter != goc.end<Vertex>(lvl); ++iter) {
    1305            0 :                         sel.select(*iter, status);
    1306              :                 }
    1307              : 
    1308            0 :                 for (EdgeIterator iter = goc.begin<Edge>(lvl); iter != goc.end<Edge>(lvl); ++iter) {
    1309            0 :                         sel.select(*iter, status);
    1310              :                 }
    1311              : 
    1312            0 :                 for (FaceIterator iter = goc.begin<Face>(lvl); iter != goc.end<Face>(lvl); ++iter) {
    1313            0 :                         sel.select(*iter, status);
    1314              :                 }
    1315              : 
    1316            0 :                 for (VolumeIterator iter = goc.begin<Volume>(lvl); iter != goc.end<Volume>(lvl); ++iter) {
    1317            0 :                         sel.select(*iter, status);
    1318              :                 }
    1319              :         }
    1320            0 : }
    1321              : 
    1322              : 
    1323              : // explicit template instantiation
    1324              : // (although used in the above function, the template functions
    1325              : // may not be compiled with external linkage!)
    1326              : template void SelectElementsByIndex<Vertex>(ISelector& sel, const std::vector<size_t>& inds);
    1327              : template void SelectElementsByIndex<Edge>(ISelector& sel, const std::vector<size_t>& inds);
    1328              : template void SelectElementsByIndex<Face>(ISelector& sel, const std::vector<size_t>& inds);
    1329              : template void SelectElementsByIndex<Volume>(ISelector& sel, const std::vector<size_t>& inds);
    1330              : 
    1331              : }//     end of namespace
        

Generated by: LCOV version 2.0-1