50 #include "VolumeMeshSelectionPlugin.hh"
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"
58 #define COLUMN_SELECTION "column-selection.png"
59 #define SHEET_SELECTION "sheet-selection.png"
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"
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"
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"
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"
86 vertexType_(0), edgeType_(0), allSupportedTypes_(0), lastPickedCell_(
HexahedralMesh::InvalidCellHandle),
87 lastPickedOrientation_(0) {
97 void VolumeMeshSelectionPlugin::initializePlugin() {
105 void VolumeMeshSelectionPlugin::pluginsInitialized() {
109 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
112 addSelectionEnvironment(
"VolumeMesh Selections",
"Select volume mesh primitives.",
120 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
130 emit addCustomSelectionMode(
environmentHandle_,
"Column Selection",
"Select entire column of cells",
134 addCustomSelectionMode(
environmentHandle_,
"Sheet Selection",
"Select entire sheet of cells",
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);
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);
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);
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);
184 registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
187 registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
190 registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
192 emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
207 SelectionInterface::PrimitiveType t = 0u;
208 emit getActivePrimitiveType(t);
213 SelectionInterface::PrimitiveType t = 0u;
214 emit getActivePrimitiveType(t);
219 SelectionInterface::PrimitiveType t = 0u;
220 emit getActivePrimitiveType(t);
225 SelectionInterface::PrimitiveType t = 0u;
226 emit getActivePrimitiveType(t);
234 SelectionInterface::PrimitiveType type = 0u;
235 emit getActivePrimitiveType(type);
241 bool targetsOnly =
false;
242 emit targetObjectsOnly(targetsOnly);
247 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
248 data_type |= DATA_TETRAHEDRAL_MESH;
251 if (_operation == V_SELECT_ALL) {
257 }
else if (_operation == V_DESELECT_ALL) {
263 }
else if (_operation == V_INVERT) {
269 }
else if (_operation == V_DELETE) {
275 }
else if (_operation == E_SELECT_ALL) {
281 }
else if (_operation == E_DESELECT_ALL) {
287 }
else if (_operation == E_INVERT) {
293 }
else if (_operation == E_DELETE) {
299 }
else if (_operation == F_SELECT_ALL) {
305 }
else if (_operation == F_DESELECT_ALL) {
311 }
else if (_operation == F_INVERT) {
317 }
else if (_operation == F_DELETE) {
323 }
else if (_operation == C_SELECT_ALL) {
329 }
else if (_operation == C_DESELECT_ALL) {
335 }
else if (_operation == C_INVERT) {
341 }
else if (_operation == C_DELETE) {
353 SelectionInterface::PrimitiveType _currentType,
bool _deselect) {
360 if(_event->button() != Qt::LeftButton)
363 size_t node_idx, target_idx;
371 node_idx, target_idx, &hit_point)
374 if(successfullyPicked) {
393 target_idx, &hit_point)
396 if(successfullyPicked) {
415 target_idx, &hit_point)
418 if(successfullyPicked) {
438 target_idx, &hit_point)
441 if(successfullyPicked) {
462 PrimitiveType _currentType,
bool _deselect)
466 if (_event->type() == QEvent::MouseButtonPress)
471 else if (_event->type() == QEvent::MouseButtonDblClick)
478 QRegion region = QRegion(p);
491 double _maxAngle, PrimitiveType _currentType,
bool _deselect)
497 size_t node_idx, target_idx;
502 _event->pos(), node_idx, target_idx, &hit_point))
511 _event->pos(), node_idx, target_idx, &hit_point))
518 target_idx, _maxAngle, _currentType, _deselect);
528 _event->pos(), node_idx, target_idx, &hit_point))
535 target_idx, _maxAngle, _currentType, _deselect);
542 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
543 else if(object->
dataType() == DATA_TETRAHEDRAL_MESH)
546 _event->pos(), node_idx, target_idx, &hit_point))
550 if(object->
dataType(DATA_TETRAHEDRAL_MESH))
553 target_idx, _maxAngle, _currentType, _deselect);
563 emit log(
LOGERR, tr(
"floodFillSelection: Unsupported dataType"));
575 bool selected =
false;
579 selected = plugin_->
volumeSelection(m, state_, ®ion_, type_, deselection_);
584 selected = plugin_->
volumeSelection(m, state_, ®ion_, type_, deselection_);
586 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
587 else if(object->
dataType(DATA_TETRAHEDRAL_MESH)) {
590 selected = plugin_->
volumeSelection(m, state_, ®ion_, type_, deselection_);
604 QString _customIdentifier,
bool _deselect) {
610 if(_event->button() != Qt::LeftButton || _event->type() != QEvent::MouseButtonPress)
622 size_t node_idx, target_idx;
624 node_idx, target_idx, &hit_point)
627 if(successfullyPicked) {
631 emit log(
LOGERR,
"Could not get hexahedral mesh object!");
641 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
642 : hexMesh->halfface_handle(fh, 0));
644 while(!hexMesh->is_boundary(cif)) {
648 if(status[ch].selected() || _deselect)
649 status[ch].set_selected(
false);
651 status[ch].set_selected(
true);
653 cif = hexMesh->opposite_halfface_handle_in_cell(cif, ch);
654 cif = hexMesh->opposite_halfface_handle(cif);
670 size_t node_idx, target_idx;
672 node_idx, target_idx, &hit_point)
675 if(successfullyPicked) {
679 emit log(
LOGERR,
"Could not get hexahedral mesh object!");
689 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
690 : hexMesh->halfface_handle(fh, 0));
707 unsigned char secondDir = hexMesh->orientation(pair.first,
lastPickedCell_);
714 std::set<OpenVolumeMesh::CellHandle> unprocessed;
716 std::set<OpenVolumeMesh::CellHandle> processed;
723 while(!unprocessed.empty() ) {
726 unprocessed.erase(cur_c);
727 status[cur_c].set_selected(!status[cur_c].selected());
728 processed.insert(cur_c);
730 std::map<OpenVolumeMesh::CellHandle, unsigned char>::iterator f =
orientationMap_.find(cur_c);
732 emit log(
LOGERR,
"Could not get orientation of current cell in sheet!");
735 unsigned char od = f->second;
738 if(processed.count(*csc_it) > 0)
742 orientationMap_.insert(std::pair<OpenVolumeMesh::CellHandle, unsigned char>(*csc_it, new_o));
743 unprocessed.insert(*csc_it);
759 unsigned char _firstOrthDirection,
769 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes1 = _mesh->halfface(firstOrthHF).halfedges();
770 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes2 = _mesh->halfface(commonHF.first).halfedges();
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);
778 if(sharedHE != HexahedralMesh::InvalidHalfEdgeHandle)
783 return _mesh->orientation(_mesh->adjacent_halfface_in_cell(commonHF.second, sharedHE), _ch2);
792 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs1 = _mesh->cell(_ch1).halffaces();
793 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs2 = _mesh->cell(_ch2).halffaces();
795 for(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it1 = hfs1.begin(); hf_it1 != hfs1.end(); ++hf_it1) {
797 for(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it2 = hfs2.begin(); hf_it2 != hfs2.end(); ++hf_it2) {
799 if(_mesh->face_handle(*hf_it1) == _mesh->face_handle(*hf_it2)) {
800 return HFPair(*hf_it1, *hf_it2);
805 return HFPair(HexahedralMesh::InvalidHalfFaceHandle, HexahedralMesh::InvalidHalfFaceHandle);
812 if (polyMeshObj != NULL)
813 return &polyMeshObj->
status();
817 if (hexMeshObj != NULL)
818 return &hexMeshObj->
status();
820 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
821 TetrahedralMeshObject* tetMeshObj = NULL;
823 if (tetMeshObj != NULL)
824 return &tetMeshObj->status();
833 if (polyMeshObj != NULL)
834 return &polyMeshObj->
status();
837 if (hexMeshObj != NULL)
838 return &hexMeshObj->
status();
840 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
841 TetrahedralMeshObject* tetMeshObj = PluginFunctions::tetrahedralMeshObject(
object);
842 if (tetMeshObj != NULL)
843 return &tetMeshObj->status();
846 emit log(
LOGERR, tr(
"Neither polyhedral nor hexahedral nor tetrahedral mesh!"));
852 void VolumeMeshSelectionPlugin::loadSelection(
int _objId,
const QString& _filename) {
868 void VolumeMeshSelectionPlugin::loadIniFile(
INIFile& _ini,
int _id) {
875 emit log(
LOGERR,
"Could not get base object data!");
879 QString section = QString(
"PolyhedralMeshSelection") +
"//" + bod->
name();
884 std::vector<int> ids;
886 _ini.
get_entry(ids, section,
"VertexSelection");
890 _ini.
get_entry(ids, section,
"EdgeSelection");
894 _ini.
get_entry(ids, section,
"HalfEdgeSelection");
898 _ini.
get_entry(ids, section,
"FaceSelection");
902 _ini.
get_entry(ids, section,
"HalfFaceSelection");
906 _ini.
get_entry(ids, section,
"CellSelection");
913 void VolumeMeshSelectionPlugin::saveIniFile(
INIFile& _ini,
int _id) {
920 emit log(
LOGERR,
"Could not get base object data!");
924 QString section = QString(
"PolyhedralMeshSelection") +
"//" + bod->
name();
941 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
942 data_type |= DATA_TETRAHEDRAL_MESH;
950 QString section = QString(
"PolyhedralMeshSelection") +
"//" + o_it->
name();
955 std::vector<int> ids;
957 _file.
get_entry(ids, section,
"VertexSelection");
961 _file.
get_entry(ids, section,
"EdgeSelection");
965 _file.
get_entry(ids, section,
"HalfEdgeSelection");
969 _file.
get_entry(ids, section,
"FaceSelection");
973 _file.
get_entry(ids, section,
"HalfFaceSelection");
977 _file.
get_entry(ids, section,
"CellSelection");
990 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
991 data_type |= DATA_TETRAHEDRAL_MESH;
999 QString section = QString(
"PolyhedralMeshSelection") +
"//" + o_it->
name();
1015 SelectionInterface::PrimitiveType type = 0u;
1017 getActivePrimitiveType(type);
1024 bool targetsOnly =
false;
1026 targetObjectsOnly(targetsOnly);
1030 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT
1031 data_type |= DATA_TETRAHEDRAL_MESH;
1034 if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
1038 if (o_it->visible()) {
1050 }
else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
1054 if (o_it->visible()) {
1066 }
else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
1070 if (o_it->visible()) {
1083 }
else if(_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
1087 if(o_it->visible()) {
1104 #if QT_VERSION < 0x050000
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.
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
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)
bool dataType(DataType _type) const
PrimitiveType cellType_
Handle to selection environment.
#define DATA_POLYHEDRAL_MESH
bool updateGL() const
should GL matrices be updated after each matrix operation
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.
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)
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.
Class for the handling of simple configuration files.
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.
void selectAllFaces(int _objectId)
Select all faces of a volume mesh.
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)
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)
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.
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
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)
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)
void selectAllEdges(int _objectId)
Select all edges of a volume mesh.