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/ParameterWidget.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 
93 void VolumeMeshSelectionPlugin::initializePlugin() {
94 
95  // Tell core about all scriptable slots
97  if(!OpenFlipper::Options::nogui())
98  parameterWidget_ = new ParameterWidget(nullptr);
99 }
100 
101 //==============================================================================================
102 
103 void 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  {
553  if(object->dataType(DATA_TETRAHEDRAL_MESH))
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 
606 void 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(std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator he_it1 = hes1.begin(); he_it1 != hes1.end(); ++he_it1) {
776  for(std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator he_it2 = hes2.begin(); he_it2 != hes2.end(); ++he_it2) {
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(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it1 = hfs1.begin(); hf_it1 != hfs1.end(); ++hf_it1) {
799 
800  for(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it2 = hfs2.begin(); hf_it2 != hfs2.end(); ++hf_it2) {
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 
865 void 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 
881 void VolumeMeshSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
882  // From INI Interface
883  // Load plugin specific settings
884 
885  BaseObjectData* bod = NULL;
886  PluginFunctions::getObject(_id, bod);
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 
926 void VolumeMeshSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
927  // From INI Interface
928  // Save plugin specific settings
929 
930  BaseObjectData* bod = NULL;
931  PluginFunctions::getObject(_id, bod);
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 
1026 void 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 
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
OpenVolumeMesh::CellHandle lastPickedCell_
Handle to selection environment.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
#define DATA_POLYHEDRAL_MESH
TetrahedralMeshObject * tetrahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an TetrahedralMeshObject if possible.
void selectFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific faces of a volume mesh.
void selectAllCells(int _objectId)
Select all cells of a volume mesh.
~VolumeMeshSelectionPlugin()
Default destructor.
unsigned char getOrthogonalOrientationOfNeighborCell(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, unsigned char _firstOrthDirection, const HexahedralMesh *_mesh) const
Handle to selection environment.
picks edges (may not be implemented for all nodes)
Definition: PickTarget.hh:80
void deselectAllEdges(int _objectId)
Deselect all edges of a volume mesh.
void selectHalfEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-edges of a volume mesh.
void selectCells(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific cells of a volume mesh.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
QString environmentHandle_
Handle to selection environment.
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
void deleteSelectedEdges(int _objectId, bool _preserveManifoldness=true)
Delete selected edges from mesh.
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
void selectAllVertices(int _objectId)
Select all vertices of a volume mesh.
void selectEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific edges of a volume mesh.
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
void slotFloodFillSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a flood fill selection.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
#define DATA_TETRAHEDRAL_MESH
#define DATA_HEXAHEDRAL_MESH
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
OpenVolumeMesh::StatusAttrib * getStatus(int _objectId)
Handle to selection environment.
double max_angle_
Handle to selection environment.
bool edgeTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
const QStringList ALL_OBJECTS
Iterable object range.
PrimitiveType allSupportedTypes_
Handle to selection environment.
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
IdList getCellSelection(int _objectId)
Get current cell selection.
Predefined datatypes.
Definition: DataTypes.hh:83
bool faceTypeActive()
Is face type active? (for use in plugins that need mesh selection)
void deleteSelectedFaces(int _objectId, bool _preserveManifoldness=true)
Delete selected faces from mesh.
int id() const
Definition: BaseObject.cc:190
IdList getHalfFaceSelection(int _objectId)
Get current half-face selection.
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
Definition: GLState.hh:235
void deselectAllVertices(int _objectId)
Deselect all vertices of a volume mesh.
HFPair getCommonFace(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, const HexahedralMesh *_mesh) const
Handle to selection environment.
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
void selectHalfFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-faces of a volume mesh.
IdList getEdgeSelection(int _objectId)
Get current edge selection.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
bool updateGL() const
should GL matrices be updated after each matrix operation
Definition: GLState.hh:233
void deleteSelectedVertices(int _objectId, bool _preserveManifoldness=true)
Delete selected vertices from mesh.
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) ...
bool vertexTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
bool operator()(BaseNode *_node)
Traverse the scenegraph and call the selection function for all mesh nodes.
void selectAllFaces(int _objectId)
Select all faces of a volume mesh.
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
bool cellTypeActive()
Is cell type active? (for use in plugins that need mesh selection)
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:730
PrimitiveType faceType_
Handle to selection environment.
void deselectAllFaces(int _objectId)
Deselect all faces of a volume mesh.
PrimitiveType cellType_
Handle to selection environment.
PrimitiveType edgeType_
Handle to selection environment.
const StatusAttrib & status() const
return a pointer to the mesh
QString columnSelectionHandle_
Handle to selection environment.
PrimitiveType vertexType_
Primitive type handles:
QStringList IteratorRestriction
Iterable object range.
void deselectAllCells(int _objectId)
Deselect all cells of a volume mesh.
void deleteSelectedCells(int _objectId, bool _preserveManifoldness=true)
Delete selected cells from mesh.
void invertEdgeSelection(int _objectId)
Invert edge selection.
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
void invertCellSelection(int _objectId)
Invert cell selection.
IdList getFaceSelection(int _objectId)
Get current face selection.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
void slotSelectionOperation(QString _operation)
A specific operation is requested.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
unsigned int id() const
Definition: BaseNode.hh:423
unsigned char lastPickedOrientation_
Handle to selection environment.
void selectAllEdges(int _objectId)
Select all edges of a volume mesh.
std::map< OpenVolumeMesh::CellHandle, unsigned char > orientationMap_
Handle to selection environment.
Class for the handling of simple configuration files.
Definition: INIFile.hh:99
ParameterWidget * parameterWidget_
Handle to selection environment.
IdList getVertexSelection(int _objectId)
Get current vertex selection.
void selectVertices(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific vertices of a volume mesh.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
picks faces (may not be implemented for all nodes)
Definition: PickTarget.hh:76
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
MeshT * mesh()
return a pointer to the mesh
std::pair< OpenVolumeMesh::HalfFaceHandle, OpenVolumeMesh::HalfFaceHandle > HFPair
Handle to selection environment.
void set_max_angle(const double _a)
set max angle for flood fill selection
void invertFaceSelection(int _objectId)
Invert face selection.
void slotCustomSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, QString _customIdentifier, bool _deselect)
Called whenever the user performs a custom selection.
double get_max_angle()
get max angle for flood fill selection
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
VolumeMeshSelectionPlugin()
Default constructor.
void invertVertexSelection(int _objectId)
Invert vertex selection.
QString sheetSelectionHandle_
Handle to selection environment.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
IdList getHalfEdgeSelection(int _objectId)
Get current half-edge selection.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
PrimitiveType floodFillSupportedTypes_
Handle to selection environment.
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::GLState & glState()
Get the glState of the Viewer.