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
45 #include <MeshTools/MeshNavigationT.hh>
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>
106 void MeshObjectSelectionPlugin::update_regions(MeshType* _mesh) {
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>
254 void MeshObjectSelectionPlugin::paintSphereSelection(MeshT* _mesh ,
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 update_dihedral_angle_threshold_from_ui();
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_) ) {
416 update_dihedral_angle_threshold_from_ui();
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
483 OpenMesh::VPropHandleT<bool> visited;
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>
555 void MeshObjectSelectionPlugin::floodFillSelection(
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>
644 void MeshObjectSelectionPlugin::componentsMeshSelection(
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
656 OpenMesh::VPropHandleT<bool> visited;
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
696 OpenMesh::FPropHandleT<bool> visited;
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
746 OpenMesh::FPropHandleT<bool> visited;
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 >
802 void MeshObjectSelectionPlugin::colorizeSelection(MeshT* _mesh,
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
880 OpenMesh::VPropHandleT<typename MeshT::VertexHandle> copyHandle;
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
UPDATE_SELECTION_VERTICES
const UpdateType UPDATE_SELECTION_VERTICES(UpdateTypeSet(1)<< 5)
Vertex selection has changed.
UpdateType
Update type class.
Definition: UpdateType.hh:60
MeshObjectSelectionPlugin::faceType_
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:579
MeshObjectSelectionPlugin::update_regions
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
OpenMesh::Vec4f
VectorT< float, 4 > Vec4f
Definition: Vector11T.hh:830
MeshObjectSelectionPlugin::vertexType_
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
Definition: MeshObjectSelectionPlugin.hh:576
MeshObjectSelectionPlugin::volumeSelection
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
Definition: MeshObjectSelectionPluginT_impl.hh:390
ACG::GLState::context_height
int context_height() const
get gl context height
Definition: GLState.hh:830
MeshObjectSelectionPlugin::createMeshFromSelection
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
Definition: MeshObjectSelectionPluginT_impl.hh:876
MeshObjectSelectionPlugin::deleteSelection
bool deleteSelection(MeshT *_mesh, PrimitiveType _primitiveType)
Delete all selected elements of a mesh.
Definition: MeshObjectSelectionPluginT_impl.hh:57
OpenMesh::Attributes::Color
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:83
MeshObjectSelectionPlugin::colorizeSelection
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.
Definition: MeshObjectSelectionPluginT_impl.hh:802
LOGERR
Definition: LoggingInterface.hh:96
MeshObjectSelectionPlugin::selectVerticesByValue
void selectVerticesByValue(int _objectId, QString _component, bool _greater, double _value)
Select vertices by their value.
Definition: VertexSelection.cc:577
MeshNavigationT.hh
Functions for getting information about a mesh.
MeshObjectSelectionPlugin::closestBoundarySelection
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
Definition: MeshObjectSelectionPluginT_impl.hh:473
ACG::Geometry::distPointLineSquared
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
ACG::GLState
Definition: GLState.hh:213
MeshObjectSelectionPlugin::toggleMeshSelection
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
Definition: MeshObjectSelectionPluginT_impl.hh:146
UPDATE_NONE
const UpdateType UPDATE_NONE(UpdateTypeSet(0))
Empty update for empty initialization of update type.
MeshObjectSelectionPlugin::edgeType_
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:577
MeshObjectSelectionPlugin::update_dihedral_angle_threshold_from_ui
void update_dihedral_angle_threshold_from_ui()
set dihedral angle threshold for edge selection
Definition: MeshObjectSelectionPlugin.cc:2302
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
MeshObjectSelectionPlugin::componentsMeshSelection
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
Definition: MeshObjectSelectionPluginT_impl.hh:644
OpenMesh::Vec4uc
VectorT< unsigned char, 4 > Vec4uc
Definition: Vector11T.hh:820
UPDATE_SELECTION_HALFEDGES
const UpdateType UPDATE_SELECTION_HALFEDGES(UpdateTypeSet(1)<< 7)
Halfedge selection has changed.
OpenMesh::VectorT
Definition: Vector11T.hh:83
MeshObjectSelectionPlugin::floodFillSelection
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) ...
Definition: MeshObjectSelectionPluginT_impl.hh:555
MeshObjectSelectionPlugin::paintSphereSelection
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.
Definition: MeshObjectSelectionPluginT_impl.hh:254
UPDATE_SELECTION_EDGES
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(1)<< 6)
Edge selection has changed.
UPDATE_SELECTION_FACES
const UpdateType UPDATE_SELECTION_FACES(UpdateTypeSet(1)<< 8)
Face selection has changed.
MeshObjectSelectionPlugin::dihedral_angle_threshold_
double dihedral_angle_threshold_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:604
MeshObjectSelectionPlugin::halfedgeType_
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:578
OpenMesh::FPropHandleT< bool >
OpenMesh::VPropHandleT< bool >