Developer Documentation
VolumeMeshSelectionPlugin.cc
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44#include "VolumeMeshSelectionPlugin.hh"
45#include "widgets/VolMeshParamWidget.hh"
47
48// Primitive type icons
49#define VERTEX_TYPE "selection_vertex.png"
50#define EDGE_TYPE "selection_edge.png"
51#define FACE_TYPE "selection_face.png"
52#define CELL_TYPE "datacontrol-boundingBox.png"
53// Custom selection mode
54#define COLUMN_SELECTION "column-selection.png"
55#define SHEET_SELECTION "sheet-selection.png"
56// =======================================
57// Define operations
58// =======================================
59// Vertices:
60#define V_SELECT_ALL "Select All Vertices"
61#define V_DESELECT_ALL "Deselect All Vertices"
62#define V_INVERT "Invert Vertex Selection"
63#define V_DELETE "Delete Selected Vertices"
64// Edges:
65#define E_SELECT_ALL "Select All Edges"
66#define E_DESELECT_ALL "Deselect All Edges"
67#define E_INVERT "Invert Edge Selection"
68#define E_DELETE "Delete Selected Edges"
69// Faces:
70#define F_SELECT_ALL "Select All Faces"
71#define F_DESELECT_ALL "Deselect All Faces"
72#define F_INVERT "Invert Face Selection"
73#define F_DELETE "Delete Selected Faces"
74// Cells:
75#define C_SELECT_ALL "Select All Cells"
76#define C_DESELECT_ALL "Deselect All Cells"
77#define C_INVERT "Invert Cell Selection"
78#define C_DELETE "Delete Selected Cells"
79
82 vertexType_(0), edgeType_(0), allSupportedTypes_(0), parameterWidget_(nullptr), max_angle_(2*M_PI),
83 lastPickedCell_(HexahedralMesh::InvalidCellHandle), lastPickedOrientation_(0) {
84}
85
86//==============================================================================================
87
89}
90
91//==============================================================================================
92
93void VolumeMeshSelectionPlugin::initializePlugin() {
94
95 // Tell core about all scriptable slots
97 if(!OpenFlipper::Options::nogui())
99}
100
101//==============================================================================================
102
103void VolumeMeshSelectionPlugin::pluginsInitialized() {
104 // Create new selection environment for volumemeshs
105 // and register volumemesh data type for the environment.
106
107 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
108
109 emit
110 addSelectionEnvironment("VolumeMesh Selections", "Select volume mesh primitives.",
111 iconPath + "datacontrol-boundingBox.png", environmentHandle_);
112
113 // Register mesh object types
114 emit
116 emit
118#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
119 emit
121#endif
122
123 emit addPrimitiveType(environmentHandle_, "Select Volume Mesh Vertices", iconPath + VERTEX_TYPE, vertexType_);
124 emit addPrimitiveType(environmentHandle_, "Select Volume Mesh Edges", iconPath + EDGE_TYPE, edgeType_);
125 emit addPrimitiveType(environmentHandle_, "Select Volume Mesh Faces", iconPath + FACE_TYPE, faceType_);
126 emit addPrimitiveType(environmentHandle_, "Select Volume Mesh Cells", iconPath + CELL_TYPE, cellType_);
127
128 emit addCustomSelectionMode(environmentHandle_, "Column Selection", "Select entire column of cells",
129 iconPath + COLUMN_SELECTION, cellType_, columnSelectionHandle_);
130
131 emit
132 addCustomSelectionMode(environmentHandle_, "Sheet Selection", "Select entire sheet of cells",
133 iconPath + SHEET_SELECTION, cellType_, sheetSelectionHandle_);
134
137
138 // Determine, which selection modes are requested
139 emit showToggleSelectionMode(environmentHandle_, true, allSupportedTypes_);
140
141 emit showVolumeLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
142 emit showFloodFillSelectionMode(environmentHandle_, true, floodFillSupportedTypes_);
143
144 // Define vertex operations
145 QStringList vertexOperations;
146 vertexOperations.append(V_SELECT_ALL);
147 vertexOperations.append(V_DESELECT_ALL);
148 vertexOperations.append(V_INVERT);
149 vertexOperations.append(V_DELETE);
150
151 QStringList edgeOperations;
152 edgeOperations.append(E_SELECT_ALL);
153 edgeOperations.append(E_DESELECT_ALL);
154 edgeOperations.append(E_INVERT);
155 edgeOperations.append(E_DELETE);
156
157 QStringList faceOperations;
158 faceOperations.append(F_SELECT_ALL);
159 faceOperations.append(F_DESELECT_ALL);
160 faceOperations.append(F_INVERT);
161 faceOperations.append(F_DELETE);
162
163 QStringList cellOperations;
164 cellOperations.append(C_SELECT_ALL);
165 cellOperations.append(C_DESELECT_ALL);
166 cellOperations.append(C_INVERT);
167 cellOperations.append(C_DELETE);
168
169 emit
170 addSelectionOperations(environmentHandle_, vertexOperations, "Vertex Operations", vertexType_);
171 emit
172 addSelectionOperations(environmentHandle_, edgeOperations, "Edge Operations", edgeType_);
173 emit
174 addSelectionOperations(environmentHandle_, faceOperations, "Face Operations", faceType_);
175 emit
176 addSelectionOperations(environmentHandle_, cellOperations, "Cell Operations", cellType_);
177
178 if(!OpenFlipper::Options::nogui())
179 emit addSelectionParameters(environmentHandle_, parameterWidget_, "Selection Parameters");
180
181 // Register key shortcuts:
182
183 // Select (a)ll
184 emit
185 registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
186 // (C)lear selection
187 emit
188 registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
189 // (I)nvert selection
190 emit
191 registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
192 // Delete selected entities
193 emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
194}
195
196//==============================================================================================
197
199
200 /*
201 * TODO: Complete this function for all supported types
202 */
203}
204
205//==============================================================================================
206
208 SelectionInterface::PrimitiveType t = 0u;
209 emit getActivePrimitiveType(t);
210 return (t & vertexType_) > 0;
211}
212
214 SelectionInterface::PrimitiveType t = 0u;
215 emit getActivePrimitiveType(t);
216 return (t & edgeType_) > 0;
217}
218
220 SelectionInterface::PrimitiveType t = 0u;
221 emit getActivePrimitiveType(t);
222 return (t & faceType_) > 0;
223}
224
226 SelectionInterface::PrimitiveType t = 0u;
227 emit getActivePrimitiveType(t);
228 return (t & cellType_) > 0;
229}
230
231//==============================================================================================
232
234
235 SelectionInterface::PrimitiveType type = 0u;
236 emit getActivePrimitiveType(type);
237
238 if((type & allSupportedTypes_) == 0)
239 return;
240
241 // Test if operation should be applied to target objects only
242 bool targetsOnly = false;
243 emit targetObjectsOnly(targetsOnly);
246
248#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
249 data_type |= DATA_TETRAHEDRAL_MESH;
250#endif
251
252 if (_operation == V_SELECT_ALL) {
253 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
254 o_it != PluginFunctions::objectsEnd(); ++o_it) {
255 if (o_it->visible())
256 selectAllVertices(o_it->id());
257 }
258 } else if (_operation == V_DESELECT_ALL) {
259 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
260 o_it != PluginFunctions::objectsEnd(); ++o_it) {
261 if (o_it->visible())
262 deselectAllVertices(o_it->id());
263 }
264 } else if (_operation == V_INVERT) {
265 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
266 o_it != PluginFunctions::objectsEnd(); ++o_it) {
267 if (o_it->visible())
268 invertVertexSelection(o_it->id());
269 }
270 } else if (_operation == V_DELETE) {
271 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
272 o_it != PluginFunctions::objectsEnd(); ++o_it) {
273 if (o_it->visible())
274 deleteSelectedVertices(o_it->id());
275 }
276 } else if (_operation == E_SELECT_ALL) {
277 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
278 o_it != PluginFunctions::objectsEnd(); ++o_it) {
279 if (o_it->visible())
280 selectAllEdges(o_it->id());
281 }
282 } else if (_operation == E_DESELECT_ALL) {
283 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
284 o_it != PluginFunctions::objectsEnd(); ++o_it) {
285 if (o_it->visible())
286 deselectAllEdges(o_it->id());
287 }
288 } else if (_operation == E_INVERT) {
289 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
290 o_it != PluginFunctions::objectsEnd(); ++o_it) {
291 if (o_it->visible())
292 invertEdgeSelection(o_it->id());
293 }
294 } else if (_operation == E_DELETE) {
295 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
296 o_it != PluginFunctions::objectsEnd(); ++o_it) {
297 if (o_it->visible())
298 deleteSelectedEdges(o_it->id());
299 }
300 } else if (_operation == F_SELECT_ALL) {
301 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
302 o_it != PluginFunctions::objectsEnd(); ++o_it) {
303 if (o_it->visible())
304 selectAllFaces(o_it->id());
305 }
306 } else if (_operation == F_DESELECT_ALL) {
307 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
308 o_it != PluginFunctions::objectsEnd(); ++o_it) {
309 if (o_it->visible())
310 deselectAllFaces(o_it->id());
311 }
312 } else if (_operation == F_INVERT) {
313 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
314 o_it != PluginFunctions::objectsEnd(); ++o_it) {
315 if (o_it->visible())
316 invertFaceSelection(o_it->id());
317 }
318 } else if (_operation == F_DELETE) {
319 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
320 o_it != PluginFunctions::objectsEnd(); ++o_it) {
321 if (o_it->visible())
322 deleteSelectedFaces(o_it->id());
323 }
324 } else if (_operation == C_SELECT_ALL) {
325 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
326 o_it != PluginFunctions::objectsEnd(); ++o_it) {
327 if (o_it->visible())
328 selectAllCells(o_it->id());
329 }
330 } else if (_operation == C_DESELECT_ALL) {
331 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
332 o_it != PluginFunctions::objectsEnd(); ++o_it) {
333 if (o_it->visible())
334 deselectAllCells(o_it->id());
335 }
336 } else if (_operation == C_INVERT) {
337 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
338 o_it != PluginFunctions::objectsEnd(); ++o_it) {
339 if (o_it->visible())
340 invertCellSelection(o_it->id());
341 }
342 } else if (_operation == C_DELETE) {
343 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
344 o_it != PluginFunctions::objectsEnd(); ++o_it) {
345 if (o_it->visible())
346 deleteSelectedCells(o_it->id());
347 }
348 }
349}
350
351//==============================================================================================
352
354 SelectionInterface::PrimitiveType _currentType, bool _deselect) {
355
356 // Return if none of the currently active types is handled by this plugin
357 if((_currentType & allSupportedTypes_) == 0)
358 return;
359
360 // Return if mouse event is not a left-button click
361 if(_event->button() != Qt::LeftButton)
362 return;
363
364 size_t node_idx, target_idx;
365 ACG::Vec3d hit_point;
366
367 BaseObjectData* object = 0;
368
369 if(_currentType & vertexType_) {
370 // Perform picking
371 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_VERTEX, _event->pos(),
372 node_idx, target_idx, &hit_point)
373 && PluginFunctions::getPickedObject(node_idx, object);
374
375 if(successfullyPicked) {
376
377 if (getStatus(object) == NULL)
378 return;
379
380 OpenVolumeMesh::StatusAttrib& status = *getStatus(object);
381
382 if(status[OpenVolumeMesh::VertexHandle(target_idx)].selected() || _deselect)
383 status[OpenVolumeMesh::VertexHandle(target_idx)].set_selected(false);
384 else
385 status[OpenVolumeMesh::VertexHandle(target_idx)].set_selected(true);
386
387 emit updatedObject(object->id(), UPDATE_SELECTION);
388 }
389 }
390
391 if(_currentType & edgeType_) {
392 // Perform picking
393 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_EDGE, _event->pos(), node_idx,
394 target_idx, &hit_point)
395 && PluginFunctions::getPickedObject(node_idx, object);
396
397 if(successfullyPicked) {
398
399 if (getStatus(object) == NULL)
400 return;
401
402 OpenVolumeMesh::StatusAttrib& status = *getStatus(object);
403
404 if(status[OpenVolumeMesh::EdgeHandle(target_idx)].selected() || _deselect)
405 status[OpenVolumeMesh::EdgeHandle(target_idx)].set_selected(false);
406 else
407 status[OpenVolumeMesh::EdgeHandle(target_idx)].set_selected(true);
408
409 emit updatedObject(object->id(), UPDATE_SELECTION);
410 }
411 }
412
413 if(_currentType & faceType_) {
414 // Perform picking
415 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx,
416 target_idx, &hit_point)
417 && PluginFunctions::getPickedObject(node_idx, object);
418
419 if(successfullyPicked) {
420
421 if (getStatus(object) == NULL)
422 return;
423
424 OpenVolumeMesh::StatusAttrib& status = *getStatus(object);
425
426 if(status[OpenVolumeMesh::FaceHandle(target_idx)].selected() || _deselect)
427 status[OpenVolumeMesh::FaceHandle(target_idx)].set_selected(false);
428 else
429 status[OpenVolumeMesh::FaceHandle(target_idx)].set_selected(true);
430
431 emit updatedObject(object->id(), UPDATE_SELECTION);
432 }
433 }
434
435 if(_currentType & cellType_) {
436
437 // Perform picking
438 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_CELL, _event->pos(), node_idx,
439 target_idx, &hit_point)
440 && PluginFunctions::getPickedObject(node_idx, object);
441
442 if(successfullyPicked) {
443
444 if (getStatus(object) == NULL)
445 return;
446
447 OpenVolumeMesh::StatusAttrib& status = *getStatus(object);
448
449 if(status[OpenVolumeMesh::CellHandle(target_idx)].selected() || _deselect) {
450 status[OpenVolumeMesh::CellHandle(target_idx)].set_selected(false);
451 } else {
452 status[OpenVolumeMesh::CellHandle(target_idx)].set_selected(true);
453 }
454
455 emit updatedObject(object->id(), UPDATE_SELECTION);
456 }
457 }
458}
459
460//==============================================================================================
461
463 PrimitiveType _currentType, bool _deselect)
464{
465 if ((_currentType & allSupportedTypes_) == 0) return;
466
467 if (_event->type() == QEvent::MouseButtonPress)
468 {
469 volumeLassoPoints_.append(_event->pos());
470 return;
471 }
472 else if (_event->type() == QEvent::MouseButtonDblClick)
473 {
475 bool updateGL = state.updateGL();
476 state.set_updateGL (false);
477
478 QPolygon p(volumeLassoPoints_);
479 QRegion region = QRegion(p);
480
481 SelectVolumeAction action(region, this, _currentType, _deselect, state);
483
484 state.set_updateGL(updateGL);
485
486 // Clear lasso points
487 volumeLassoPoints_.clear();
488 }
489}
490
492 PrimitiveType _currentType, bool _deselect)
493{
494 // Return if none of the currently active types is handled by this plugin
495 if ((_currentType & floodFillSupportedTypes_) == 0)
496 return;
497
498 size_t node_idx, target_idx;
499 ACG::Vec3d hit_point;
500
501 if(!OpenFlipper::Options::nogui())
502 max_angle_ = parameterWidget_->maxAngle->value();
503 // pick Anything to find all possible objects
505 _event->pos(), node_idx, target_idx, &hit_point))
506 {
507 BaseObjectData* object = 0;
508
509 if (PluginFunctions::getPickedObject(node_idx, object))
510 {
511 if (object->dataType() == DATA_POLYHEDRAL_MESH)
512 {
514 _event->pos(), node_idx, target_idx, &hit_point))
515 {
516 if (PluginFunctions::getPickedObject(node_idx, object))
517 {
518 if (object->dataType(DATA_POLYHEDRAL_MESH))
519 {
521 target_idx, max_angle_, _currentType, _deselect);//TODO max angle
522
523 emit updatedObject(object->id(), UPDATE_SELECTION);
524 }
525 }
526 }
527 }
528 else if(object->dataType() == DATA_HEXAHEDRAL_MESH)
529 {
531 _event->pos(), node_idx, target_idx, &hit_point))
532 {
533 if(PluginFunctions::getPickedObject(node_idx, object) )
534 {
535 if(object->dataType(DATA_HEXAHEDRAL_MESH))
536 {
538 target_idx, max_angle_, _currentType, _deselect);
539
540 emit updatedObject(object->id(), UPDATE_SELECTION);
541 }
542 }
543 }
544 }
545#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
546 else if(object->dataType() == DATA_TETRAHEDRAL_MESH)
547 {
549 _event->pos(), node_idx, target_idx, &hit_point))
550 {
551 if(PluginFunctions::getPickedObject(node_idx, object) )
552 {
554 {
556 target_idx, max_angle_, _currentType, _deselect);
557
558 emit updatedObject(object->id(), UPDATE_SELECTION);
559 }
560 }
561 }
562 }
563#endif
564 else
565 {
566 emit log(LOGERR, tr("floodFillSelection: Unsupported dataType"));
567 }
568 }
569 }
570}
571
574{
575 BaseObjectData* object = 0;
576 if (PluginFunctions::getPickedObject(_node->id(), object))
577 {
578 bool selected = false;
579 if (object->dataType(DATA_POLYHEDRAL_MESH))
580 {
582 selected = plugin_->volumeSelection(m, state_, &region_, type_, deselection_);
583
584 } else if(object->dataType(DATA_HEXAHEDRAL_MESH)) {
585
587 selected = plugin_->volumeSelection(m, state_, &region_, type_, deselection_);
588 }
589#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
590 else if(object->dataType(DATA_TETRAHEDRAL_MESH)) {
591
593 selected = plugin_->volumeSelection(m, state_, &region_, type_, deselection_);
594 }
595#endif
596
597 if (selected){
598 emit plugin_->updatedObject(object->id(), UPDATE_SELECTION);
599 }
600 }
601 return true;
602}
603
604//==============================================================================================
605
606void VolumeMeshSelectionPlugin::slotCustomSelection(QMouseEvent *_event, PrimitiveType _currentType,
607 QString _customIdentifier, bool _deselect) {
608
609 if(_customIdentifier != columnSelectionHandle_ && _customIdentifier != sheetSelectionHandle_)
610 return;
611
612 // Return if mouse event is not a left-button click
613 if(_event->button() != Qt::LeftButton || _event->type() != QEvent::MouseButtonPress)
614 return;
615
616 if(_customIdentifier == columnSelectionHandle_) {
617
618 ACG::Vec3d hit_point;
619
620 if(_currentType & cellType_) {
621
622 BaseObjectData* object = 0;
623
624 // Perform picking
625 size_t node_idx, target_idx;
626 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),
627 node_idx, target_idx, &hit_point)
628 && PluginFunctions::getPickedObject(node_idx, object);
629
630 if(successfullyPicked) {
631
633 if(!hexMeshObject) {
634 emit log(LOGERR, "Could not get hexahedral mesh object!");
635 return;
636 }
637 OpenVolumeMesh::StatusAttrib& status = hexMeshObject->status();
638
639 HexahedralMesh* hexMesh = hexMeshObject->mesh();
640
641 // Get first inside halfface
644 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
645 : hexMesh->halfface_handle(fh, 0));
646
647 while(!hexMesh->is_boundary(cif)) {
648 // Get associated cell
649 OpenVolumeMesh::CellHandle ch = hexMesh->incident_cell(cif);
650
651 if(status[ch].selected() || _deselect)
652 status[ch].set_selected(false);
653 else
654 status[ch].set_selected(true);
655
656 cif = hexMesh->opposite_halfface_handle_in_cell(cif, ch);
657 cif = hexMesh->opposite_halfface_handle(cif);
658 }
659
660 emit updatedObject(object->id(), UPDATE_SELECTION);
661 }
662 }
663 }
664
665 if(_customIdentifier == sheetSelectionHandle_) {
666
667 if(_currentType & cellType_) {
668
669 BaseObjectData* object = 0;
670 ACG::Vec3d hit_point;
671
672 // Perform picking
673 size_t node_idx, target_idx;
674 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),
675 node_idx, target_idx, &hit_point)
676 && PluginFunctions::getPickedObject(node_idx, object);
677
678 if(successfullyPicked) {
679
681 if(!hexMeshObject) {
682 emit log(LOGERR, "Could not get hexahedral mesh object!");
683 return;
684 }
685 OpenVolumeMesh::StatusAttrib& status = hexMeshObject->status();
686
687 HexahedralMesh* hexMesh = hexMeshObject->mesh();
688
689 // Get first inside halfface
692 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
693 : hexMesh->halfface_handle(fh, 0));
694
695 // Get picked cell
696 OpenVolumeMesh::CellHandle ch = hexMesh->incident_cell(cif);
697
698 if(lastPickedCell_ == HexahedralMesh::InvalidCellHandle) {
699
700 lastPickedCell_ = ch;
701 lastPickedOrientation_ = hexMesh->orientation(cif, ch);
702 status[lastPickedCell_].set_selected(!status[lastPickedCell_].selected());
703 emit updatedObject(object->id(), UPDATE_SELECTION);
704 } else {
705
706 // Select whole sheet
707 // Get orientation of common face
708 HFPair pair = getCommonFace(lastPickedCell_, ch, hexMesh);
709
710 unsigned char secondDir = hexMesh->orientation(pair.first, lastPickedCell_);
711 unsigned char orthDir = hexMesh->orthogonal_orientation(lastPickedOrientation_, secondDir);
712
713 orientationMap_.clear();
714 status[lastPickedCell_].set_selected(!status[lastPickedCell_].selected());
715
716 // Start with last picked cell
717 std::set<OpenVolumeMesh::CellHandle> unprocessed;
718 unprocessed.insert(lastPickedCell_);
719 std::set<OpenVolumeMesh::CellHandle> processed;
720
721 orientationMap_.insert(
722 std::pair<OpenVolumeMesh::CellHandle, unsigned char>(lastPickedCell_,
723 orthDir));
724
725 // Flood-fill cell sheet
726 while(!unprocessed.empty() ) {
727
728 OpenVolumeMesh::CellHandle cur_c = *unprocessed.begin();
729 unprocessed.erase(cur_c);
730 status[cur_c].set_selected(!status[cur_c].selected());
731 processed.insert(cur_c);
732
733 std::map<OpenVolumeMesh::CellHandle, unsigned char>::iterator f = orientationMap_.find(cur_c);
734 if(f == orientationMap_.end()) {
735 emit log(LOGERR, "Could not get orientation of current cell in sheet!");
736 return;
737 }
738 unsigned char od = f->second;
739
740 for(OpenVolumeMesh::CellSheetCellIter csc_it = hexMesh->csc_iter(cur_c, od); csc_it.valid(); ++csc_it) {
741 if(processed.count(*csc_it) > 0)
742 continue;
743
744 unsigned char new_o = getOrthogonalOrientationOfNeighborCell(cur_c, *csc_it, od, hexMesh);
745 orientationMap_.insert(std::pair<OpenVolumeMesh::CellHandle, unsigned char>(*csc_it, new_o));
746 unprocessed.insert(*csc_it);
747 }
748 }
749
750 lastPickedCell_ = HexahedralMesh::InvalidCellHandle;
751 emit updatedObject(object->id(), UPDATE_SELECTION);
752 }
753 }
754 }
755 }
756}
757
758//==============================================================================================
759
761 const OpenVolumeMesh::CellHandle& _ch2,
762 unsigned char _firstOrthDirection,
763 const HexahedralMesh* _mesh) const {
764
765 // Return orientation of halfface in _ch2 that corresponds to
766 // _firstOrthDirection in the first cell
767
768 OpenVolumeMesh::HalfFaceHandle firstOrthHF = _mesh->get_oriented_halfface(_firstOrthDirection, _ch1);
769 HFPair commonHF = getCommonFace(_ch1, _ch2, _mesh);
770
771 // Get edge that's shared on the orth side
772 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes1 = _mesh->halfface(firstOrthHF).halfedges();
773 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes2 = _mesh->halfface(commonHF.first).halfedges();
774 OpenVolumeMesh::HalfEdgeHandle sharedHE = HexahedralMesh::InvalidHalfEdgeHandle;
775 for(auto he_it1 : hes1) {
776 for(auto he_it2 : hes2) {
777 if(_mesh->edge_handle(he_it1) == _mesh->edge_handle(he_it2)) {
778 sharedHE = _mesh->opposite_halfedge_handle(he_it2);
779 break;
780 }
781 if(sharedHE != HexahedralMesh::InvalidHalfEdgeHandle)
782 break;
783 }
784 }
785
786 return _mesh->orientation(_mesh->adjacent_halfface_in_cell(commonHF.second, sharedHE), _ch2);
787}
788
789//==============================================================================================
790
792 const OpenVolumeMesh::CellHandle& _ch2,
793 const HexahedralMesh* _mesh) const {
794
795 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs1 = _mesh->cell(_ch1).halffaces();
796 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs2 = _mesh->cell(_ch2).halffaces();
797
798 for(auto hf_it1 : hfs1) {
799
800 for(auto hf_it2 : hfs2) {
801
802 if(_mesh->face_handle(hf_it1) == _mesh->face_handle(hf_it2)) {
803 return HFPair(hf_it1, hf_it2);
804 }
805 }
806 }
807
808 return HFPair(HexahedralMesh::InvalidHalfFaceHandle, HexahedralMesh::InvalidHalfFaceHandle);
809}
810
812{
813 PolyhedralMeshObject* polyMeshObj = NULL;
814 PluginFunctions::getObject(_objectId, polyMeshObj);
815 if (polyMeshObj != NULL)
816 return &polyMeshObj->status();
817
818 HexahedralMeshObject* hexMeshObj = NULL;
819 PluginFunctions::getObject(_objectId, hexMeshObj);
820 if (hexMeshObj != NULL)
821 return &hexMeshObj->status();
822
823#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
824 TetrahedralMeshObject* tetMeshObj = NULL;
825 PluginFunctions::getObject(_objectId, tetMeshObj);
826 if (tetMeshObj != NULL)
827 return &tetMeshObj->status();
828#endif
829
830 return NULL;
831}
832
834{
836 if (polyMeshObj != NULL)
837 return &polyMeshObj->status();
838
840 if (hexMeshObj != NULL)
841 return &hexMeshObj->status();
842
843#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
845 if (tetMeshObj != NULL)
846 return &tetMeshObj->status();
847#endif
848
849 emit log(LOGERR, tr("Neither polyhedral nor hexahedral nor tetrahedral mesh!"));
850 return NULL;
851}
852
854{
855 max_angle_ = _a;
856}
857
859{
860 return max_angle_;
861}
862
863//==============================================================================================
864
865void VolumeMeshSelectionPlugin::loadSelection(int _objId, const QString& _filename) {
866
867// // Load ini file
868// INIFile file;
869//
870// if(!file.connect(_filename, false)) {
871// emit log(LOGERR, QString("Could not read file '%1'!").arg(_filename));
872// return;
873// }
874//
875// // Load selection from file
876// loadIniFile(file, _objId);
877}
878
879//==============================================================================================
880
881void VolumeMeshSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
882 // From INI Interface
883 // Load plugin specific settings
884
885 BaseObjectData* bod = NULL;
887 if(!bod) {
888 emit log(LOGERR, "Could not get base object data!");
889 return;
890 }
891
892 QString section = QString("PolyhedralMeshSelection") + "//" + bod->name();
893 if(!_ini.section_exists(section)) {
894 return;
895 }
896
897 std::vector<int> ids;
898 // Load vertex selection:
899 _ini.get_entry(ids, section, "VertexSelection");
900 selectVertices(_id, ids);
901 ids.clear();
902 // Load edge selection:
903 _ini.get_entry(ids, section, "EdgeSelection");
904 selectEdges(_id, ids);
905 ids.clear();
906 // Load half-edge selection:
907 _ini.get_entry(ids, section, "HalfEdgeSelection");
908 selectHalfEdges(_id, ids);
909 ids.clear();
910 // Load face selection:
911 _ini.get_entry(ids, section, "FaceSelection");
912 selectFaces(_id, ids);
913 ids.clear();
914 // Load half-face selection:
915 _ini.get_entry(ids, section, "HalfFaceSelection");
916 selectHalfFaces(_id, ids);
917 ids.clear();
918 // Load cell selection:
919 _ini.get_entry(ids, section, "CellSelection");
920 selectCells(_id, ids);
921 ids.clear();
922}
923
924//==============================================================================================
925
926void VolumeMeshSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
927 // From INI Interface
928 // Save plugin specific settings
929
930 BaseObjectData* bod = NULL;
932 if(!bod) {
933 emit log(LOGERR, "Could not get base object data!");
934 return;
935 }
936
937 QString section = QString("PolyhedralMeshSelection") + "//" + bod->name();
938
939 _ini.add_entry(section, "VertexSelection", getVertexSelection(_id));
940 _ini.add_entry(section, "EdgeSelection", getEdgeSelection(_id));
941 _ini.add_entry(section, "HalfEdgeSelection", getHalfEdgeSelection(_id));
942 _ini.add_entry(section, "FaceSelection", getFaceSelection(_id));
943 _ini.add_entry(section, "HalfFaceSelection", getHalfFaceSelection(_id));
944 _ini.add_entry(section, "CellSelection", getCellSelection(_id));
945}
946
947//==============================================================================================
948
950
951 // Iterate over all polyhedral mesh objects in the scene and save
952 // the selections for all supported entity types
954#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
955 data_type |= DATA_TETRAHEDRAL_MESH;
956#endif
957
959 o_it != PluginFunctions::objectsEnd(); ++o_it) {
960
961 // Read section for each object
962 // Append object name to section identifier
963 QString section = QString("PolyhedralMeshSelection") + "//" + o_it->name();
964 if(!_file.section_exists(section)) {
965 continue;
966 }
967
968 std::vector<int> ids;
969 // Load vertex selection:
970 _file.get_entry(ids, section, "VertexSelection");
971 selectVertices(o_it->id(), ids);
972 ids.clear();
973 // Load edge selection:
974 _file.get_entry(ids, section, "EdgeSelection");
975 selectEdges(o_it->id(), ids);
976 ids.clear();
977 // Load half-edge selection:
978 _file.get_entry(ids, section, "HalfEdgeSelection");
979 selectHalfEdges(o_it->id(), ids);
980 ids.clear();
981 // Load face selection:
982 _file.get_entry(ids, section, "FaceSelection");
983 selectFaces(o_it->id(), ids);
984 ids.clear();
985 // Load half-face selection:
986 _file.get_entry(ids, section, "HalfFaceSelection");
987 selectHalfFaces(o_it->id(), ids);
988 ids.clear();
989 // Load cell selection:
990 _file.get_entry(ids, section, "CellSelection");
991 selectCells(o_it->id(), ids);
992 ids.clear();
993 }
994}
995
996//==============================================================================================
997
999
1000 // Iterate over all volumemesh objects in the scene and save
1001 // the selections for all vertices
1003#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1004 data_type |= DATA_TETRAHEDRAL_MESH;
1005#endif
1006
1008 o_it != PluginFunctions::objectsEnd(); ++o_it) {
1009
1010 // Create section for each object
1011 // Append object name to section identifier
1012 QString section = QString("PolyhedralMeshSelection") + "//" + o_it->name();
1013
1014 // Store vertex selection:
1015 _file.add_entry(section, "VertexSelection", getVertexSelection(o_it->id()));
1016 _file.add_entry(section, "EdgeSelection", getEdgeSelection(o_it->id()));
1017 _file.add_entry(section, "HalfEdgeSelection", getHalfEdgeSelection(o_it->id()));
1018 _file.add_entry(section, "FaceSelection", getFaceSelection(o_it->id()));
1019 _file.add_entry(section, "HalfFaceSelection", getHalfFaceSelection(o_it->id()));
1020 _file.add_entry(section, "CellSelection", getCellSelection(o_it->id()));
1021 }
1022}
1023
1024//==============================================================================================
1025
1026void VolumeMeshSelectionPlugin::slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) {
1027
1028 SelectionInterface::PrimitiveType type = 0u;
1029 emit
1030 getActivePrimitiveType(type);
1031
1032 if((type & allSupportedTypes_) == 0) {
1033 // No supported type is active
1034 return;
1035 }
1036
1037 bool targetsOnly = false;
1038 emit
1039 targetObjectsOnly(targetsOnly);
1043#ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1044 data_type |= DATA_TETRAHEDRAL_MESH;
1045#endif
1046
1047 if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
1048 // Select all entities
1049 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
1050 o_it != PluginFunctions::objectsEnd(); ++o_it) {
1051 if (o_it->visible()) {
1052 if(type & vertexType_)
1053 selectAllVertices(o_it->id());
1054 if(type & edgeType_)
1055 selectAllEdges(o_it->id());
1056 if(type & faceType_)
1057 selectAllFaces(o_it->id());
1058 if(type & cellType_)
1059 selectAllCells(o_it->id());
1060 }
1061 emit updatedObject(o_it->id(), UPDATE_SELECTION);
1062 }
1063 } else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
1064 // Deselect all entities
1065 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
1066 o_it != PluginFunctions::objectsEnd(); ++o_it) {
1067 if (o_it->visible()) {
1068 if(type & vertexType_)
1069 deselectAllVertices(o_it->id());
1070 if(type & edgeType_)
1071 deselectAllEdges(o_it->id());
1072 if(type & faceType_)
1073 deselectAllFaces(o_it->id());
1074 if(type & cellType_)
1075 deselectAllCells(o_it->id());
1076 }
1077 emit updatedObject(o_it->id(), UPDATE_SELECTION);
1078 }
1079 } else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
1080 // Invert entity selection
1081 for (PluginFunctions::ObjectIterator o_it(restriction, data_type);
1082 o_it != PluginFunctions::objectsEnd(); ++o_it) {
1083 if (o_it->visible()) {
1084 if(type & vertexType_)
1085 invertVertexSelection(o_it->id());
1086 if(type & edgeType_)
1087 invertEdgeSelection(o_it->id());
1088 if(type & faceType_)
1089 invertFaceSelection(o_it->id());
1090 if(type & cellType_)
1091 invertCellSelection(o_it->id());
1092 }
1093 emit updatedObject(o_it->id(), UPDATE_SELECTION);
1094 }
1095
1096 } else if(_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
1097 // Delete selected entities and its children
1098 for(PluginFunctions::ObjectIterator o_it(restriction, data_type);
1099 o_it != PluginFunctions::objectsEnd(); ++o_it) {
1100 if(o_it->visible()) {
1101 if(type & vertexType_)
1102 deleteSelectedVertices(o_it->id());
1103 if(type & edgeType_)
1104 deleteSelectedEdges(o_it->id());
1105 if(type & faceType_)
1106 deleteSelectedFaces(o_it->id());
1107 if(type & cellType_)
1108 deleteSelectedCells(o_it->id());
1109 }
1110 emit updatedObject(o_it->id(), UPDATE_ALL);
1111 }
1112 }
1113}
1114
1115//==============================================================================================
1116
1117
1118
@ LOGERR
#define DATA_HEXAHEDRAL_MESH
#define DATA_POLYHEDRAL_MESH
#define DATA_TETRAHEDRAL_MESH
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
Definition: GLState.hh:235
bool updateGL() const
should GL matrices be updated after each matrix operation
Definition: GLState.hh:233
unsigned int id() const
Definition: BaseNode.hh:423
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:728
bool dataType(DataType _type) const
Definition: BaseObject.cc:219
int id() const
Definition: BaseObject.cc:188
Predefined datatypes.
Definition: DataTypes.hh:83
Class for the handling of simple configuration files.
Definition: INIFile.hh:100
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
CellHandle incident_cell(HalfFaceHandle _halfFaceHandle) const
Get cell that is incident to the given halfface.
const Cell & cell(CellHandle _cellHandle) const
Get cell with handle _cellHandle.
static EdgeHandle edge_handle(HalfEdgeHandle _h)
Handle conversion.
static HalfFaceHandle halfface_handle(FaceHandle _h, const unsigned char _subIdx)
Conversion function.
Face halfface(HalfFaceHandle _halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
HalfFaceHandle adjacent_halfface_in_cell(HalfFaceHandle _halfFaceHandle, HalfEdgeHandle _halfEdgeHandle) const
Get halfface that is adjacent (w.r.t. a common halfedge) within the same cell. It correctly handles s...
Traverse the scenegraph and call the selection function for all mesh nodes.
bool operator()(BaseNode *_node)
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::GLState & glState()
Get the glState of the Viewer.
MeshT * mesh()
return a pointer to the mesh
const StatusAttrib & status() const
return a pointer to the mesh
void slotCustomSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, QString _customIdentifier, bool _deselect) override
Called whenever the user performs a custom selection.
bool vertexTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
PrimitiveType vertexType_
Primitive type handles:
void invertFaceSelection(int _objectId)
Invert face selection.
void invertCellSelection(int _objectId)
Invert cell selection.
void selectHalfFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-faces of a volume mesh.
void deleteSelectedVertices(int _objectId, bool _preserveManifoldness=true)
Delete selected vertices from mesh.
bool edgeTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) override
One of the previously registered keys has been pressed.
void floodFillSelection(MeshT *_mesh, uint _fh, double _maxAngle, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are connected (and do not exceed the maximum dihedral angle)
void selectAllEdges(int _objectId)
Select all edges of a volume mesh.
void selectFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific faces of a volume mesh.
unsigned char lastPickedOrientation_
Handle to selection environment.
bool faceTypeActive()
Is face type active? (for use in plugins that need mesh selection)
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a volume lasso selection.
IdList getCellSelection(int _objectId)
Get current cell selection.
PrimitiveType floodFillSupportedTypes_
Handle to selection environment.
PrimitiveType cellType_
Handle to selection environment.
IdList getHalfFaceSelection(int _objectId)
Get current half-face selection.
void selectAllCells(int _objectId)
Select all cells of a volume mesh.
void deleteSelectedCells(int _objectId, bool _preserveManifoldness=true)
Delete selected cells from mesh.
IdList getFaceSelection(int _objectId)
Get current face selection.
VolMeshParamWidget * parameterWidget_
Handle to selection environment.
void deleteSelectedEdges(int _objectId, bool _preserveManifoldness=true)
Delete selected edges from mesh.
std::map< OpenVolumeMesh::CellHandle, unsigned char > orientationMap_
Handle to selection environment.
void set_max_angle(const double _a)
set max angle for flood fill selection
void invertEdgeSelection(int _objectId)
Invert edge selection.
bool cellTypeActive()
Is cell type active? (for use in plugins that need mesh selection)
QString columnSelectionHandle_
Handle to selection environment.
void deleteSelectedFaces(int _objectId, bool _preserveManifoldness=true)
Delete selected faces from mesh.
void selectVertices(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific vertices of a volume mesh.
VolumeMeshSelectionPlugin()
Default constructor.
~VolumeMeshSelectionPlugin()
Default destructor.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a toggle selection.
HFPair getCommonFace(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, const HexahedralMesh *_mesh) const
Handle to selection environment.
IdList getHalfEdgeSelection(int _objectId)
Get current half-edge selection.
void selectHalfEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-edges of a volume mesh.
void selectAllVertices(int _objectId)
Select all vertices of a volume mesh.
void slotSaveSelection(INIFile &_file) override
Save selection for all objects in the scene.
void deselectAllCells(int _objectId)
Deselect all cells of a volume mesh.
void selectEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific edges of a volume mesh.
PrimitiveType edgeType_
Handle to selection environment.
double max_angle_
Handle to selection environment.
std::pair< OpenVolumeMesh::HalfFaceHandle, OpenVolumeMesh::HalfFaceHandle > HFPair
Handle to selection environment.
QString sheetSelectionHandle_
Handle to selection environment.
void invertVertexSelection(int _objectId)
Invert vertex selection.
void deselectAllVertices(int _objectId)
Deselect all vertices of a volume mesh.
double get_max_angle()
get max angle for flood fill selection
unsigned char getOrthogonalOrientationOfNeighborCell(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, unsigned char _firstOrthDirection, const HexahedralMesh *_mesh) const
Handle to selection environment.
PrimitiveType faceType_
Handle to selection environment.
IdList getEdgeSelection(int _objectId)
Get current edge selection.
void slotSelectionOperation(QString _operation) override
A specific operation is requested.
OpenVolumeMesh::CellHandle lastPickedCell_
Handle to selection environment.
void deselectAllFaces(int _objectId)
Deselect all faces of a volume mesh.
void deselectAllEdges(int _objectId)
Deselect all edges of a volume mesh.
void slotFloodFillSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a flood fill selection.
void slotLoadSelection(const INIFile &_file) override
Load selection for specific objects in the scene.
IdList getVertexSelection(int _objectId)
Get current vertex selection.
void selectCells(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific cells of a volume mesh.
void selectAllFaces(int _objectId)
Select all faces of a volume mesh.
OpenVolumeMesh::StatusAttrib * getStatus(int _objectId)
Handle to selection environment.
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
PrimitiveType allSupportedTypes_
Handle to selection environment.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
QString environmentHandle_
Handle to selection environment.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
Definition: PickTarget.hh:80
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
@ PICK_CELL
picks faces (may not be implemented for all nodes)
Definition: PickTarget.hh:76
@ PICK_FACE
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
TetrahedralMeshObject * tetrahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an TetrahedralMeshObject if possible.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
QStringList IteratorRestriction
Iterable object range.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.