Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MouseAndKeyPlugin.cc
1 //=============================================================================
2 //
3 // OpenFlipper
4 // Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
5 // www.openflipper.org
6 //
7 //-----------------------------------------------------------------------------
8 //
9 // License
10 //
11 // OpenFlipper is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // OpenFlipper is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
23 //
24 //-----------------------------------------------------------------------------
25 //
26 // $Revision$
27 // $Author$
28 // $Date$
29 //
30 //=============================================================================
31
32 #include "MouseAndKeyPlugin.hh"
33
34
35 #include <ObjectTypes/PolyMesh/PolyMesh.hh>
36 #include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
37
38 #include "OpenFlipper/BasePlugin/PluginFunctions.hh"
39
40 /*
41 * Constructor
42 */
43 MouseAndKeyPlugin::MouseAndKeyPlugin() :
44 contextMenuEntry_(0),
45 tool_(0),
46 pickButton_(0),
47 activeObject_(-1),
48 axis_x_(ACG::Vec3d(1.0, 0.0, 0.0)),
49 axis_y_(ACG::Vec3d(0.0, 1.0, 0.0))
50 {
51
52 }
53
54 /*
55 * Initialize plugin
56 */
57 void MouseAndKeyPlugin::initializePlugin() {
58
59 // Register keys
60 emit registerKey(Qt::Key_J, Qt::NoModifier, "Rotate object down");
61 emit registerKey(Qt::Key_K, Qt::NoModifier, "Rotate object up");
62 emit registerKey(Qt::Key_H, Qt::NoModifier, "Rotate object left");
63 emit registerKey(Qt::Key_L, Qt::NoModifier, "Rotate object right");
64
65 tool_ = new QWidget();
66 QSize size(300, 300);
67 tool_->resize(size);
68
69 // Create button that can be toggled
70 // to (de)activate plugin's picking mode
71 pickButton_ = new QPushButton(tr("Select object"));
72 pickButton_->setCheckable(true);
73
74 // Create label
75 QLabel* label = new QLabel();
76 label->setText("(De)activate pick mode");
77
78 // Set label to be above the button
79 QGridLayout* grid = new QGridLayout;
80 grid->addWidget(label, 0, 0);
81 grid->addWidget(pickButton_, 1, 0);
82
83 tool_->setLayout(grid);
84
85 // Connect button to slotButtonClicked()
86 connect(pickButton_, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
87
88 // Add the Toolbox
89 emit addToolbox(tr("Mouse and Key"), tool_);
90
91 } // End initializePlugin
92
93 /*
94 * Is called after all plugins have been initialized
95 */
96 void MouseAndKeyPlugin::pluginsInitialized() {
97
98 // Add pickmode
99 emit addPickMode("MouseAndKeyPlugin");
100
101 // Add context menu entry
102
103 // Create submenu
104 contextMenuEntry_ = new QMenu("Mouse and key plugin");
105
106 QAction* lastAction;
107
108 // Add action to recently created menu
109 lastAction = contextMenuEntry_->addAction( "Hide object" );
110 lastAction->setToolTip("Hide selected object");
111 lastAction->setStatusTip( lastAction->toolTip() );
112
113 // Finally insert created context submenu to OpenFlipper's context menu
114 // We want our action to be visible for triangle and polygon meshes
115 emit addContextMenuItem(contextMenuEntry_->menuAction() , DATA_TRIANGLE_MESH , CONTEXTOBJECTMENU );
116 emit addContextMenuItem(contextMenuEntry_->menuAction() , DATA_POLY_MESH , CONTEXTOBJECTMENU );
117
118 // Connect the created context menu entry to local function contextMenuItemSelected(QAction*)
119 connect(contextMenuEntry_, SIGNAL(triggered(QAction*)), this, SLOT(contextMenuItemSelected(QAction*)));
120
121 } // End pluginsInitialized
122
123
124 /*
125 * Is called when button in toolbox has been clicked
126 */
127 void MouseAndKeyPlugin::slotButtonClicked() {
128
129 if(pickButton_->isChecked()) {
130 // Picking mode of our plugin shall be activated
131 // set OpenFlipper's action mode to picking
132 PluginFunctions::actionMode( Viewer::PickingMode );
133
134 // Now activate our picking mode
135 PluginFunctions::pickMode( "MouseAndKeyPlugin" );
136 } else {
137 // Picking mode shall be deactivated
138 PluginFunctions::actionMode( Viewer::ExamineMode );
139 }
140
141 } // End slotButtonClicked
142
143 /*
144 * Is called when pick mode is changed in OpenFlipper
145 */
146 void MouseAndKeyPlugin::slotPickModeChanged(const std::string& _mode) {
147
148 // Set button checked if pick mode is our
149 // plugin's pick mode
150 pickButton_->setChecked(_mode == "MouseAndKeyPlugin");
151
152 } // End slotPickModeChanged
153
154 /*
155 * Is called each time the mouse has moved or been clicked
156 */
157 void MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* _event) {
158
159 if ( PluginFunctions::pickMode() == "MouseAndKeyPlugin" &&
160 PluginFunctions::actionMode() == Viewer::PickingMode ) {
161
162 // If double click has been performed
163 if (_event->type() == QEvent::MouseButtonDblClick) {
164
165 unsigned int node_idx, target_idx;
166 OpenMesh::Vec3d hitPoint;
167
168 // Get picked object's identifier
169 if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,_event->pos(), node_idx, target_idx, &hitPoint) ) {
170
171 BaseObjectData* object;
172
173 // Get picked object
174 if ( PluginFunctions::getPickedObject(node_idx, object) ) {
175
176 // Show small dialog window
177 QDialog* dlg = new QDialog;
178
179 QGridLayout* grid = new QGridLayout;
180 QLabel* label = new QLabel;
181 QString str = QString("You selected object ");
182 str += QString::number(node_idx);
183 label->setText(str);
184 grid->addWidget(label, 0,0);
185
186 dlg->setLayout(grid);
187
188 dlg->show();
189
190 // Set last selected object
191 activeObject_ = node_idx;
192 }
193 else {
194 emit log(LOGINFO, "Picking failed");
195 }
196 }
197
198 return;
199 }
200
201 // Continue traversing scene graph
202 ACG::SceneGraph::MouseEventAction action(_event, PluginFunctions::viewerProperties().glState());
203 PluginFunctions::traverse(action);
204 }
205
206 } // End slotMouseEvent
207
208 /*
209 * Is called when a key on the keyboard is pressed
210 */
211 void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {
212
213 BaseObjectData* object;
214
215 // Get last clicked object (selected in pick mode)
216 if ( PluginFunctions::getPickedObject(activeObject_, object) ) {
217
218 // Switch pressed keys
219 switch (_event->key())
220 {
221 case Qt::Key_J:
222
223 object->manipulatorNode()->loadIdentity();
224 object->manipulatorNode()->rotate(10.0, axis_x_);
225
226 break;
227
228 case Qt::Key_K :
229
230 object->manipulatorNode()->loadIdentity();
231 object->manipulatorNode()->rotate(-10.0, axis_x_);
232
233 break;
234
235 case Qt::Key_H :
236
237 object->manipulatorNode()->loadIdentity();
238 object->manipulatorNode()->rotate(10.0, axis_y_);
239
240 break;
241
242 case Qt::Key_L :
243
244 object->manipulatorNode()->loadIdentity();
245 object->manipulatorNode()->rotate(-10.0, axis_y_);
246
247 break;
248
249 default:
250 break;
251 }
252
253 // Perform rotation
254 if ( object->dataType( DATA_TRIANGLE_MESH ) )
255 transformMesh(object->manipulatorNode()->matrix(), (*PluginFunctions::triMesh(object)));
256 if ( object->dataType( DATA_POLY_MESH ) )
257 transformMesh(object->manipulatorNode()->matrix(), (*PluginFunctions::polyMesh(object)));
258
259 // Tell core that object has been modified
260 emit updatedObject(object->id(), UPDATE_GEOMETRY);
261
262 // Update view
263 emit updateView();
264 } else {
265 emit log(LOGINFO, "No object has been selected to rotate! Select object first.");
266 }
267
268 } // End slotKeyEvent
269
270 /*
271 * Transform a mesh with the given transformation matrix
272 *
273 * _mat : transformation matrix
274 * _mesh : the mesh
275 */
276 template<typename MeshT>
277 void MouseAndKeyPlugin::transformMesh(ACG::Matrix4x4d _mat, MeshT& _mesh) {
278
279 typename MeshT::VertexIter v_it = _mesh.vertices_begin();
280 typename MeshT::VertexIter v_end = _mesh.vertices_end();
281
282 // Iterator over all vertices and transform them by _mat
283 // Update normals
284 for (; v_it != v_end; ++v_it) {
285 _mesh.set_point(v_it, (typename MeshT::Point) _mat.transform_point(
286 (OpenMesh::Vec3d)(_mesh.point(v_it))));
287 _mesh.set_normal(v_it, (typename MeshT::Point) _mat.transform_vector(
288 (OpenMesh::Vec3d)(_mesh.normal(v_it))));
289 }
290
291 typename MeshT::FaceIter f_it = _mesh.faces_begin();
292 typename MeshT::FaceIter f_end = _mesh.faces_end();
293
294 // Iterate over all faces and update face normals
295 for (; f_it != f_end; ++f_it)
296 _mesh.set_normal(f_it, (typename MeshT::Point) _mat.transform_vector(
297 (OpenMesh::Vec3d)(_mesh.normal(f_it))));
298
299 } // End transformMesh
300
301 /*
302 * Is called when context menu entry has been clicked
303 */
304 void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {
305
306 // Get object id from QAction object
307 QVariant contextObject = _action->data();
308 int objectId = contextObject.toInt();
309
310 if (objectId == -1) {
311
312 log(LOGINFO, "Could not get associated object id.");
313 return;
314 }
315
316 // Get node associated to object id
317 ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node(
318 PluginFunctions::getSceneGraphRootNode(), objectId);
319
320 // Return if node id was not valid
321 if (!node) {
322
323 log(LOGINFO, "Could not find associated object.");
324 return;
325 }
326
327 BaseObjectData* obj;
328 if (!PluginFunctions::getObject(objectId, obj))
329 return;
330
331 // Hide object
332 obj->hide();
333
334 } // End contextMenuItemSelected
335
336 Q_EXPORT_PLUGIN2( mouseandkeyplugin , MouseAndKeyPlugin );
337
PluginFunctions::viewerProperties
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
Definition: PluginFunctions.cc:613
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::SceneGraph::BaseNode
Definition: BaseNode.hh:135
UPDATE_GEOMETRY
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
BaseObjectData
Definition: BaseObjectData.hh:105
TriangleMesh.hh
ACG::SceneGraph::MouseEventAction
Definition: SceneGraph.hh:805
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
BaseObjectData::manipulatorNode
QtTranslationManipulatorNode * manipulatorNode()
Definition: BaseObjectData.cc:261
ACG::SceneGraph::TransformNode::loadIdentity
void loadIdentity()
Definition: TransformNode.cc:97
PluginFunctions::getObject
bool getObject(int _identifier, BSplineCurveObject *&_object)
Definition: PluginFunctionsBSplineCurve.cc:75
PluginFunctions::polyMesh
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Definition: PluginFunctionsPolyMesh.cc:134
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
ACG::Matrix4x4T::transform_vector
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
Definition: Matrix4x4T.cc:225
PluginFunctions::getSceneGraphRootNode
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
Definition: PluginFunctions.cc:961
BaseObjectData::hide
virtual void hide()
Sets the whole Scenegraph subtree of this node to invisible.
Definition: BaseObjectData.cc:203
BaseObject::dataType
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
PluginFunctions::triMesh
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
Definition: PluginFunctionsTriangleMesh.cc:140
PluginFunctions::pickMode
const std::string pickMode()
Get the current Picking mode.
Definition: PluginFunctions.cc:579
OpenMesh::VectorT
Definition: Vector11T.hh:83
DATA_POLY_MESH
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
ACG::SceneGraph::TransformNode::matrix
const GLMatrixd & matrix() const
Returns a const reference to the current transformation matrix.
Definition: TransformNode.hh:158
PolyMesh.hh
LOGINFO
Definition: LoggingInterface.hh:105
ACG::Matrix4x4T::transform_point
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
CONTEXTOBJECTMENU
The Menu will be shown when an object was picked.
Definition: ContextMenuInterface.hh:75
MouseAndKeyPlugin
Definition: MouseAndKeyPlugin.hh:13
ACG::SceneGraph::find_node
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:83
PluginFunctions::scenegraphPick
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
Definition: PluginFunctions.cc:482
PluginFunctions.hh
PluginFunctions::actionMode
Viewer::ActionMode actionMode()
Get the current Action mode.
Definition: PluginFunctions.cc:590
PluginFunctions::getPickedObject
bool getPickedObject(const unsigned int _node_idx, BaseObjectData *&_object)
Get the picked mesh.
Definition: PluginFunctions.cc:263
DATA_TRIANGLE_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
ACG::Matrix4x4T< double >
BaseObject::id
int id() const
Definition: BaseObject.cc:201
PluginFunctions::traverse
void traverse(ACG::SceneGraph::MouseEventAction &_action)
Definition: PluginFunctions.cc:573