MouseAndKeyPlugin.cc 8.83 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  OpenFlipper is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  OpenFlipper is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision: 5409 $
//   $Author: kremer $
//   $Date: 2009-03-23 12:47:01 +0100 (Mo, 23 Mär 2009) $
//
//=============================================================================

#include "MouseAndKeyPlugin.hh"


#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"

/*
 * Initialize plugin
 */
void MouseAndKeyPlugin::initializePlugin() {

	// Set active object to -1
	activeObject_ = -1;

	// 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");
}

/*
 * Is called after all plugins have been initialized
 */
void MouseAndKeyPlugin::pluginsInitialized() {

	// Add pickmode
	emit addPickMode("MouseAndKeyPlugin");

	// Add context menu entry

	// Create submenu
	contextMenuEntry_ = new QMenu("Mouse and key plugin");

	QAction* lastAction;

	// Add action to recently created menu
	lastAction = contextMenuEntry_->addAction( "Hide object" );
	lastAction->setToolTip("Hide selected object");
	lastAction->setStatusTip( lastAction->toolTip() );

	// Finally insert created context submenu to OpenFlipper's context menu
	// We want our action to be visible for triangle and polygon meshes
	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*)) );
}

/*
 * Initialize toolbox
 */
bool MouseAndKeyPlugin::initializeToolbox(QWidget*& _widget)
{

  tool_ = new QWidget();
  _widget = tool_;
  QSize size(300, 300);
  tool_->resize(size);

  // Create button that can be toggled
  // to (de)activate plugins picking mode
  pickButton_ = new QPushButton(tr("Select object"));
  pickButton_->setCheckable(true);

  // Create label the button
  QLabel* label = new QLabel();
  label->setText("(De)activate pick mode");

  // Set label to be above the button
  QGridLayout* grid = new QGridLayout;
  grid->addWidget(label, 0, 0);
  grid->addWidget(pickButton_, 1, 0);

  tool_->setLayout(grid);

  // Connect button to slotButtonClicked()
  connect( pickButton_, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));

  return true;
}

Mike Kremer's avatar
Mike Kremer committed
121
122
123
/*
 * Is called when button in toolbox has been clicked
 */
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
void MouseAndKeyPlugin::slotButtonClicked() {

	if(pickButton_->isChecked()) {
		// Picking mode of our plugin shall be activated
		// set OpenFlipper's action mode to picking
		PluginFunctions::actionMode( Viewer::PickingMode );

		// Now activate our picking mode
		PluginFunctions::pickMode( "MouseAndKeyPlugin" );
	} else {
		// Picking mode shall be deactivated
		PluginFunctions::actionMode( Viewer::ExamineMode );
	}
}

/*
 * Is called when pick mode is changed in OpenFlipper
 */
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 ) {

	if ( PluginFunctions::pickMode() == "MouseAndKeyPlugin" &&
		PluginFunctions::actionMode() == Viewer::PickingMode ) {

		// If double click has been performed
		if (_event->type() == QEvent::MouseButtonDblClick) {

			unsigned int node_idx, target_idx;
			OpenMesh::Vec3d hitPoint;

			// Get picked object's identifier
			if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,_event->pos(), node_idx, target_idx, &hitPoint) ) {

				BaseObjectData* object;

				// Get picked object
				if ( PluginFunctions::getPickedObject(node_idx, object) ) {

					// Show small dialog window
					QDialog* dlg = new QDialog;

					QGridLayout* grid = new QGridLayout;
					QLabel* label = new QLabel;
					QString str = QString("You selected object ");
					str += QString::number(node_idx);
					label->setText(str);
					grid->addWidget(label, 0,0);

					dlg->setLayout(grid);

					dlg->show();

					// Set last selected object
					activeObject_ = node_idx;
				}
				else {
					emit log(LOGINFO, "Picking failed");
				}
			}

			return;
		}

		// Continue traversing scene graph
		ACG::SceneGraph::MouseEventAction action(_event);
		PluginFunctions::traverse(action);
	}
}

/*
 * Is called when a key on the keyboard is pressed
 */
void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {

	BaseObjectData* object;
Mike Kremer's avatar
Mike Kremer committed
205
206

	// Get last clicked object (selected in pick mode)
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
	if ( PluginFunctions::getPickedObject(activeObject_, object) ) {

		// Switch pressed keys
		switch (_event->key())
		{
			case Qt::Key_W:

				object->manipulatorNode()->loadIdentity();
				object->manipulatorNode()->rotate(10.0, axis_x_);

				break;

			case Qt::Key_S :

				object->manipulatorNode()->loadIdentity();
				object->manipulatorNode()->rotate(-10.0, axis_x_);

				break;

			case Qt::Key_A :

				object->manipulatorNode()->loadIdentity();
				object->manipulatorNode()->rotate(10.0, axis_y_);

				break;

			case Qt::Key_D :

				object->manipulatorNode()->loadIdentity();
				object->manipulatorNode()->rotate(-10.0, axis_y_);

				break;

			default:
			break;
		}

		// Perform rotation
		if ( object->dataType( DATA_TRIANGLE_MESH ) )
			transformMesh(object->manipulatorNode()->matrix(), (*PluginFunctions::triMesh(object)));
		if ( object->dataType( DATA_POLY_MESH ) )
			transformMesh(object->manipulatorNode()->matrix(), (*PluginFunctions::polyMesh(object)));

		// Tell core that object has been modified
		updatedObject(object->id());

		// Update view
		emit updateView();
	} else {
		emit log(LOGINFO, "No object has been selected to rotate! Select object first.");
	}
}

/*
 * Transform a mesh with the given transformation matrix
 *
 * _mat : transformation matrix
 * _mesh : the mesh
 */
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();
   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))));
   }

   typename MeshT::FaceIter f_it     = _mesh.faces_begin();
   typename MeshT::FaceIter f_end = _mesh.faces_end();
   for (; f_it != f_end; ++f_it)
            _mesh.set_normal(f_it,(typename MeshT::Point)_mat.transform_vector((OpenMesh::Vec3d)(_mesh.normal(f_it))));
}

Mike Kremer's avatar
Mike Kremer committed
281
282
283
/*
 * Is called when context menu entry has been clicked
 */
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {

	// Get needed data from QAction object
	QVariant contextObject = _action->data();
    int objectId = contextObject.toInt();

    if ( objectId == -1) {

    	log(LOGINFO, "Could not get associated object id.");
    	return;
    }

    // Get node associated to object id
    ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node( PluginFunctions::getSceneGraphRootNode(), objectId );

    // Return if node id was not valid
    if(!node) {

    	log(LOGINFO, "Could not find associated object.");
    	return;
    }

    BaseObjectData* obj;
    if ( ! PluginFunctions::getObject(objectId,obj) )
        return;

    // Hide object
    obj->hide();

    // Tell core that object's visibility has changed
    visibilityChanged(objectId);
}

Q_EXPORT_PLUGIN2( mouseandkeyplugin , MouseAndKeyPlugin );