Developer Documentation
MeshObjectSelectionPluginT_impl.hh
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright(C)2001-2010 by Computer Graphics Group, RWTH Aachen *
5  * www.openflipper.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenFlipper. *
9  * *
10  * OpenFlipper is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or(at your option)any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenFlipper is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenFlipper. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision$ *
38  * $Author$ *
39  * $Date: 2010-09-24 14:05:45 +0200(Fri, 24 Sep 2010)$ *
40  * *
41 \*===========================================================================*/
42 
43 #include "MeshObjectSelectionPlugin.hh"
44 
46 #include <OpenMesh/Core/Geometry/MathDefs.hh>
47 
48 #include <set>
49 
56 template<typename MeshT>
57 bool MeshObjectSelectionPlugin::deleteSelection(MeshT* _mesh, PrimitiveType _primitiveType) {
58 
59  bool changed = false;
60 
61  if(_primitiveType & vertexType_) {
62  typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
63 
64  for(v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it) {
65  if(_mesh->status(*v_it).selected()) {
66  _mesh->delete_vertex(*v_it);
67  changed = true;
68  }
69  }
70  }
71 
72  if(_primitiveType & edgeType_) {
73  typename MeshT::EdgeIter e_it, e_end(_mesh->edges_end());
74 
75  for(e_it=_mesh->edges_begin(); e_it!=e_end; ++e_it) {
76  if(_mesh->status(*e_it).selected()) {
77  _mesh->delete_edge(*e_it);
78  changed = true;
79  }
80  }
81  }
82 
83  if(_primitiveType & faceType_) {
84  typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
85 
86  for(f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
87  if(_mesh->status(*f_it).selected()) {
88  _mesh->delete_face(*f_it);
89  changed = true;
90  }
91  }
92  }
93 
94  _mesh->garbage_collection();
95 
96  return changed;
97 }
98 
99 //***********************************************************************************
100 
105 template<typename MeshType>
107 
108  // Set face status
109  typename MeshType::FaceIter f_it, f_end=_mesh->faces_end();
110  typename MeshType::FaceVertexIter fv_it;
111  typename MeshType::VertexHandle v0, v1, v2;
112 
113  for(f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
114  fv_it = _mesh->fv_iter(*f_it);
115  v0 = *( fv_it);
116  v1 = *(++fv_it);
117  v2 = *(++fv_it);
118 
119  const bool a =(_mesh->status(v0).is_bit_set(AREA)|| _mesh->status(v1).is_bit_set(AREA)|| _mesh->status(v2).is_bit_set(AREA));
120  bool h =(_mesh->status(v0).is_bit_set(HANDLEAREA)&&
121  _mesh->status(v1).is_bit_set(HANDLEAREA)&&
122  _mesh->status(v2).is_bit_set(HANDLEAREA));
123 
124  if(!(a || h))
125  if(_mesh->status(v0).is_bit_set(HANDLEAREA)||
126  _mesh->status(v1).is_bit_set(HANDLEAREA)||
127  _mesh->status(v2).is_bit_set(HANDLEAREA))
128  h = true;
129 
130  _mesh->status(*f_it).change_bit(AREA , a);
131  _mesh->status(*f_it).change_bit(HANDLEAREA, h);
132  }
133 }
134 
135 //***********************************************************************************
136 
145 template<class MeshT>
146 void MeshObjectSelectionPlugin::toggleMeshSelection(int _objectId, MeshT* _mesh, uint _fh, ACG::Vec3d& _hit_point, PrimitiveType _primitiveType) {
147 
148  typename MeshT::FaceHandle fh = _mesh->face_handle(_fh);
149 
150  if(!fh.is_valid())
151  return;
152 
153  //Vertex Selection
154  if(_primitiveType & vertexType_) {
155 
156  typename MeshT::FaceVertexIter fv_it(*_mesh, fh);
157  typename MeshT::VertexHandle closest = *fv_it;
158  typename MeshT::Scalar shortest_distance =(_mesh->point(closest)- _hit_point).sqrnorm();
159 
160  do {
161  if((_mesh->point(*fv_it)- _hit_point).sqrnorm()<shortest_distance) {
162  shortest_distance =(_mesh->point(*fv_it)- _hit_point).sqrnorm();
163  closest = *fv_it;
164  }
165 
166  ++fv_it;
167 
168  } while( fv_it.is_valid() );
169 
170  _mesh->status(closest).set_selected(!_mesh->status(closest).selected());
171 
172  if(_mesh->status(closest).selected())
173  emit scriptInfo("selectVertices(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest.idx())+ "])");
174  else
175  emit scriptInfo("unselectVertices(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest.idx())+ "])");
176  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
177  }
178 
179  //Edge Selection
180  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_) ) {
181 
182  typename MeshT::FaceHalfedgeIter fhe_it(*_mesh, fh);
183 
184  typename MeshT::HalfedgeHandle closest(-1);
185  typename MeshT::Scalar closest_dist(-1);
186 
187  typename MeshT::Point pp =(typename MeshT::Point)_hit_point;
188 
189  for(; fhe_it.is_valid(); ++fhe_it) {
190 
191  // typename MeshT::HalfedgeHandle heh0 = _mesh->halfedge_handle(*fe_it, 0);
192  // typename MeshT::HalfedgeHandle heh1 = _mesh->halfedge_handle(*fe_it, 1);
193 
194  typename MeshT::Point lp0 = _mesh->point(_mesh->to_vertex_handle (*fhe_it));
195  typename MeshT::Point lp1 = _mesh->point(_mesh->from_vertex_handle(*fhe_it));
196 
197  double dist_new = ACG::Geometry::distPointLineSquared(pp, lp0, lp1);
198 
199  if(dist_new <closest_dist || closest_dist == -1) {
200 
201  // save closest Edge
202  closest_dist = dist_new;
203  closest = *fhe_it;
204  }
205  }
206 
207  typename MeshT::EdgeHandle closest_eh = _mesh->edge_handle(closest);
208 
209  if(_primitiveType & edgeType_) {
210 
211  _mesh->status(closest_eh).set_selected(!_mesh->status(closest_eh).selected());
212 
213  if(_mesh->status(closest_eh).selected())
214  emit scriptInfo("selectEdges(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest_eh.idx())+ "])");
215  else
216  emit scriptInfo("unselectEdges(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest_eh.idx())+ "])");
217  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
218  } else {
219  _mesh->status(closest).set_selected(!_mesh->status(closest).selected());
220 
221  if(_mesh->status(closest).selected())
222  emit scriptInfo("selectHalfedges(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest.idx())+ "])");
223  else
224  emit scriptInfo("unselectHalfedges(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(closest.idx())+ "])");
225  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
226  }
227  }
228 
229  //Face Selection
230  if(_primitiveType & faceType_) {
231  _mesh->status(fh).set_selected(!_mesh->status(fh).selected());
232 
233  if(_mesh->status(fh).selected())
234  emit scriptInfo("selectFaces(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(fh.idx())+ "])");
235  else
236  emit scriptInfo("unselectFaces(ObjectId(" + QString::number(_objectId) + ") , [" + QString::number(fh.idx())+ "])");
237  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
238  }
239 }
240 
241 //***********************************************************************************
242 
253 template <class MeshT>
255  int _objectId ,
256  int _target_idx ,
257  typename MeshT::Point _hitpoint,
258  double _radius,
259  PrimitiveType _primitiveType,
260  bool _deselection) {
261 
262 
263  const float sqr_radius = _radius * _radius;
264 
265  // select or deselect primitives
266  const bool sel = !_deselection;
267 
268  // TODO:: replace with unordered set if c++11 is our standard
269  std::set< typename MeshT::FaceHandle > visited;
270 
271  typename MeshT::FaceHandle hitface = _mesh->face_handle(_target_idx);
272 
273  if(!hitface.is_valid())
274  return;
275 
276  visited.insert(hitface);
277 
278 
279  std::vector<typename MeshT::FaceHandle> face_handles;
280  face_handles.reserve(50);
281  face_handles.push_back(hitface);
282 
283 
284  // find primitives to be selected
285  while(!face_handles.empty()) {
286  typename MeshT::FaceHandle fh = face_handles.back();
287  visited.insert(fh);
288  face_handles.pop_back();
289 
290 
291  // Check how many points of the new face lie inside the sphere
292  unsigned int fVertices = 0;
293 
294  // Test the halfedges of this face:
295  std::vector<typename MeshT::EdgeHandle> edge_handles;
296 
297  for(typename MeshT::FaceHalfedgeIter fh_it(*_mesh,fh); fh_it.is_valid(); ++fh_it) {
298 
299  const typename MeshT::VertexHandle vh = _mesh->from_vertex_handle(*fh_it);
300 
301  if((_mesh->point(vh) - _hitpoint).sqrnorm() <= sqr_radius) {
302 
303  // Select one vertex here, the other vertex will be selected on one of the other halfedges
304  if(_primitiveType & vertexType_)
305  _mesh->status(vh).set_selected(sel);
306 
307 
308  if((_mesh->point(_mesh->to_vertex_handle(*fh_it))- _hitpoint).sqrnorm()<= sqr_radius)
309  edge_handles.push_back(_mesh->edge_handle(*fh_it));
310 
311  fVertices++;
312  }
313 
314  }
315 
316 
317  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_)) {
319 
320  for( size_t i=0; i < edge_handles.size(); i++) {
321  if (_primitiveType & halfedgeType_)
322  if(!_mesh->has_face_normals() || std::abs(_mesh->calc_dihedral_angle_fast(edge_handles[i])) >= dihedral_angle_threshold_)
323  {
324  _mesh->status( _mesh->halfedge_handle(edge_handles[i],0) ).set_selected(sel) ;
325  _mesh->status( _mesh->halfedge_handle(edge_handles[i],1) ).set_selected(sel) ;
326  }
327 
328  if (_primitiveType & edgeType_)
329  if(!_mesh->has_face_normals() || std::abs(_mesh->calc_dihedral_angle_fast(edge_handles[i])) >= dihedral_angle_threshold_)
330  _mesh->status(edge_handles[i]).set_selected(sel);
331  }
332 
333  }
334 
335  if(_primitiveType & faceType_) {
336 
337  // If all vertices of the face are inside the sphere, we can select the face as well
338  if( _mesh->valence(fh ) == fVertices) {
339  _mesh->status(fh).set_selected(sel);
340  }
341  }
342 
343  //if something was tagged also check the 1-ring
344  if( fVertices > 0) {
345 
346  // _mesh->property(checkedProp, *ff_it)= true;
347  for(typename MeshT::FaceFaceIter ff_it(*_mesh,fh); ff_it.is_valid(); ++ff_it) {
348  if ( visited.count(*ff_it) == 0 )
349  face_handles.push_back(*ff_it);
350  }
351 
352  }
353 
354  }
355 
356  // Collect all updates into one update call
357  UpdateType update(UPDATE_NONE);
358 
359  if(_primitiveType & vertexType_)
360  update |= UPDATE_SELECTION_VERTICES;
361 
362 
363  if(_primitiveType & edgeType_)
364  update |= UPDATE_SELECTION_EDGES;
365 
366  if(_primitiveType & halfedgeType_)
367  update |= UPDATE_SELECTION_HALFEDGES;
368 
369  if(_primitiveType & faceType_)
370  update |= UPDATE_SELECTION_FACES;
371 
372  // Run the update
373  emit updatedObject(_objectId, update);
374 
375 }
376 
377 //***********************************************************************************
378 
389 template<class MeshT>
390 bool MeshObjectSelectionPlugin::volumeSelection(MeshT* _mesh, int _objectId, ACG::GLState& _state, QRegion *_region,
391  PrimitiveType _primitiveType, bool _deselection) {
392  ACG::Vec3d proj;
393  bool rv = false;
394 
395  //reset tagged status
396  typename MeshT::VertexIter v_it, v_end(_mesh->vertices_end());
397  for(v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it)
398  _mesh->status(*v_it).set_tagged(false);
399 
400  //tag all vertices that are projected into region
401  for(v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it) {
402 
403  proj = _state.project(_mesh->point(*v_it));
404 
405  if(_region->contains(QPoint((int)proj[0], _state.context_height()- (int)proj[1]))) {
406 
407  _mesh->status(*v_it).set_tagged(true);
408  rv = true;
409  if(_primitiveType & vertexType_) {
410  _mesh->status(*v_it).set_selected(!_deselection);
411  }
412  }
413  }
414 
415  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_) ) {
417  typename MeshT::EdgeIter e_it, e_end(_mesh->edges_end());
418  for(e_it=_mesh->edges_begin(); e_it!=e_end; ++e_it) {
419 
420  if(_mesh->status(_mesh->to_vertex_handle(_mesh->halfedge_handle(*e_it, 0))).tagged()||
421  _mesh->status(_mesh->to_vertex_handle(_mesh->halfedge_handle(*e_it, 1))).tagged()) {
422 
423  if(_primitiveType & edgeType_)
424  if(!_mesh->has_face_normals() || std::abs(_mesh->calc_dihedral_angle_fast(*e_it)) >= dihedral_angle_threshold_)
425  _mesh->status(*e_it).set_selected(!_deselection);
426 
427  if(_primitiveType & halfedgeType_)
428  if(!_mesh->has_face_normals() || std::abs(_mesh->calc_dihedral_angle_fast(*e_it)) >= dihedral_angle_threshold_)
429  {
430  _mesh->status(_mesh->halfedge_handle(*e_it,0)).set_selected(!_deselection);
431  _mesh->status(_mesh->halfedge_handle(*e_it,1)).set_selected(!_deselection);
432  }
433  }
434  }
435  }
436 
437  if(_primitiveType & faceType_) {
438  typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
439  for(f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
440 
441  bool select = false;
442  for(typename MeshT::FaceVertexIter fv_it(*_mesh,*f_it); fv_it.is_valid(); ++fv_it)
443  if(_mesh->status(*fv_it).tagged())
444  select = true;
445 
446  if(select)
447  _mesh->status(*f_it).set_selected(!_deselection);
448  }
449  }
450 
451  if(_primitiveType & vertexType_)
452  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
453  if(_primitiveType & edgeType_)
454  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
455  if(_primitiveType & halfedgeType_)
456  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
457  if(_primitiveType & faceType_)
458  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
459 
460  return rv;
461 }
462 
463 //***********************************************************************************
464 
472 template<class MeshT>
473 void MeshObjectSelectionPlugin::closestBoundarySelection(MeshT* _mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection) {
474 
475  typename MeshT::VertexHandle vh = _mesh->vertex_handle(_vh);
476 
477  if(vh.is_valid()) {
478  //get boundary vertex
479  typename MeshT::VertexHandle vhBound = MeshNavigation::findClosestBoundary(_mesh , vh);
480  if(vhBound.is_valid()) {
481 
482  //walk around the boundary and select primitves
484  if(!_mesh->get_property_handle(visited,"Visited Vertices"))
485  _mesh->add_property(visited, "Visited Vertices");
486 
487  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
488  for(v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it)
489  _mesh->property(visited, *v_it)= false;
490 
491  std::stack<typename MeshT::VertexHandle> stack;
492  stack.push(vhBound);
493 
494  while(!stack.empty()) {
495 
496  typename MeshT::VertexHandle vh = stack.top();
497  stack.pop();
498 
499  if(_mesh->property(visited,vh))
500  continue;
501 
502  //find outgoing boundary-edges
503  for(typename MeshT::VertexOHalfedgeIter voh_it(*_mesh,vh); voh_it.is_valid(); ++voh_it) {
504 
505  if(_mesh->is_boundary(_mesh->edge_handle(*voh_it))) {
506 
507  stack.push(_mesh->to_vertex_handle(*voh_it));
508 
509  if(_primitiveTypes & edgeType_)
510  _mesh->status(_mesh->edge_handle(*voh_it)).set_selected(!_deselection);
511 
512  if(_primitiveTypes & halfedgeType_) {
513  typename MeshT::HalfedgeHandle heh = *voh_it;
514  if(!_mesh->is_boundary(heh))heh = _mesh->opposite_halfedge_handle(heh);
515  _mesh->status(heh).set_selected(!_deselection);
516  }
517  }
518 
519  if(_primitiveTypes & faceType_) {
520  typename MeshT::FaceHandle f1 = _mesh->face_handle(*voh_it);
521  typename MeshT::FaceHandle f2 = _mesh->face_handle(_mesh->opposite_halfedge_handle(*voh_it));
522  if(f1.is_valid())_mesh->status(f1).set_selected(!_deselection);
523  if(f2.is_valid())_mesh->status(f2).set_selected(!_deselection);
524  }
525  }
526 
527  _mesh->property(visited,vh)= true;
528 
529  if(_primitiveTypes & vertexType_)
530  _mesh->status(vh).set_selected(!_deselection);
531  }
532  _mesh->remove_property(visited);
533 
534 
535  } else {
536  emit log(LOGERR, tr("Unable to find boundary."));
537  }
538  } else {
539  emit log(LOGERR, tr("Invalid vertex handle."));
540  }
541 }
542 
543 //***********************************************************************************
544 
554 template<class MeshT>
556  MeshT* _mesh, int _objectId, uint _fh, double _maxAngle,
557  PrimitiveType _primitiveTypes, bool _deselection) {
558 
559  // reset tagged status
560  typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
561  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
562  _mesh->status(*f_it).set_tagged(false);
563 
564  std::vector<typename MeshT::FaceHandle> face_handles;
565 
566 
567  typename MeshT::FaceHandle hitFace = typename MeshT::FaceHandle(_fh);
568  face_handles.reserve(50);
569  face_handles.push_back(hitFace);
570  _mesh->status(hitFace).set_tagged(true);
571 
572  typename MeshT::Point n1 = _mesh->normal(hitFace);
573 
574  double maxAngle = OpenMesh::deg_to_rad(_maxAngle);
575 
576  while (!face_handles.empty()) {
577  typename MeshT::FaceHandle fh = face_handles.back();
578  face_handles.pop_back();
579 
580  for (typename MeshT::FaceFaceIter ff_it(*_mesh,fh) ; ff_it.is_valid() ; ++ff_it) {
581 
582  // Check if already tagged
583  if (_mesh->status(*ff_it).tagged())
584  continue;
585 
586  typename MeshT::Point n2 = _mesh->normal(*ff_it);
587 
588  double angle = acos(n1 | n2);
589 
590  if (angle <= maxAngle) {
591  _mesh->status(*ff_it).set_tagged(true);
592  face_handles.push_back(*ff_it);
593  }
594  }
595  }
596 
597  // now select all tagged primitives
598  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
599  if (_mesh->status(*f_it).tagged()) {
600 
601  if(_primitiveTypes & vertexType_) {
602  for (typename MeshT::FaceVertexIter fv_it(*_mesh,*f_it) ; fv_it.is_valid(); ++fv_it)
603  _mesh->status(*fv_it).set_selected(!_deselection);
604  }
605 
606  if(_primitiveTypes & edgeType_) {
607  for (typename MeshT::FaceEdgeIter fe_it(*_mesh,*f_it) ; fe_it.is_valid(); ++fe_it)
608  _mesh->status(*fe_it).set_selected(!_deselection);
609  }
610 
611  if(_primitiveTypes & halfedgeType_) {
612  for (typename MeshT::FaceHalfedgeIter fhe_it(*_mesh,*f_it) ; fhe_it.is_valid(); ++fhe_it)
613  _mesh->status(*fhe_it).set_selected(!_deselection);
614  }
615 
616  if(_primitiveTypes & faceType_) {
617  _mesh->status(*f_it).set_selected(!_deselection);
618  }
619  }
620  }
621 
622 
623  if(_primitiveTypes & vertexType_)
624  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
625  if(_primitiveTypes & edgeType_)
626  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
627  if(_primitiveTypes & halfedgeType_)
628  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
629  if(_primitiveTypes & faceType_)
630  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
631 }
632 
633 //***********************************************************************************
634 
643 template<class MeshT>
645  MeshT* _mesh, int _objectId, uint _fh, ACG::Vec3d& _hit_point,
646  PrimitiveType _primitiveType) {
647 
648  typename MeshT::FaceHandle fh = _mesh->face_handle(_fh);
649 
650  if(!fh.is_valid())
651  return;
652 
653  //Vertex Selection
654  if(_primitiveType & vertexType_) {
655 
657  _mesh->add_property(visited);
658 
659  typename MeshT::VertexIter v_it;
660  typename MeshT::VertexIter v_end = _mesh->vertices_end();
661 
662  // Initialize vertex tag
663  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it)
664  _mesh->property(visited, *v_it) = false;
665 
666  // Get some vertex incident to the clicked face
667  typename MeshT::VertexHandle current = *(_mesh->fv_iter(fh));
668  if(!current.is_valid())
669  return;
670 
671  std::set<typename MeshT::VertexHandle> unprocessed;
672  unprocessed.insert(current);
673 
674  while( !unprocessed.empty() ) {
675 
676  // Select current vertex
677  current = *unprocessed.begin();
678  _mesh->status(current).set_selected(!(_mesh->status(current)).selected());
679  _mesh->property(visited, current) = true;
680  unprocessed.erase(current);
681 
682  // Go over all neighbors
683  for(typename MeshT::VertexVertexIter vv_it = _mesh->vv_iter(current); vv_it.is_valid(); ++vv_it) {
684  if(_mesh->property(visited, *vv_it) == true) continue;
685  unprocessed.insert(*vv_it);
686  }
687 
688  }
689 
690  _mesh->remove_property(visited);
691  }
692 
693  //Edge Selection
694  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_ ) ) {
695 
697  _mesh->add_property(visited);
698 
699  typename MeshT::FaceIter f_it;
700  typename MeshT::FaceIter f_end = _mesh->faces_end();
701 
702  // Initialize face tag
703  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it)
704  _mesh->property(visited, *f_it) = false;
705 
706 
707  typename MeshT::FaceHandle current = fh;
708 
709  std::set<typename MeshT::FaceHandle> unprocessed;
710  unprocessed.insert(current);
711 
712  typename MeshT::EdgeHandle firstEdge = *(_mesh->fe_iter(fh));
713  if(!firstEdge.is_valid()) return;
714  bool selected = _mesh->status(firstEdge).selected();
715 
716  while( !unprocessed.empty() ) {
717 
718  // Select all edges incident to current face
719  current = *unprocessed.begin();
720  for(typename MeshT::FaceHalfedgeIter fh_it = _mesh->fh_iter(current); fh_it.is_valid(); ++fh_it) {
721  if(_primitiveType & halfedgeType_) {
722  _mesh->status(*fh_it).set_selected(!(_mesh->status(*fh_it)).selected());
723  }
724  if(_primitiveType & edgeType_) {
725  _mesh->status(_mesh->edge_handle(*fh_it)).set_selected(!selected);
726  }
727  }
728 
729  _mesh->property(visited, current) = true;
730  unprocessed.erase(current);
731 
732  // Go over all neighbors
733  for(typename MeshT::FaceFaceIter ff_it = _mesh->ff_iter(current); ff_it.is_valid(); ++ff_it) {
734  if(_mesh->property(visited, *ff_it) == true) continue;
735  unprocessed.insert(*ff_it);
736  }
737 
738  }
739 
740  _mesh->remove_property(visited);
741  }
742 
743  //Face Selection
744  if(_primitiveType & faceType_) {
745 
747  _mesh->add_property(visited);
748 
749  typename MeshT::FaceIter f_it;
750  typename MeshT::FaceIter f_end = _mesh->faces_end();
751 
752  // Initialize face tag
753  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it)
754  _mesh->property(visited, *f_it) = false;
755 
756 
757  typename MeshT::FaceHandle current = fh;
758 
759  std::set<typename MeshT::FaceHandle> unprocessed;
760  unprocessed.insert(current);
761 
762  while( !unprocessed.empty() ) {
763 
764  // Select all edges incident to current face
765  current = *unprocessed.begin();
766  _mesh->status(current).set_selected(!(_mesh->status(current)).selected());
767  _mesh->property(visited, current) = true;
768  unprocessed.erase(current);
769 
770  // Go over all neighbors
771  for(typename MeshT::FaceFaceIter ff_it = _mesh->ff_iter(current); ff_it.is_valid(); ++ff_it) {
772  if(_mesh->property(visited, *ff_it) == true) continue;
773  unprocessed.insert(*ff_it);
774  }
775 
776  }
777 
778  _mesh->remove_property(visited);
779  }
780  if(_primitiveType & vertexType_)
781  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
782  if(_primitiveType & edgeType_)
783  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
784  if(_primitiveType & halfedgeType_)
785  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
786  if(_primitiveType & faceType_)
787  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
788 }
789 
790 //***********************************************************************************
791 
801 template< typename MeshT >
803  PrimitiveType _primitiveTypes,
804  int _red,
805  int _green,
806  int _blue,
807  int _alpha) {
808 
809  typename MeshT::Color color = OpenMesh::color_cast<OpenMesh::Vec4f,OpenMesh::Vec4uc>(OpenMesh::Vec4uc(_red,_green,_blue,_alpha));
810  /*color[0] = _red;
811  color[1] = _green;
812  color[2] = _blue;
813  color[3] = _alpha;
814  */
815 
816  if (_primitiveTypes & vertexType_) {
817  typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
818 
819  // Request vertex color attribute
820  if ( !_mesh->has_vertex_colors() )
821  _mesh->request_vertex_colors();
822 
823  for (v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it)
824  if ( _mesh->status(*v_it).selected() )
825  _mesh->set_color(*v_it, color);
826  }
827 
828  if (_primitiveTypes & faceType_) {
829  typename MeshT::FaceIter f_it, f_end( _mesh->faces_end() );
830 
831  // Request face color attribute
832  if ( !_mesh->has_face_colors() )
833  _mesh->request_face_colors();
834 
835  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
836  if ( _mesh->status(*f_it).selected() )
837  _mesh->set_color(*f_it, color);
838  }
839 
840  if (_primitiveTypes & edgeType_) {
841  typename MeshT::EdgeIter e_it, e_end( _mesh->edges_end() );
842 
843  // Request edge color attribute
844  if ( !_mesh->has_edge_colors() )
845  _mesh->request_edge_colors();
846 
847  for (e_it=_mesh->edges_begin(); e_it!=e_end; ++e_it)
848  if ( _mesh->status(*e_it).selected() )
849  _mesh->set_color(*e_it, color);
850  }
851 
852  if (_primitiveTypes & halfedgeType_) {
853  typename MeshT::HalfedgeIter h_it, h_end( _mesh->halfedges_end() );
854 
855  // Request halfedge color attribute
856  if ( !_mesh->has_halfedge_colors() )
857  _mesh->request_halfedge_colors();
858 
859  for (h_it=_mesh->halfedges_begin(); h_it!=h_end; ++h_it)
860  if ( _mesh->status(*h_it).selected() )
861  _mesh->set_color(*h_it, color);
862  }
863 }
864 
865 //***********************************************************************************
866 
867 
875 template<class MeshT>
876 void MeshObjectSelectionPlugin::createMeshFromSelection(MeshT& _mesh, MeshT& _newMesh, PrimitiveType _primitiveType)
877 {
878 
879  // Tracking during copy action
881  _mesh.add_property(copyHandle, "copyHandle Property");
882 
883  //first copy vertices
884  typename MeshT::VertexIter v_it, v_end = _mesh.vertices_end();
885  for (v_it = _mesh.vertices_begin(); v_it != v_end; ++v_it) {
886 
887  bool copy = false;
888 
889  //if the vertex belongs to the selection copy it
890  if (_primitiveType & vertexType_)
891  copy = _mesh.status(*v_it).selected();
892  else if (_primitiveType & edgeType_) {
893 
894  for (typename MeshT::VertexOHalfedgeIter voh_it(_mesh, *v_it); voh_it.is_valid(); ++voh_it)
895  if (_mesh.status(_mesh.edge_handle(*voh_it)).selected()) {
896  copy = true;
897  break;
898  }
899 
900  } else if (_primitiveType & faceType_) {
901  for (typename MeshT::VertexFaceIter vf_it(_mesh, *v_it); vf_it.is_valid(); ++vf_it)
902  if (_mesh.status(*vf_it).selected()) {
903  copy = true;
904  break;
905  }
906  }
907 
908  //copy it
909  if (copy) {
910  _mesh.property(copyHandle, *v_it) = _newMesh.add_vertex(_mesh.point(*v_it));
911  } else {
912  _mesh.property(copyHandle, *v_it) = typename MeshT::VertexHandle(-1);
913  }
914  }
915 
916  //now check all faces
917  //if all vertices of the face exist in the new mesh -> copy it
918  typename MeshT::FaceIter f_it, f_end = _mesh.faces_end();
919  for (f_it = _mesh.faces_begin(); f_it != f_end; ++f_it) {
920 
921  std::vector<typename MeshT::VertexHandle> v;
922 
923  bool skip = false;
924 
925  for (typename MeshT::FaceVertexIter fv_it(_mesh, *f_it); fv_it.is_valid(); ++fv_it)
926  if (_mesh.property(copyHandle, *fv_it).is_valid())
927  v.push_back(_mesh.property(copyHandle, *fv_it));
928  else {
929  skip = true;
930  break;
931  }
932 
933  if (!skip)
934  _newMesh.add_face(v);
935  }
936 
937  _newMesh.update_normals();
938 
939  _mesh.remove_property(copyHandle);
940 
941 }
942 
943 template<class MeshT>
944 void MeshObjectSelectionPlugin::selectVerticesByValue(MeshT* _mesh, QString _component, bool _greater, double _value)
945 {
946 
947  //first copy vertices
948  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
949  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it) {
950  const typename MeshT::Point p = _mesh->point(*v_it);
951 
952  bool select = false;
953 
954  if (_component.contains("x",Qt::CaseInsensitive) ) {
955  select = (p[0] > _value);
956  } else if (_component.contains("y",Qt::CaseInsensitive) ) {
957  select = (p[1] > _value);
958  } else if (_component.contains("z",Qt::CaseInsensitive) ) {
959  select = (p[2] > _value);
960  } else {
961  emit log(LOGERR,tr("selectVerticesByValue, undefined component ") + _component );
962  }
963 
964 
965  // invert if requested
966  if (! _greater )
967  select = !select;
968 
969  // set selection status only if the vertex was previously unselected
970  if ( ! _mesh->status(*v_it).selected() )
971  _mesh->status(*v_it).set_selected(select);
972 
973  }
974 
975 }
976 
const UpdateType UPDATE_SELECTION_VERTICES(UpdateTypeSet(1)<< 5)
Vertex selection has changed.
Update type class.
Definition: UpdateType.hh:60
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
VectorT< float, 4 > Vec4f
Definition: Vector11T.hh:830
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
int context_height() const
get gl context height
Definition: GLState.hh:830
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
bool deleteSelection(MeshT *_mesh, PrimitiveType _primitiveType)
Delete all selected elements of a mesh.
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:83
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.
void selectVerticesByValue(int _objectId, QString _component, bool _greater, double _value)
Select vertices by their value.
Functions for getting information about a mesh.
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
Vec::value_type distPointLineSquared(const Vec &_p, const Vec &_v0, const Vec &_v1, Vec *_min_v)
squared distance from point _p to line segment (_v0,_v1)
Definition: Algorithms.cc:290
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
const UpdateType UPDATE_NONE(UpdateTypeSet(0))
Empty update for empty initialization of update type.
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
void update_dihedral_angle_threshold_from_ui()
set dihedral angle threshold for edge selection
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
VectorT< unsigned char, 4 > Vec4uc
Definition: Vector11T.hh:820
const UpdateType UPDATE_SELECTION_HALFEDGES(UpdateTypeSet(1)<< 7)
Halfedge selection has changed.
void floodFillSelection(MeshT *_mesh, int _objectId, uint _fh, double _maxAngle, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are connected (and do not exceed the maximum dihedral angle) ...
void paintSphereSelection(MeshT *_mesh, int _objectId, int _target_idx, typename MeshT::Point _hitpoint, double _radius, PrimitiveType _primitiveTypes, bool _deselection)
Use the event to paint selection with a sphere.
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(1)<< 6)
Edge selection has changed.
const UpdateType UPDATE_SELECTION_FACES(UpdateTypeSet(1)<< 8)
Face selection has changed.
double dihedral_angle_threshold_
Handle to selection environment.
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.