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