MeshSelectionT.cc 38.4 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
Jan Möbius's avatar
Jan Möbius committed
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
Jan Möbius's avatar
Jan Möbius committed
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59




//=============================================================================
//
//  IMPLEMENTATION
//
//=============================================================================

#define MESHSELECTION_C

//== INCLUDES =================================================================

#include "MeshSelectionT.hh"
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>

#include <stack>
60
#include <set>
Jan Möbius's avatar
 
Jan Möbius committed
61
62
63
64
65
66
67
//== NAMESPACES ===============================================================

namespace MeshSelection {

//== IMPLEMENTATION ==========================================================

//=========================================================
68
69
70
//== Vertex Selection =====================================
//=========================================================

Jan Möbius's avatar
 
Jan Möbius committed
71
template< typename MeshT >
72
inline
73
void selectVertices(MeshT* _mesh, const std::vector< int >& _vertices) {
Jan Möbius's avatar
 
Jan Möbius committed
74
  const int n_vertices = (int)_mesh->n_vertices();
75
76

  for ( uint i = 0 ; i < _vertices.size() ; ++i )
77
    if ( (_vertices[i] >= 0) && ( _vertices[i] < n_vertices ) )  {
Jan Möbius's avatar
 
Jan Möbius committed
78
79
80
81
      typename MeshT::VertexHandle vh(_vertices[i]);
      _mesh->status(vh).set_selected(true);
    }
}
82

Jan Möbius's avatar
 
Jan Möbius committed
83
//=========================================================
84

Jan Möbius's avatar
 
Jan Möbius committed
85
template< typename MeshT >
86
inline
87
void unselectVertices(MeshT* _mesh, const std::vector< int >& _vertices) {
Jan Möbius's avatar
 
Jan Möbius committed
88
  const int n_vertices = (int)_mesh->n_vertices();
89
90

  for ( uint i = 0 ; i < _vertices.size() ; ++i )
91
    if ( (_vertices[i] >= 0) && ( _vertices[i] < n_vertices ) )  {
Jan Möbius's avatar
 
Jan Möbius committed
92
93
94
95
96
97
      typename MeshT::VertexHandle vh(_vertices[i]);
      _mesh->status(vh).set_selected(false);
    }
}

//=========================================================
98

Jan Möbius's avatar
 
Jan Möbius committed
99
template< typename MeshT >
100
inline
Jan Möbius's avatar
 
Jan Möbius committed
101
102
void selectAllVertices(MeshT* _mesh) {
   typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
103
104

   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
105
      _mesh->status(*v_it).set_selected(true);
106
107

}
Jan Möbius's avatar
 
Jan Möbius committed
108
109

//=========================================================
110

Jan Möbius's avatar
 
Jan Möbius committed
111
112
113
114
template< typename MeshT >
inline
void clearVertexSelection(MeshT* _mesh) {
   typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
115
116

   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
117
      _mesh->status(*v_it).set_selected(false);
Jan Möbius's avatar
 
Jan Möbius committed
118
119
120
121
122
}

//=========================================================

template< typename MeshT >
123
inline
Jan Möbius's avatar
 
Jan Möbius committed
124
125
void invertVertexSelection(MeshT* _mesh) {
   typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
126
127

   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
128
      _mesh->status(*v_it).set_selected( ! _mesh->status(*v_it).selected());
Jan Möbius's avatar
 
Jan Möbius committed
129
130
131
132
}

//=========================================================

133

Jan Möbius's avatar
 
Jan Möbius committed
134
135
136
137
template< typename MeshT >
inline
void selectBoundaryVertices(MeshT* _mesh) {
   typename MeshT::HalfedgeIter he_it, he_end=_mesh->halfedges_end();
138
139

   for (he_it = _mesh->halfedges_begin(); he_it != he_end ; ++he_it)
Jan Möbius's avatar
Jan Möbius committed
140
141
142
      if (_mesh->is_boundary(*he_it) ) {
         _mesh->status(_mesh->to_vertex_handle(*he_it)).set_selected(true);
         _mesh->status(_mesh->from_vertex_handle(*he_it)).set_selected(true);
Jan Möbius's avatar
 
Jan Möbius committed
143
144
145
146
147
148
      }
}

//-----------------------------------------------------------------------------

template< typename MeshT >
149
inline
Jan Möbius's avatar
 
Jan Möbius committed
150
151
void shrinkVertexSelection(MeshT* _mesh) {
   OpenMesh::VPropHandleT< bool > temp_shrink;
152

Jan Möbius's avatar
 
Jan Möbius committed
153
   _mesh->add_property( temp_shrink, "Temp property for Vertex selection shrinking" );
154

Jan Möbius's avatar
 
Jan Möbius committed
155
   typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
156

Jan Möbius's avatar
 
Jan Möbius committed
157
   // initialize property ( copy status to new property )
158
   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
159
      _mesh->property(temp_shrink,*v_it) = _mesh->status(*v_it).selected();
160

Jan Möbius's avatar
 
Jan Möbius committed
161
   // update selection
162
   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
163
164
      if ( _mesh->property(temp_shrink,*v_it) ) {
         _mesh->status(*v_it).set_selected( true );
165

Jan Möbius's avatar
Jan Möbius committed
166
         for ( typename MeshT::VertexVertexIter vv_it(*_mesh,*v_it); vv_it.is_valid(); ++vv_it)
Jan Möbius's avatar
Jan Möbius committed
167
168
            if ( ! _mesh->property(temp_shrink,*vv_it) ){
                _mesh->status(*v_it).set_selected( false );
Jan Möbius's avatar
 
Jan Möbius committed
169
170
171
                break;
            }
      }
172

Jan Möbius's avatar
 
Jan Möbius committed
173
174
175
   _mesh->remove_property(temp_shrink);
}

176
//=========================================================
Jan Möbius's avatar
 
Jan Möbius committed
177
178

template< typename MeshT >
179
inline
Jan Möbius's avatar
 
Jan Möbius committed
180
181
void growVertexSelection(MeshT* _mesh) {
   OpenMesh::VPropHandleT< bool > temp_grow;
182

Jan Möbius's avatar
 
Jan Möbius committed
183
   _mesh->add_property( temp_grow, "Temp property for Vertex selection growing" );
184

Jan Möbius's avatar
 
Jan Möbius committed
185
186
   // initialize property ( copy status to new property )
   typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
187
   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
188
      _mesh->property(temp_grow,*v_it) = _mesh->status(*v_it).selected();
189

Jan Möbius's avatar
 
Jan Möbius committed
190
   // update selection
191
   for (v_it = _mesh->vertices_begin(); v_it != v_end ; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
192
193
194
      if ( _mesh->property(temp_grow,*v_it) )
         for ( typename MeshT::VertexVertexIter vv_it(*_mesh,*v_it); vv_it.is_valid(); ++vv_it)
            _mesh->status(*vv_it).set_selected( true );
195

Jan Möbius's avatar
 
Jan Möbius committed
196
197
198
   _mesh->remove_property(temp_grow);
}

199
//=========================================================
Jan Möbius's avatar
 
Jan Möbius committed
200
201

template< typename MeshT >
202
inline
Jan Möbius's avatar
 
Jan Möbius committed
203
204
std::vector< int > getVertexSelection(MeshT* _mesh) {
  std::vector< int > selection;
205

Jan Möbius's avatar
 
Jan Möbius committed
206
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
207
208
    if ( _mesh->status(*v_it).selected() )
      selection.push_back( v_it->idx() );
209

Jan Möbius's avatar
 
Jan Möbius committed
210
211
212
  return selection;
}

213
//=========================================================
Jan Möbius's avatar
 
Jan Möbius committed
214
215

template< typename MeshT >
216
inline
Jan Möbius's avatar
 
Jan Möbius committed
217
218
std::vector< int > getVertexSelection(MeshT* _mesh, bool& _invert) {
  std::vector< int > selection;
219

Jan Möbius's avatar
 
Jan Möbius committed
220
  int count = 0;
221

Jan Möbius's avatar
 
Jan Möbius committed
222
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
223
    if ( _mesh->status(*v_it).selected() )
Jan Möbius's avatar
 
Jan Möbius committed
224
      ++count;
225

Jan Möbius's avatar
 
Jan Möbius committed
226
227
  if ( count > (int)( _mesh->n_vertices() / 2) )
    _invert = true;
228
  else
Jan Möbius's avatar
 
Jan Möbius committed
229
    _invert = false;
230

Jan Möbius's avatar
 
Jan Möbius committed
231
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
232
233
    if ( _mesh->status(*v_it).selected() ^ _invert )
      selection.push_back( v_it->idx() );
234

Jan Möbius's avatar
 
Jan Möbius committed
235
236
237
238
239
  return selection;
}


template< typename MeshT >
240
inline
241
void selectBoundaryVertices(MeshT* _mesh, const typename MeshT::VertexHandle& _vh){
242

Jan Möbius's avatar
 
Jan Möbius committed
243
244
245
246
247
  OpenMesh::VPropHandleT< bool > visited;
  _mesh->add_property(visited, "Visited Vertices");

  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it)
Jan Möbius's avatar
Jan Möbius committed
248
    _mesh->property(visited, *v_it) = false;
Jan Möbius's avatar
 
Jan Möbius committed
249
250
251
252
253
254
255
256
257
258
259
260
261

  std::stack< typename MeshT::VertexHandle > stack;
  stack.push( _vh );

  while (!stack.empty()){

    typename MeshT::VertexHandle vh = stack.top();
    stack.pop();

    if (_mesh->property(visited,vh))
      continue;

    //find outgoing boundary-edges
Jan Möbius's avatar
Jan Möbius committed
262
    for (typename MeshT::VertexOHalfedgeIter voh_it(*_mesh,vh); voh_it.is_valid(); ++voh_it)
Jan Möbius's avatar
Jan Möbius committed
263
264
      if ( _mesh->is_boundary( _mesh->edge_handle( *voh_it ) ) )
        stack.push( _mesh->to_vertex_handle(*voh_it) );
Jan Möbius's avatar
 
Jan Möbius committed
265
266
267
268
269
270
271
272

    //select vertex
    _mesh->property(visited,vh) = true;
    _mesh->status( vh ).set_selected(true);
  }
  _mesh->remove_property(visited);
}

273
274
template< typename MeshT >
inline
275
void convertVertexToEdgeSelection(MeshT* _mesh, const std::vector< int >& _vertices) {
276

277
  for ( std::vector<int>::const_iterator v = _vertices.begin(); v != _vertices.end(); ++v) {
278

279
    typename MeshT::VertexHandle vh(*v);
280
281
    typename MeshT::VertexOHalfedgeIter ohe_iter = _mesh->voh_iter(vh);

Jan Möbius's avatar
Jan Möbius committed
282
    for (; ohe_iter.is_valid(); ++ohe_iter) {
283
      // test if both incident vertices are in _vertices
Jan Möbius's avatar
Jan Möbius committed
284
      typename MeshT::VertexHandle ovh = _mesh->to_vertex_handle(*ohe_iter);
285
      // search for ovh in _vertices
286
      for(std::vector<int>::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it) {
287
        if((*it) == ovh.idx()) {
Jan Möbius's avatar
Jan Möbius committed
288
          _mesh->status(_mesh->edge_handle(*ohe_iter)).set_selected(true);
289
290
291
          break;
        }
      }
292
293
294
295
296
297
298
299
300
    }
  }
}

template< typename MeshT >
inline
void convertVertexToEdgeSelection(MeshT* _mesh) {

  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
301
  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it) {
302

Jan Möbius's avatar
Jan Möbius committed
303
    if ( _mesh->status( *v_it ).selected() ) {
Jan Möbius's avatar
Jan Möbius committed
304
      typename MeshT::VertexOHalfedgeIter ohe_iter = _mesh->voh_iter(*v_it);
305

Jan Möbius's avatar
Jan Möbius committed
306
      for (; ohe_iter.is_valid(); ++ohe_iter) {
307
        // test if both incident vertices are in _vertices
Jan Möbius's avatar
Jan Möbius committed
308
        typename MeshT::VertexHandle ovh = _mesh->to_vertex_handle(*ohe_iter);
309
        if (_mesh->status(ovh).selected())
Jan Möbius's avatar
Jan Möbius committed
310
          _mesh->status(_mesh->edge_handle(*ohe_iter)).set_selected(true);
311
      }
312
    }
313
  }
314
315
}

316
317
template< typename MeshT >
inline
318
void convertVertexToHalfedgeSelection(MeshT* _mesh, const std::vector< int >& _vertices) {
319

320
  for (std::vector<int>::const_iterator v = _vertices.begin(); v != _vertices.end(); ++v) {
321
322

    typename MeshT::VertexHandle vh(*v);
323
324
    typename MeshT::VertexOHalfedgeIter ohe_iter = _mesh->voh_iter(vh);

Jan Möbius's avatar
Jan Möbius committed
325
    for (; ohe_iter.is_valid(); ++ohe_iter) {
326
      // test if both incident vertices are in _vertices
Jan Möbius's avatar
Jan Möbius committed
327
      typename MeshT::VertexHandle ovh = _mesh->to_vertex_handle(*ohe_iter);
328
      // search for ovh in _vertices
329
      for(std::vector<int>::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it) {
330
        if((*it) == ovh.idx()) {
Jan Möbius's avatar
Jan Möbius committed
331
332
          _mesh->status(*ohe_iter).set_selected(true);
          _mesh->status(_mesh->opposite_halfedge_handle(*ohe_iter)).set_selected(true);
333
334
335
          break;
        }
      }
336
337
338
339
340
341
342
343
344
345
    }
  }
}

template< typename MeshT >
inline
void convertVertexToHalfedgeSelection(MeshT* _mesh) {

  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
  
346
  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it) {
347

Jan Möbius's avatar
Jan Möbius committed
348
    if ( _mesh->status( *v_it ).selected() ) {
349

Jan Möbius's avatar
Jan Möbius committed
350
      typename MeshT::VertexOHalfedgeIter ohe_iter = _mesh->voh_iter(*v_it);
351

Jan Möbius's avatar
Jan Möbius committed
352
      for (; ohe_iter.is_valid(); ++ohe_iter) {
353
        // test if both incident vertices are in _vertices
Jan Möbius's avatar
Jan Möbius committed
354
        typename MeshT::VertexHandle ovh = _mesh->to_vertex_handle(*ohe_iter);
355
        if (_mesh->status(ovh).selected()) {
Jan Möbius's avatar
Jan Möbius committed
356
357
          _mesh->status(*ohe_iter).set_selected(true);
          _mesh->status(_mesh->opposite_halfedge_handle(*ohe_iter)).set_selected(true);
358
        }
359
360
      }
    }
361
  }
362
363
}

364
365
template< typename MeshT >
inline
366
void convertVertexToFaceSelection(MeshT* _mesh, const std::vector< int >& _vertices) {
367

368
  for(typename MeshT::FaceIter f_it = _mesh->faces_begin(); f_it != _mesh->faces_end(); ++f_it) {
Jan Möbius's avatar
Jan Möbius committed
369
    typename MeshT::FaceVertexIter fv_it = _mesh->fv_iter(*f_it);
370
371
    // go over each vertex of each face and test if it's selected
    bool allfound = true;
Jan Möbius's avatar
Jan Möbius committed
372
    for(; fv_it.is_valid(); ++fv_it) {
373
374
      // search fv_it in _vertices
      bool onefound = false;
375
      for(std::vector<int>::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it) {
Jan Möbius's avatar
Jan Möbius committed
376
        if((*it) == fv_it->idx()) { onefound = true; break; }
377
378
379
380
381
382
383
384
      }
      if(!onefound) {
        allfound = false;
        break;
      }
    }
    if(allfound) {
      // all incident vertices are selected -> select face
Jan Möbius's avatar
Jan Möbius committed
385
      _mesh->status(*f_it).set_selected(true);
386
387
    }
  }
388
389
}

390
391
392
393
template< typename MeshT >
inline
void convertVertexToFaceSelection(MeshT* _mesh) {

394
  typename MeshT::FaceIter f_it, f_end = _mesh->faces_end();
395
  
396
397
  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it) {

Jan Möbius's avatar
Jan Möbius committed
398
    typename MeshT::FaceVertexIter fv_it = _mesh->fv_iter(*f_it);
399
400
    // test if all incident vertices are selected
    bool allfound = true;
Jan Möbius's avatar
Jan Möbius committed
401
402
    for(; fv_it.is_valid(); ++fv_it) {
      if(!_mesh->status(*fv_it).selected()) {
403
404
405
        allfound = false;
        break;
      }
406
    }
407
    if(allfound)
Jan Möbius's avatar
Jan Möbius committed
408
      _mesh->status(*f_it).set_selected(true);
409
  }
410
411
}

412
413
414
415
416
417
template< typename MeshT >
inline
void convertVertexSelectionToFeatureVertices(MeshT* _mesh) {

    for (typename MeshT::VertexIter v_it = _mesh->vertices_begin(); v_it != _mesh->vertices_end(); ++v_it) {

Jan Möbius's avatar
Jan Möbius committed
418
        if (_mesh->status(*v_it).selected()) {
419

Jan Möbius's avatar
Jan Möbius committed
420
            _mesh->status(*v_it).set_feature(true);
421
        } else {
Jan Möbius's avatar
Jan Möbius committed
422
            _mesh->status(*v_it).set_feature(false);
423
424
425
426
427
428
429
430
431
432
        }
    }
}

template< typename MeshT >
inline
void convertFeatureVerticesToVertexSelection(MeshT* _mesh) {

    for (typename MeshT::VertexIter v_it = _mesh->vertices_begin(); v_it != _mesh->vertices_end(); ++v_it) {

Jan Möbius's avatar
Jan Möbius committed
433
        if (_mesh->status(*v_it).feature()) {
434

Jan Möbius's avatar
Jan Möbius committed
435
            _mesh->status(*v_it).set_selected(true);
436
        } else {
Jan Möbius's avatar
Jan Möbius committed
437
            _mesh->status(*v_it).set_selected(false);
438
439
440
441
442
443
444
445
446
447
        }
    }
}

template< typename MeshT >
inline
void clearFeatureVertices(MeshT* _mesh) {

    for (typename MeshT::VertexIter v_it = _mesh->vertices_begin(); v_it != _mesh->vertices_end(); ++v_it) {

Jan Möbius's avatar
Jan Möbius committed
448
        _mesh->status(*v_it).set_feature(false);
449
450
451
    }
}

452
453
//=========================================================
//== Modeling Regions =====================================
Jan Möbius's avatar
 
Jan Möbius committed
454
455
456
//=========================================================

template< typename MeshT >
457
inline
458
void setArea(MeshT* _mesh, const std::vector< int >& _vertices , unsigned int _type, bool _state) {
Jan Möbius's avatar
 
Jan Möbius committed
459
460
  for ( uint i = 0 ; i < _vertices.size() ; ++i ) {
    if ( _vertices[i] > (int)_mesh->n_vertices() )
461
462
      continue;

Jan Möbius's avatar
 
Jan Möbius committed
463
464
465
466
467
468
    typename MeshT::VertexHandle vh(_vertices[i]);
    _mesh->status(vh).change_bit(_type, _state);
  }
}

template< typename MeshT >
469
inline
Jan Möbius's avatar
 
Jan Möbius committed
470
void setArea(MeshT* _mesh , unsigned int _type, bool _state) {
471
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
472
    _mesh->status(*v_it).change_bit(_type,  _state);
Jan Möbius's avatar
 
Jan Möbius committed
473
474
475
}

template< typename MeshT >
476
inline
Jan Möbius's avatar
 
Jan Möbius committed
477
478
std::vector< int > getArea(MeshT* _mesh, unsigned int _type) {
  std::vector< int > selection;
479

Jan Möbius's avatar
 
Jan Möbius committed
480
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
481
482
    if ( _mesh->status(*v_it).is_bit_set( _type ) )
      selection.push_back( v_it->idx() );
483
484

  return selection;
Jan Möbius's avatar
 
Jan Möbius committed
485
486
487
}

template< typename MeshT >
488
inline
Jan Möbius's avatar
 
Jan Möbius committed
489
490
std::vector< int > getArea(MeshT* _mesh, unsigned int _type , bool& _invert) {
  std::vector< int > selection;
491

Jan Möbius's avatar
 
Jan Möbius committed
492
  int count = 0;
493

Jan Möbius's avatar
 
Jan Möbius committed
494
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
495
    if ( _mesh->status(*v_it).is_bit_set( _type ) )
Jan Möbius's avatar
 
Jan Möbius committed
496
      ++count;
497

Jan Möbius's avatar
 
Jan Möbius committed
498
499
  if ( count > (int)( _mesh->n_vertices() / 2) )
    _invert = true;
500
  else
Jan Möbius's avatar
 
Jan Möbius committed
501
    _invert = false;
502

Jan Möbius's avatar
 
Jan Möbius committed
503
  for ( typename MeshT::VertexIter v_it= _mesh->vertices_begin() ; v_it != _mesh->vertices_end() ; ++v_it )
Jan Möbius's avatar
Jan Möbius committed
504
505
    if ( _mesh->status(*v_it).is_bit_set( _type ) ^ _invert )
      selection.push_back( v_it->idx() );
506

Jan Möbius's avatar
 
Jan Möbius committed
507
508
509
510
511
  return selection;
}


//=========================================================
512
513
514
//== Edge Selection =====================================
//=========================================================

Jan Möbius's avatar
 
Jan Möbius committed
515
template< typename MeshT >
516
inline
517
void selectEdges(MeshT* _mesh, const std::vector< int >& _edges) {
Jan Möbius's avatar
 
Jan Möbius committed
518
  const int n_edges = (int)_mesh->n_edges();
519
520

  for ( uint i = 0 ; i < _edges.size() ; ++i )
521
    if ( (_edges[i] >= 0) && ( _edges[i] < n_edges ) )  {
Jan Möbius's avatar
 
Jan Möbius committed
522
523
524
525
      typename MeshT::EdgeHandle eh(_edges[i]);
      _mesh->status(eh).set_selected(true);
    }
}
526

Jan Möbius's avatar
 
Jan Möbius committed
527
//=========================================================
528

Jan Möbius's avatar
 
Jan Möbius committed
529
template< typename MeshT >
530
inline
531
void unselectEdges(MeshT* _mesh, const std::vector< int >& _edges) {
Jan Möbius's avatar
 
Jan Möbius committed
532
  const int n_edges = (int)_mesh->n_edges();
533
534

  for ( uint i = 0 ; i < _edges.size() ; ++i )
535
    if ( (_edges[i] >= 0) && ( _edges[i] < n_edges ) )  {
Jan Möbius's avatar
 
Jan Möbius committed
536
537
538
      typename MeshT::EdgeHandle eh(_edges[i]);
      _mesh->status(eh).set_selected(false);
    }
539
540
}

Jan Möbius's avatar
 
Jan Möbius committed
541
//=========================================================
542

Jan Möbius's avatar
 
Jan Möbius committed
543
template< typename MeshT >
544
inline
Jan Möbius's avatar
 
Jan Möbius committed
545
546
void selectAllEdges(MeshT* _mesh) {
  typename MeshT::EdgeIter e_it, e_end=_mesh->edges_end();
547
548

  for (e_it = _mesh->edges_begin(); e_it != e_end ; ++e_it)
Jan Möbius's avatar
Jan Möbius committed
549
  _mesh->status(*e_it).set_selected(true);
550
}
Jan Möbius's avatar
 
Jan Möbius committed
551
552
553
554

//=========================================================

template< typename MeshT >
555
inline
Jan Möbius's avatar
 
Jan Möbius committed
556
557
558
void clearEdgeSelection(MeshT* _mesh) {
  typename MeshT::EdgeIter e_it, e_end=_mesh->edges_end();

559
  for (e_it = _mesh->edges_begin(); e_it != e_end ; ++e_it)
Jan Möbius's avatar
Jan Möbius committed
560
    _mesh->status(*e_it).set_selected(false);
561
}
Jan Möbius's avatar
 
Jan Möbius committed
562
563
564
565

//=========================================================

template< typename MeshT >
566
inline
Jan Möbius's avatar
 
Jan Möbius committed
567
568
569
void invertEdgeSelection(MeshT* _mesh) {
  typename MeshT::EdgeIter e_it, e_end=_mesh->edges_end();

570
  for (e_it = _mesh->edges_begin(); e_it != e_end ; ++e_it)
Jan Möbius's avatar
Jan Möbius committed
571
    _mesh->status(*e_it).set_selected( ! _mesh->status(*e_it).selected());
572
}
Jan Möbius's avatar
 
Jan Möbius committed
573
574
575

//=========================================================

576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
template<typename MeshT>
inline
void growEdgeSelection(MeshT* _mesh) {
    std::set<typename MeshT::EdgeHandle> selectedEhs;
    for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(), e_end = _mesh->edges_end();
            e_it != e_end; ++e_it) {

        if (!_mesh->status(*e_it).selected()) continue;

        const typename MeshT::HalfedgeHandle he = _mesh->halfedge_handle(*e_it, 0);
        const typename MeshT::VertexHandle vhs[] = { _mesh->from_vertex_handle(he),
                                                     _mesh->to_vertex_handle(he) };

        for (int i = 0; i < 2; ++i) {
            for (typename MeshT::VertexEdgeIter ve_it = _mesh->ve_begin(vhs[i]), ve_end = _mesh->ve_end(vhs[i]);
                    ve_it != ve_end; ++ve_it) {

                selectedEhs.insert(ve_it.handle());
            }
        }

    }

    for (typename std::set<typename MeshT::EdgeHandle>::const_iterator it = selectedEhs.begin(); it != selectedEhs.end(); ++it)
        _mesh->status(*it).set_selected(true);
}

//=========================================================

605

Jan Möbius's avatar
 
Jan Möbius committed
606
607
608
609
610
template< typename MeshT >
inline
void selectBoundaryEdges(MeshT* _mesh) {
  typename MeshT::EdgeIter e_it, e_end=_mesh->edges_end();

611
  for (e_it = _mesh->edges_begin(); e_it != e_end ; ++e_it)
Jan Möbius's avatar
Jan Möbius committed
612
613
614
    if ( _mesh->is_boundary( _mesh->halfedge_handle(*e_it,0) ) ||
         _mesh->is_boundary( _mesh->halfedge_handle(*e_it,1) ) )
      _mesh->status(*e_it).set_selected( true );
Jan Möbius's avatar
 
Jan Möbius committed
615
616
}

617
//=========================================================
Jan Möbius's avatar
 
Jan Möbius committed
618
619

template< typename MeshT >
620
inline
Jan Möbius's avatar
 
Jan Möbius committed
621
622
std::vector< int > getEdgeSelection(MeshT* _mesh) {
  std::vector< int > selection;
623

Jan Möbius's avatar
 
Jan Möbius committed
624
  for ( typename MeshT::EdgeIter e_it= _mesh->edges_begin() ; e_it != _mesh->edges_end() ; ++e_it )
Jan Möbius's avatar
Jan Möbius committed
625
626
    if ( _mesh->status(*e_it).selected() )
      selection.push_back( e_it->idx() );
627

Jan Möbius's avatar
 
Jan Möbius committed
628
629
630
  return selection;
}

631
//=========================================================
Jan Möbius's avatar
 
Jan Möbius committed
632
633

template< typename MeshT >
634
inline
Jan Möbius's avatar
 
Jan Möbius committed
635
636
std::vector< int > getEdgeSelection(MeshT* _mesh, bool& _invert) {
  std::vector< int > selection;
637

Jan Möbius's avatar
 
Jan Möbius committed
638
  int count = 0;
639

Jan Möbius's avatar
 
Jan Möbius committed
640
  for ( typename MeshT::VertexIter e_it= _mesh->edges_begin() ; e_it != _mesh->edges_end() ; ++e_it )
Jan Möbius's avatar
Jan Möbius committed
641
    if ( _mesh->status(*e_it).selected() )
Jan Möbius's avatar
 
Jan Möbius committed
642
      ++count;
643

Jan Möbius's avatar
 
Jan Möbius committed
644
645
  if ( count > (int)( _mesh->n_vertices() / 2) )
    _invert = true;
646
  else
Jan Möbius's avatar
 
Jan Möbius committed
647
    _invert = false;
648

Jan Möbius's avatar
 
Jan Möbius committed
649
  for ( typename MeshT::VertexIter e_it= _mesh->edges_begin() ; e_it != _mesh->edges_end() ; ++e_it )
Jan Möbius's avatar
Jan Möbius committed
650
651
    if ( _mesh->status(*e_it).selected() ^ _invert )
      selection.push_back( e_it->idx() );
652

Jan Möbius's avatar
 
Jan Möbius committed
653
654
655
  return selection;
}

656
657
template< typename MeshT >
inline
658
void convertEdgeToVertexSelection(MeshT* _mesh, const std::vector< int >& _edges) {
659

660
	for (std::vector<int>::const_iterator e = _edges.begin(); e != _edges.end(); ++e) {
661
662
663
664
665
666
667
668
669
670
671
672

		typename MeshT::EdgeHandle eh(*e);
		typename MeshT::HalfedgeHandle heh0 = _mesh->halfedge_handle(eh, 0);

		typename MeshT::VertexHandle vh0 = _mesh->to_vertex_handle(heh0);
		typename MeshT::VertexHandle vh1 = _mesh->from_vertex_handle(heh0);

		_mesh->status(vh0).set_selected(true);
		_mesh->status(vh1).set_selected(true);
	}
}

673
674
675
676
677
678
template< typename MeshT >
inline
void convertEdgeToVertexSelection(MeshT* _mesh) {

  for ( typename MeshT::EdgeIter e_it= _mesh->edges_begin() ; e_it != _mesh->edges_end() ; ++e_it )
    
Jan Möbius's avatar
Jan Möbius committed
679
    if ( _mesh->status(*e_it).selected() ){
680

Jan Möbius's avatar
Jan Möbius committed
681
      typename MeshT::HalfedgeHandle heh0 = _mesh->halfedge_handle(*e_it, 0);
682
683
684
685
686
687
688
689
690

      typename MeshT::VertexHandle vh0 = _mesh->to_vertex_handle(heh0);
      typename MeshT::VertexHandle vh1 = _mesh->from_vertex_handle(heh0);

      _mesh->status(vh0).set_selected(true);
      _mesh->status(vh1).set_selected(true);
    }
}

691
692
template< typename MeshT >
inline
693
void convertEdgeToFaceSelection(MeshT* _mesh, const std::vector< int >& _edges) {
694

695
  for(typename MeshT::FaceIter f_it = _mesh->faces_begin(); f_it != _mesh->faces_end(); ++f_it) {
Jan Möbius's avatar
Jan Möbius committed
696
    typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(*f_it);
697
698
    // go over each edge of each face and test if it's selected
    bool allfound = true;
Jan Möbius's avatar
Jan Möbius committed
699
    for(; fe_it.is_valid(); ++fe_it) {
700
701
      // search fe_it in _edges
      bool onefound = false;
702
      for(std::vector<int>::const_iterator it = _edges.begin(); it != _edges.end(); ++it) {
Jan Möbius's avatar
Jan Möbius committed
703
        if((*it) == fe_it->idx()) { onefound = true; break; }
704
705
706
707
708
709
710
711
      }
      if(!onefound) {
        allfound = false;
        break;
      }
    }
    if(allfound) {
      // all incident vertices are selected -> select face
Jan Möbius's avatar
Jan Möbius committed
712
      _mesh->status(*f_it).set_selected(true);
713
714
    }
  }
715
716
}

717
718
719
720
template< typename MeshT >
inline
void convertEdgeToFaceSelection(MeshT* _mesh) {

721
722
723
724
  typename MeshT::FaceIter f_it, f_end = _mesh->faces_end();
  
  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it) {

Jan Möbius's avatar
Jan Möbius committed
725
    typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(*f_it);
726
727
    // test if all incident edges are selected
    bool allfound = true;
Jan Möbius's avatar
Jan Möbius committed
728
729
    for(; fe_it.is_valid(); ++fe_it) {
      if(!_mesh->status(*fe_it).selected()) {
730
731
732
        allfound = false;
        break;
      }
733
    }
734
    if(allfound)
Jan Möbius's avatar
Jan Möbius committed
735
      _mesh->status(*f_it).set_selected(true);
736
  }
737
}
Jan Möbius's avatar
 
Jan Möbius committed
738

739
740
741
742
743
744
template< typename MeshT >
inline
void convertEdgeToHalfedgeSelection(MeshT* _mesh) {

  for ( typename MeshT::EdgeIter e_it= _mesh->edges_begin() ; e_it != _mesh->edges_end() ; ++e_it )
    
Jan Möbius's avatar
Jan Möbius committed
745
    if ( _mesh->status(*e_it).selected() ){
746

Jan Möbius's avatar
Jan Möbius committed
747
748
      _mesh->status(_mesh->halfedge_handle(*e_it, 0)).set_selected(true);
      _mesh->status(_mesh->halfedge_handle(*e_it, 1)).set_selected(true);
749
750
751
    }
}

752
753
template< typename MeshT >
inline
754
void convertEdgeSelectionToFeatureEdges(MeshT* _mesh) {
755
756
757

    for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(); e_it != _mesh->edges_end(); ++e_it) {

Jan Möbius's avatar
Jan Möbius committed
758
        if (_mesh->status(*e_it).selected()) {
759

Jan Möbius's avatar
Jan Möbius committed
760
            _mesh->status(*e_it).set_feature(true);
761
        } else {
Jan Möbius's avatar
Jan Möbius committed
762
            _mesh->status(*e_it).set_feature(false);
763
764
765
766
767
768
        }
    }
}

template< typename MeshT >
inline
769
void convertFeatureEdgesToEdgeSelection(MeshT* _mesh) {
770
771

    for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(); e_it != _mesh->edges_end(); ++e_it) {
David Bommes's avatar
David Bommes committed
772

Jan Möbius's avatar
Jan Möbius committed
773
        if (_mesh->status(*e_it).feature()) {
774

Jan Möbius's avatar
Jan Möbius committed
775
            _mesh->status(*e_it).set_selected(true);
776
        } else {
Jan Möbius's avatar
Jan Möbius committed
777
            _mesh->status(*e_it).set_selected(false);
778
779
780
781
782
783
        }
    }
}

template< typename MeshT >
inline
784
void clearFeatureEdges(MeshT* _mesh) {
785
786
787

    for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(); e_it != _mesh->edges_end(); ++e_it) {

Jan Möbius's avatar
Jan Möbius committed
788
        _mesh->status(*e_it).set_feature(false);
789
790
    }
}
David Bommes's avatar
David Bommes committed
791
792
793
794
795
796
797

//=========================================================
//== Halfedge Selection =====================================
//=========================================================

template< typename MeshT >
inline
798
void selectHalfedges(MeshT* _mesh, const std::vector< int >& _halfedges) {
David Bommes's avatar
David Bommes committed
799
800
801
  const int n_halfedges = (int)_mesh->n_halfedges();

  for ( uint i = 0 ; i < _halfedges.size() ; ++i )
802
    if ( (_halfedges[i] >= 0) && ( _halfedges[i] < n_halfedges ) )  {
David Bommes's avatar
David Bommes committed
803
804
805
806
807
808
809
810
811
      typename MeshT::HalfedgeHandle heh(_halfedges[i]);
      _mesh->status(heh).set_selected(true);
    }
}

//=========================================================

template< typename MeshT >
inline
812
void unselectHalfedges(MeshT* _mesh, const std::vector< int >& _halfedges) {
David Bommes's avatar
David Bommes committed
813
814
815
  const int n_halfedges = (int)_mesh->n_halfedges();

  for ( uint i = 0 ; i < _halfedges.size() ; ++i )
816
    if ( (_halfedges[i] >= 0) && ( _halfedges[i] < n_halfedges ) )  {
David Bommes's avatar
David Bommes committed
817
818
819
820
821
822
823
824
825
826
827
828
829
      typename MeshT::HalfedgeHandle heh(_halfedges[i]);
      _mesh->status(heh).set_selected(false);
    }
}

//=========================================================

template< typename MeshT >
inline
void selectAllHalfedges(MeshT* _mesh) {
  typename MeshT::HalfedgeIter he_it, he_end=_mesh->halfedges_end();

  for (he_it = _mesh->halfedges_begin(); he_it != he_end ; ++he_it)
Jan Möbius's avatar
Jan Möbius committed
830
  _mesh->status(*he_it).set_selected(true);
David Bommes's avatar
David Bommes committed
831
832
833
834
835
836
837
838
839
840
}

//=========================================================

template< typename MeshT >
inline
void clearHalfedgeSelection(MeshT* _mesh) {
  typename MeshT::HalfedgeIter he_it, he_end=_mesh->halfedges_end();

  for (he_it = _mesh->halfedges_begin(); he_it != he_end ; ++he_it)
Jan Möbius's avatar
Jan Möbius committed
841
    _mesh->status(*he_it).set_selected(false);
David Bommes's avatar
David Bommes committed
842
843
844
845
846
847
848
849
850
851
}

//=========================================================

template< typename MeshT >
inline
void invertHalfedgeSelection(MeshT* _mesh) {
  typename MeshT::HalfedgeIter he_it, he_end=_mesh->halfedges_end();

  for (he_it = _mesh->halfedges_begin(); he_it != he_end ; ++he_it)
Jan Möbius's avatar
Jan Möbius committed
852
    _mesh->status(*he_it).set_selected( ! _mesh->status(*he_it).selected());
David Bommes's avatar
David Bommes committed
853
854
855
856
857
858
859
860
861
862
863
}

//=========================================================


template< typename MeshT >
inline
void selectBoundaryHalfedges(MeshT* _mesh) {
  typename MeshT::HalfedgeIter he_it, he_end=_mesh->halfedges_end();

  for (he_it = _mesh->halfedges_begin(); he_it != he_end ; ++he_it)
Jan Möbius's avatar
Jan Möbius committed
864
865
    if ( _mesh->is_boundary( *he_it))
      _mesh->status(*he_it).set_selected( true );
David Bommes's avatar
David Bommes committed
866
867
868
869
870
871
872
873
874
875
}

//=========================================================

template< typename MeshT >
inline
std::vector< int > getHalfedgeSelection(MeshT* _mesh) {
  std::vector< int > selection;

  for ( typename MeshT::HalfedgeIter he_it= _mesh->halfedges_begin() ; he_it != _mesh->halfedges_end() ; ++he_it )
Jan Möbius's avatar
Jan Möbius committed
876
877
    if ( _mesh->status(*he_it).selected() )
      selection.push_back( he_it->idx() );
David Bommes's avatar
David Bommes committed
878
879
880
881

  return selection;
}

882
883
884
885
886
887
template< typename MeshT >
inline
void convertHalfedgeToVertexSelection(MeshT* _mesh) {
    
    for ( typename MeshT::HalfedgeIter he_it= _mesh->halfedges_begin() ; he_it != _mesh->halfedges_end() ; ++he_it ) {
        
Jan Möbius's avatar
Jan Möbius committed
888
889
890
        if(_mesh->status(*he_it).selected()) {
            _mesh->status(_mesh->to_vertex_handle(*he_it)).set_selected(true);
            _mesh->status(_mesh->from_vertex_handle(*he_it)).set_selected(true);
891
892
893
894
895
896
897
898
899
900
        }
    }
}

template< typename MeshT >
inline
void convertHalfedgeToEdgeSelection(MeshT* _mesh) {
    
    for ( typename MeshT::HalfedgeIter he_it= _mesh->halfedges_begin() ; he_it != _mesh->halfedges_end() ; ++he_it ) {
        
Jan Möbius's avatar
Jan Möbius committed
901
902
        if(_mesh->status(*he_it).selected()) {
            _mesh->status(_mesh->edge_handle(*he_it)).set_selected(true);
903
904
905
906
907
908
909
        }
    }
}

template< typename MeshT >
inline
void convertHalfedgeToFaceSelection(MeshT* _mesh) {
910
911
912
913
    // Note: A face is not only selected
    // iff all incident halfedges are selected but
    // at least one of them. This is, however,
    // desired in some cases.
914
915
    for ( typename MeshT::HalfedgeIter he_it= _mesh->halfedges_begin() ; he_it != _mesh->halfedges_end() ; ++he_it ) {
        
Jan Möbius's avatar
Jan Möbius committed
916
917
        if(_mesh->status(*he_it).selected()) {
            _mesh->status(_mesh->face_handle(*he_it)).set_selected(true);
918
919
920
921
        }
    }
}

Jan Möbius's avatar
 
Jan Möbius committed
922
923
924
925
926
//=========================================================
//== Face Selection =======================================
//=========================================================

template< typename MeshT >
927
inline
Jan Möbius's avatar
Jan Möbius committed
928
void selectFaces(MeshT* _mesh, const std::vector< int >& _faces) {
Jan Möbius's avatar
 
Jan Möbius committed
929
  const int n_faces = (int)_mesh->n_faces();
930
931