Commit 6b3fd060 authored by Mike Kremer's avatar Mike Kremer

Added tutorial #3

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@5465 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 9d9a1190
......@@ -48,14 +48,14 @@ void MouseAndKeyPlugin::initializePlugin() {
// Set rotation axes to x, y and z axis
axis_x_ = ACG::Vec3d(1.0, 0.0, 0.0);
axis_y_ = ACG::Vec3d(0.0, 1.0, 0.0);
axis_z_ = ACG::Vec3d(0.0, 0.0, 1.0);
// Register keys
emit registerKey(Qt::Key_W, Qt::NoModifier, "Rotate object down");
emit registerKey(Qt::Key_S, Qt::NoModifier, "Rotate object up");
emit registerKey(Qt::Key_A, Qt::NoModifier, "Rotate object left");
emit registerKey(Qt::Key_D, Qt::NoModifier, "Rotate object right");
}
} // End initializePlugin
/*
* Is called after all plugins have been initialized
......@@ -82,8 +82,10 @@ void MouseAndKeyPlugin::pluginsInitialized() {
emit addContextMenuItem(contextMenuEntry_->menuAction() , DATA_TRIANGLE_MESH , CONTEXTOBJECTMENU );
emit addContextMenuItem(contextMenuEntry_->menuAction() , DATA_POLY_MESH , CONTEXTOBJECTMENU );
connect( contextMenuEntry_ , SIGNAL( triggered(QAction*) ), this, SLOT(contextMenuItemSelected(QAction*)) );
}
// Connect the created context menu entry to local function contextMenuItemSelected(QAction*)
connect(contextMenuEntry_, SIGNAL(triggered(QAction*)), this, SLOT(contextMenuItemSelected(QAction*)));
} // End pluginsInitialized
/*
* Initialize toolbox
......@@ -97,11 +99,11 @@ bool MouseAndKeyPlugin::initializeToolbox(QWidget*& _widget)
tool_->resize(size);
// Create button that can be toggled
// to (de)activate plugins picking mode
// to (de)activate plugin's picking mode
pickButton_ = new QPushButton(tr("Select object"));
pickButton_->setCheckable(true);
// Create label the button
// Create label
QLabel* label = new QLabel();
label->setText("(De)activate pick mode");
......@@ -116,7 +118,8 @@ bool MouseAndKeyPlugin::initializeToolbox(QWidget*& _widget)
connect( pickButton_, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
return true;
}
} // End initializeToolbox
/*
* Is called when button in toolbox has been clicked
......@@ -134,19 +137,24 @@ void MouseAndKeyPlugin::slotButtonClicked() {
// Picking mode shall be deactivated
PluginFunctions::actionMode( Viewer::ExamineMode );
}
}
} // End slotButtonClicked
/*
* Is called when pick mode is changed in OpenFlipper
*/
void MouseAndKeyPlugin::slotPickModeChanged( const std::string& _mode) {
void MouseAndKeyPlugin::slotPickModeChanged(const std::string& _mode) {
// Set button checked if pick mode is our
// plugin's pick mode
pickButton_->setChecked(_mode == "MouseAndKeyPlugin");
}
void MouseAndKeyPlugin::slotMouseEvent( QMouseEvent* _event ) {
} // End slotPickModeChanged
/*
* Is called each time the mouse has moved or been clicked
*/
void MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* _event) {
if ( PluginFunctions::pickMode() == "MouseAndKeyPlugin" &&
PluginFunctions::actionMode() == Viewer::PickingMode ) {
......@@ -194,7 +202,8 @@ void MouseAndKeyPlugin::slotMouseEvent( QMouseEvent* _event ) {
ACG::SceneGraph::MouseEventAction action(_event);
PluginFunctions::traverse(action);
}
}
} // End slotMouseEvent
/*
* Is called when a key on the keyboard is pressed
......@@ -255,7 +264,8 @@ void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {
} else {
emit log(LOGINFO, "No object has been selected to rotate! Select object first.");
}
}
} // End slotKeyEvent
/*
* Transform a mesh with the given transformation matrix
......@@ -265,25 +275,32 @@ void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {
*/
template< typename MeshT >
void MouseAndKeyPlugin::transformMesh(ACG::Matrix4x4d _mat , MeshT& _mesh ) {
typename MeshT::VertexIter v_it = _mesh.vertices_begin();
typename MeshT::VertexIter v_end = _mesh.vertices_end();
// Iterator over all vertices and transform them by _mat
// Update normals
for (; v_it!=v_end; ++v_it) {
_mesh.set_point(v_it,(typename MeshT::Point)_mat.transform_point((OpenMesh::Vec3d)(_mesh.point(v_it))));
_mesh.set_normal(v_it,(typename MeshT::Point)_mat.transform_vector((OpenMesh::Vec3d)(_mesh.normal(v_it))));
_mesh.set_point(v_it,(typename MeshT::Point)_mat.transform_point((OpenMesh::Vec3d)(_mesh.point(v_it))));
_mesh.set_normal(v_it,(typename MeshT::Point)_mat.transform_vector((OpenMesh::Vec3d)(_mesh.normal(v_it))));
}
typename MeshT::FaceIter f_it = _mesh.faces_begin();
typename MeshT::FaceIter f_end = _mesh.faces_end();
// Iterate over all faces and update face normals
for (; f_it != f_end; ++f_it)
_mesh.set_normal(f_it,(typename MeshT::Point)_mat.transform_vector((OpenMesh::Vec3d)(_mesh.normal(f_it))));
}
_mesh.set_normal(f_it,(typename MeshT::Point)_mat.transform_vector((OpenMesh::Vec3d)(_mesh.normal(f_it))));
} // End transformMesh
/*
* Is called when context menu entry has been clicked
*/
void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {
// Get needed data from QAction object
// Get object id from QAction object
QVariant contextObject = _action->data();
int objectId = contextObject.toInt();
......@@ -312,7 +329,8 @@ void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {
// Tell core that object's visibility has changed
visibilityChanged(objectId);
}
} // End contextMenuItemSelected
Q_EXPORT_PLUGIN2( mouseandkeyplugin , MouseAndKeyPlugin );
......@@ -38,12 +38,12 @@ class MouseAndKeyPlugin: public QObject,
void log(QString _message);
//ContextMenuInterface
void addContextMenuItem(QAction* _action , ContextMenuType _type);
void addContextMenuItem(QAction* _action , DataType _objectType , ContextMenuType _type );
//PickingInterface
void addPickMode(const std::string _mode);
void addHiddenPickMode(const std::string _mode);
//KeyInterface
void registerKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description, bool _multiUse = false);
void addContextMenuItem(QAction* _action , DataType _objectType , ContextMenuType _type );
//PickingInterface
void addPickMode(const std::string _mode);
void addHiddenPickMode(const std::string _mode);
//KeyInterface
void registerKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description, bool _multiUse = false);
private slots:
......@@ -84,7 +84,6 @@ class MouseAndKeyPlugin: public QObject,
// Rotation axes
ACG::Vec3d axis_x_;
ACG::Vec3d axis_y_;
ACG::Vec3d axis_z_;
private slots:
......
......@@ -8,8 +8,10 @@
* simple keyboard shortcuts. In addition we will focus a little bit on
* what is explained in \ref geometryData. The plugin will provide the following functions:
*
* - Hide objects by clicking at our own context menu entry
* - Rotate an object by hitting the arrow keys on the keyboard
* - Hide object by right-clicking at it and selecting our defined action
* - Select an object by entering user defined pick mode and double-clicking
* at object in the scene
* - Rotate selected object by hitting the w,s,a,d keys on the keyboard
*
* For this purpose we will make use of the following \ref interfaces:
*
......@@ -17,5 +19,109 @@
* - \ref MouseInterface
* - \ref PickingInterface
* - \ref KeyInterface
* - \ref ContextMenuInterface
* - \ref ToolboxInterface
* - \ref LoggingInterface
*
* Since we outlined the details of overriding the BaseInterface methods
* in the previous tutorials (\ref ex1 and \ref ex2) we can directly switch
* over to what happens within these methods. When initializing our plugin
* we set the active object identifier to -1 since no object has been selected yet.
* We initialize the axis vectors that we'll need for the rotation later on.
* Then we tell OpenFlipper that we will use the w, a, s and d key on the
* keyboard (so it'll call slotKeyEvent() each time one of
* the keys has been pressed). Note: OpenFlipper will show up a warning message in the log
* widget if the desired keys are already assigned to another plugin or core function.
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::initializePlugin() {
* \until } // End initializePlugin
*
* If all plugins have been initialized, we add our own pick mode named "MouseAndKeyPlugin"
* to OpenFlipper and create the context menu entry (which is actually a QMenu object containing
* one (or generally multiple) object(s) of type QAction) which we connect to contextMenuItemSelected().
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::pluginsInitialized() {
* \until } // End pluginsInitialized
*
* In intializeToolbox() we create a simple toolbox containing a label and a push-button.
* We connect the button to our method slotButtonClicked() which will then be called
* each time the button is clicked.
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip bool MouseAndKeyPlugin::initializeToolbox(QWidget*& _widget)
* \until } // End initializeToolbox
*
* Now each time the button in our toolbox is clicked we want to activate
* the picking mode, such that if the button is checked pick mode "MouseAndKeyPlugin"
* that we defined at the beginning will be active and OpenFlipper switches over from
* ExamineMode to PickingMode (see \ref PluginFunctions for details). Clicking once more
* at the button will return to ExamineMode (in which the user can navigate through the scene).
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::slotButtonClicked() {
* \until } // End slotButtonClicked
*
* If the pick mode has been changed externally, we want our button in the toolbox
* to appear pressed (or unpressed respectively). _mode holds the name of the
* currently selected pick mode.
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::slotPickModeChanged(const std::string& _mode) {
* \until } // End slotPickModeChanged
*
* In the next method we describe how mouse actions are to be handled by the plugin.
* We want our plugin only to react to mouse events if our pick mode is active otherwise
* don't do anything. If OpenFlipper is in PickingMode and the currently active pick mode
* is "MouseAndKeyPlugin" we try to get the object on that the user has double clicked.
* If the object can be found, we'll show up a dialog window displaying the picked object's
* identifier and assign it to the member variable that holds the active object.
* Otherwise we display "Picking failed" in the log widget. Note that if object picking
* failed the mouse event has to be traversed through the rest of the scene graph.
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* _event) {
* \until } // End slotMouseEvent
*
* Next method is called whenever any of the keys w, s, a or d is pressed. If an object has
* been selected (accordingly the member variable activeObject_ holds a valid objects
* identifier -as described before-) we try to get its handle by calling
* PluginFunctions::getPickedObject(). We then set the rotation matrix of the selected
* object's transform node (manipulatorNode) to hold a matrix that describes
* a rotation around the x (if w or s is pressed) or y axis (if a or d is pressed) by +/- 10 degrees.
* We then call the method transformMesh and pass the recently calculated matrix and
* a handle to the mesh (triangle or polygon). As said in \ref geometryData we have to
* inform OpenFlipper's core about the changes by calling BaseInterface::updatedObject(int).
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {
* \until } // End slotKeyEvent
*
* This template method transforms the given mesh:
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip template< typename MeshT >
* \until } // End transformMesh
*
* Last but not least, the method that is called each time our context menu has been clicked.
* We get the object's id on which the user has performed a right click from the action data.
* Then we try to get the node and its BaseObjectData handle. If successfully passed to this
* point we hide the object by calling its hide() method. As described in \ref geometryData
* we now have to call BaseInterface::visibilityChanged() for the core to be informed about
* the changes.
*
* \dontinclude MouseAndKeyPlugin.cc
* \skip void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {
* \until } // End contextMenuItemSelected
*
* \section ex3_source The complete source code of this example
*
* We use the same project file as created in \ref ex1b.
*
* MouseAndKeyPlugin.hh
* \include MouseAndKeyPlugin.hh
*
* MouseAndKeyPlugin.cc
* \include MouseAndKeyPlugin.cc
*/
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment