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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-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              : #ifndef __H__LIB_GRID__SELECTION_UTIL_IMPL__
      34              : #define __H__LIB_GRID__SELECTION_UTIL_IMPL__
      35              : 
      36              : #include <vector>
      37              : #include <queue>
      38              : #include "lib_grid/algorithms/geom_obj_util/geom_obj_util.h"
      39              : #include "common/util/metaprogramming_util.h"
      40              : 
      41              : namespace ug
      42              : {
      43              : 
      44              : ////////////////////////////////////////////////////////////////////////
      45              : ////////////////////////////////////////////////////////////////////////
      46              : //      selection util methods
      47              : 
      48              : ////////////////////////////////////////////////////////////////////////
      49              : //      CalculateCenter
      50              : template <class TAAPosVRT>
      51              : bool CalculateCenter(typename TAAPosVRT::ValueType& centerOut,
      52              :                                          Selector& sel, TAAPosVRT& aaPos)
      53              : {
      54              :         if(!sel.grid()){
      55              :                 throw(UGError("No grid assigned to selector"));
      56              :         }
      57              :         
      58              :         Grid& grid = *sel.grid();
      59              :         
      60              : //      collect all vertices that are adjacent to selected elements
      61              : //      we have to make sure that each vertex is only counted once.
      62              : //      we do this by using grid::mark.
      63              :         grid.begin_marking();
      64              : 
      65              : //      std::vector<Vertex*> vrts;
      66              : //      vrts.assign(sel.vertices_begin(), sel.vertices_end());
      67              : //      grid.mark(sel.vertices_begin(), sel.vertices_end());
      68              : 
      69              :         VecSet(centerOut, 0);
      70              :         size_t n = 0;
      71              :         for(VertexIterator iter = sel.vertices_begin();
      72              :                 iter != sel.vertices_end(); ++iter)
      73              :         {
      74              :                 VecAdd(centerOut, centerOut, aaPos[*iter]);
      75              :                 grid.mark(*iter);
      76              :                 ++n;
      77              :         }
      78              : 
      79              :         for(EdgeIterator iter = sel.edges_begin();
      80              :                 iter != sel.edges_end(); ++iter)
      81              :         {
      82              :                 Edge::ConstVertexArray vrts = (*iter)->vertices();
      83              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
      84              :                         if(!grid.is_marked(vrts[i])){
      85              :                                 grid.mark(vrts[i]);
      86              :                                 VecAdd(centerOut, centerOut, aaPos[vrts[i]]);
      87              :                                 ++n;
      88              :                         }
      89              :                 }
      90              :         }
      91              : 
      92              :         for(FaceIterator iter = sel.faces_begin();
      93              :                 iter != sel.faces_end(); ++iter)
      94              :         {
      95              :                 Face::ConstVertexArray vrts = (*iter)->vertices();
      96              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
      97              :                         if(!grid.is_marked(vrts[i])){
      98              :                                 grid.mark(vrts[i]);
      99              :                                 VecAdd(centerOut, centerOut, aaPos[vrts[i]]);
     100              :                                 ++n;
     101              :                         }
     102              :                 }
     103              :         }
     104              : 
     105              :         for(VolumeIterator iter = sel.volumes_begin();
     106              :                 iter != sel.volumes_end(); ++iter)
     107              :         {
     108              :                 Volume::ConstVertexArray vrts = (*iter)->vertices();
     109              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     110              :                         if(!grid.is_marked(vrts[i])){
     111              :                                 grid.mark(vrts[i]);
     112              :                                 VecAdd(centerOut, centerOut, aaPos[vrts[i]]);
     113              :                                 ++n;
     114              :                         }
     115              :                 }
     116              :         }
     117              : 
     118              :         grid.end_marking();
     119              : 
     120              :         if(n > 0){
     121              :                 VecScale(centerOut, centerOut, 1. / (number)n);
     122              :                 return true;
     123              :         }
     124              :         return false;
     125              : }
     126              : 
     127              : template <class TAAPosVRT>
     128              : void TranslateSelection(Selector& sel, const typename TAAPosVRT::ValueType& offset,
     129              :                                                 TAAPosVRT& aaPos)
     130              : {
     131              :         if(!sel.grid()){
     132              :                 throw(UGError("No grid assigned to selector"));
     133              :         }
     134              : 
     135              :         Grid& grid = *sel.grid();
     136              : 
     137              : //      collect all vertices that are adjacent to selected elements
     138              : //      we have to make sure that each vertex is only counted once.
     139              : //      we do this by using grid::mark.
     140              :         grid.begin_marking();
     141              : 
     142              :         for(VertexIterator iter = sel.vertices_begin();
     143              :                 iter != sel.vertices_end(); ++iter)
     144              :         {
     145              :                 VecAdd(aaPos[*iter], aaPos[*iter], offset);
     146              :                 grid.mark(*iter);
     147              :         }
     148              : 
     149              :         for(EdgeIterator iter = sel.edges_begin();
     150              :                 iter != sel.edges_end(); ++iter)
     151              :         {
     152              :                 Edge::ConstVertexArray vrts = (*iter)->vertices();
     153              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     154              :                         if(!grid.is_marked(vrts[i])){
     155              :                                 grid.mark(vrts[i]);
     156              :                                 VecAdd(aaPos[vrts[i]], aaPos[vrts[i]], offset);
     157              :                         }
     158              :                 }
     159              :         }
     160              : 
     161              :         for(FaceIterator iter = sel.faces_begin();
     162              :                 iter != sel.faces_end(); ++iter)
     163              :         {
     164              :                 Face::ConstVertexArray vrts = (*iter)->vertices();
     165              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     166              :                         if(!grid.is_marked(vrts[i])){
     167              :                                 grid.mark(vrts[i]);
     168              :                                 VecAdd(aaPos[vrts[i]], aaPos[vrts[i]], offset);
     169              :                         }
     170              :                 }
     171              :         }
     172              : 
     173              :         for(VolumeIterator iter = sel.volumes_begin();
     174              :                 iter != sel.volumes_end(); ++iter)
     175              :         {
     176              :                 Volume::ConstVertexArray vrts = (*iter)->vertices();
     177              :                 for(size_t i = 0; i < (*iter)->num_vertices(); ++i){
     178              :                         if(!grid.is_marked(vrts[i])){
     179              :                                 grid.mark(vrts[i]);
     180              :                                 VecAdd(aaPos[vrts[i]], aaPos[vrts[i]], offset);
     181              :                         }
     182              :                 }
     183              :         }
     184              : 
     185              :         grid.end_marking();
     186              : }
     187              : 
     188              : ////////////////////////////////////////////////////////////////////////
     189              : //      InvertSelection
     190              : template <class TSelector, class TIterator>
     191            0 : void InvertSelection(TSelector& sel, TIterator begin, TIterator end)
     192              : {
     193            0 :         for(TIterator iter = begin; iter != end;){
     194              :         //      be careful - since iterator could be an iterator of the selector,
     195              :         //      we have to make sure, that we will not invalidate it.
     196              :                 typename TIterator::value_type v = *iter;
     197              :                 ++iter;
     198              :                 
     199            0 :                 if(sel.is_selected(v))
     200            0 :                         sel.deselect(v);
     201              :                 else
     202            0 :                         sel.select(v);
     203              :         }
     204            0 : }
     205              : 
     206              : ////////////////////////////////////////////////////////////////////////
     207              : template <class TElem, class TIterator>
     208              : void
     209            0 : SelectAssociated(ISelector& sel, TIterator begin, TIterator end,
     210              :                                  ISelector::status_t status)
     211              : {
     212              :         Grid* pGrid = sel.grid();
     213            0 :         if(!pGrid)
     214            0 :                 return;
     215              : 
     216              :         Grid& grid = *pGrid;
     217              :         std::vector<TElem*> elems;
     218            0 :         for(TIterator iter = begin; iter != end; ++iter){
     219              :                 CollectAssociated(elems, grid, *iter);
     220            0 :                 for(size_t i = 0; i < elems.size(); ++i){
     221            0 :                         sel.select(elems[i], status);
     222              :                 }
     223              :         }
     224            0 : }
     225              : 
     226              : ////////////////////////////////////////////////////////////////////////
     227              : //      SelectAssociatedVertices
     228              : template <class TSelector, class TElemIterator>
     229            0 : void SelectAssociatedVertices(TSelector& sel, TElemIterator elemsBegin,
     230              :                                                           TElemIterator elemsEnd, ISelector::status_t status)
     231              : {
     232            0 :         while(elemsBegin != elemsEnd)
     233              :         {
     234            0 :                 uint numVrts = (*elemsBegin)->num_vertices();
     235            0 :                 for(uint i = 0; i < numVrts; ++i)
     236            0 :                         sel.select((*elemsBegin)->vertex(i), status);
     237              :                 elemsBegin++;
     238              :         }
     239            0 : }
     240              : 
     241              : ////////////////////////////////////////////////////////////////////////
     242              : //      SelectAssociatedEdges
     243              : template <class TSelector, class TElemIterator>
     244            0 : void SelectAssociatedEdges(TSelector& sel, TElemIterator elemsBegin,
     245              :                                                    TElemIterator elemsEnd, ISelector::status_t status)
     246              : {
     247              :         Grid* pGrid = sel.grid();
     248            0 :         if(pGrid)
     249              :         {
     250              :                 Grid& grid = *pGrid;
     251              :                 std::vector<Edge*> vEdges;
     252            0 :                 while(elemsBegin != elemsEnd)
     253              :                 {
     254            0 :                         CollectEdges(vEdges, grid, *elemsBegin);
     255            0 :                         for(uint i = 0; i < vEdges.size(); ++i)
     256            0 :                                 sel.select(vEdges[i], status);
     257              :                         elemsBegin++;
     258              :                 }
     259            0 :         }
     260            0 : }
     261              : 
     262              : ////////////////////////////////////////////////////////////////////////
     263              : //      SelectAssociatedFaces
     264              : template <class TSelector, class TElemIterator>
     265            0 : void SelectAssociatedFaces(TSelector& sel, TElemIterator elemsBegin,
     266              :                                                    TElemIterator elemsEnd, ISelector::status_t status)
     267              : {
     268              :         Grid* pGrid = sel.grid();
     269            0 :         if(pGrid)
     270              :         {
     271              :                 Grid& grid = *pGrid;
     272              :                 std::vector<Face*> vFaces;
     273            0 :                 while(elemsBegin != elemsEnd)
     274              :                 {
     275            0 :                         CollectFaces(vFaces, grid, *elemsBegin);
     276            0 :                         for(uint i = 0; i < vFaces.size(); ++i)
     277            0 :                                 sel.select(vFaces[i], status);
     278              :                         elemsBegin++;
     279              :                 }
     280            0 :         }
     281            0 : }
     282              : 
     283              : ////////////////////////////////////////////////////////////////////////
     284              : //      SelectAssociatedFaces
     285              : template <class TSelector, class TElemIterator>
     286              : void SelectAssociatedVolumes(TSelector& sel, TElemIterator elemsBegin,
     287              :                                                      TElemIterator elemsEnd, ISelector::status_t status)
     288              : {
     289              :         SelectAssociated<Volume>(sel, elemsBegin, elemsEnd, status);
     290              : }
     291              : 
     292              : 
     293              : template <class TElem, class TSelector>
     294              : void AssignSelectionStateToSides(TSelector& sel, bool recursive)
     295              : {
     296              :         typedef typename TSelector::template traits<TElem>::level_iterator TIter;
     297              :         typedef typename TElem::side TSide;
     298              : 
     299              :         UG_ASSERT(sel.grid(), "A selector has to operate on a grid");
     300              : 
     301              :         Grid& g = *sel.grid();
     302              :         typename Grid::traits<TSide>::secure_container sides;
     303              : 
     304              :         for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl){
     305              :                 for(TIter iter = sel.template begin<TElem>(lvl);
     306              :                         iter != sel.template end<TElem>(lvl); ++iter)
     307              :                 {
     308              :                         TElem* e = *iter;
     309              :                         ISelector::status_t elemStatus = sel.get_selection_status(e);
     310              :                         g.associated_elements(sides, e);
     311              : 
     312              :                         for(size_t i = 0; i < sides.size(); ++i){
     313              :                                 ISelector::status_t sideStatus = sel.get_selection_status(sides[i]);
     314              :                                 sel.select(sides[i], elemStatus | sideStatus);
     315              :                         }
     316              :                 }
     317              :         }
     318              : 
     319              :         if(recursive && TSide::HAS_SIDES){
     320              :                 AssignSelectionStateToSides<TSide>(sel, recursive);
     321              :         }
     322              : }
     323              : 
     324              : 
     325              : template <class TElemIterator>
     326            0 : void SelectBoundaryElements(ISelector& sel, TElemIterator elemsBegin,
     327              :                                                  TElemIterator elemsEnd)
     328              : {
     329              :         UG_ASSERT(sel.grid(), "A grid has to be associated with the selector");
     330              :         Grid& grid = *sel.grid();
     331              : 
     332            0 :         for(TElemIterator iter = elemsBegin; iter != elemsEnd; ++iter){
     333              :                 typename TElemIterator::value_type e = *iter;
     334            0 :                 if(LiesOnBoundary(grid, e)){
     335              :                         sel.select(e);
     336              :                 }
     337              :         }
     338            0 : }
     339              : 
     340              : template <class TElemIterator>
     341              : void SelectInnerElements(ISelector& sel, TElemIterator elemsBegin,
     342              :                                                  TElemIterator elemsEnd)
     343              : {
     344              :         UG_ASSERT(sel.grid(), "A grid has to be associated with the selector");
     345              :         Grid& grid = *sel.grid();
     346              : 
     347              :         for(TElemIterator iter = elemsBegin; iter != elemsEnd; ++iter){
     348              :                 typename TElemIterator::value_type e = *iter;
     349              :                 if(!LiesOnBoundary(grid, e)){
     350              :                         sel.select(e);
     351              :                 }
     352              :         }
     353              : }
     354              : 
     355              : 
     356              : 
     357              : template <class TSelector, class TAAPos>
     358              : void ExtendSelectionInDirection(
     359              :                 TSelector& sel,
     360              :         size_t extSize,
     361              :         const typename TAAPos::ValueType& dir,
     362              :         number minAngle,
     363              :         number maxAngle,
     364              :         const TAAPos& aaPos,
     365              :                 ISelector::status_t status)
     366              : {
     367              :         if(!sel.grid()){
     368              :                 UG_LOG("ERROR in ExtendSelection: Selector has to be assigned to a grid.\n");
     369              :                 return;
     370              :         }
     371              :         
     372              :         Grid& grid = *sel.grid();
     373              :         
     374              : //      first select associated elements of volumes, faces and edges.
     375              : //      then select associated elements of selected vertices.
     376              : //      do this extSize times.
     377              : //      elements that have already been processed are marked.
     378              :         
     379              :         grid.begin_marking();
     380              :         
     381              : //      perform iteration
     382              :         for(size_t extIters = 0; extIters < extSize; ++extIters)
     383              :         {
     384              : //TODO: speed-up by only calling SelectAssociatedGridObjects once before the loop.
     385              : //              During the loop only newly selected elements should be checked for associated elements.
     386              : 
     387              :         //      select associated elements
     388              :                 SelectAssociatedGridObjects(sel, status);
     389              : 
     390              :         //      iterate over all selected vertices.
     391              :                 for(size_t lvl = 0; lvl < sel.num_levels(); ++lvl){
     392              :                         for(VertexIterator iter = sel.template begin<Vertex>(lvl);
     393              :                                 iter != sel.template end<Vertex>(lvl); ++iter)
     394              :                         {
     395              :                                 Vertex* vrt = *iter;
     396              :                         //      all marked vertices have already been processed.
     397              :                                 if(!grid.is_marked(vrt)){
     398              :                                         grid.mark(vrt);
     399              : 
     400              :                                 //      select associated volumes, faces and edges.
     401              :                                         for(Grid::AssociatedEdgeIterator asIter = grid.associated_edges_begin(vrt);
     402              :                                                 asIter != grid.associated_edges_end(vrt); ++asIter)
     403              :                                         {
     404              :                                                 if(CheckDirection(vrt, *asIter, aaPos, dir, minAngle, maxAngle))
     405              :                                                         sel.select(*asIter, status);
     406              :                                         }
     407              : 
     408              :                                         for(Grid::AssociatedFaceIterator asIter = grid.associated_faces_begin(vrt);
     409              :                                                 asIter != grid.associated_faces_end(vrt); ++asIter)
     410              :                                         {
     411              :                                                 if(CheckDirection(vrt, *asIter, aaPos, dir, minAngle, maxAngle))
     412              :                                                         sel.select(*asIter, status);
     413              :                                         }
     414              : 
     415              :                                         for(Grid::AssociatedVolumeIterator asIter = grid.associated_volumes_begin(vrt);
     416              :                                                 asIter != grid.associated_volumes_end(vrt); ++asIter)
     417              :                                         {
     418              :                                                 if(CheckDirection(vrt, *asIter, aaPos, dir, minAngle, maxAngle))
     419              :                                                         sel.select(*asIter, status);
     420              :                                         }
     421              :                                 }
     422              :                         }
     423              :                 }
     424              :         }
     425              :         
     426              :         grid.end_marking();
     427              : }
     428              : 
     429              : ////////////////////////////////////////////////////////////////////////
     430              : template <class TAAPos>
     431              : void SelectEdgesByDirection(
     432              :                                 Selector& sel,
     433              :                                 TAAPos& aaPos,
     434              :                                 const vector3& dir,
     435              :                                 number minDeviationAngle,
     436              :                                 number maxDeviationAngle,
     437              :                                 bool selectFlipped)
     438              : {
     439              : 
     440              :         UG_COND_THROW(!sel.grid(), "A grid has to be assigned to the given selector");
     441              : 
     442              :         Grid& g = *sel.grid();
     443              :         vector3 n;
     444              :         VecNormalize(n, dir);
     445              : 
     446              :         number maxDot = cos(deg_to_rad(minDeviationAngle));
     447              :         number minDot = cos(deg_to_rad(maxDeviationAngle));
     448              : 
     449              :         lg_for_each(Edge, e, g){
     450              :                 vector3 dir;
     451              :                 VecSubtract(dir, aaPos[e->vertex(1)], aaPos[e->vertex(0)]);
     452              :                 VecNormalize(dir, dir);
     453              :                 number d = VecDot(dir, n);
     454              :                 if((d >= minDot - SMALL && d <= maxDot + SMALL) ||
     455              :                         (selectFlipped && (-d >= minDot - SMALL && -d <= maxDot + SMALL)))
     456              :                 {
     457              :                         sel.select(e);
     458              :                 }
     459              :         }lg_end_for;
     460              : }
     461              : 
     462              : ////////////////////////////////////////////////////////////////////////
     463              : template <class TAAPos>
     464              : void SelectSubsetEdgesByDirection(
     465              :                                 Selector& sel,
     466              :                                 SubsetHandler& sh,
     467              :                                 int subsetIndex,
     468              :                                 TAAPos& aaPos,
     469              :                                 const vector3& dir,
     470              :                                 number minDeviationAngle,
     471              :                                 number maxDeviationAngle,
     472              :                                 bool selectFlipped)
     473              : {
     474              : 
     475              :         UG_COND_THROW(!sel.grid(), "A grid has to be assigned to the given selector");
     476              : 
     477              :         vector3 n;
     478              :         VecNormalize(n, dir);
     479              : 
     480              :         number maxDot = cos(deg_to_rad(minDeviationAngle));
     481              :         number minDot = cos(deg_to_rad(maxDeviationAngle));
     482              : 
     483              :         lg_for_each_in_subset(Edge, e, sh, subsetIndex){
     484              :                 vector3 dir;
     485              :                 VecSubtract(dir, aaPos[e->vertex(1)], aaPos[e->vertex(0)]);
     486              :                 VecNormalize(dir, dir);
     487              :                 number d = VecDot(dir, n);
     488              :                 if((d >= minDot - SMALL && d <= maxDot + SMALL) ||
     489              :                         (selectFlipped && (-d >= minDot - SMALL && -d <= maxDot + SMALL)))
     490              :                 {
     491              :                         sel.select(e);
     492              :                 }
     493              :         }lg_end_for;
     494              : }
     495              : 
     496              : 
     497              : ////////////////////////////////////////////////////////////////////////
     498              : template <class TEdgeIterator>
     499              : void SelectCreaseEdges(ISelector& sel, TEdgeIterator edgesBegin, TEdgeIterator edgesEnd,
     500              :                                                 number minAngle, APosition aPos,
     501              :                                                 bool ignoreBoundaryEdges, ISelector::status_t state)
     502              : {
     503              :         if(!sel.grid())
     504              :                 return;
     505              : 
     506              :         Grid& grid = *sel.grid();
     507              : 
     508              : //      get the position accessor
     509              :         if(!grid.has_vertex_attachment(aPos))
     510              :                 return;
     511              : 
     512              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
     513              : 
     514              : //      we'll store face normals in those vectors:
     515              :         vector3 n[2];
     516              : 
     517              : //      associated faces are stored in this array
     518              :         Face* f[2];
     519              : 
     520              : //      all dot-products between normals lower than minDot mark a crease.
     521              :         number minDot = cos(minAngle * 3.14159265 / 180.f);
     522              : 
     523              : //      iterate through the edges
     524              :         for(TEdgeIterator iter = edgesBegin; iter != edgesEnd; ++iter)
     525              :         {
     526              :                 Edge* e = *iter;
     527              :                 if(!(ignoreBoundaryEdges && IsBoundaryEdge2D(grid, e))){
     528              :                 //      get the associated faces
     529              :                 //      all edges that do not have exactly 2 associated edges
     530              :                 //      are regarded as crease-edges
     531              :                         if(GetAssociatedFaces(f, grid, e, 2) == 2){
     532              :                         //      get the normals of the associated faces
     533              :                                 CalculateNormal(n[0], f[0], aaPos);
     534              :                                 CalculateNormal(n[1], f[1], aaPos);
     535              :                         //      if the dot-product is lower than minDot, then the edge is a crease edge.
     536              :                                 if(VecDot(n[0], n[1]) < minDot)
     537              :                                         sel.select(e, state);
     538              :                         }
     539              :                         else{
     540              :                                 sel.select(e, state);
     541              :                         }
     542              :                 }
     543              :         }
     544              : }
     545              : 
     546              : 
     547              : ////////////////////////////////////////////////////////////////////////
     548              : template <class TIter>
     549            0 : void SelectAreaBoundary(ISelector& sel, const TIter begin, const TIter end)
     550              : {
     551              :         typedef typename Pointer2Value<typename TIter::value_type>::type  TElem;
     552              :         typedef typename TElem::side                                                                            TSide;
     553              : 
     554            0 :         if(!sel.grid())
     555            0 :                 return;
     556              : 
     557              :         Grid& grid = *sel.grid();
     558              : 
     559            0 :         grid.begin_marking();
     560              : 
     561              :         std::vector<TSide*> sides;
     562              :         TIter iter = begin;
     563            0 :         while(iter != end){
     564              :                 TElem* elem = *iter;
     565              :                 ++iter;
     566              :                 CollectAssociated(sides, grid, elem);
     567            0 :                 for(size_t i = 0; i < sides.size(); ++i){
     568            0 :                         TSide* side = sides[i];
     569            0 :                         if(!grid.is_marked(side)){
     570              :                         //      if the side was initially selected, it should stay that way
     571            0 :                                 if(!sel.is_selected(side)){
     572              :                                         grid.mark(side);
     573              :                                         sel.select(side);
     574              :                                 }
     575              :                         }
     576              :                         else{
     577              :                         //      if the side is marked, then it is an inner side
     578            0 :                                 sel.deselect(side);
     579              :                         }
     580              :                 }
     581              :         }
     582              : 
     583            0 :         grid.end_marking();
     584            0 : }
     585              : 
     586              : ////////////////////////////////////////////////////////////////////////
     587              : template <class TIter>
     588            0 : void SelectInterfaceElements(ISelector& sel, ISubsetHandler& sh,
     589              :                                                          const TIter begin, const TIter end,
     590              :                                                          bool regardSelectedNbrsOnly)
     591              : {
     592              :         typedef typename Pointer2Value<typename TIter::value_type>::type  TElem;
     593              :         typedef typename TElem::sideof                                                                          TNbr;
     594              : 
     595              :         if(!TElem::CAN_BE_SIDE)
     596            0 :                 return;
     597              : 
     598            0 :         if(!sel.grid())
     599              :                 return;
     600              : 
     601              :         Grid& grid = *sel.grid();
     602              : 
     603              :         std::vector<TNbr*> nbrs;
     604              : 
     605            0 :         for(TIter iter = begin; iter != end;){
     606              :                 TElem* elem = *iter;
     607              :                 ++iter;
     608              : 
     609              :                 CollectAssociated(nbrs, grid, elem);
     610              : 
     611              :                 int si = -2;
     612            0 :                 for(size_t i = 0; i < nbrs.size(); ++i){
     613            0 :                         if(!regardSelectedNbrsOnly || sel.is_selected(nbrs[i])){
     614            0 :                                 if(sh.get_subset_index(nbrs[i]) != si){
     615            0 :                                         if(si == -2)
     616            0 :                                                 si = sh.get_subset_index(nbrs[i]);
     617              :                                         else{
     618              :                                         //      elem is an interface element
     619              :                                                 sel.select(elem);
     620              :                                                 break;
     621              :                                         }
     622              :                                 }
     623              :                         }
     624              :                 }
     625              :         }
     626            0 : }
     627              : 
     628              : template <class TElem>
     629            0 : void SelectSubsetElements(ISelector& sel, ISubsetHandler& sh, int subsetIndex,
     630              :                                                   ISelector::status_t status)
     631              : {
     632              :         typedef typename GridObjectCollection::traits<TElem>::iterator    TIter;
     633            0 :         GridObjectCollection goc = sh.get_grid_objects_in_subset(subsetIndex);
     634              : 
     635            0 :         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
     636            0 :                 for(TIter iter = goc.begin<TElem>(lvl); iter != goc.end<TElem>(lvl); ++iter)
     637            0 :                         sel.select(*iter, status);
     638              :         }
     639            0 : }
     640              : 
     641              : 
     642              : template <class TGeomObj, class TAAPos>
     643              : bool SelectRegion(Selector& sel, const typename TAAPos::ValueType& p, TAAPos& aaPos,
     644              :                                   typename Grid::traits<typename TGeomObj::side>::callback cbRegionBoundary)
     645              : {
     646              :         typedef typename Grid::traits<TGeomObj>::iterator TIter;
     647              : 
     648              :         if(!sel.grid())
     649              :                 return false;
     650              : 
     651              :         Grid& g = *sel.grid();
     652              : 
     653              : //      first try to find the element which contains p
     654              :         TGeomObj* startElem = NULL;
     655              :         for(TIter iter = g.begin<TGeomObj>(); iter != g.end<TGeomObj>(); ++iter){
     656              :                 if(ContainsPoint(*iter, p, aaPos)){
     657              :                         startElem = *iter;
     658              :                         break;
     659              :                 }
     660              :         }
     661              : 
     662              :         if(!startElem)
     663              :                 return false;
     664              : 
     665              :         sel.clear<TGeomObj>();
     666              :         sel.select(startElem);
     667              :         SelectionFill<TGeomObj>(sel, cbRegionBoundary);
     668              : 
     669              :         return true;
     670              : }
     671              : 
     672              : template <class TAAPos>
     673              : void SelectShortPolychains(ISelector& sel, number maxLength, bool closedChainsOnly,
     674              :                                                    TAAPos aaPos)
     675              : {
     676              :         if(!sel.grid())
     677              :                 return;
     678              :         Grid& grid = *sel.grid();
     679              : 
     680              : //      we'll collect all contained short polychains in this vector before deciding
     681              : //      to select them or not. If a polychain is already longer than maxLength
     682              : //      we won't add its edges to the vector
     683              :         std::vector<Edge*> curChain;
     684              :         std::queue<Edge*> nextEdges;
     685              :         Grid::edge_traits::secure_container edges;
     686              : 
     687              :         std::vector<Vertex*> junctionPoints;
     688              : 
     689              :         grid.begin_marking();
     690              : 
     691              :         for(EdgeIterator eiter = grid.begin<Edge>(); eiter != grid.end<Edge>(); ++eiter){
     692              :                 if(grid.is_marked(*eiter))
     693              :                         continue;
     694              : 
     695              :                 bool curChainIsClosed = true;
     696              :                 number curChainLength = 0;
     697              : 
     698              :                 curChain.clear();
     699              :                 junctionPoints.clear();
     700              :                 
     701              :                 nextEdges.push(*eiter);
     702              :                 grid.mark(*eiter);
     703              : 
     704              :                 while(!nextEdges.empty()){
     705              :                         Edge* e = nextEdges.front();
     706              :                         nextEdges.pop();
     707              :                         
     708              :                         curChainLength += EdgeLength(e, aaPos);
     709              :                         if(curChainLength <= maxLength)
     710              :                                 curChain.push_back(e);
     711              : 
     712              :                         for(size_t ivrt = 0; ivrt < 2; ++ivrt){
     713              :                                 Vertex* vrt = e->vertex(ivrt);
     714              :                                 grid.associated_elements(edges, vrt);
     715              :                                 if(edges.size() < 2)
     716              :                                         curChainIsClosed = false;
     717              :                                 else if(edges.size() == 2){
     718              :                                         for(size_t iedge = 0; iedge < 2; ++iedge){
     719              :                                                 Edge* nextEdge = edges[iedge];
     720              :                                                 if(!grid.is_marked(nextEdge)){
     721              :                                                         grid.mark(nextEdge);
     722              :                                                         nextEdges.push(nextEdge);
     723              :                                                 }
     724              :                                         }
     725              :                                 }
     726              :                                 else{
     727              :                                         junctionPoints.push_back(vrt);
     728              :                                 }
     729              :                         }
     730              :                 }
     731              : 
     732              :                 if((curChainLength <= maxLength)){
     733              :                         if(closedChainsOnly && curChainIsClosed && !junctionPoints.empty()){
     734              :                         //      count the number of associated edges of each junction-point
     735              :                         //      in curChain. If one is associated with != 2 vertices the chain
     736              :                         //      is considered as not closed 
     737              :                                 for(size_t ivrt = 0; ivrt < junctionPoints.size(); ++ivrt){
     738              :                                         Vertex* vrt = junctionPoints[ivrt];
     739              :                                         size_t numConnectedEdges = 0;
     740              :                                         for(size_t iedge = 0; iedge < curChain.size(); ++iedge){
     741              :                                                 if(EdgeContains(curChain[iedge], vrt))
     742              :                                                         ++numConnectedEdges;
     743              :                                         }
     744              : 
     745              :                                         if(numConnectedEdges != 2){
     746              :                                                 curChainIsClosed = false;
     747              :                                                 break;
     748              :                                         }
     749              :                                 }
     750              : 
     751              :                         }
     752              : 
     753              :                         if(curChainIsClosed || !closedChainsOnly)
     754              :                                 sel.select(curChain.begin(), curChain.end());
     755              :                 }
     756              :         }
     757              : 
     758              :         grid.end_marking();
     759              : }
     760              : 
     761              : template <class TElem>
     762              : void SelectLinkedElements(ISelector& sel,
     763              :                   typename Grid::traits<TElem>::callback cbIsSelectable,
     764              :                   typename Grid::traits<typename TElem::side>::callback cbIsTraversable)
     765              : {
     766              :         using namespace std;
     767              :         typedef typename Grid::traits<TElem>::iterator    ElemIter;
     768              :         typedef typename TElem::side Side;
     769              : 
     770              :         if(!sel.grid())
     771              :                 return;
     772              :         Grid& grid = *sel.grid();
     773              :         
     774              :         queue<TElem*> qElems;
     775              :         
     776              : //      add all currently selected elements to the qElems queue
     777              :         GridObjectCollection goc = sel.get_grid_objects();
     778              :         for(size_t i = 0; i < goc.num_levels(); ++i){
     779              :                 for(ElemIter iter = goc.begin<TElem>(i); iter != goc.end<TElem>(i); ++iter)
     780              :                         qElems.push(*iter);
     781              :         }
     782              :         
     783              :         typename Grid::traits<TElem>::secure_container    nbrs;
     784              :         typename Grid::traits<Side>::secure_container     sides;
     785              :         
     786              :         while(!qElems.empty()){
     787              :                 TElem* e = qElems.front();
     788              :                 qElems.pop();
     789              :                 
     790              :                 grid.associated_elements(sides, e);
     791              :                 
     792              :                 for(size_t i_side = 0; i_side < sides.size(); ++i_side){
     793              :                         Side* side = sides[i_side];
     794              :                 //      if stopAtSelectedSides is active and if the side is selected,
     795              :                 //      we won't traverse it.
     796              :                         if(!cbIsTraversable(side))
     797              :                                 continue;
     798              :                         
     799              :                 //      get all neighboring elements of side. Check for each unselected,
     800              :                 //      whether it lies on a boundary. If it does, select it and push it
     801              :                 //      to the queue.
     802              :                         grid.associated_elements(nbrs, side);
     803              :                         
     804              :                         for(size_t i_nbr = 0; i_nbr < nbrs.size(); ++i_nbr){
     805              :                                 TElem* nbr = nbrs[i_nbr];
     806              :                                 if(sel.is_selected(nbr))
     807              :                                         continue;
     808              :                                 if(!cbIsSelectable(nbr))
     809              :                                         continue;
     810              :                                 
     811              :                         //      we found a new linked boundary element
     812              :                                 sel.select(nbr);
     813              :                                 qElems.push(nbr);
     814              :                         }
     815              :                 }
     816              :         }
     817              : }
     818              : 
     819              : template <class TAAPosVRT>
     820              : UG_API
     821            0 : number FaceArea(ISelector& sel, TAAPosVRT& aaPos)
     822              : {
     823              :         number sum = 0.;
     824              : 
     825            0 :         if(!sel.grid()) {
     826              :                 UG_WARNING("A grid has to be associated with the selector!");
     827              :                 return sum;
     828              :         }
     829              : 
     830              :         typedef Grid::traits<Face>::const_iterator FaceIter;
     831            0 :         GridObjectCollection goc = sel.get_grid_objects();
     832              : 
     833            0 :         for(size_t i = 0; i < goc.num_levels(); ++i)
     834            0 :                 for(FaceIter iter = goc.begin<Face>(i); iter != goc.end<Face>(i); ++iter)
     835            0 :                         sum += FaceArea(*iter, aaPos);
     836              : 
     837              :         return sum;
     838              : }
     839              : 
     840              : }// end of namespace
     841              : 
     842              : #endif
        

Generated by: LCOV version 2.0-1