Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
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
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
477 OpenMesh::VPropHandleT<bool> visited;
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>
549 void MeshObjectSelectionPlugin::floodFillSelection(
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>
638 void MeshObjectSelectionPlugin::componentsMeshSelection(
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
650 OpenMesh::VPropHandleT<bool> visited;
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
690 OpenMesh::FPropHandleT<bool> visited;
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
740 OpenMesh::FPropHandleT<bool> visited;
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 >
796 void MeshObjectSelectionPlugin::colorizeSelection(MeshT* _mesh,
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
874 OpenMesh::VPropHandleT<typename MeshT::VertexHandle> copyHandle;
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
OpenMesh::Attributes::Color
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:88
MeshObjectSelectionPlugin::colorizeSelection
void colorizeSelection(MeshT *_mesh, PrimitiveType _primitiveTypes, int _red, int _green, int _blue, int _alpha)
Colorize the selection.
Definition: MeshObjectSelectionPluginT.cc:796
ACG::GLState::context_height
int context_height() const
get gl context height
Definition: GLState.hh:833
UPDATE_SELECTION_VERTICES
const UpdateType UPDATE_SELECTION_VERTICES(UpdateTypeSet(1)<< 5)
Vertex selection has changed.
LOGERR
Definition: LoggingInterface.hh:107
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.cc:254
MeshObjectSelectionPlugin::faceType_
SelectionInterface::PrimitiveType faceType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:570
MeshObjectSelectionPlugin::deleteSelection
bool deleteSelection(MeshT *_mesh, PrimitiveType _primitiveType)
Delete all selected elements of a mesh.
Definition: MeshObjectSelectionPluginT.cc:57
UpdateType
Update type class.
Definition: UpdateType.hh:70
MeshObjectSelectionPlugin::volumeSelection
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
Definition: MeshObjectSelectionPluginT.cc:387
MeshObjectSelectionPlugin::createMeshFromSelection
void createMeshFromSelection(MeshT &_mesh, MeshT &_newMesh, PrimitiveType _primitiveType)
Create a new mesh from the selection.
Definition: MeshObjectSelectionPluginT.cc:870
MeshObjectSelectionPlugin::selectVerticesByValue
void selectVerticesByValue(int _objectId, QString _component, bool _greater, double _value)
Select vertices by their value.
Definition: VertexSelection.cc:577
UPDATE_NONE
const UpdateType UPDATE_NONE(UpdateTypeSet(0))
Empty update for empty initialization of update type.
ACG::GLState
Definition: GLState.hh:220
MeshNavigationT.hh
Functions for getting information about a mesh.
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.cc:549
OpenMesh::VPropHandleT< bool >
OpenMesh::VectorT
Definition: Vector11T.hh:83
UPDATE_SELECTION_EDGES
const UpdateType UPDATE_SELECTION_EDGES(UpdateTypeSet(1)<< 6)
Edge selection has changed.
MeshObjectSelectionPlugin::edgeType_
SelectionInterface::PrimitiveType edgeType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:568
UPDATE_SELECTION_HALFEDGES
const UpdateType UPDATE_SELECTION_HALFEDGES(UpdateTypeSet(1)<< 7)
Halfedge selection has changed.
MeshObjectSelectionPlugin::componentsMeshSelection
void componentsMeshSelection(MeshT *_mesh, int _objectId, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Connected component mesh selection.
Definition: MeshObjectSelectionPluginT.cc:638
OpenMesh::Vec4uc
VectorT< unsigned char, 4 > Vec4uc
Definition: Vector11T.hh:778
OpenMesh::FPropHandleT< bool >
MeshObjectSelectionPlugin::vertexType_
SelectionInterface::PrimitiveType vertexType_
Primitive type handles:
Definition: MeshObjectSelectionPlugin.hh:567
MeshObjectSelectionPlugin::halfedgeType_
SelectionInterface::PrimitiveType halfedgeType_
Handle to selection environment.
Definition: MeshObjectSelectionPlugin.hh:569
MeshObjectSelectionPlugin::update_regions
void update_regions(MeshT *_mesh)
Update face selection to correspond to the vertex selection.
UPDATE_SELECTION_FACES
const UpdateType UPDATE_SELECTION_FACES(UpdateTypeSet(1)<< 8)
Face selection has changed.
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:638
MeshObjectSelectionPlugin::toggleMeshSelection
void toggleMeshSelection(int _objectId, MeshT *_mesh, uint _fh, ACG::Vec3d &_hit_point, PrimitiveType _primitiveType)
Toggle mesh selection.
Definition: MeshObjectSelectionPluginT.cc:146
OpenMesh::Vec4f
VectorT< float, 4 > Vec4f
Definition: Vector11T.hh:788
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:300
MeshObjectSelectionPlugin::closestBoundarySelection
void closestBoundarySelection(MeshT *_mesh, int _vh, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are incident to closest boundary.
Definition: MeshObjectSelectionPluginT.cc:467