44#include "VolumeMeshSelectionPlugin.hh"
45#include "widgets/VolMeshParamWidget.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) {
93void VolumeMeshSelectionPlugin::initializePlugin() {
97 if(!OpenFlipper::Options::nogui())
103void 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!");
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!");
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(
auto he_it1 : hes1) {
776 for(
auto he_it2 : hes2) {
778 sharedHE = _mesh->opposite_halfedge_handle(he_it2);
781 if(sharedHE != HexahedralMesh::InvalidHalfEdgeHandle)
795 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs1 = _mesh->
cell(_ch1).halffaces();
796 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs2 = _mesh->
cell(_ch2).halffaces();
798 for(
auto hf_it1 : hfs1) {
800 for(
auto hf_it2 : hfs2) {
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!"));
865void VolumeMeshSelectionPlugin::loadSelection(
int _objId,
const QString& _filename) {
881void 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");
926void 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()) {
#define DATA_HEXAHEDRAL_MESH
#define DATA_POLYHEDRAL_MESH
#define DATA_TETRAHEDRAL_MESH
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
bool updateGL() const
should GL matrices be updated after each matrix operation
QString name() const
return the name of the object. The name defaults to NONAME if unset.
bool dataType(DataType _type) const
Class for the handling of simple configuration files.
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
bool volumeSelection(MeshT *_mesh, int _objectId, ACG::GLState &_state, QRegion *_region, PrimitiveType _primitiveTypes, bool _deselection)
Surface volume selection tool.
CellHandle incident_cell(HalfFaceHandle _halfFaceHandle) const
Get cell that is incident to the given halfface.
const Cell & cell(CellHandle _cellHandle) const
Get cell with handle _cellHandle.
static EdgeHandle edge_handle(HalfEdgeHandle _h)
Handle conversion.
static HalfFaceHandle halfface_handle(FaceHandle _h, const unsigned char _subIdx)
Conversion function.
Face halfface(HalfFaceHandle _halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
HalfFaceHandle adjacent_halfface_in_cell(HalfFaceHandle _halfFaceHandle, HalfEdgeHandle _halfEdgeHandle) const
Get halfface that is adjacent (w.r.t. a common halfedge) within the same cell. It correctly handles s...
Traverse the scenegraph and call the selection function for all mesh nodes.
bool operator()(BaseNode *_node)
Traverse the scenegraph and call the selection function for all mesh nodes.
ACG::GLState & glState()
Get the glState of the Viewer.
MeshT * mesh()
return a pointer to the mesh
const StatusAttrib & status() const
return a pointer to the mesh
void slotCustomSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, QString _customIdentifier, bool _deselect) override
Called whenever the user performs a custom selection.
bool vertexTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
PrimitiveType vertexType_
Primitive type handles:
void invertFaceSelection(int _objectId)
Invert face selection.
void invertCellSelection(int _objectId)
Invert cell selection.
void selectHalfFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-faces of a volume mesh.
void deleteSelectedVertices(int _objectId, bool _preserveManifoldness=true)
Delete selected vertices from mesh.
bool edgeTypeActive()
Is vertex type active? (for use in plugins that need mesh selection)
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) override
One of the previously registered keys has been pressed.
void floodFillSelection(MeshT *_mesh, uint _fh, double _maxAngle, PrimitiveType _primitiveTypes, bool _deselection)
Select all entities that are connected (and do not exceed the maximum dihedral angle)
void selectAllEdges(int _objectId)
Select all edges of a volume mesh.
void selectFaces(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific faces of a volume mesh.
unsigned char lastPickedOrientation_
Handle to selection environment.
bool faceTypeActive()
Is face type active? (for use in plugins that need mesh selection)
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a volume lasso selection.
IdList getCellSelection(int _objectId)
Get current cell selection.
PrimitiveType floodFillSupportedTypes_
Handle to selection environment.
PrimitiveType cellType_
Handle to selection environment.
IdList getHalfFaceSelection(int _objectId)
Get current half-face selection.
void selectAllCells(int _objectId)
Select all cells of a volume mesh.
void deleteSelectedCells(int _objectId, bool _preserveManifoldness=true)
Delete selected cells from mesh.
IdList getFaceSelection(int _objectId)
Get current face selection.
VolMeshParamWidget * parameterWidget_
Handle to selection environment.
void deleteSelectedEdges(int _objectId, bool _preserveManifoldness=true)
Delete selected edges from mesh.
std::map< OpenVolumeMesh::CellHandle, unsigned char > orientationMap_
Handle to selection environment.
void set_max_angle(const double _a)
set max angle for flood fill selection
void invertEdgeSelection(int _objectId)
Invert edge selection.
bool cellTypeActive()
Is cell type active? (for use in plugins that need mesh selection)
QString columnSelectionHandle_
Handle to selection environment.
void deleteSelectedFaces(int _objectId, bool _preserveManifoldness=true)
Delete selected faces from mesh.
void selectVertices(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific vertices of a volume mesh.
VolumeMeshSelectionPlugin()
Default constructor.
~VolumeMeshSelectionPlugin()
Default destructor.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a toggle selection.
HFPair getCommonFace(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, const HexahedralMesh *_mesh) const
Handle to selection environment.
IdList getHalfEdgeSelection(int _objectId)
Get current half-edge selection.
void selectHalfEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific half-edges of a volume mesh.
void selectAllVertices(int _objectId)
Select all vertices of a volume mesh.
void slotSaveSelection(INIFile &_file) override
Save selection for all objects in the scene.
void deselectAllCells(int _objectId)
Deselect all cells of a volume mesh.
void selectEdges(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific edges of a volume mesh.
PrimitiveType edgeType_
Handle to selection environment.
double max_angle_
Handle to selection environment.
std::pair< OpenVolumeMesh::HalfFaceHandle, OpenVolumeMesh::HalfFaceHandle > HFPair
Handle to selection environment.
QString sheetSelectionHandle_
Handle to selection environment.
void invertVertexSelection(int _objectId)
Invert vertex selection.
void deselectAllVertices(int _objectId)
Deselect all vertices of a volume mesh.
double get_max_angle()
get max angle for flood fill selection
unsigned char getOrthogonalOrientationOfNeighborCell(const OpenVolumeMesh::CellHandle &_ch1, const OpenVolumeMesh::CellHandle &_ch2, unsigned char _firstOrthDirection, const HexahedralMesh *_mesh) const
Handle to selection environment.
PrimitiveType faceType_
Handle to selection environment.
IdList getEdgeSelection(int _objectId)
Get current edge selection.
void slotSelectionOperation(QString _operation) override
A specific operation is requested.
OpenVolumeMesh::CellHandle lastPickedCell_
Handle to selection environment.
void deselectAllFaces(int _objectId)
Deselect all faces of a volume mesh.
void deselectAllEdges(int _objectId)
Deselect all edges of a volume mesh.
void slotFloodFillSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a flood fill selection.
void slotLoadSelection(const INIFile &_file) override
Load selection for specific objects in the scene.
IdList getVertexSelection(int _objectId)
Get current vertex selection.
void selectCells(int _objectId, const IdList &_ids, bool _deselect=false)
Select specific cells of a volume mesh.
void selectAllFaces(int _objectId)
Select all faces of a volume mesh.
OpenVolumeMesh::StatusAttrib * getStatus(int _objectId)
Handle to selection environment.
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
PrimitiveType allSupportedTypes_
Handle to selection environment.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
QString environmentHandle_
Handle to selection environment.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
void traverse(BaseNode *_node, Action &_action)
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
@ PICK_CELL
picks faces (may not be implemented for all nodes)
@ PICK_FACE
picks faces (should be implemented for all nodes)
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
TetrahedralMeshObject * tetrahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an TetrahedralMeshObject if possible.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
QStringList IteratorRestriction
Iterable object range.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.