Developer Documentation
MeshObjectSelectionPluginT.cc
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_)) {
318 
319 
320  for( size_t i=0; i < edge_handles.size(); i++) {
321  if (_primitiveType & halfedgeType_) {
322  _mesh->status( _mesh->halfedge_handle(edge_handles[i],0) ).set_selected(sel) ;
323  _mesh->status( _mesh->halfedge_handle(edge_handles[i],1) ).set_selected(sel) ;
324  }
325 
326  if (_primitiveType & edgeType_)
327  _mesh->status(edge_handles[i]).set_selected(sel);
328  }
329 
330  }
331 
332  if(_primitiveType & faceType_) {
333 
334  // If all vertices of the face are inside the sphere, we can select the face as well
335  if( _mesh->valence(fh ) == fVertices) {
336  _mesh->status(fh).set_selected(sel);
337  }
338  }
339 
340  //if something was tagged also check the 1-ring
341  if( fVertices > 0) {
342 
343  // _mesh->property(checkedProp, *ff_it)= true;
344  for(typename MeshT::FaceFaceIter ff_it(*_mesh,fh); ff_it.is_valid(); ++ff_it) {
345  if ( visited.count(*ff_it) == 0 )
346  face_handles.push_back(*ff_it);
347  }
348 
349  }
350 
351  }
352 
353  // Collect all updates into one update call
354  UpdateType update(UPDATE_NONE);
355 
356  if(_primitiveType & vertexType_)
357  update |= UPDATE_SELECTION_VERTICES;
358 
359 
360  if(_primitiveType & edgeType_)
361  update |= UPDATE_SELECTION_EDGES;
362 
363  if(_primitiveType & halfedgeType_)
364  update |= UPDATE_SELECTION_HALFEDGES;
365 
366  if(_primitiveType & faceType_)
367  update |= UPDATE_SELECTION_FACES;
368 
369  // Run the update
370  emit updatedObject(_objectId, update);
371 
372 }
373 
374 //***********************************************************************************
375 
386 template<class MeshT>
387 bool MeshObjectSelectionPlugin::volumeSelection(MeshT* _mesh, int _objectId, ACG::GLState& _state, QRegion *_region,
388  PrimitiveType _primitiveType, bool _deselection) {
389  ACG::Vec3d proj;
390  bool rv = false;
391 
392  //reset tagged status
393  typename MeshT::VertexIter v_it, v_end(_mesh->vertices_end());
394  for(v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it)
395  _mesh->status(*v_it).set_tagged(false);
396 
397  //tag all vertices that are projected into region
398  for(v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it) {
399 
400  proj = _state.project(_mesh->point(*v_it));
401 
402  if(_region->contains(QPoint((int)proj[0], _state.context_height()- (int)proj[1]))) {
403 
404  _mesh->status(*v_it).set_tagged(true);
405  rv = true;
406  if(_primitiveType & vertexType_) {
407  _mesh->status(*v_it).set_selected(!_deselection);
408  }
409  }
410  }
411 
412  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_) ) {
413  typename MeshT::EdgeIter e_it, e_end(_mesh->edges_end());
414  for(e_it=_mesh->edges_begin(); e_it!=e_end; ++e_it) {
415 
416  if(_mesh->status(_mesh->to_vertex_handle(_mesh->halfedge_handle(*e_it, 0))).tagged()||
417  _mesh->status(_mesh->to_vertex_handle(_mesh->halfedge_handle(*e_it, 1))).tagged()) {
418 
419  if(_primitiveType & edgeType_)
420  _mesh->status(*e_it).set_selected(!_deselection);
421 
422  if(_primitiveType & halfedgeType_) {
423 
424  _mesh->status(_mesh->halfedge_handle(*e_it,0)).set_selected(!_deselection);
425  _mesh->status(_mesh->halfedge_handle(*e_it,1)).set_selected(!_deselection);
426  }
427  }
428  }
429  }
430 
431  if(_primitiveType & faceType_) {
432  typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
433  for(f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
434 
435  bool select = false;
436  for(typename MeshT::FaceVertexIter fv_it(*_mesh,*f_it); fv_it.is_valid(); ++fv_it)
437  if(_mesh->status(*fv_it).tagged())
438  select = true;
439 
440  if(select)
441  _mesh->status(*f_it).set_selected(!_deselection);
442  }
443  }
444 
445  if(_primitiveType & vertexType_)
446  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
447  if(_primitiveType & edgeType_)
448  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
449  if(_primitiveType & halfedgeType_)
450  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
451  if(_primitiveType & faceType_)
452  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
453 
454  return rv;
455 }
456 
457 //***********************************************************************************
458 
466 template<class MeshT>
467 void MeshObjectSelectionPlugin::closestBoundarySelection(MeshT* _mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection) {
468 
469  typename MeshT::VertexHandle vh = _mesh->vertex_handle(_vh);
470 
471  if(vh.is_valid()) {
472  //get boundary vertex
473  typename MeshT::VertexHandle vhBound = MeshNavigation::findClosestBoundary(_mesh , vh);
474  if(vhBound.is_valid()) {
475 
476  //walk around the boundary and select primitves
478  if(!_mesh->get_property_handle(visited,"Visited Vertices"))
479  _mesh->add_property(visited, "Visited Vertices");
480 
481  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
482  for(v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it)
483  _mesh->property(visited, *v_it)= false;
484 
485  std::stack<typename MeshT::VertexHandle> stack;
486  stack.push(vhBound);
487 
488  while(!stack.empty()) {
489 
490  typename MeshT::VertexHandle vh = stack.top();
491  stack.pop();
492 
493  if(_mesh->property(visited,vh))
494  continue;
495 
496  //find outgoing boundary-edges
497  for(typename MeshT::VertexOHalfedgeIter voh_it(*_mesh,vh); voh_it.is_valid(); ++voh_it) {
498 
499  if(_mesh->is_boundary(_mesh->edge_handle(*voh_it))) {
500 
501  stack.push(_mesh->to_vertex_handle(*voh_it));
502 
503  if(_primitiveTypes & edgeType_)
504  _mesh->status(_mesh->edge_handle(*voh_it)).set_selected(!_deselection);
505 
506  if(_primitiveTypes & halfedgeType_) {
507  typename MeshT::HalfedgeHandle heh = *voh_it;
508  if(!_mesh->is_boundary(heh))heh = _mesh->opposite_halfedge_handle(heh);
509  _mesh->status(heh).set_selected(!_deselection);
510  }
511  }
512 
513  if(_primitiveTypes & faceType_) {
514  typename MeshT::FaceHandle f1 = _mesh->face_handle(*voh_it);
515  typename MeshT::FaceHandle f2 = _mesh->face_handle(_mesh->opposite_halfedge_handle(*voh_it));
516  if(f1.is_valid())_mesh->status(f1).set_selected(!_deselection);
517  if(f2.is_valid())_mesh->status(f2).set_selected(!_deselection);
518  }
519  }
520 
521  _mesh->property(visited,vh)= true;
522 
523  if(_primitiveTypes & vertexType_)
524  _mesh->status(vh).set_selected(!_deselection);
525  }
526  _mesh->remove_property(visited);
527 
528 
529  } else {
530  emit log(LOGERR, tr("Unable to find boundary."));
531  }
532  } else {
533  emit log(LOGERR, tr("Invalid vertex handle."));
534  }
535 }
536 
537 //***********************************************************************************
538 
548 template<class MeshT>
550  MeshT* _mesh, int _objectId, uint _fh, double _maxAngle,
551  PrimitiveType _primitiveTypes, bool _deselection) {
552 
553  // reset tagged status
554  typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
555  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
556  _mesh->status(*f_it).set_tagged(false);
557 
558  std::vector<typename MeshT::FaceHandle> face_handles;
559 
560 
561  typename MeshT::FaceHandle hitFace = typename MeshT::FaceHandle(_fh);
562  face_handles.reserve(50);
563  face_handles.push_back(hitFace);
564  _mesh->status(hitFace).set_tagged(true);
565 
566  typename MeshT::Point n1 = _mesh->normal(hitFace);
567 
568  double maxAngle = OpenMesh::deg_to_rad(_maxAngle);
569 
570  while (!face_handles.empty()) {
571  typename MeshT::FaceHandle fh = face_handles.back();
572  face_handles.pop_back();
573 
574  for (typename MeshT::FaceFaceIter ff_it(*_mesh,fh) ; ff_it.is_valid() ; ++ff_it) {
575 
576  // Check if already tagged
577  if (_mesh->status(*ff_it).tagged())
578  continue;
579 
580  typename MeshT::Point n2 = _mesh->normal(*ff_it);
581 
582  double angle = acos(n1 | n2);
583 
584  if (angle <= maxAngle) {
585  _mesh->status(*ff_it).set_tagged(true);
586  face_handles.push_back(*ff_it);
587  }
588  }
589  }
590 
591  // now select all tagged primitives
592  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it) {
593  if (_mesh->status(*f_it).tagged()) {
594 
595  if(_primitiveTypes & vertexType_) {
596  for (typename MeshT::FaceVertexIter fv_it(*_mesh,*f_it) ; fv_it.is_valid(); ++fv_it)
597  _mesh->status(*fv_it).set_selected(!_deselection);
598  }
599 
600  if(_primitiveTypes & edgeType_) {
601  for (typename MeshT::FaceEdgeIter fe_it(*_mesh,*f_it) ; fe_it.is_valid(); ++fe_it)
602  _mesh->status(*fe_it).set_selected(!_deselection);
603  }
604 
605  if(_primitiveTypes & halfedgeType_) {
606  for (typename MeshT::FaceHalfedgeIter fhe_it(*_mesh,*f_it) ; fhe_it.is_valid(); ++fhe_it)
607  _mesh->status(*fhe_it).set_selected(!_deselection);
608  }
609 
610  if(_primitiveTypes & faceType_) {
611  _mesh->status(*f_it).set_selected(!_deselection);
612  }
613  }
614  }
615 
616 
617  if(_primitiveTypes & vertexType_)
618  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
619  if(_primitiveTypes & edgeType_)
620  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
621  if(_primitiveTypes & halfedgeType_)
622  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
623  if(_primitiveTypes & faceType_)
624  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
625 }
626 
627 //***********************************************************************************
628 
637 template<class MeshT>
639  MeshT* _mesh, int _objectId, uint _fh, ACG::Vec3d& _hit_point,
640  PrimitiveType _primitiveType) {
641 
642  typename MeshT::FaceHandle fh = _mesh->face_handle(_fh);
643 
644  if(!fh.is_valid())
645  return;
646 
647  //Vertex Selection
648  if(_primitiveType & vertexType_) {
649 
651  _mesh->add_property(visited);
652 
653  typename MeshT::VertexIter v_it;
654  typename MeshT::VertexIter v_end = _mesh->vertices_end();
655 
656  // Initialize vertex tag
657  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it)
658  _mesh->property(visited, *v_it) = false;
659 
660  // Get some vertex incident to the clicked face
661  typename MeshT::VertexHandle current = *(_mesh->fv_iter(fh));
662  if(!current.is_valid())
663  return;
664 
665  std::set<typename MeshT::VertexHandle> unprocessed;
666  unprocessed.insert(current);
667 
668  while( !unprocessed.empty() ) {
669 
670  // Select current vertex
671  current = *unprocessed.begin();
672  _mesh->status(current).set_selected(!(_mesh->status(current)).selected());
673  _mesh->property(visited, current) = true;
674  unprocessed.erase(current);
675 
676  // Go over all neighbors
677  for(typename MeshT::VertexVertexIter vv_it = _mesh->vv_iter(current); vv_it.is_valid(); ++vv_it) {
678  if(_mesh->property(visited, *vv_it) == true) continue;
679  unprocessed.insert(*vv_it);
680  }
681 
682  }
683 
684  _mesh->remove_property(visited);
685  }
686 
687  //Edge Selection
688  if( (_primitiveType & edgeType_) || (_primitiveType & halfedgeType_ ) ) {
689 
691  _mesh->add_property(visited);
692 
693  typename MeshT::FaceIter f_it;
694  typename MeshT::FaceIter f_end = _mesh->faces_end();
695 
696  // Initialize face tag
697  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it)
698  _mesh->property(visited, *f_it) = false;
699 
700 
701  typename MeshT::FaceHandle current = fh;
702 
703  std::set<typename MeshT::FaceHandle> unprocessed;
704  unprocessed.insert(current);
705 
706  typename MeshT::EdgeHandle firstEdge = *(_mesh->fe_iter(fh));
707  if(!firstEdge.is_valid()) return;
708  bool selected = _mesh->status(firstEdge).selected();
709 
710  while( !unprocessed.empty() ) {
711 
712  // Select all edges incident to current face
713  current = *unprocessed.begin();
714  for(typename MeshT::FaceHalfedgeIter fh_it = _mesh->fh_iter(current); fh_it.is_valid(); ++fh_it) {
715  if(_primitiveType & halfedgeType_) {
716  _mesh->status(*fh_it).set_selected(!(_mesh->status(*fh_it)).selected());
717  }
718  if(_primitiveType & edgeType_) {
719  _mesh->status(_mesh->edge_handle(*fh_it)).set_selected(!selected);
720  }
721  }
722 
723  _mesh->property(visited, current) = true;
724  unprocessed.erase(current);
725 
726  // Go over all neighbors
727  for(typename MeshT::FaceFaceIter ff_it = _mesh->ff_iter(current); ff_it.is_valid(); ++ff_it) {
728  if(_mesh->property(visited, *ff_it) == true) continue;
729  unprocessed.insert(*ff_it);
730  }
731 
732  }
733 
734  _mesh->remove_property(visited);
735  }
736 
737  //Face Selection
738  if(_primitiveType & faceType_) {
739 
741  _mesh->add_property(visited);
742 
743  typename MeshT::FaceIter f_it;
744  typename MeshT::FaceIter f_end = _mesh->faces_end();
745 
746  // Initialize face tag
747  for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it)
748  _mesh->property(visited, *f_it) = false;
749 
750 
751  typename MeshT::FaceHandle current = fh;
752 
753  std::set<typename MeshT::FaceHandle> unprocessed;
754  unprocessed.insert(current);
755 
756  while( !unprocessed.empty() ) {
757 
758  // Select all edges incident to current face
759  current = *unprocessed.begin();
760  _mesh->status(current).set_selected(!(_mesh->status(current)).selected());
761  _mesh->property(visited, current) = true;
762  unprocessed.erase(current);
763 
764  // Go over all neighbors
765  for(typename MeshT::FaceFaceIter ff_it = _mesh->ff_iter(current); ff_it.is_valid(); ++ff_it) {
766  if(_mesh->property(visited, *ff_it) == true) continue;
767  unprocessed.insert(*ff_it);
768  }
769 
770  }
771 
772  _mesh->remove_property(visited);
773  }
774  if(_primitiveType & vertexType_)
775  emit updatedObject(_objectId, UPDATE_SELECTION_VERTICES);
776  if(_primitiveType & edgeType_)
777  emit updatedObject(_objectId, UPDATE_SELECTION_EDGES);
778  if(_primitiveType & halfedgeType_)
779  emit updatedObject(_objectId, UPDATE_SELECTION_HALFEDGES);
780  if(_primitiveType & faceType_)
781  emit updatedObject(_objectId, UPDATE_SELECTION_FACES);
782 }
783 
784 //***********************************************************************************
785 
795 template< typename MeshT >
797  PrimitiveType _primitiveTypes,
798  int _red,
799  int _green,
800  int _blue,
801  int _alpha) {
802 
803  typename MeshT::Color color = OpenMesh::color_cast<OpenMesh::Vec4f,OpenMesh::Vec4uc>(OpenMesh::Vec4uc(_red,_green,_blue,_alpha));
804  /*color[0] = _red;
805  color[1] = _green;
806  color[2] = _blue;
807  color[3] = _alpha;
808  */
809 
810  if (_primitiveTypes & vertexType_) {
811  typename MeshT::VertexIter v_it, v_end=_mesh->vertices_end();
812 
813  // Request vertex color attribute
814  if ( !_mesh->has_vertex_colors() )
815  _mesh->request_vertex_colors();
816 
817  for (v_it=_mesh->vertices_begin(); v_it!=v_end; ++v_it)
818  if ( _mesh->status(*v_it).selected() )
819  _mesh->set_color(*v_it, color);
820  }
821 
822  if (_primitiveTypes & faceType_) {
823  typename MeshT::FaceIter f_it, f_end( _mesh->faces_end() );
824 
825  // Request face color attribute
826  if ( !_mesh->has_face_colors() )
827  _mesh->request_face_colors();
828 
829  for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
830  if ( _mesh->status(*f_it).selected() )
831  _mesh->set_color(*f_it, color);
832  }
833 
834  if (_primitiveTypes & edgeType_) {
835  typename MeshT::EdgeIter e_it, e_end( _mesh->edges_end() );
836 
837  // Request edge color attribute
838  if ( !_mesh->has_edge_colors() )
839  _mesh->request_edge_colors();
840 
841  for (e_it=_mesh->edges_begin(); e_it!=e_end; ++e_it)
842  if ( _mesh->status(*e_it).selected() )
843  _mesh->set_color(*e_it, color);
844  }
845 
846  if (_primitiveTypes & halfedgeType_) {
847  typename MeshT::HalfedgeIter h_it, h_end( _mesh->halfedges_end() );
848 
849  // Request halfedge color attribute
850  if ( !_mesh->has_halfedge_colors() )
851  _mesh->request_halfedge_colors();
852 
853  for (h_it=_mesh->halfedges_begin(); h_it!=h_end; ++h_it)
854  if ( _mesh->status(*h_it).selected() )
855  _mesh->set_color(*h_it, color);
856  }
857 }
858 
859 //***********************************************************************************
860 
861 
869 template<class MeshT>
870 void MeshObjectSelectionPlugin::createMeshFromSelection(MeshT& _mesh, MeshT& _newMesh, PrimitiveType _primitiveType)
871 {
872 
873  // Tracking during copy action
875  _mesh.add_property(copyHandle, "copyHandle Property");
876 
877  //first copy vertices
878  typename MeshT::VertexIter v_it, v_end = _mesh.vertices_end();
879  for (v_it = _mesh.vertices_begin(); v_it != v_end; ++v_it) {
880 
881  bool copy = false;
882 
883  //if the vertex belongs to the selection copy it
884  if (_primitiveType & vertexType_)
885  copy = _mesh.status(*v_it).selected();
886  else if (_primitiveType & edgeType_) {
887 
888  for (typename MeshT::VertexOHalfedgeIter voh_it(_mesh, *v_it); voh_it.is_valid(); ++voh_it)
889  if (_mesh.status(_mesh.edge_handle(*voh_it)).selected()) {
890  copy = true;
891  break;
892  }
893 
894  } else if (_primitiveType & faceType_) {
895  for (typename MeshT::VertexFaceIter vf_it(_mesh, *v_it); vf_it.is_valid(); ++vf_it)
896  if (_mesh.status(*vf_it).selected()) {
897  copy = true;
898  break;
899  }
900  }
901 
902  //copy it
903  if (copy) {
904  _mesh.property(copyHandle, *v_it) = _newMesh.add_vertex(_mesh.point(*v_it));
905  } else {
906  _mesh.property(copyHandle, *v_it) = typename MeshT::VertexHandle(-1);
907  }
908  }
909 
910  //now check all faces
911  //if all vertices of the face exist in the new mesh -> copy it
912  typename MeshT::FaceIter f_it, f_end = _mesh.faces_end();
913  for (f_it = _mesh.faces_begin(); f_it != f_end; ++f_it) {
914 
915  std::vector<typename MeshT::VertexHandle> v;
916 
917  bool skip = false;
918 
919  for (typename MeshT::FaceVertexIter fv_it(_mesh, *f_it); fv_it.is_valid(); ++fv_it)
920  if (_mesh.property(copyHandle, *fv_it).is_valid())
921  v.push_back(_mesh.property(copyHandle, *fv_it));
922  else {
923  skip = true;
924  break;
925  }
926 
927  if (!skip)
928  _newMesh.add_face(v);
929  }
930 
931  _newMesh.update_normals();
932 
933  _mesh.remove_property(copyHandle);
934 
935 }
936 
937 template<class MeshT>
938 void MeshObjectSelectionPlugin::selectVerticesByValue(MeshT* _mesh, QString _component, bool _greater, double _value)
939 {
940 
941  //first copy vertices
942  typename MeshT::VertexIter v_it, v_end = _mesh->vertices_end();
943  for (v_it = _mesh->vertices_begin(); v_it != v_end; ++v_it) {
944  const typename MeshT::Point p = _mesh->point(*v_it);
945 
946  bool select = false;
947 
948  if (_component.contains("x",Qt::CaseInsensitive) ) {
949  select = (p[0] > _value);
950  } else if (_component.contains("y",Qt::CaseInsensitive) ) {
951  select = (p[1] > _value);
952  } else if (_component.contains("z",Qt::CaseInsensitive) ) {
953  select = (p[2] > _value);
954  } else {
955  emit log(LOGERR,tr("selectVerticesByValue, undefined component ") + _component );
956  }
957 
958 
959  // invert if requested
960  if (! _greater )
961  select = !select;
962 
963  // set selection status only if the vertex was previously unselected
964  if ( ! _mesh->status(*v_it).selected() )
965  _mesh->status(*v_it).set_selected(select);
966 
967  }
968 
969 }
970 
bool deleteSelection(MeshT *_mesh, PrimitiveType _primitiveType)
Delete all selected elements of a mesh.
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.
int context_height() const
get gl context height
Definition: GLState.hh:833
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:300
const UpdateType UPDATE_SELECTION_HALFEDGES(UpdateTypeSet(1)<< 7)
Halfedge selection has changed.
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
const UpdateType UPDATE_SELECTION_FACES(UpdateTypeSet(1)<< 8)
Face selection has changed.
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:638
Update type class.
Definition: UpdateType.hh:70
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
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) ...
VectorT< float, 4 > Vec4f
Definition: Vector11T.hh:788
Functions for getting information about a mesh.
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
void selectVerticesByValue(int _objectId, QString _component, bool _greater, double _value)
Select vertices by their value.
VectorT< unsigned char, 4 > Vec4uc
Definition: Vector11T.hh:778
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:88
const UpdateType UPDATE_SELECTION_VERTICES(UpdateTypeSet(1)<< 5)
Vertex selection has changed.
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
const UpdateType UPDATE_NONE(UpdateTypeSet(0))
Empty update for empty initialization of update type.
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(1)<< 6)
Edge selection has changed.
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.