44 #include "VolumeMeshSelectionPlugin.hh" 45 #include "widgets/ParameterWidget.hh" 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" 54 #define COLUMN_SELECTION "column-selection.png" 55 #define SHEET_SELECTION "sheet-selection.png" 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" 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" 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" 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" 82 vertexType_(0), edgeType_(0), allSupportedTypes_(0), parameterWidget_(nullptr), max_angle_(2*M_PI),
83 lastPickedCell_(
HexahedralMesh::InvalidCellHandle), lastPickedOrientation_(0) {
93 void VolumeMeshSelectionPlugin::initializePlugin() {
97 if(!OpenFlipper::Options::nogui())
103 void VolumeMeshSelectionPlugin::pluginsInitialized() {
107 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
110 addSelectionEnvironment(
"VolumeMesh Selections",
"Select volume mesh primitives.",
118 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 128 emit addCustomSelectionMode(
environmentHandle_,
"Column Selection",
"Select entire column of cells",
132 addCustomSelectionMode(
environmentHandle_,
"Sheet Selection",
"Select entire sheet of cells",
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);
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);
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);
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);
178 if(!OpenFlipper::Options::nogui())
185 registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
188 registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
191 registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
193 emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
208 SelectionInterface::PrimitiveType t = 0u;
209 emit getActivePrimitiveType(t);
214 SelectionInterface::PrimitiveType t = 0u;
215 emit getActivePrimitiveType(t);
220 SelectionInterface::PrimitiveType t = 0u;
221 emit getActivePrimitiveType(t);
226 SelectionInterface::PrimitiveType t = 0u;
227 emit getActivePrimitiveType(t);
235 SelectionInterface::PrimitiveType type = 0u;
236 emit getActivePrimitiveType(type);
242 bool targetsOnly =
false;
243 emit targetObjectsOnly(targetsOnly);
248 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 252 if (_operation == V_SELECT_ALL) {
258 }
else if (_operation == V_DESELECT_ALL) {
264 }
else if (_operation == V_INVERT) {
270 }
else if (_operation == V_DELETE) {
276 }
else if (_operation == E_SELECT_ALL) {
282 }
else if (_operation == E_DESELECT_ALL) {
288 }
else if (_operation == E_INVERT) {
294 }
else if (_operation == E_DELETE) {
300 }
else if (_operation == F_SELECT_ALL) {
306 }
else if (_operation == F_DESELECT_ALL) {
312 }
else if (_operation == F_INVERT) {
318 }
else if (_operation == F_DELETE) {
324 }
else if (_operation == C_SELECT_ALL) {
330 }
else if (_operation == C_DESELECT_ALL) {
336 }
else if (_operation == C_INVERT) {
342 }
else if (_operation == C_DELETE) {
354 SelectionInterface::PrimitiveType _currentType,
bool _deselect) {
361 if(_event->button() != Qt::LeftButton)
364 size_t node_idx, target_idx;
372 node_idx, target_idx, &hit_point)
375 if(successfullyPicked) {
394 target_idx, &hit_point)
397 if(successfullyPicked) {
416 target_idx, &hit_point)
419 if(successfullyPicked) {
439 target_idx, &hit_point)
442 if(successfullyPicked) {
463 PrimitiveType _currentType,
bool _deselect)
467 if (_event->type() == QEvent::MouseButtonPress)
472 else if (_event->type() == QEvent::MouseButtonDblClick)
479 QRegion region = QRegion(p);
492 PrimitiveType _currentType,
bool _deselect)
498 size_t node_idx, target_idx;
501 if(!OpenFlipper::Options::nogui())
505 _event->pos(), node_idx, target_idx, &hit_point))
514 _event->pos(), node_idx, target_idx, &hit_point))
521 target_idx,
max_angle_, _currentType, _deselect);
531 _event->pos(), node_idx, target_idx, &hit_point))
538 target_idx,
max_angle_, _currentType, _deselect);
545 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 549 _event->pos(), node_idx, target_idx, &hit_point))
556 target_idx,
max_angle_, _currentType, _deselect);
566 emit log(
LOGERR, tr(
"floodFillSelection: Unsupported dataType"));
578 bool selected =
false;
582 selected = plugin_->volumeSelection(m, state_, ®ion_, type_, deselection_);
587 selected = plugin_->volumeSelection(m, state_, ®ion_, type_, deselection_);
589 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 593 selected = plugin_->volumeSelection(m, state_, ®ion_, type_, deselection_);
607 QString _customIdentifier,
bool _deselect) {
613 if(_event->button() != Qt::LeftButton || _event->type() != QEvent::MouseButtonPress)
625 size_t node_idx, target_idx;
627 node_idx, target_idx, &hit_point)
630 if(successfullyPicked) {
634 emit log(
LOGERR,
"Could not get hexahedral mesh object!");
644 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
645 : hexMesh->halfface_handle(fh, 0));
647 while(!hexMesh->is_boundary(cif)) {
651 if(status[ch].selected() || _deselect)
652 status[ch].set_selected(
false);
654 status[ch].set_selected(
true);
656 cif = hexMesh->opposite_halfface_handle_in_cell(cif, ch);
657 cif = hexMesh->opposite_halfface_handle(cif);
673 size_t node_idx, target_idx;
675 node_idx, target_idx, &hit_point)
678 if(successfullyPicked) {
682 emit log(
LOGERR,
"Could not get hexahedral mesh object!");
692 (hexMesh->is_boundary(hexMesh->halfface_handle(fh, 0)) ? hexMesh->halfface_handle(fh, 1)
693 : hexMesh->halfface_handle(fh, 0));
710 unsigned char secondDir = hexMesh->orientation(pair.first,
lastPickedCell_);
717 std::set<OpenVolumeMesh::CellHandle> unprocessed;
719 std::set<OpenVolumeMesh::CellHandle> processed;
726 while(!unprocessed.empty() ) {
729 unprocessed.erase(cur_c);
730 status[cur_c].set_selected(!status[cur_c].selected());
731 processed.insert(cur_c);
733 std::map<OpenVolumeMesh::CellHandle, unsigned char>::iterator f =
orientationMap_.find(cur_c);
735 emit log(
LOGERR,
"Could not get orientation of current cell in sheet!");
738 unsigned char od = f->second;
741 if(processed.count(*csc_it) > 0)
745 orientationMap_.insert(std::pair<OpenVolumeMesh::CellHandle, unsigned char>(*csc_it, new_o));
746 unprocessed.insert(*csc_it);
762 unsigned char _firstOrthDirection,
772 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes1 = _mesh->halfface(firstOrthHF).halfedges();
773 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes2 = _mesh->halfface(commonHF.first).halfedges();
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);
781 if(sharedHE != HexahedralMesh::InvalidHalfEdgeHandle)
786 return _mesh->orientation(_mesh->adjacent_halfface_in_cell(commonHF.second, sharedHE), _ch2);
795 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs1 = _mesh->cell(_ch1).halffaces();
796 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs2 = _mesh->cell(_ch2).halffaces();
798 for(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it1 = hfs1.begin(); hf_it1 != hfs1.end(); ++hf_it1) {
800 for(std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator hf_it2 = hfs2.begin(); hf_it2 != hfs2.end(); ++hf_it2) {
802 if(_mesh->face_handle(*hf_it1) == _mesh->face_handle(*hf_it2)) {
803 return HFPair(*hf_it1, *hf_it2);
808 return HFPair(HexahedralMesh::InvalidHalfFaceHandle, HexahedralMesh::InvalidHalfFaceHandle);
815 if (polyMeshObj != NULL)
816 return &polyMeshObj->
status();
820 if (hexMeshObj != NULL)
821 return &hexMeshObj->
status();
823 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 826 if (tetMeshObj != NULL)
827 return &tetMeshObj->
status();
836 if (polyMeshObj != NULL)
837 return &polyMeshObj->
status();
840 if (hexMeshObj != NULL)
841 return &hexMeshObj->
status();
843 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 845 if (tetMeshObj != NULL)
846 return &tetMeshObj->
status();
849 emit log(
LOGERR, tr(
"Neither polyhedral nor hexahedral nor tetrahedral mesh!"));
865 void VolumeMeshSelectionPlugin::loadSelection(
int _objId,
const QString& _filename) {
881 void VolumeMeshSelectionPlugin::loadIniFile(
INIFile& _ini,
int _id) {
888 emit log(
LOGERR,
"Could not get base object data!");
892 QString section = QString(
"PolyhedralMeshSelection") +
"//" + bod->
name();
897 std::vector<int> ids;
899 _ini.
get_entry(ids, section,
"VertexSelection");
903 _ini.
get_entry(ids, section,
"EdgeSelection");
907 _ini.
get_entry(ids, section,
"HalfEdgeSelection");
911 _ini.
get_entry(ids, section,
"FaceSelection");
915 _ini.
get_entry(ids, section,
"HalfFaceSelection");
919 _ini.
get_entry(ids, section,
"CellSelection");
926 void VolumeMeshSelectionPlugin::saveIniFile(
INIFile& _ini,
int _id) {
933 emit log(
LOGERR,
"Could not get base object data!");
937 QString section = QString(
"PolyhedralMeshSelection") +
"//" + bod->
name();
954 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 963 QString section = QString(
"PolyhedralMeshSelection") +
"//" + o_it->name();
968 std::vector<int> ids;
970 _file.
get_entry(ids, section,
"VertexSelection");
974 _file.
get_entry(ids, section,
"EdgeSelection");
978 _file.
get_entry(ids, section,
"HalfEdgeSelection");
982 _file.
get_entry(ids, section,
"FaceSelection");
986 _file.
get_entry(ids, section,
"HalfFaceSelection");
990 _file.
get_entry(ids, section,
"CellSelection");
1003 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 1012 QString section = QString(
"PolyhedralMeshSelection") +
"//" + o_it->name();
1028 SelectionInterface::PrimitiveType type = 0u;
1030 getActivePrimitiveType(type);
1037 bool targetsOnly =
false;
1039 targetObjectsOnly(targetsOnly);
1043 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 1047 if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
1051 if (o_it->visible()) {
1063 }
else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
1067 if (o_it->visible()) {
1079 }
else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
1083 if (o_it->visible()) {
1096 }
else if(_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
1100 if(o_it->visible()) {
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)
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)
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.
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.
IdList getCellSelection(int _objectId)
Get current cell selection.
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.
IdList getHalfFaceSelection(int _objectId)
Get current half-face selection.
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
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
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
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)
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)
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.
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 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.
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)
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.
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)
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::GLState & glState()
Get the glState of the Viewer.