MovePlugin.cc 67.8 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

#include <QtGui>

#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
66
67
68
#ifdef ENABLE_TSPLINEMESH_SUPPORT
#include <ObjectTypes/TSplineMesh/TSplineMesh.hh>
#endif
Jan Möbius's avatar
 
Jan Möbius committed
69

Dirk Wilden's avatar
Dirk Wilden committed
70
71
72
73
#ifdef ENABLE_SKELETON_SUPPORT
#include <ObjectTypes/Skeleton/Helper/SkeletonTransform.hh>
#endif

Jan Möbius's avatar
 
Jan Möbius committed
74
/** \brief Default Constructor
75
 *
Jan Möbius's avatar
 
Jan Möbius committed
76
 */
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
77
MovePlugin::MovePlugin() :
78
79
80
81
    placeAndSnapAction_(0),
    manMode_(QtTranslationManipulatorNode::TranslationRotation),
    contextAction_(0),
    toAllTargets_(0),
Dirk Wilden's avatar
Dirk Wilden committed
82
    placeMode_(false)
Jan Möbius's avatar
 
Jan Möbius committed
83
84
85
86
87
88
89
90
91
{
    manip_size_          = 1.0;
    manip_size_modifier_ = 1.0;

    selectionType_ = VERTEX;
    selectionConnected_ = false;

    axisA_ = 0;
    axisB_ = 1;
92
93

    hide_ = true;
94
    allTargets_ = false;
Jan Möbius's avatar
 
Jan Möbius committed
95
96
}

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/** \brief Deconstructor
 *
 */
MovePlugin::~MovePlugin() {

	if(contextAction_) {
		delete contextAction_;
	}

	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
119
120
121
122
123
124

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

/** \brief Initialization of the plugin when it is loaded by the core
125
 *
Jan Möbius's avatar
 
Jan Möbius committed
126
127
128
129
130
131
132
133
134
135
 */
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
136
  //KEYS
Jan Möbius's avatar
Jan Möbius committed
137
138
139
140
  emit registerKey (Qt::Key_Shift, Qt::ShiftModifier, tr("Manipulator rotation"), true);
  emit registerKey (Qt::Key_Shift, Qt::NoModifier, tr("Manipulator rotation"), true);
  emit registerKey (Qt::Key_Control, Qt::ControlModifier, tr("Resize"), true);
  emit registerKey (Qt::Key_Control, Qt::NoModifier, tr("Resize"), true);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
141

Jan Möbius's avatar
 
Jan Möbius committed
142
143
  //SCRIPTING SLOT DESCRIPTIONS
  setDescriptions();
144

145
  // CONTEXT MENU
Jan Möbius's avatar
Jan Möbius committed
146
  toAllTargets_ = new QAction(tr("Apply to all targets"), this);
147
  toAllTargets_->setCheckable(true);
Jan Möbius's avatar
Jan Möbius committed
148
  toAllTargets_->setToolTip(tr("Apply transformation to all target objects"));
149
150
  toAllTargets_->setStatusTip( toAllTargets_->toolTip() );

Jan Möbius's avatar
Jan Möbius committed
151
152
  contextAction_ = new QAction(tr("Set properties"), this);
  contextAction_->setToolTip(tr("Set properties"));
153
  contextAction_->setStatusTip( contextAction_->toolTip() );
Jan Möbius's avatar
Jan Möbius committed
154
  contextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-properties.png") );
155
  
156
157
158
159
  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") );
160

161
162
  emit addContextMenuItem(toAllTargets_      , CONTEXTNODEMENU );
  emit addContextMenuItem(contextAction_     , CONTEXTNODEMENU );
163
  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
164

165
166
  connect( toAllTargets_  ,     SIGNAL(toggled(bool) ), this, SLOT(setAllTargets(bool)));
  connect( contextAction_ ,     SIGNAL( triggered() ),  this, SLOT(showProps()) );
167
  connect( contextActionHide_ , SIGNAL( triggered() ),  this, SLOT(hideManipulator()) );
Jan Möbius's avatar
 
Jan Möbius committed
168
169

  //TOOLBAR
Jan Möbius's avatar
Jan Möbius committed
170
  toolbar_ = new QToolBar(tr("Transform and Move"));
Jan Möbius's avatar
 
Jan Möbius committed
171
172
173

  toolBarActions_ = new QActionGroup(toolbar_);

174
  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
Jan Möbius's avatar
 
Jan Möbius committed
175
176
177
178
179
  moveAction_->setStatusTip(tr("Move object in 3D."));
  moveAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-objects.png") );
  moveAction_->setCheckable(true);
  toolbar_->addAction(moveAction_);

180
  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
181
182
183
184
  moveSelectionAction_->setStatusTip(tr("Move selections in 3D."));
  moveSelectionAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-selections.png") );
  moveSelectionAction_->setCheckable(true);
  toolbar_->addAction(moveSelectionAction_);
185
  
Jan Möbius's avatar
 
Jan Möbius committed
186
187
188
  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );

  emit addToolbar(toolbar_);
189

Jan Möbius's avatar
Jan Möbius committed
190
  pickToolbar_ = new QToolBar(tr("Transform and Move"));
191
  pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
192
193
194
195
196
  pickToolBarActions_ = new QActionGroup(pickToolbar_);
  pickToolBarActions_->setExclusive (false);

  placeAction_ = new QAction(tr("Place manipulator"), pickToolBarActions_);
  placeAction_->setStatusTip(tr("Place manipulator on object. <Doubleclick>"));
197
  placeAction_->setToolTip(tr("Place manipulator on object. <Doubleclick>"));
198
199
200
201
202
203
  placeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-place.png") );
  placeAction_->setCheckable(true);
  pickToolbar_->addAction(placeAction_);

  pickToolbar_->addSeparator ();

204
205
  rotateTranslateAction_ = new QAction(tr("Rotate/Translate object"), pickToolBarActions_);
  rotateTranslateAction_->setStatusTip(tr("Rotate/Translate object."));
206
  rotateTranslateAction_->setToolTip(tr("Rotate/Translate object."));
207
208
209
210
  rotateTranslateAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-translaterotate.png") );
  rotateTranslateAction_->setCheckable(true);
  rotateTranslateAction_->setChecked(true);
  pickToolbar_->addAction(rotateTranslateAction_);
211
212
213

  resizeAction_ = new QAction(tr("Resize object"), pickToolBarActions_);
  resizeAction_->setStatusTip(tr("Resize object. <Control>"));
214
  resizeAction_->setToolTip(tr("Resize object. <Control>"));
215
216
217
218
219
220
  resizeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-resize.png") );
  resizeAction_->setCheckable(true);
  pickToolbar_->addAction(resizeAction_);

  pickToolbar_->addSeparator ();

221
222
  rotateManipAction_ = new QAction(tr("Rotate manipulator"), pickToolBarActions_);
  rotateManipAction_->setStatusTip(tr("Rotate manipulator. <Shift>"));
223
  rotateManipAction_->setToolTip(tr("Rotate manipulator. <Shift>"));
224
225
226
  rotateManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-maniprotate.png") );
  rotateManipAction_->setCheckable(true);
  pickToolbar_->addAction(rotateManipAction_);
227

228
229
  placeAndSnapAction_ = new QAction(tr("Locally translate manipulator"), pickToolBarActions_);
  placeAndSnapAction_->setStatusTip(tr("Locally translate manipulator. Press and hold <Alt> for snapping."));
Mike Kremer's avatar
Mike Kremer committed
230
  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
231
232
233
  placeAndSnapAction_->setCheckable(true);
  pickToolbar_->addAction(placeAndSnapAction_);

234
235
  smallerManipAction_ = new QAction(tr("Decrease size of manipulator"), pickToolBarActions_);
  smallerManipAction_->setStatusTip(tr("Make manipulator smaller. <Mouse wheel up>"));
236
  smallerManipAction_->setToolTip(tr("Make manipulator smaller. <Mouse wheel up>"));
237
238
239
240
  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
241
  biggerManipAction_ = new QAction(tr("Increase size of manipulator"), pickToolBarActions_);
242
  biggerManipAction_->setStatusTip(tr("Make manipulator bigger. <Mouse wheel down>"));
243
  biggerManipAction_->setToolTip(tr("Make manipulator bigger. <Mouse wheel down>"));
244
245
246
  biggerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipbig.png") );
  biggerManipAction_->setCheckable(false);
  pickToolbar_->addAction(biggerManipAction_);
247
  
248
249
250
251
  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
252
253
254
255
256
257
258
}


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

Jan Möbius's avatar
Jan Möbius committed
259
void MovePlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
{
   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));

   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));

   lastActiveManipulator_ = -1;

Dirk Wilden's avatar
Dirk Wilden committed
275
276
   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
277
278
279
280
281
282
283
284
}


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

/** \brief MouseWheel event occured
285
 *
Jan Möbius's avatar
 
Jan Möbius committed
286
287
288
289
 * @param _event the event that occured
 */
void MovePlugin::slotMouseWheelEvent(QWheelEvent * _event, const std::string & /*_mode*/)
{
290
  // Skip execution if this is not our pick mode
291
  if( ( (PluginFunctions::pickMode() != "Move")
Dirk Wilden's avatar
Dirk Wilden committed
292
     && (PluginFunctions::pickMode() != "MoveSelection") )
293
    || PluginFunctions::actionMode() != Viewer::PickingMode)
294
295
296
297
298
299
300
301
302
303
304
    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
305
306
307
308
309
310
}


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

/** \brief MousePress event occured
311
 *
Jan Möbius's avatar
 
Jan Möbius committed
312
313
 * @param _event the event that occured
 */
314
void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
315
    if (((PluginFunctions::pickMode() == ("Move"))
Dirk Wilden's avatar
Dirk Wilden committed
316
      || (PluginFunctions::pickMode() == ("MoveSelection")))
317
            && PluginFunctions::actionMode() == Viewer::PickingMode) {
Jan Möbius's avatar
 
Jan Möbius committed
318

319
320
        if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
                && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
Dirk Wilden's avatar
Dirk Wilden committed
321
322

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

324
            placeManip(_event, snap);
325
326
            placeAction_->setChecked(false);
            updateManipulatorDialog();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
            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.
351
             *
352
353
             */

354
            placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
355
356
357
358
359
            updateManipulatorDialog();
            return;
        }

        // interaction
360
        ACG::SceneGraph::MouseEventAction action(_event,PluginFunctions::viewerProperties().glState());
361
362
363
        PluginFunctions::traverse(action);

        if (_event->buttons() == Qt::LeftButton)
364
          emit nodeVisibilityChanged(-1);
365
366

    }
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
367
368
369
370
371
372
373
374
375
}

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

void MovePlugin::slotKeyEvent (QKeyEvent* _event)
{
  if (_event->key() == Qt::Key_Control)
376
    setManipMode (QtTranslationManipulatorNode::Resize);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
377
  else if (_event->key () == Qt::Key_Shift)
378
    setManipMode (QtTranslationManipulatorNode::LocalRotation);
Jan Möbius's avatar
 
Jan Möbius committed
379
380
}

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
381
382
383
384
385
386
//------------------------------------------------------------------------------

void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
{
  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
      (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
387
    setManipMode (QtTranslationManipulatorNode::TranslationRotation);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
388
}
Jan Möbius's avatar
 
Jan Möbius committed
389
390
391
392
393
394

/*******************************************************************************
        PickingInterface implementation
 *******************************************************************************/

/** \brief slot is called when the pickMode changed
395
 *
Jan Möbius's avatar
 
Jan Möbius committed
396
397
398
399
 * @param _mode new pickMode
 */
void MovePlugin::slotPickModeChanged( const std::string& _mode)
{
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
400
401
  moveAction_->setChecked(_mode == "Move");
  moveSelectionAction_->setChecked(_mode == "MoveSelection");
402

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

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
405
406
407
408
409
410
411
412
413
414
415
416
  showManipulators();

  if (!hide_)
  {
    switch (manMode_)
    {
      case QtTranslationManipulatorNode::Resize:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        PluginFunctions::setViewObjectMarker (&objectMarker_);
        break;
417
418
419
      case QtTranslationManipulatorNode::Place:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
420
421
422
423
424
425
426
      case QtTranslationManipulatorNode::TranslationRotation:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
    }
  }
  else
    PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
Jan Möbius's avatar
 
Jan Möbius committed
427
428
429
430
431
432
433
434
}


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

/** \brief Move object with given transformation matrix
435
 *
Jan Möbius's avatar
 
Jan Möbius committed
436
437
438
439
440
 * @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
441
  if ( ! PluginFunctions::getObject(_id,object) )
Jan Möbius's avatar
 
Jan Möbius committed
442
443
    return;

444
445
446
447
  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
448
449
450
451
#ifdef ENABLE_TSPLINEMESH_SUPPORT
  } else  if  ( object->dataType()  == DATA_TSPLINE_MESH ) {
    transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
#endif
452
#ifdef ENABLE_POLYLINE_SUPPORT
453
454
  } else  if  ( object->dataType()  == DATA_POLY_LINE ) {
    transformPolyLine(mat , *PluginFunctions::polyLine(object) );
Dirk Wilden's avatar
Dirk Wilden committed
455
456
457
458
#endif
#ifdef ENABLE_SKELETON_SUPPORT
  } else  if  ( object->dataType()  == DATA_SKELETON ) {
    transformSkeleton(mat , *PluginFunctions::skeleton(object) );
459
#endif
Dirk Wilden's avatar
Dirk Wilden committed
460
461
  } else  if  ( object->dataType()  == DATA_PLANE ) {
    PluginFunctions::planeNode(object)->transform(mat);
462
463
  } else {

Jan Möbius's avatar
Jan Möbius committed
464
    emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
465
    return;
Jan Möbius's avatar
 
Jan Möbius committed
466
467
  }

468
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
469
470
471
472
473
474
475
  emit createBackup(_id,"Move");
}


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

/** \brief Move selection on an object with given transformation matrix
476
 *
Jan Möbius's avatar
 
Jan Möbius committed
477
478
479
480
 * 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.
 *
481
482
 * @param mat
 * @param _id
Jan Möbius's avatar
 
Jan Möbius committed
483
484
485
486
487
488
489
490
491
492
 */
void MovePlugin::moveSelection(ACG::Matrix4x4d mat, int _id) {

  if (selectionType_ == VERTEX)
    transformVertexSelection( _id , mat );
  else if (selectionType_ == FACE)
    transformFaceSelection( _id , mat );
  else if (selectionType_ == EDGE)
    transformEdgeSelection( _id , mat );

493
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
494
495
496
//   emit createBackup(_id,"MoveSelection");
}

497
498
//------------------------------------------------------------------------------

499
500
501
502
503
504
505
506
507
508
/** \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
509
    if ((PluginFunctions::pickMode() == "Move" ) || (PluginFunctions::pickMode() == "MoveSelection" )) {
510
511
512
513
        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
514
515
516
517
518
      if (!hide_)
        switch (manMode_)
        {
          case QtTranslationManipulatorNode::Resize:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
519
            placeMode_ = false;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
520
521
522
            break;
          case QtTranslationManipulatorNode::LocalRotation:
            PluginFunctions::setViewObjectMarker (&objectMarker_);
523
524
525
526
527
            placeMode_ = false;
            break;
          case QtTranslationManipulatorNode::Place:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
            placeMode_ = true;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
528
529
530
            break;
          case QtTranslationManipulatorNode::TranslationRotation:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
531
            placeMode_ = false;
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
532
533
            break;
        }
534
535
536
537
538
    }
    switch (manMode_)
    {
      case QtTranslationManipulatorNode::Resize:
        resizeAction_->setChecked (true);
539
540
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
541
        placeAndSnapAction_->setChecked (false);
542
543
544
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        resizeAction_->setChecked (false);
545
546
        rotateManipAction_->setChecked (true);
        rotateTranslateAction_->setChecked (false);
547
        placeAndSnapAction_->setChecked (false);
548
549
550
        break;
      case QtTranslationManipulatorNode::TranslationRotation:
        resizeAction_->setChecked (false);
551
552
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (true);
553
554
555
556
557
558
559
        placeAndSnapAction_->setChecked (false);
        break;
      case QtTranslationManipulatorNode::Place:
        resizeAction_->setChecked (false);
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
        placeAndSnapAction_->setChecked (true);
560
561
562
563
564
565
566
        break;
    }
  }
}

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

567
/** \brief Hide context menu entry when right clicking on node other than manipulator node
568
 *
569
570
 * @param _nodeId Identifier of node that has been clicked
 */
571
void MovePlugin::slotUpdateContextMenuNode(int _nodeId) {
572

573
    ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node(PluginFunctions::getSceneGraphRootNode(), _nodeId);
574

575
576
    if (node == 0)
        return;
577

578
579
580
581
    if (node->className() != "QtTranslationManipulatorNode") {
        contextAction_->setVisible(false);
    } else {
        contextAction_->setVisible(true);
582
583
    }
}
Jan Möbius's avatar
 
Jan Möbius committed
584
585
586
587

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

/** \brief move the object when its manipulator moves
588
 *
Jan Möbius's avatar
 
Jan Möbius committed
589
590
591
592
593
594
 * @param _node the manipulator node
 * @param _event the mouse event
 */
void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {

  // React on event only in move mode
595
  if ( PluginFunctions::pickMode() != "Move"
Dirk Wilden's avatar
Dirk Wilden committed
596
    && PluginFunctions::pickMode() != "MoveSelection" )
Jan Möbius's avatar
 
Jan Möbius committed
597
    return;
598
  
Jan Möbius's avatar
 
Jan Möbius committed
599
600
  OpenFlipper::Options::redrawDisabled( true );

Dirk Wilden's avatar
Dirk Wilden committed
601
  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
602
603
  if ( !placeMode_ && ((_event->type() == QEvent::MouseButtonRelease) || 
             (PluginFunctions::pickMode() != "Move" && _event->buttons() != Qt::NoButton)) ) {
Jan Möbius's avatar
 
Jan Möbius committed
604
605
606
607
608
609
610
611
612
613
614

    int objectId = _node->getIdentifier();

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

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

615
    // move the object which corresponds to the manipulator
616
    if (PluginFunctions::pickMode() == "Move")
Jan Möbius's avatar
 
Jan Möbius committed
617
      moveObject( mat, objectId );
618
    else if (PluginFunctions::pickMode() == "MoveSelection")
Jan Möbius's avatar
 
Jan Möbius committed
619
620
      moveSelection( mat, objectId );

621
    // move all other targets without manipulator
622
    if(allTargets_) {
623
624
625
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS); o_it
          != PluginFunctions::objectsEnd(); ++o_it) {
        if ((o_it->id() != objectId) && !o_it->manipulatorNode()->visible()) { // If it has its own manipulator active, dont move it
Dirk Wilden's avatar
Dirk Wilden committed
626

627
628
629
630
631
          // move the object which corresponds to the manipulator
          if (PluginFunctions::pickMode() == "Move")
            moveObject( mat, o_it->id() );
          else if (PluginFunctions::pickMode() == "MoveSelection")
            moveSelection( mat, o_it->id() );
632
633
634
        }
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
635
636
637
638
639
640
641
642
643
644
645
646
647

    lastActiveManipulator_ = objectId;
    updateManipulatorDialog();
  }

  OpenFlipper::Options::redrawDisabled( false );

}


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

/** \brief update object when its manipulator changes position
648
 *
Jan Möbius's avatar
 
Jan Möbius committed
649
650
651
652
653
654
655
 * @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
656
657
658
659
  if ( objectId > 0 ){

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

Dirk Wilden's avatar
Dirk Wilden committed
661
662
663
    // Assume that it has a good position now
    object->manipPlaced( true );
  }
Jan Möbius's avatar
 
Jan Möbius committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677

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

  lastActiveManipulator_ = objectId;
  updateManipulatorDialog();

}


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

/** \brief Place and show the Manipulator
678
 *
Jan Möbius's avatar
 
Jan Möbius committed
679
680
 * @param _event  mouseEvent that occured
 */
681
682
683
684
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
685

686
    bool successfullyPicked = false;
Jan Möbius's avatar
 
Jan Möbius committed
687

688
689
    int data = -1;
    
690
691
692
693
694
695
    /*
     * Snap manipulator to nearest geometry
     * element depending on which selection type is
     * active.
     */
    if (_snap) {
696
697
698
699
700
701
702
703
 
          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
704

705
706
707
708
709
          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
710
#ifdef ENABLE_TSPLINEMESH_SUPPORT
711
712
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
713
#endif
714
715
716
717
718
719
              }
          } 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
720
#ifdef ENABLE_TSPLINEMESH_SUPPORT
721
722
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
723
#endif
724
725
726
727
728
729
              }
          } 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
730
#ifdef ENABLE_TSPLINEMESH_SUPPORT
731
732
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
733
#endif
734
735
              }
          }
Jan Möbius's avatar
 
Jan Möbius committed
736

737
738
739
740
    } 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
741

742
    if (successfullyPicked) {
Jan Möbius's avatar
 
Jan Möbius committed
743

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

746
747
        if (data != -1)
          object->manipulatorNode()->setData( data );
Jan Möbius's avatar
 
Jan Möbius committed
748

749
750
751
752
753
754
755
        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
756

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

759
760
761
762
763
764
765
766
        // 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.
767
768
769
770
771
772
773
774
775
        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();
776
777
778
779
780
781
782
783
784
785
786
       
        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() );
787
788
789
790

    } else {
        //emit log(LOGWARN, tr("Picking failed"));
    }
Jan Möbius's avatar
 
Jan Möbius committed
791
792
793
794
795
796
}


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

/** \brief Checks if the manipulators should be visible or not
797
 *
Jan Möbius's avatar
 
Jan Möbius committed
798
799
800
 */
void MovePlugin::showManipulators( )
{
Dirk Wilden's avatar
Dirk Wilden committed
801

802
  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
Dirk Wilden's avatar
Dirk Wilden committed
803
                                || (PluginFunctions::pickMode() == "MoveSelection"))) {
804
    
805
806
807
808
809
810
811
812
813
814
    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());
815
      }
816
    }
Jan Möbius's avatar
 
Jan Möbius committed
817

818
  } else {
819
820
821
822
823
824
825
826
827
828
829
    
    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());
      }
830
831
832
833
    }
  }

  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
834
835
836

}

837
//------------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
838

839
/** \brief Get Dialog Widget that contains the button
840
 *
841
842
843
844
845
846
847
 * @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
848
849
850
//------------------------------------------------------------------------------

/** \brief Position of manipulator in tab changed
851
 *
Jan Möbius's avatar
 
Jan Möbius committed
852
853
 */
void MovePlugin::slotSetPosition() {
854

855
856
857
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
858

859
    TriMesh::Point newpos;
860

861
862
    bool ok = false;
    newpos[0] =  (pW->nposx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
863
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
864
    newpos[1] =  (pW->nposy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
865
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
866
    newpos[2] =  (pW->nposz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
867
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
868

869
870
871
872
873
874
875
    BaseObjectData* object;
    if ( PluginFunctions::getObject(lastActiveManipulator_ , object) ) {
	if (  object->manipulatorNode()->visible() )
	    object->manipulatorNode()->set_center( newpos );
	updateManipulatorDialog();
	emit updateView();
    }
Jan Möbius's avatar
 
Jan Möbius committed
876
877
878
879
880
881
}


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

/** \brief Toggle the first axis for changing direction in tab
882
 *
Jan Möbius's avatar
 
Jan Möbius committed
883
884
 */
void MovePlugin::slotToggleAxisA() {
885

886
887
888
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
889
890

    axisA_ = (axisA_ + 1) % 3;
891

892
893
    if (axisA_ == axisB_)
	axisA_ = (axisA_ + 1) % 3;
894

895
    switch(axisA_){
Jan Möbius's avatar
Jan Möbius committed
896
897
898
	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;
899
900
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
901
902
903
904
905
906
}


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

/** \brief Toggle the second axis for changing direction in tab
907
 *
Jan Möbius's avatar
 
Jan Möbius committed
908
909
 */
void MovePlugin::slotToggleAxisB() {
910

911
912
913
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
914
915

    axisB_ = (axisB_ + 1) % 3;
916

917
918
    if (axisA_ == axisB_)
	axisB_ = (axisB_ + 1) % 3;
919

920
    switch(axisB_){
Jan Möbius's avatar
Jan Möbius committed
921
922
923
	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;
924
925
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
926
927
928
929
930
931
}


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

/** \brief Set Direction of manipulator in tab changed
932
 *
Jan Möbius's avatar
 
Jan Möbius committed
933
934
 */
void MovePlugin::slotSetDirection() {
935