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