ug4
selection_util_impl.hpp
Go to the documentation of this file.
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>
40 
41 namespace ug
42 {
43 
46 // selection util methods
47 
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 
189 // InvertSelection
190 template <class TSelector, class TIterator>
191 void InvertSelection(TSelector& sel, TIterator begin, TIterator end)
192 {
193  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  if(sel.is_selected(v))
200  sel.deselect(v);
201  else
202  sel.select(v);
203  }
204 }
205 
207 template <class TElem, class TIterator>
208 void
209 SelectAssociated(ISelector& sel, TIterator begin, TIterator end,
210  ISelector::status_t status)
211 {
212  Grid* pGrid = sel.grid();
213  if(!pGrid)
214  return;
215 
216  Grid& grid = *pGrid;
217  std::vector<TElem*> elems;
218  for(TIterator iter = begin; iter != end; ++iter){
219  CollectAssociated(elems, grid, *iter);
220  for(size_t i = 0; i < elems.size(); ++i){
221  sel.select(elems[i], status);
222  }
223  }
224 }
225 
227 // SelectAssociatedVertices
228 template <class TSelector, class TElemIterator>
229 void SelectAssociatedVertices(TSelector& sel, TElemIterator elemsBegin,
230  TElemIterator elemsEnd, ISelector::status_t status)
231 {
232  while(elemsBegin != elemsEnd)
233  {
234  uint numVrts = (*elemsBegin)->num_vertices();
235  for(uint i = 0; i < numVrts; ++i)
236  sel.select((*elemsBegin)->vertex(i), status);
237  elemsBegin++;
238  }
239 }
240 
242 // SelectAssociatedEdges
243 template <class TSelector, class TElemIterator>
244 void SelectAssociatedEdges(TSelector& sel, TElemIterator elemsBegin,
245  TElemIterator elemsEnd, ISelector::status_t status)
246 {
247  Grid* pGrid = sel.grid();
248  if(pGrid)
249  {
250  Grid& grid = *pGrid;
251  std::vector<Edge*> vEdges;
252  while(elemsBegin != elemsEnd)
253  {
254  CollectEdges(vEdges, grid, *elemsBegin);
255  for(uint i = 0; i < vEdges.size(); ++i)
256  sel.select(vEdges[i], status);
257  elemsBegin++;
258  }
259  }
260 }
261 
263 // SelectAssociatedFaces
264 template <class TSelector, class TElemIterator>
265 void SelectAssociatedFaces(TSelector& sel, TElemIterator elemsBegin,
266  TElemIterator elemsEnd, ISelector::status_t status)
267 {
268  Grid* pGrid = sel.grid();
269  if(pGrid)
270  {
271  Grid& grid = *pGrid;
272  std::vector<Face*> vFaces;
273  while(elemsBegin != elemsEnd)
274  {
275  CollectFaces(vFaces, grid, *elemsBegin);
276  for(uint i = 0; i < vFaces.size(); ++i)
277  sel.select(vFaces[i], status);
278  elemsBegin++;
279  }
280  }
281 }
282 
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();
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 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  for(TElemIterator iter = elemsBegin; iter != elemsEnd; ++iter){
333  typename TElemIterator::value_type e = *iter;
334  if(LiesOnBoundary(grid, e)){
335  sel.select(e);
336  }
337  }
338 }
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>
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.
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 
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 
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 
430 template <class TAAPos>
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 
463 template <class TAAPos>
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 
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 
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 
548 template <class TIter>
549 void SelectAreaBoundary(ISelector& sel, const TIter begin, const TIter end)
550 {
552  typedef typename TElem::side TSide;
553 
554  if(!sel.grid())
555  return;
556 
557  Grid& grid = *sel.grid();
558 
559  grid.begin_marking();
560 
561  std::vector<TSide*> sides;
562  TIter iter = begin;
563  while(iter != end){
564  TElem* elem = *iter;
565  ++iter;
566  CollectAssociated(sides, grid, elem);
567  for(size_t i = 0; i < sides.size(); ++i){
568  TSide* side = sides[i];
569  if(!grid.is_marked(side)){
570  // if the side was initially selected, it should stay that way
571  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  sel.deselect(side);
579  }
580  }
581  }
582 
583  grid.end_marking();
584 }
585 
587 template <class TIter>
589  const TIter begin, const TIter end,
590  bool regardSelectedNbrsOnly)
591 {
593  typedef typename TElem::sideof TNbr;
594 
595  if(!TElem::CAN_BE_SIDE)
596  return;
597 
598  if(!sel.grid())
599  return;
600 
601  Grid& grid = *sel.grid();
602 
603  std::vector<TNbr*> nbrs;
604 
605  for(TIter iter = begin; iter != end;){
606  TElem* elem = *iter;
607  ++iter;
608 
609  CollectAssociated(nbrs, grid, elem);
610 
611  int si = -2;
612  for(size_t i = 0; i < nbrs.size(); ++i){
613  if(!regardSelectedNbrsOnly || sel.is_selected(nbrs[i])){
614  if(sh.get_subset_index(nbrs[i]) != si){
615  if(si == -2)
616  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 }
627 
628 template <class TElem>
629 void SelectSubsetElements(ISelector& sel, ISubsetHandler& sh, int subsetIndex,
630  ISelector::status_t status)
631 {
632  typedef typename GridObjectCollection::traits<TElem>::iterator TIter;
633  GridObjectCollection goc = sh.get_grid_objects_in_subset(subsetIndex);
634 
635  for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
636  for(TIter iter = goc.begin<TElem>(lvl); iter != goc.end<TElem>(lvl); ++iter)
637  sel.select(*iter, status);
638  }
639 }
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;
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>
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
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 
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 number FaceArea(ISelector& sel, TAAPosVRT& aaPos)
822 {
823  number sum = 0.;
824 
825  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;
832 
833  for(size_t i = 0; i < goc.num_levels(); ++i)
834  for(FaceIter iter = goc.begin<Face>(i); iter != goc.end<Face>(i); ++iter)
835  sum += FaceArea(*iter, aaPos);
836 
837  return sum;
838 }
839 
840 }// end of namespace
841 
842 #endif
parameterString p
A generic specialization of IAttachment.
Definition: attachment_pipe.h:263
Base-class for edges.
Definition: grid_base_objects.h:397
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:366
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
EdgeContainer::iterator AssociatedEdgeIterator
used to iterate over associated edges of vertices, faces and volumes
Definition: grid.h:249
void end_marking()
ends a marking sequence. Call this method when you're done with marking.
Definition: grid.cpp:1285
AssociatedFaceIterator associated_faces_begin(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:944
AssociatedEdgeIterator associated_edges_begin(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:882
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition: grid_impl.hpp:843
AssociatedEdgeIterator associated_edges_end(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:892
VolumeContainer::iterator AssociatedVolumeIterator
used to iterate over associated volumes of vertices, edges and faces
Definition: grid.h:253
void mark(GridObject *obj)
marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition: grid_impl.hpp:773
AssociatedVolumeIterator associated_volumes_begin(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:1006
void begin_marking()
begin marking.
Definition: grid.cpp:1262
AssociatedFaceIterator associated_faces_end(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:954
geometry_traits< TGeomObj >::iterator begin()
Definition: grid_impl.hpp:164
bool has_vertex_attachment(IAttachment &attachment)
Definition: grid.h:798
void associated_elements(traits< Vertex >::secure_container &elemsOut, TElem *e)
Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut.
Definition: grid_impl.hpp:466
AssociatedVolumeIterator associated_volumes_end(Vertex *vrt)
DO NOT INVOKE! Subject to change.
Definition: grid.cpp:1016
FaceContainer::iterator AssociatedFaceIterator
used to iterate over associated faces of vertices, edges and volumes
Definition: grid.h:251
geometry_traits< TGeomObj >::iterator end()
Definition: grid_impl.hpp:175
a helper class that holds a collection of possibly unconnected geometric-objects.
Definition: grid_object_collection.h:96
geometry_traits< TGeomObj >::iterator begin(size_t level=0)
Definition: grid_object_collection_impl.hpp:95
geometry_traits< TGeomObj >::iterator end(size_t level=0)
Definition: grid_object_collection_impl.hpp:106
size_t num_levels() const
returns the number of levels
Definition: grid_object_collection.h:128
Partitions elements of a grid into several subsets.
Definition: subset_handler_grid.h:53
base-implementation of a selector
Definition: selector_interface.h:126
virtual GridObjectCollection get_grid_objects() const =0
returns a geometric object collection, containing all selected objects
bool is_selected(TElem *elem) const
returns true if an element is selected
Definition: selector_interface.h:215
Grid * grid() const
Definition: selector_interface.h:218
void select(GridObject *elem, byte status)
selects an element
Definition: selector_interface_impl.hpp:56
void deselect(GridObject *elem)
Definition: selector_interface_impl.hpp:96
byte status_t
Definition: selector_interface.h:128
Definition: subset_handler_interface.h:223
int get_subset_index(GridObject *elem) const
Definition: subset_handler_interface.cpp:560
virtual GridObjectCollection get_grid_objects_in_subset(int subsetInd) const =0
Returns the geometric object collection for the given subset.
Vertex *const * ConstVertexArray
Definition: grid_base_objects.h:319
Container which holds an array of pointers.
Definition: pointer_const_array.h:84
size_t size() const
returns the size of the associated array.
Definition: pointer_const_array_impl.hpp:106
specialization of ISelector for a grid of class Grid.
Definition: selector_grid.h:96
VertexIterator vertices_end()
Definition: selector_grid.h:173
virtual void clear()
Definition: selector_grid.cpp:155
VolumeIterator volumes_end()
Definition: selector_grid.h:179
VolumeIterator volumes_begin()
Definition: selector_grid.h:178
VertexIterator vertices_begin()
Definition: selector_grid.h:172
EdgeIterator edges_end()
Definition: selector_grid.h:175
EdgeIterator edges_begin()
Definition: selector_grid.h:174
FaceIterator faces_end()
Definition: selector_grid.h:177
FaceIterator faces_begin()
Definition: selector_grid.h:176
Instances of this class or of derived classes are thrown if errors arise.
Definition: error.h:104
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
static number FaceArea(TDomain &dom, ISubsetHandler &sh, int si, size_t lvl)
Definition: domain_bridge.cpp:262
bool EdgeContains(EdgeVertices *e, Vertex *vrt)
Definition: grid_util_impl.hpp:45
bool LiesOnBoundary(Grid &grid, Edge *e)
returns true, if the edge lies on a 2d or 3d boundary
Definition: edge_util.cpp:169
int CalculateNormal(vector3 &vNormOut, Grid &grid, Edge *e, Grid::AttachmentAccessor< Vertex, APosition > &aaPos, Grid::AttachmentAccessor< Face, ANormal > *paaNormFACE)
Calculates the normal of the given edge.
Definition: edge_util.cpp:314
bool IsBoundaryEdge2D(Grid &grid, Edge *e)
returns whether an edge lies on the boundary of a 2D grid.
Definition: edge_util.cpp:112
int GetAssociatedFaces(Face **facesOut, Grid &grid, Edge *e, int maxNumFaces)
writes associated faces of e to facesOut.
Definition: edge_util.cpp:186
UG_API number EdgeLength(const EdgeVertices *e, TAAPosVRT &aaPos)
Calculates the length of the given edge.
Definition: edge_util_impl.hpp:80
UG_API bool ContainsPoint(const EdgeVertices *e, const vector_t &p, TAAPos aaPos)
Returns true if the given point lies on the given edge.
Definition: edge_util_impl.hpp:513
bool CheckDirection(TElem1 *e1, TElem2 *e2, const TAAPos &aaPos, const typename TAAPos::ValueType &dir, number minAngle, number maxAngle)
Checks whether the center of e2 can be reached from the center of e1 in the given direction.
Definition: misc_util_impl.hpp:338
void CollectEdges(std::vector< Edge * > &vEdgesOut, Grid &grid, Vertex *vrt, bool clearContainer)
Collects all edges which exist in the given grid and which are part of the given vertex.
Definition: grid_util.cpp:295
void CollectFaces(std::vector< Face * > &vFacesOut, Grid &grid, Vertex *vrt, bool clearContainer)
Collects all faces that exist in the given grid which contain the given vertex.
Definition: grid_util.cpp:458
UG_API void CollectAssociated(std::vector< Vertex * > &vVertexOut, Grid &grid, GridObject *obj, bool clearContainer=true)
Definition: grid_util_impl.hpp:169
void SelectCreaseEdges(ISelector &sel, TEdgeIterator edgesBegin, TEdgeIterator edgesEnd, number minAngle, APosition aVrtPos, bool ignoreBoundaryEdges=true, ISelector::status_t state=ISelector::SELECTED)
Selects edges which at which triangles meet in a large angle.
Definition: selection_util_impl.hpp:499
void SelectLinkedElements(ISelector &sel, typename Grid::traits< TElem >::callback cbIsSelectable=ConsiderAll(), typename Grid::traits< typename TElem::side >::callback cbIsTraversable=ConsiderAll())
Repeatedly traverses sides of selected elements and selects associated elements.
Definition: selection_util_impl.hpp:762
void SelectSubsetEdgesByDirection(Selector &sel, SubsetHandler &sh, int subsetIndex, TAAPos &aaPos, const vector3 &dir, number minDeviationAngle, number maxDeviationAngle, bool selectFlipped)
Selects all subset edges that face a given direction.
Definition: selection_util_impl.hpp:464
void SelectAssociated(ISelector &sel, TIterator begin, TIterator end, ISelector::status_t status=ISelector::SELECTED)
Selects all elements of type TElem, which touch an element between begin and end.
Definition: selection_util_impl.hpp:209
void InvertSelection(TSelector &sel)
Inverts the selection.
Definition: selection_util.cpp:167
void SelectAreaBoundary(ISelector &sel, const TIter begin, const TIter end)
selects sides that are only adjacent to one of the given inner elements
Definition: selection_util_impl.hpp:549
bool SelectRegion(Selector &sel, const typename TAAPos::ValueType &p, TAAPos &aaPos, typename Grid::traits< typename TGeomObj::side >::callback cbRegionBoundary)
Selects the region which contains the given point.
Definition: selection_util_impl.hpp:643
void SelectAssociatedVertices(TSelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd, ISelector::status_t status=ISelector::SELECTED)
selects all associated vertices of the elements between elemsBegin and elemsEnd
Definition: selection_util_impl.hpp:229
void SelectAssociatedGridObjects(TSelector &sel, ISelector::status_t status)
selects associated geometric objects of selected ones on each level.
Definition: selection_util.cpp:221
void AssignSelectionStateToSides(TSelector &sel, bool recursive)
Assigns the selection state of selected elements to associated sides.
Definition: selection_util_impl.hpp:294
void SelectInnerElements(ISelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd)
selects elements that do not lie on the associated grid's boundary
Definition: selection_util_impl.hpp:341
void SelectInterfaceElements(ISelector &sel, ISubsetHandler &sh, const TIter begin, const TIter end, bool regardSelectedNbrsOnly=false)
Selects elements which are adjacent to higher dimensional elements of different subsets.
Definition: selection_util_impl.hpp:588
UG_API void ExtendSelectionInDirection(TSelector &sel, size_t extSize, const typename TAAPos::ValueType &dir, number minAngle, number maxAngle, const TAAPos &aaPos, ISelector::status_t status=ISelector::SELECTED)
extends the selection to neighbours of selected elements in the given direction.
Definition: selection_util_impl.hpp:358
void SelectBoundaryElements(ISelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd)
selects elements that lie on the associated grid's boundary
Definition: selection_util_impl.hpp:326
void SelectAssociatedVolumes(TSelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd, ISelector::status_t status=ISelector::SELECTED)
selects all associated faces of the elements between elemsBegin and elemsEnd
Definition: selection_util_impl.hpp:286
void SelectAssociatedFaces(TSelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd, ISelector::status_t status=ISelector::SELECTED)
selects all associated faces of the elements between elemsBegin and elemsEnd
Definition: selection_util_impl.hpp:265
void SelectSubsetElements(ISelector &sel, ISubsetHandler &sh, int subsetIndex, ISelector::status_t status=ISelector::SELECTED)
selects all elements of the given type in the given subset
Definition: selection_util_impl.hpp:629
void TranslateSelection(Selector &sel, const typename TAAPosVRT::ValueType &offset, TAAPosVRT &aaPos)
moves all vertices touching the selection by the specified offset.
Definition: selection_util_impl.hpp:128
void SelectAssociatedEdges(TSelector &sel, TElemIterator elemsBegin, TElemIterator elemsEnd, ISelector::status_t status=ISelector::SELECTED)
selects all associated edges of the elements between elemsBegin and elemsEnd
Definition: selection_util_impl.hpp:244
void SelectShortPolychains(ISelector &sel, number maxLength, bool closedChainsOnly, TAAPos aaPos)
Selects regular polygonal chains which are shorter than a given threshold.
Definition: selection_util_impl.hpp:673
void SelectEdgesByDirection(Selector &sel, TAAPos &aaPos, const vector3 &dir, number minDeviationAngle, number maxDeviationAngle, bool selectFlipped)
Selects all edges that face a given direction.
Definition: selection_util_impl.hpp:431
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_API
Definition: ug_config.h:65
#define UG_LOG(msg)
Definition: log.h:367
unsigned int uint
Definition: types.h:114
#define UG_WARNING(msg)
Definition: log.h:328
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
void CalculateCenter(vector_t &centerOut, const vector_t *pointSet, size_t numPoints)
calculates the center of a point-set
Definition: math_util_impl.hpp:98
TNumber deg_to_rad(TNumber deg)
Definition: math_util_impl.hpp:49
void VecSet(vector_t &vInOut, typename vector_t::value_type s)
Set each vector component to scalar (componentwise)
Definition: math_vector_functions_common_impl.hpp:539
void VecNormalize(vector_t &vOut, const vector_t &v)
scales a vector_t to unit length
Definition: math_vector_functions_common_impl.hpp:501
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition: math_vector_functions_common_impl.hpp:226
void VecAdd(vector_t &vOut, const vector_t &v1, const vector_t &v2)
adds two MathVector<N>s and stores the result in a third one
Definition: math_vector_functions_common_impl.hpp:185
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
scales a MathVector<N>
Definition: math_vector_functions_common_impl.hpp:252
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition: math_vector_functions_common_impl.hpp:385
#define lg_for_each_in_subset(_feType, _feVar, _feCon, _feSubset)
Definition: lg_for_each.h:64
#define lg_for_each(_feType, _feVar, _feCon)
Definition: lg_for_each.h:38
#define lg_end_for
Definition: lg_for_each.h:88
Definition: smart_pointer.h:814
the ug namespace
ElementStorage< Vertex >::SectionContainer::iterator VertexIterator
This Iterator will be used as base-class for iterators of specialized geometric objects.
Definition: grid_base_object_traits.h:73
ElementStorage< Face >::SectionContainer::iterator FaceIterator
Definition: grid_base_object_traits.h:79
const number SMALL
Definition: math_constants.h:41
ElementStorage< Edge >::SectionContainer::iterator EdgeIterator
Definition: grid_base_object_traits.h:76
ElementStorage< Volume >::SectionContainer::iterator VolumeIterator
Definition: grid_base_object_traits.h:82
T value_type
Definition: sparsematrix_interface.h:2
boost::function< bool(base_object *)> callback
callback type for the elements base type.
Definition: grid.h:150
geometry_traits< TElem >::const_iterator const_iterator
Definition: grid.h:144
geometry_traits< TElem >::iterator iterator
Definition: grid.h:143
geometry_traits< TElem >::iterator iterator
Definition: grid_object_collection.h:101
Definition: metaprogramming_util.h:48