MovePlugin.cc 91.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
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
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  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 with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  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 LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42

Matthias Möller's avatar
Matthias Möller committed
43
44
45
46
47
48

#if QT_VERSION >= 0x050000 
  #include <QtWidgets>
#else
  #include <QtGui>
#endif
Jan Möbius's avatar
 
Jan Möbius committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

#include "MovePlugin.hh"

#include <iostream>
#include <ACG/GL/GLState.hh>
#include <QStringList>
#include <ACG/QtScenegraph/QtTranslationManipulatorNode.hh>

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>

#include <MeshTools/MeshFunctions.hh>
#include <MeshTools/MeshInfoT.hh>

#ifdef USE_OPENMP
#include <omp.h>
#endif

#ifdef ENABLE_POLYLINE_SUPPORT
#include <ObjectTypes/PolyLine/PolyLine.hh>
#endif

Henrik Zimmer's avatar
Henrik Zimmer committed
71
72
73
#ifdef ENABLE_TSPLINEMESH_SUPPORT
#include <ObjectTypes/TSplineMesh/TSplineMesh.hh>
#endif
Jan Möbius's avatar
 
Jan Möbius committed
74

Dirk Wilden's avatar
Dirk Wilden committed
75
76
77
78
#ifdef ENABLE_SKELETON_SUPPORT
#include <ObjectTypes/Skeleton/Helper/SkeletonTransform.hh>
#endif

79
80
81
82
83
84
85
86
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
#include <ObjectTypes/HexahedralMesh/HexahedralMesh.hh>
#endif

#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
#include <ObjectTypes/PolyhedralMesh/PolyhedralMesh.hh>
#endif

Jan Möbius's avatar
 
Jan Möbius committed
87
/** \brief Default Constructor
88
 *
Jan Möbius's avatar
 
Jan Möbius committed
89
 */
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
90
MovePlugin::MovePlugin() :
Jan Möbius's avatar
Jan Möbius committed
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
121
axisA_(0),
axisB_(1),
toolboxActive_(false),
tool_(0),
toolIcon_(0),
moveAction_(0),
moveSelectionAction_(0),
toolBarActions_(0),
toolbar_(0),
pickToolbar_(0),
placeAction_(0),
rotateTranslateAction_(0),
rotateManipAction_(0),
resizeAction_(0),
biggerManipAction_(0),
smallerManipAction_(0),
fixChildManipAction_(0),
transformRefPoseManipAction_(0),
currentPoseManipAction_(0),
placeAndSnapAction_(0),
pickToolBarActions_(0),
manip_size_(1.0),
manip_size_modifier_(1.0),
lastActiveManipulator_(-1),
manMode_(QtTranslationManipulatorNode::TranslationRotation),
selectionType_(VERTEX),
contextAction_(0),
contextActionHide_(0),
toAllTargets_(0),
hide_(true),
allTargets_(false),
122
123
placeMode_(false),
transformedSelected_(false)
Jan Möbius's avatar
 
Jan Möbius committed
124
125
126
127
{

}

128
129
130
131
132
133
134
135
136
/** \brief Deconstructor
 *
 */
MovePlugin::~MovePlugin() {

	if(contextAction_) {
		delete contextAction_;
	}

Jan Möbius's avatar
Jan Möbius committed
137
138
139
140
  if(contextActionHide_) {
    delete contextActionHide_;
  }

141
142
143
144
145
146
147
148
149
150
151
152
153
	if(toAllTargets_) {
		delete toAllTargets_;
	}

	for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
		it != propsWindows_.end(); ++it) {

		if(*it) {
			delete *it;
		}
	}
}

Jan Möbius's avatar
 
Jan Möbius committed
154
155
156
157
158
159

/*******************************************************************************
        BaseInterface implementation
 *******************************************************************************/

/** \brief Initialization of the plugin when it is loaded by the core
160
 *
Jan Möbius's avatar
 
Jan Möbius committed
161
162
163
164
165
166
167
168
169
170
 */
void MovePlugin::pluginsInitialized() {

  //PICKMODES
  emit addPickMode("Separator");
  emit addHiddenPickMode("Move");
  emit setPickModeMouseTracking ("Move", true);
  emit addHiddenPickMode("MoveSelection");
  emit setPickModeMouseTracking ("MoveSelection", true);

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
171
  //KEYS
Mike Kremer's avatar
Mike Kremer committed
172
  emit registerKey (Qt::Key_Shift, Qt::NoModifier, tr("Manipulator rotation"), true);
Jan Möbius's avatar
Jan Möbius committed
173
  emit registerKey (Qt::Key_Shift, Qt::ShiftModifier, tr("Manipulator rotation"), true);
174
  emit registerKey (Qt::Key_Shift, Qt::ControlModifier | Qt::ShiftModifier, tr("Manipulator rotation"), true);
Mike Kremer's avatar
Mike Kremer committed
175
  emit registerKey (Qt::Key_Control, Qt::NoModifier, tr("Resize"), true);
Jan Möbius's avatar
Jan Möbius committed
176
  emit registerKey (Qt::Key_Control, Qt::ControlModifier, tr("Resize"), true);
Mike Kremer's avatar
Mike Kremer committed
177
  emit registerKey (Qt::Key_Control, Qt::ShiftModifier | Qt::ControlModifier, tr("Resize"), true);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
178

Jan Möbius's avatar
 
Jan Möbius committed
179
180
  //SCRIPTING SLOT DESCRIPTIONS
  setDescriptions();
181

182
  // CONTEXT MENU
Jan Möbius's avatar
Jan Möbius committed
183
  toAllTargets_ = new QAction(tr("Apply to all targets"), this);
184
  toAllTargets_->setCheckable(true);
Jan Möbius's avatar
Jan Möbius committed
185
  toAllTargets_->setToolTip(tr("Apply transformation to all target objects"));
186
187
  toAllTargets_->setStatusTip( toAllTargets_->toolTip() );

Jan Möbius's avatar
Jan Möbius committed
188
189
  contextAction_ = new QAction(tr("Set properties"), this);
  contextAction_->setToolTip(tr("Set properties"));
190
  contextAction_->setStatusTip( contextAction_->toolTip() );
Jan Möbius's avatar
Jan Möbius committed
191
  contextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-properties.png") );
192
  
193
194
195
196
  contextActionHide_ = new QAction(tr("Hide Manipulator"), this);
  contextActionHide_->setToolTip(tr("Hide Manipulator"));
  contextActionHide_->setStatusTip( contextActionHide_->toolTip() );
  contextActionHide_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-hide.png") );
197

198
199
  emit addContextMenuItem(toAllTargets_      , CONTEXTNODEMENU );
  emit addContextMenuItem(contextAction_     , CONTEXTNODEMENU );
200
  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
201

202
203
  connect( toAllTargets_  ,     SIGNAL(toggled(bool) ), this, SLOT(setAllTargets(bool)));
  connect( contextAction_ ,     SIGNAL( triggered() ),  this, SLOT(showProps()) );
204
  connect( contextActionHide_ , SIGNAL( triggered() ),  this, SLOT(hideManipulator()) );
Jan Möbius's avatar
 
Jan Möbius committed
205
206

  //TOOLBAR
207
208
209
210

  WhatsThisGenerator whatsThis("Move");
  WhatsThisGenerator whatsThisUser("user");

Jan Möbius's avatar
Jan Möbius committed
211
  toolbar_ = new QToolBar(tr("Transform and Move"));
212
  toolbar_->setObjectName("TransformAndMoveToolBar");
Jan Möbius's avatar
 
Jan Möbius committed
213
214
215

  toolBarActions_ = new QActionGroup(toolbar_);

216
  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
Jan Möbius's avatar
 
Jan Möbius committed
217
218
219
  moveAction_->setStatusTip(tr("Move object in 3D."));
  moveAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-objects.png") );
  moveAction_->setCheckable(true);
220
  whatsThis.setWhatsThis(moveAction_,tr("Move the whole object."));
Jan Möbius's avatar
 
Jan Möbius committed
221
222
  toolbar_->addAction(moveAction_);

223
  moveSelectionAction_ = new QAction(tr("<B>Move Selection</B><br>Move a selection on an object"), toolBarActions_);
Jan Möbius's avatar
 
Jan Möbius committed
224
225
226
  moveSelectionAction_->setStatusTip(tr("Move selections in 3D."));
  moveSelectionAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-selections.png") );
  moveSelectionAction_->setCheckable(true);
227
  whatsThis.setWhatsThis(moveSelectionAction_,tr("Move only a selection."));
Jan Möbius's avatar
 
Jan Möbius committed
228
  toolbar_->addAction(moveSelectionAction_);
229
  
Jan Möbius's avatar
 
Jan Möbius committed
230
231
232
  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );

  emit addToolbar(toolbar_);
233

234
235
236
  pickToolbar_ = new QToolBar(tr("Transform and Move PickTool bar"));
  pickToolbar_->setObjectName("TransformAndMovePickToolBar");

237
  pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
238
239
240
241
242
  pickToolBarActions_ = new QActionGroup(pickToolbar_);
  pickToolBarActions_->setExclusive (false);

  placeAction_ = new QAction(tr("Place manipulator"), pickToolBarActions_);
  placeAction_->setStatusTip(tr("Place manipulator on object. <Doubleclick>"));
243
  placeAction_->setToolTip(tr("Place manipulator on object. <Doubleclick>"));
244
  placeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-place.png") );
245
  whatsThisUser.setWhatsThis(placeAction_,tr("Place the manipulator."),"obj_man","manipulator.html");
246
247
248
249
250
  placeAction_->setCheckable(true);
  pickToolbar_->addAction(placeAction_);

  pickToolbar_->addSeparator ();

251
252
  rotateTranslateAction_ = new QAction(tr("Rotate/Translate object"), pickToolBarActions_);
  rotateTranslateAction_->setStatusTip(tr("Rotate/Translate object."));
253
  rotateTranslateAction_->setToolTip(tr("Rotate/Translate object."));
254
255
256
  rotateTranslateAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-translaterotate.png") );
  rotateTranslateAction_->setCheckable(true);
  rotateTranslateAction_->setChecked(true);
257
  whatsThisUser.setWhatsThis(rotateTranslateAction_,tr("Rotate or translate an object or selection."),"obj_translation","manipulator.html");
258
  pickToolbar_->addAction(rotateTranslateAction_);
259
260
261

  resizeAction_ = new QAction(tr("Resize object"), pickToolBarActions_);
  resizeAction_->setStatusTip(tr("Resize object. <Control>"));
262
  resizeAction_->setToolTip(tr("Resize object. <Control>"));
263
  resizeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-resize.png") );
264
  whatsThisUser.setWhatsThis(resizeAction_,tr("Resize object or selection."),"obj_resizing","manipulator.html");
265
266
267
268
269
  resizeAction_->setCheckable(true);
  pickToolbar_->addAction(resizeAction_);

  pickToolbar_->addSeparator ();

270
271
  rotateManipAction_ = new QAction(tr("Rotate manipulator"), pickToolBarActions_);
  rotateManipAction_->setStatusTip(tr("Rotate manipulator. <Shift>"));
272
  rotateManipAction_->setToolTip(tr("Rotate manipulator. <Shift>"));
273
  rotateManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-maniprotate.png") );
274
  whatsThisUser.setWhatsThis(rotateManipAction_,tr("Rotate only the Manipulator."),"man_rotating","manipulator.html");
275
276
  rotateManipAction_->setCheckable(true);
  pickToolbar_->addAction(rotateManipAction_);
277

278
279
  placeAndSnapAction_ = new QAction(tr("Locally translate manipulator"), pickToolBarActions_);
  placeAndSnapAction_->setStatusTip(tr("Locally translate manipulator. Press and hold <Alt> for snapping."));
280
  whatsThisUser.setWhatsThis(placeAndSnapAction_,tr("Translate only the Manipulator."),"man_translation","manipulator.html");
Mike Kremer's avatar
Mike Kremer committed
281
  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
282
283
284
  placeAndSnapAction_->setCheckable(true);
  pickToolbar_->addAction(placeAndSnapAction_);

285
286
  smallerManipAction_ = new QAction(tr("Decrease size of manipulator"), pickToolBarActions_);
  smallerManipAction_->setStatusTip(tr("Make manipulator smaller. <Mouse wheel up>"));
287
  smallerManipAction_->setToolTip(tr("Make manipulator smaller. <Mouse wheel up>"));
288
  whatsThisUser.setWhatsThis(smallerManipAction_,tr("Resize the Manipulator to a smaller one."),"man_resizing","manipulator.html");
289
290
291
292
  smallerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipsmall.png") );
  smallerManipAction_->setCheckable(false);
  pickToolbar_->addAction(smallerManipAction_);

Jan Möbius's avatar
Jan Möbius committed
293
  biggerManipAction_ = new QAction(tr("Increase size of manipulator"), pickToolBarActions_);
294
  biggerManipAction_->setStatusTip(tr("Make manipulator bigger. <Mouse wheel down>"));
295
  biggerManipAction_->setToolTip(tr("Make manipulator bigger. <Mouse wheel down>"));
296
  whatsThisUser.setWhatsThis(biggerManipAction_,tr("Resize the Manipulator to a bigger one."),"man_resizing","manipulator.html");
297
298
299
  biggerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipbig.png") );
  biggerManipAction_->setCheckable(false);
  pickToolbar_->addAction(biggerManipAction_);
300
  
301
302
303
304
  connect(pickToolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotPickToolbarAction(QAction*)) );

  emit setPickModeToolbar ("Move", pickToolbar_);
  emit setPickModeToolbar ("MoveSelection", pickToolbar_);
Jan Möbius's avatar
 
Jan Möbius committed
305
306
307
308
309
310
311
}


/*******************************************************************************
        ToolBoxInterface implementation
 *******************************************************************************/

Jan Möbius's avatar
Jan Möbius committed
312
void MovePlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
313
314
315
316
317
318
319
320
{
   toolboxActive_ = false;
   tool_ = new moveToolbarWidget();

   connect(tool_->moveToOrigin,SIGNAL(clicked() ),this,SLOT(slotMoveToOrigin()));

   tool_->moveToOrigin->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "moveToCOG.png") );
   tool_->moveToOrigin->setIconSize(QSize(48,48));
321
322
323
   WhatsThisGenerator whatsThis("Move");
   tool_->moveToOrigin->setWhatsThis(QString(tr("Moves the selected objects such that their center of gravity is at the origin."))
       +whatsThis.generateLink("move_cog"));
Jan Möbius's avatar
 
Jan Möbius committed
324
325
326
327

   connect(tool_->unifyBoundingBoxDiagonal,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxDiagonal()));
   tool_->unifyBoundingBoxDiagonal->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB.png") );
   tool_->unifyBoundingBoxDiagonal->setIconSize(QSize(48,48));
328
329
   tool_->unifyBoundingBoxDiagonal->setWhatsThis(QString(tr("Rescale objects such that its bounding box diagonal has length one."))
          +whatsThis.generateLink("unifyBB"));
Jan Möbius's avatar
 
Jan Möbius committed
330
331
332

   lastActiveManipulator_ = -1;

Dirk Wilden's avatar
Dirk Wilden committed
333
334
   toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-toolBox.png");
   emit addToolbox( tr("Move") , tool_, toolIcon_ );
Jan Möbius's avatar
 
Jan Möbius committed
335
336
337
338
339
340
341
342
343
}


/*******************************************************************************
        MouseInterface implementation
 *******************************************************************************/

void MovePlugin::slotMouseWheelEvent(QWheelEvent * _event, const std::string & /*_mode*/)
{
344
  // Skip execution if this is not our pick mode
345
  if( ( (PluginFunctions::pickMode() != "Move")
Dirk Wilden's avatar
Dirk Wilden committed
346
     && (PluginFunctions::pickMode() != "MoveSelection") )
347
    || PluginFunctions::actionMode() != Viewer::PickingMode)
348
349
350
351
352
353
354
355
356
357
358
    return;
  
  // compute the manipulator size modifier based on the mouse wheel change
  manip_size_modifier_ = manip_size_modifier_ - (float)_event->delta() / 120.0 * 0.1;
  
  // Resize all manipulators based on the modifier on all objects
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
      o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);

  // Redraw scene with updated manipulators
  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
359
360
361
362
363
364
}


//------------------------------------------------------------------------------

/** \brief MousePress event occured
365
 *
Jan Möbius's avatar
 
Jan Möbius committed
366
367
 * @param _event the event that occured
 */
368
void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
369
    if (((PluginFunctions::pickMode() == ("Move"))
Dirk Wilden's avatar
Dirk Wilden committed
370
      || (PluginFunctions::pickMode() == ("MoveSelection")))
371
            && PluginFunctions::actionMode() == Viewer::PickingMode) {
Jan Möbius's avatar
 
Jan Möbius committed
372

373
374
        if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
                && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
Dirk Wilden's avatar
Dirk Wilden committed
375
376

            bool snap = (placeMode_ && (PluginFunctions::pickMode() == ("MoveSelection")));
Jan Möbius's avatar
 
Jan Möbius committed
377

378
            placeManip(_event, snap);
379
380
            placeAction_->setChecked(false);
            updateManipulatorDialog();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
381

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
            if (placeMode_) {
                manMode_ = QtTranslationManipulatorNode::TranslationRotation;

                for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS); o_it
                        != PluginFunctions::objectsEnd(); ++o_it)
                    if (o_it->manipPlaced())
                        o_it->manipulatorNode()->setMode(manMode_);

                resizeAction_->setChecked(false);
                rotateManipAction_->setChecked(false);
                rotateTranslateAction_->setChecked(true);
                placeAndSnapAction_->setChecked(false);
            }

            placeMode_ = false;
            return;

        } else if (placeMode_) {

            /*
             * Move manipulator along with cursor if placeAndSnap mode
             * is active. Snap to nearest geometry element (vertex, line, face center)
             * depending on which selection type is active.
405
             *
406
407
             */

408
            placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
409
410
411
412
413
            updateManipulatorDialog();
            return;
        }

        // interaction
414
        ACG::SceneGraph::MouseEventAction action(_event,PluginFunctions::viewerProperties().glState());
415
416
417
        PluginFunctions::traverse(action);

        if (_event->buttons() == Qt::LeftButton)
418
          emit nodeVisibilityChanged(-1);
419
420

    }
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
421
422
423
424
425
426
427
428
}

/*******************************************************************************
        KeyInterface implementation
 *******************************************************************************/

void MovePlugin::slotKeyEvent (QKeyEvent* _event)
{
429
  if ((_event->key() == Qt::Key_Control) && _event->modifiers() != Qt::ShiftModifier) {
430
    setManipMode (QtTranslationManipulatorNode::Resize);
431
432
    return;
  } else if ((_event->key () == Qt::Key_Shift) && _event->modifiers() != Qt::ControlModifier) {
433
    setManipMode (QtTranslationManipulatorNode::LocalRotation);
434
435
436
437
438
439
    return;
  }

  // Return to normal mode if Ctrl + Shift is pressed since this
  // is used in translation manipulator node for rotation rasterization
  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
Jan Möbius's avatar
 
Jan Möbius committed
440
441
}

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
442
443
//------------------------------------------------------------------------------

444
445
void MovePlugin::slotEnableSelectionMode()
{
446
  PluginFunctions::pickMode("MoveSelection");
447
448
449
450
451
452
453
454
455
}

//------------------------------------------------------------------------------
void MovePlugin::slotEnableObjectMode()
{
  PluginFunctions::pickMode("Move");
}
//------------------------------------------------------------------------------

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
456
457
458
459
void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
{
  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
      (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
460
    setManipMode (QtTranslationManipulatorNode::TranslationRotation);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
461
}
Jan Möbius's avatar
 
Jan Möbius committed
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
void MovePlugin::setPickModeProps(movePropsWidget* _pW, const std::string &_pickmode)
{
  if (_pickmode == "Move")
  {
    _pW->objectRadioButton->setChecked(true);
  }
  else if (_pickmode == "MoveSelection")
  {
    _pW->selectionRadioButton->setChecked(true);
  }
  else
  {
    //not supported, so deselect all radio buttons
    _pW->objectRadioButton->setAutoExclusive(false);
    _pW->selectionRadioButton->setAutoExclusive(false);
    _pW->objectRadioButton->setChecked(false);
    _pW->selectionRadioButton->setChecked(false);
    _pW->objectRadioButton->setAutoExclusive(true);
    _pW->selectionRadioButton->setAutoExclusive(true);
  }
}

Jan Möbius's avatar
 
Jan Möbius committed
485
486
487
488
489
/*******************************************************************************
        PickingInterface implementation
 *******************************************************************************/

/** \brief slot is called when the pickMode changed
490
 *
Jan Möbius's avatar
 
Jan Möbius committed
491
492
493
494
 * @param _mode new pickMode
 */
void MovePlugin::slotPickModeChanged( const std::string& _mode)
{
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
495
496
  moveAction_->setChecked(_mode == "Move");
  moveSelectionAction_->setChecked(_mode == "MoveSelection");
497

Dirk Wilden's avatar
Dirk Wilden committed
498
  hide_ = !(_mode == "Move" || _mode == "MoveSelection");
Jan Möbius's avatar
 
Jan Möbius committed
499

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
500
501
502
503
504
505
  showManipulators();

  if (!hide_)
  {
    switch (manMode_)
    {
506
507
508
      case QtTranslationManipulatorNode::Rotation:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
509
510
511
512
513
514
      case QtTranslationManipulatorNode::Resize:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        PluginFunctions::setViewObjectMarker (&objectMarker_);
        break;
515
516
517
      case QtTranslationManipulatorNode::Place:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
518
519
520
521
522
523
524
      case QtTranslationManipulatorNode::TranslationRotation:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
    }
  }
  else
    PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
525
526

  //change the selection mode in propety widget
527
  for (int i = 0; i < propsWindows_.size(); ++i)
528
529
    setPickModeProps(propsWindows_[i], _mode);

Jan Möbius's avatar
 
Jan Möbius committed
530
531
532
533
534
535
536
537
}


/*******************************************************************************
        MovePlugin implementation
 *******************************************************************************/

/** \brief Move object with given transformation matrix
538
 *
Jan Möbius's avatar
 
Jan Möbius committed
539
540
541
542
543
 * @param mat transformation matrix
 * @param _id id of the object
 */
void MovePlugin::moveObject(ACG::Matrix4x4d mat, int _id) {
  BaseObjectData* object;
Dirk Wilden's avatar
Dirk Wilden committed
544
  if ( ! PluginFunctions::getObject(_id,object) )
Jan Möbius's avatar
 
Jan Möbius committed
545
546
    return;

Dirk Wilden's avatar
Dirk Wilden committed
547
548
549
  if ( mat.is_identity() )
    return;

550
551
552
553
  if  ( object->dataType()  == DATA_TRIANGLE_MESH ) {
    transformMesh(mat , *PluginFunctions::triMesh(object) );
  } else  if  ( object->dataType()  == DATA_POLY_MESH ) {
    transformMesh(mat , *PluginFunctions::polyMesh(object) );
Henrik Zimmer's avatar
Henrik Zimmer committed
554
555
556
557
#ifdef ENABLE_TSPLINEMESH_SUPPORT
  } else  if  ( object->dataType()  == DATA_TSPLINE_MESH ) {
    transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
#endif
558
#ifdef ENABLE_POLYLINE_SUPPORT
559
560
  } else  if  ( object->dataType()  == DATA_POLY_LINE ) {
    transformPolyLine(mat , *PluginFunctions::polyLine(object) );
Dirk Wilden's avatar
Dirk Wilden committed
561
562
563
564
#endif
#ifdef ENABLE_SKELETON_SUPPORT
  } else  if  ( object->dataType()  == DATA_SKELETON ) {
    transformSkeleton(mat , *PluginFunctions::skeleton(object) );
565
566
567
568
569
570
571
572
573
574
#endif
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
  } else  if  ( object->dataType()  == DATA_HEXAHEDRAL_MESH ) {
    HexahedralMeshObject* obj = PluginFunctions::hexahedralMeshObject(object);
    transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
  } else  if  ( object->dataType()  == DATA_POLYHEDRAL_MESH ) {
    PolyhedralMeshObject* obj = PluginFunctions::polyhedralMeshObject(object);
    transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
575
#endif
Dirk Wilden's avatar
Dirk Wilden committed
576
  } else  if  ( object->dataType()  == DATA_PLANE ) {
Jan Möbius's avatar
   
Jan Möbius committed
577
    PluginFunctions::plane(object)->transform(mat);
578
579
  } else {

Jan Möbius's avatar
Jan Möbius committed
580
    emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
581
    return;
Jan Möbius's avatar
 
Jan Möbius committed
582
583
  }

584
  emit updatedObject(_id, UPDATE_GEOMETRY);
Dirk Wilden's avatar
Dirk Wilden committed
585
  emit createBackup(_id, "Move Object", UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
586
587
588
589
590
591
}


//------------------------------------------------------------------------------

/** \brief Move selection on an object with given transformation matrix
592
 *
Jan Möbius's avatar
 
Jan Möbius committed
593
594
595
596
 * Which Selection (Vertex, Edge, Face) is used is determined by the
 * current SelectionMode in SelectionPlugin.
 * If the Plugin is unable to communicate with SelectionPlugin, Vertex Selection is used.
 *
Jan Möbius's avatar
Jan Möbius committed
597
598
599
 * @param _mat  Matrix that should be applied to the selection
 * @param _id   Object id of the target object
 * @param _type Type of mouse event ( release of the button creates a backup)
Jan Möbius's avatar
 
Jan Möbius committed
600
 */
Jan Möbius's avatar
Jan Möbius committed
601
void MovePlugin::moveSelection(ACG::Matrix4x4d _mat, int _id, QEvent::Type _type) {
602
603
  // Get currently active primitive type
  updateSelectionType();
604

Jan Möbius's avatar
Jan Möbius committed
605
  if ( !_mat.is_identity() ){
606
    if (selectionType_ & VERTEX) {
607
      transformedSelected_ = transformVertexSelection( _id , _mat );
608
    }
609
    if (selectionType_ & FACE) {
610
      transformedSelected_ = transformFaceSelection( _id , _mat );
611
    }
612
    if (selectionType_ & EDGE) {
613
      transformedSelected_ = transformEdgeSelection( _id , _mat );
614
    }
615
616
617
    if (selectionType_ & CELL) {
      transformedSelected_ = transformCellSelection( _id , _mat );
    }
Jan Möbius's avatar
 
Jan Möbius committed
618

Dirk Wilden's avatar
Dirk Wilden committed
619
620
621
    emit updatedObject(_id, UPDATE_GEOMETRY);
  }

622
623
  //only create backups on mouseRelease and something has to have been selected and transformed
  if ( _type == QEvent::MouseButtonRelease && transformedSelected_ )
Dirk Wilden's avatar
Dirk Wilden committed
624
    emit createBackup(_id,"Move Selection", UPDATE_GEOMETRY);
625

Jan Möbius's avatar
 
Jan Möbius committed
626
627
}

628
629
//------------------------------------------------------------------------------

630
631
632
633
634
635
636
637
638
/** \brief Set the manipulator manipulation mode
 *
 * @param _mode Mode
 */
void MovePlugin::setManipMode (QtTranslationManipulatorNode::ManipulatorMode _mode)
{
  if (_mode != manMode_)
  {
    manMode_ = _mode;
Dirk Wilden's avatar
Dirk Wilden committed
639
    if ((PluginFunctions::pickMode() == "Move" ) || (PluginFunctions::pickMode() == "MoveSelection" )) {
640
641
642
643
        for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ;
              o_it != PluginFunctions::objectsEnd(); ++o_it)
           if ( o_it->manipPlaced() )
                o_it->manipulatorNode()->setMode (_mode);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
644
645
646
      if (!hide_)
        switch (manMode_)
        {
647
648
649
650
          case QtTranslationManipulatorNode::Rotation:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
            placeMode_ = false;
            break;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
651
652
          case QtTranslationManipulatorNode::Resize:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
653
            placeMode_ = false;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
654
655
656
            break;
          case QtTranslationManipulatorNode::LocalRotation:
            PluginFunctions::setViewObjectMarker (&objectMarker_);
657
658
659
660
661
            placeMode_ = false;
            break;
          case QtTranslationManipulatorNode::Place:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
            placeMode_ = true;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
662
663
664
            break;
          case QtTranslationManipulatorNode::TranslationRotation:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
665
            placeMode_ = false;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
666
667
            break;
        }
668
669
670
671
672
    }
    switch (manMode_)
    {
      case QtTranslationManipulatorNode::Resize:
        resizeAction_->setChecked (true);
673
674
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
675
        placeAndSnapAction_->setChecked (false);
676
677
678
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        resizeAction_->setChecked (false);
679
680
        rotateManipAction_->setChecked (true);
        rotateTranslateAction_->setChecked (false);
681
        placeAndSnapAction_->setChecked (false);
682
683
684
        break;
      case QtTranslationManipulatorNode::TranslationRotation:
        resizeAction_->setChecked (false);
685
686
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (true);
687
688
689
690
691
692
693
        placeAndSnapAction_->setChecked (false);
        break;
      case QtTranslationManipulatorNode::Place:
        resizeAction_->setChecked (false);
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
        placeAndSnapAction_->setChecked (true);
694
        break;
Matthias Möller's avatar
Matthias Möller committed
695
696
697
698
699
700
      case QtTranslationManipulatorNode::Rotation:
        resizeAction_->setChecked(false);
        rotateManipAction_->setChecked(true);
        rotateTranslateAction_->setChecked(false);
        placeAndSnapAction_->setChecked(false);
        break;
701
702
703
704
705
706
    }
  }
}

//------------------------------------------------------------------------------

707
/** \brief Hide context menu entry when right clicking on node other than manipulator node
708
 *
709
710
 * @param _nodeId Identifier of node that has been clicked
 */
711
void MovePlugin::slotUpdateContextMenuNode(int _nodeId) {
712

713
    ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node(PluginFunctions::getSceneGraphRootNode(), _nodeId);
714

715
716
    if (node == 0)
        return;
717

718
719
720
721
    if (node->className() != "QtTranslationManipulatorNode") {
        contextAction_->setVisible(false);
    } else {
        contextAction_->setVisible(true);
722
723
    }
}
Jan Möbius's avatar
 
Jan Möbius committed
724
725
726
727

//------------------------------------------------------------------------------

/** \brief move the object when its manipulator moves
728
 *
Jan Möbius's avatar
 
Jan Möbius committed
729
730
731
732
733
734
 * @param _node the manipulator node
 * @param _event the mouse event
 */
void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {

  // React on event only in move mode
735
  if ( PluginFunctions::pickMode() != "Move"
Dirk Wilden's avatar
Dirk Wilden committed
736
    && PluginFunctions::pickMode() != "MoveSelection" )
Jan Möbius's avatar
 
Jan Möbius committed
737
    return;
738
  
Jan Möbius's avatar
 
Jan Möbius committed
739
740
  OpenFlipper::Options::redrawDisabled( true );

Dirk Wilden's avatar
Dirk Wilden committed
741
  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
742
743
  if ( !placeMode_ && ((_event->type() == QEvent::MouseButtonRelease) || 
             (PluginFunctions::pickMode() != "Move" && _event->buttons() != Qt::NoButton)) ) {
Jan Möbius's avatar
 
Jan Möbius committed
744
745
746
747
748
749
750
751
752
753
754

    int objectId = _node->getIdentifier();

    ACG::Matrix4x4d mat;
    mat.identity();
    mat = _node->matrix();

    // Reset Node
    _node->loadIdentity();
    _node->set_center(mat.transform_point(_node->center()));

755
    // move the object which corresponds to the manipulator
756
    if (PluginFunctions::pickMode() == "Move")
Jan Möbius's avatar
 
Jan Möbius committed
757
      moveObject( mat, objectId );
758
    else if (PluginFunctions::pickMode() == "MoveSelection")
Dirk Wilden's avatar
Dirk Wilden committed
759
      moveSelection( mat, objectId, _event->type() );
Jan Möbius's avatar
 
Jan Möbius committed
760

761
    // move all other targets without manipulator
762
    if(allTargets_) {
763
764
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS); o_it
          != PluginFunctions::objectsEnd(); ++o_it) {
765
        if ((o_it->id() != objectId) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
Dirk Wilden's avatar
Dirk Wilden committed
766

767
768
769
770
          // move the object which corresponds to the manipulator
          if (PluginFunctions::pickMode() == "Move")
            moveObject( mat, o_it->id() );
          else if (PluginFunctions::pickMode() == "MoveSelection")
Dirk Wilden's avatar
Dirk Wilden committed
771
            moveSelection( mat, o_it->id(), _event->type() );
772
773
774
        }
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
775
776
777
778
779
780
781
782
783
784
785
786

    lastActiveManipulator_ = objectId;
    updateManipulatorDialog();
  }

  OpenFlipper::Options::redrawDisabled( false );
}


//------------------------------------------------------------------------------

/** \brief update object when its manipulator changes position
787
 *
Jan Möbius's avatar
 
Jan Möbius committed
788
789
790
791
792
793
794
 * @param _node the manipulator node
 */
void MovePlugin::ManipulatorPositionChanged(QtTranslationManipulatorNode* _node ) {

  // Position has been changed of the manipulator by a direct function
  int objectId = _node->getIdentifier();

Dirk Wilden's avatar
Dirk Wilden committed
795
796
797
798
  if ( objectId > 0 ){

    BaseObjectData* object;
    PluginFunctions::getObject(objectId,object);
Jan Möbius's avatar
 
Jan Möbius committed
799

Dirk Wilden's avatar
Dirk Wilden committed
800
801
802
    // Assume that it has a good position now
    object->manipPlaced( true );
  }
Jan Möbius's avatar
 
Jan Möbius committed
803
804
805
806
807
808
809
810
811
812
813
814
815
816

  // Show manipulator only if in Move mode
  if ( PluginFunctions::pickMode() == "Move" )
    _node->show();

  lastActiveManipulator_ = objectId;
  updateManipulatorDialog();

}


//------------------------------------------------------------------------------

/** \brief Place and show the Manipulator
817
 *
Jan Möbius's avatar
Jan Möbius committed
818
819
 * @param _event  mouseEvent that occurred
 * @param _snap   Snap manipulator to nearest geometry primitive?
Jan Möbius's avatar
 
Jan Möbius committed
820
 */
821
822
823
824
void MovePlugin::placeManip(QMouseEvent * _event, bool _snap) {
    unsigned int node_idx, target_idx;
    OpenMesh::Vec3d hitPoint;
    BaseObjectData* object;
Jan Möbius's avatar
 
Jan Möbius committed
825

826
    bool successfullyPicked = false;
Jan Möbius's avatar
 
Jan Möbius committed
827

828
    
829

830
831
832
833
834
835
    /*
     * Snap manipulator to nearest geometry
     * element depending on which selection type is
     * active.
     */
    if (_snap) {
836
837
838
839
840
841
842
843
 
          successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx,
                               target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);

          if(!successfullyPicked) {
              //emit log(LOGWARN, tr("Picking failed"));
              return;
          }
Jan Möbius's avatar
 
Jan Möbius committed
844

845
846
847
848
849
          if (selectionType_ == VERTEX) {
              if ( object->dataType(DATA_TRIANGLE_MESH) ) {
                  hitPoint = getNearestVertex(PluginFunctions::triMesh(object), target_idx, hitPoint);
              } else if ( object->dataType(DATA_POLY_MESH) ) {
                  hitPoint = getNearestVertex(PluginFunctions::polyMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
850
#ifdef ENABLE_TSPLINEMESH_SUPPORT
851
852
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
853
#endif
854
855
856
857
858
859
              }
          } else if (selectionType_ == EDGE) {
              if ( object->dataType(DATA_TRIANGLE_MESH) ) {
                  hitPoint = getNearestEdge(PluginFunctions::triMesh(object), target_idx, hitPoint);
              } else if ( object->dataType(DATA_POLY_MESH) ) {
                  hitPoint = getNearestEdge(PluginFunctions::polyMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
860
#ifdef ENABLE_TSPLINEMESH_SUPPORT
861
862
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
863
#endif
864
865
866
867
868
869
              }
          } else if (selectionType_ == FACE) {
              if ( object->dataType(DATA_TRIANGLE_MESH) ) {
                  hitPoint = getNearestFace(PluginFunctions::triMesh(object), target_idx, hitPoint);
              } else if ( object->dataType(DATA_POLY_MESH) ) {
                  hitPoint = getNearestFace(PluginFunctions::polyMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
870
#ifdef ENABLE_TSPLINEMESH_SUPPORT
871
872
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
873
#endif
874
875
              }
          }
Jan Möbius's avatar
 
Jan Möbius committed
876

877
878
879
880
    } else {
        successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
                target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
    }
Jan Möbius's avatar
 
Jan Möbius committed
881

882
    if (successfullyPicked) {
Jan Möbius's avatar
 
Jan Möbius committed
883

884
        object->manipPlaced(true);
Jan Möbius's avatar
 
Jan Möbius committed
885

886
887
        /// TODO: Whats this?
        int data = -1;
888
889
        if (data != -1)
          object->manipulatorNode()->setData( data );
Jan Möbius's avatar
 
Jan Möbius committed
890

891
892
893
894
895
896
897
        object->manipulatorNode()->loadIdentity();
        object->manipulatorNode()->set_center(hitPoint);
        object->manipulatorNode()->set_draw_cylinder(true);
        object->manipulatorNode()->set_autosize(QtTranslationManipulatorNode::Once);
        object->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
        object->manipulatorNode()->setMode(manMode_);
        object->manipulatorNode()->show();
Jan Möbius's avatar
 
Jan Möbius committed
898

899
        object->manipulatorNode()->apply_transformation(PluginFunctions::pickMode() == "Move");
Jan Möbius's avatar
 
Jan Möbius committed
900

901
902
903
904
905
906
907
908
        // Disconnect a previously connected Signal
        disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
                   this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
                
        disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
                  this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*)));
        
        // Reconnect the signals.
909
910
911
912
913
914
915
916
917
        connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
                this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));

        connect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
                this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*)));

        lastActiveManipulator_ = object->id();

        emit updateView();
918
919
920
921
922
923
924
925
926
927
928
       
        bool found = false;
        
        for (uint i=0; i < activeManipulators_.size(); i++)
          if ( activeManipulators_[i] == object->id() ){
            found = true;
            break;
          }
        
        if ( !found )
          activeManipulators_.push_back( object->id() );
929
930
931
932

    } else {
        //emit log(LOGWARN, tr("Picking failed"));
    }
Jan Möbius's avatar
 
Jan Möbius committed
933
934
935
936
937
938
}


//------------------------------------------------------------------------------

/** \brief Checks if the manipulators should be visible or not
939
 *
Jan Möbius's avatar
 
Jan Möbius committed
940
941
942
 */
void MovePlugin::showManipulators( )
{
Dirk Wilden's avatar
Dirk Wilden committed
943

944
  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
Dirk Wilden's avatar
Dirk Wilden committed
945
                                || (PluginFunctions::pickMode() == "MoveSelection"))) {
946
    
947
948
949
950
951
952
953
954
955
956
    for (uint i=0; i < activeManipulators_.size(); i++){
      
      BaseObjectData* obj = 0;
      
      PluginFunctions::getObject( activeManipulators_[i], obj );
      
      if (obj != 0 && obj->manipPlaced()) {
        obj->manipulatorNode()->show();
        obj->manipulatorNode()->apply_transformation( PluginFunctions::pickMode() == "Move" );
        emit nodeVisibilityChanged(obj->id());
957
      }
958
    }
Jan Möbius's avatar
 
Jan Möbius committed
959

960
  } else {
961
962
963
964
965
966
967
968
969
970
971
    
    for (uint i=0; i < activeManipulators_.size(); i++){
      
      BaseObjectData* obj = 0;
      
      PluginFunctions::getObject( activeManipulators_[i], obj );
      
      if ( obj != 0 ) {
        obj->manipulatorNode()->hide();
        emit nodeVisibilityChanged(obj->id());
      }
972
973
974
975
    }
  }

  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
976
977
978

}

979
//------------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
980

981
/** \brief Get Dialog Widget that contains the button
982
 *
983
984
985
986
987
988
989
 * @param _but Reference to QPushButton object that has been pressed
 */
movePropsWidget* MovePlugin::getDialogFromButton(QPushButton* _but) {

    if(_but == 0) return 0;
    return dynamic_cast<movePropsWidget*>((((_but->parentWidget())->parentWidget())->parentWidget()));
}
Jan Möbius's avatar
 
Jan Möbius committed
990
991
992
//------------------------------------------------------------------------------

/** \brief Position of manipulator in tab changed
993
 *
Jan Möbius's avatar
 
Jan Möbius committed
994
995
 */
void MovePlugin::slotSetPosition() {
996

997
998
999
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
1000

1001
    TriMesh::Point newpos;
1002

1003
1004
    bool ok = false;
    newpos[0] =  (pW->nposx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1005
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1006
    newpos[1] =  (pW->nposy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1007
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1008
    newpos[2] =  (pW->nposz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1009
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1010

1011
1012
    BaseObjectData* object;
    if ( PluginFunctions::getObject(lastActiveManipulator_ , object) ) {
1013
1014
1015
1016
1017
1018
1019
1020
1021
	if (  object->manipulatorNode()->visible() ) {
        // Compute translation vector
	    ACG::Vec3d translation = newpos;
        translation -= object->manipulatorNode()->center();
        object->manipulatorNode()->set_center(newpos);
        // Stuff it into transformation matrix
        ACG::GLMatrixd m;
        m.identity();
        m.translate(translation);
1022
1023
1024
1025
        if (PluginFunctions::pickMode() == "Move")
        {
          // ...and transform mesh
          if(object->dataType() == DATA_TRIANGLE_MESH)
1026
            transformMesh(m, *PluginFunctions::triMesh(object));
1027
          else if(object->dataType() == DATA_POLY_MESH)
1028
            transformMesh(m, *PluginFunctions::polyMesh(object));
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
        }
        else if (PluginFunctions::pickMode() == "MoveSelection")
        {
          updateSelectionType();
          if (selectionType_ & VERTEX) {
            transformVertexSelection(object->id(), m);
          }
          if (selectionType_ & FACE) {
            transformFaceSelection(object->id(), m);
          }
          if (selectionType_ & EDGE) {
            transformEdgeSelection(object->id(), m);
          }
        }
1043
        
1044

1045
1046
        emit updatedObject(object->id(), UPDATE_GEOMETRY);
    }
1047
1048
1049
	updateManipulatorDialog();
	emit updateView();
    }
Jan Möbius's avatar
 
Jan Möbius committed
1050
1051
1052
1053
1054
1055
}


//------------------------------------------------------------------------------

/** \brief Toggle the first axis for changing direction in tab
1056
 *
Jan Möbius's avatar
 
Jan Möbius committed
1057
1058
 */
void MovePlugin::slotToggleAxisA() {
1059

1060
1061
1062
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1063
1064

    axisA_ = (axisA_ + 1) % 3;
1065

1066
1067
    if (axisA_ == axisB_)
	axisA_ = (axisA_ + 1) % 3;
1068

1069
    switch(axisA_){
Jan Möbius's avatar
Jan Möbius committed
1070
1071
1072
	case 0: pW->axisAButton->setText(tr("X Direction")); break;
	case 1: pW->axisAButton->setText(tr("Y Direction")); break;
	case 2: pW->axisAButton->setText(tr("Z Direction")); break;
1073
1074
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
1075
1076
1077
1078
1079
1080
}


//------------------------------------------------------------------------------

/** \brief Toggle the second axis for changing direction in tab
1081
 *
Jan Möbius's avatar
 
Jan Möbius committed
1082
1083
 */
void MovePlugin::slotToggleAxisB() {
1084

1085
1086
1087
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1088
1089

    axisB_ = (axisB_ + 1) % 3;
1090

1091
1092
    if (axisA_ == axisB_)
	axisB_ = (axisB_ + 1) % 3;
1093

1094
    switch(axisB_){
Jan Möbius's avatar
Jan Möbius committed
1095
1096
1097
	case 0: pW->axisBButton->setText(tr("X Direction")); break;
	case 1: pW->axisBButton->setText(tr("Y Direction")); break;
	case 2: pW->axisBButton->setText(tr("Z Direction")); break;
1098
1099
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
1100
1101
1102
1103
1104
1105
}


//------------------------------------------------------------------------------

/** \brief Set Direction of manipulator in tab changed
1106
 *
Jan Möbius's avatar
 
Jan Möbius committed
1107
1108
 */
void MovePlugin::slotSetDirection() {
1109

1110
1111
1112
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1113

1114
1115
1116
    ACG::Vec3d newdirA,newdirB;
    ACG::Vec3d dirX,dirY;
    ACG::Vec3d dirZ(0.0,0.0,0.0);
1117

1118
1119
    bool ok = false;
    newdirA[0] =  (pW->ndirAx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1120
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate"));  return; }
1121
    newdirA[1] =  (pW->ndirAy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1122
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1123
    newdirA[2] =  (pW->ndirAz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1124
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1125