Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
41namespace ug
42{
43
46// selection util methods
47
49// CalculateCenter
50template <class TAAPosVRT>
51bool 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
127template <class TAAPosVRT>
128void 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
190template <class TSelector, class TIterator>
191void 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
207template <class TElem, class TIterator>
208void
209SelectAssociated(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
228template <class TSelector, class TElemIterator>
229void 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
243template <class TSelector, class TElemIterator>
244void 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
264template <class TSelector, class TElemIterator>
265void 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
285template <class TSelector, class TElemIterator>
286void SelectAssociatedVolumes(TSelector& sel, TElemIterator elemsBegin,
287 TElemIterator elemsEnd, ISelector::status_t status)
288{
289 SelectAssociated<Volume>(sel, elemsBegin, elemsEnd, status);
290}
291
292
293template <class TElem, class TSelector>
294void 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
325template <class TElemIterator>
326void 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
340template <class TElemIterator>
341void 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
357template <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
430template <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
463template <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
498template <class TEdgeIterator>
499void 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
548template <class TIter>
549void 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
587template <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
628template <class TElem>
629void SelectSubsetElements(ISelector& sel, ISubsetHandler& sh, int subsetIndex,
630 ISelector::status_t status)
631{
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
642template <class TGeomObj, class TAAPos>
643bool 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
672template <class TAAPos>
673void 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
761template <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
819template <class TAAPosVRT>
820UG_API
821number 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
void select(GridObject *elem, byte status)
selects an element
Definition selector_interface_impl.hpp:56
Grid * grid() const
Definition selector_interface.h:218
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
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
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
PointerConstArray< TElem * > secure_container
Definition grid.h:146
geometry_traits< TElem >::iterator iterator
Definition grid_object_collection.h:101
Definition metaprogramming_util.h:48