MovePlugin.cc 67.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*                                                                            *
*                              OpenFlipper                                   *
*      Copyright (C) 2001-2010 by Computer Graphics Group, RWTH Aachen       *
*                           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
70

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

    selectionType_ = VERTEX;
    selectionConnected_ = false;

    axisA_ = 0;
    axisB_ = 1;
88
89

    hide_ = true;
90
    allTargets_ = false;
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
/** \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
115
116
117
118
119
120

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

/** \brief Initialization of the plugin when it is loaded by the core
121
 *
Jan Möbius's avatar
 
Jan Möbius committed
122
123
124
125
126
127
128
129
130
131
 */
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
132
  //KEYS
Jan Möbius's avatar
Jan Möbius committed
133
134
135
136
  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
137

Jan Möbius's avatar
 
Jan Möbius committed
138
139
  //SCRIPTING SLOT DESCRIPTIONS
  setDescriptions();
140

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

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

157
158
  emit addContextMenuItem(toAllTargets_      , CONTEXTNODEMENU );
  emit addContextMenuItem(contextAction_     , CONTEXTNODEMENU );
159
  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
160

161
162
  connect( toAllTargets_  ,     SIGNAL(toggled(bool) ), this, SLOT(setAllTargets(bool)));
  connect( contextAction_ ,     SIGNAL( triggered() ),  this, SLOT(showProps()) );
163
  connect( contextActionHide_ , SIGNAL( triggered() ),  this, SLOT(hideManipulator()) );
Jan Möbius's avatar
 
Jan Möbius committed
164
165

  //TOOLBAR
Jan Möbius's avatar
Jan Möbius committed
166
  toolbar_ = new QToolBar(tr("Transform and Move"));
Jan Möbius's avatar
 
Jan Möbius committed
167
168
169

  toolBarActions_ = new QActionGroup(toolbar_);

170
  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
Jan Möbius's avatar
 
Jan Möbius committed
171
172
173
174
175
  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_);

176
  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
177
178
179
180
  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_);
181
  
Jan Möbius's avatar
 
Jan Möbius committed
182
183
184
  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );

  emit addToolbar(toolbar_);
185

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

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

  pickToolbar_->addSeparator ();

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

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

  pickToolbar_->addSeparator ();

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

224
225
  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
226
  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
227
228
229
  placeAndSnapAction_->setCheckable(true);
  pickToolbar_->addAction(placeAndSnapAction_);

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


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

Jan Möbius's avatar
Jan Möbius committed
255
void MovePlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
{
   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
271
272
   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
273
274
275
276
277
278
279
280
}


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

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


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

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

315
316
        if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
                && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
Dirk Wilden's avatar
Dirk Wilden committed
317
318

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

320
            placeManip(_event, snap);
321
322
            placeAction_->setChecked(false);
            updateManipulatorDialog();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
323

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

350
            placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
351
352
353
354
355
            updateManipulatorDialog();
            return;
        }

        // interaction
356
        ACG::SceneGraph::MouseEventAction action(_event,PluginFunctions::viewerProperties().glState());
357
358
359
        PluginFunctions::traverse(action);

        if (_event->buttons() == Qt::LeftButton)
360
          emit nodeVisibilityChanged(-1);
361
362

    }
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
363
364
365
366
367
368
369
370
371
}

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

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

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
377
378
379
380
381
382
//------------------------------------------------------------------------------

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

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

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

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

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
401
402
403
404
405
406
407
408
409
410
411
412
  showManipulators();

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


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

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

440
441
  if  ( object->dataType()  == DATA_TRIANGLE_MESH ) {
    transformMesh(mat , *PluginFunctions::triMesh(object) );
442
    PluginFunctions::triMesh(object)->update_normals();
443
444
  } else  if  ( object->dataType()  == DATA_POLY_MESH ) {
    transformMesh(mat , *PluginFunctions::polyMesh(object) );
445
    PluginFunctions::polyMesh(object)->update_normals();
Henrik Zimmer's avatar
Henrik Zimmer committed
446
447
448
#ifdef ENABLE_TSPLINEMESH_SUPPORT
  } else  if  ( object->dataType()  == DATA_TSPLINE_MESH ) {
    transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
449
    PluginFunctions::tsplineMesh(object)->update_normals();
Henrik Zimmer's avatar
Henrik Zimmer committed
450
#endif
451
#ifdef ENABLE_POLYLINE_SUPPORT
452
453
  } else  if  ( object->dataType()  == DATA_POLY_LINE ) {
    transformPolyLine(mat , *PluginFunctions::polyLine(object) );
454
#endif
Dirk Wilden's avatar
Dirk Wilden committed
455
456
  } else  if  ( object->dataType()  == DATA_PLANE ) {
    PluginFunctions::planeNode(object)->transform(mat);
457
458
  } else {

Jan Möbius's avatar
Jan Möbius committed
459
    emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
460
    return;
Jan Möbius's avatar
 
Jan Möbius committed
461
462
  }

463
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
464
465
466
467
468
469
470
  emit createBackup(_id,"Move");
}


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

/** \brief Move selection on an object with given transformation matrix
471
 *
Jan Möbius's avatar
 
Jan Möbius committed
472
473
474
475
 * 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.
 *
476
477
 * @param mat
 * @param _id
Jan Möbius's avatar
 
Jan Möbius committed
478
479
480
481
482
483
484
485
486
487
 */
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 );

488
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
489
490
491
//   emit createBackup(_id,"MoveSelection");
}

492
493
//------------------------------------------------------------------------------

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

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

562
/** \brief Hide context menu entry when right clicking on node other than manipulator node
563
 *
564
565
 * @param _nodeId Identifier of node that has been clicked
 */
566
void MovePlugin::slotUpdateContextMenuNode(int _nodeId) {
567

568
    ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node(PluginFunctions::getSceneGraphRootNode(), _nodeId);
569

570
571
    if (node == 0)
        return;
572

573
574
575
576
    if (node->className() != "QtTranslationManipulatorNode") {
        contextAction_->setVisible(false);
    } else {
        contextAction_->setVisible(true);
577
578
    }
}
Jan Möbius's avatar
 
Jan Möbius committed
579
580
581
582

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

/** \brief move the object when its manipulator moves
583
 *
Jan Möbius's avatar
 
Jan Möbius committed
584
585
586
587
588
589
 * @param _node the manipulator node
 * @param _event the mouse event
 */
void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {

  // React on event only in move mode
590
  if ( PluginFunctions::pickMode() != "Move"
Dirk Wilden's avatar
Dirk Wilden committed
591
    && PluginFunctions::pickMode() != "MoveSelection" )
Jan Möbius's avatar
 
Jan Möbius committed
592
593
594
595
    return;

  OpenFlipper::Options::redrawDisabled( true );

Dirk Wilden's avatar
Dirk Wilden committed
596
  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
597
  if ( ((_event->type() == QEvent::MouseButtonRelease) || (PluginFunctions::pickMode() != "Move")) && !placeMode_) {
Jan Möbius's avatar
 
Jan Möbius committed
598
599
600
601
602
603
604
605
606
607
608

    int objectId = _node->getIdentifier();

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

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

609
    // move the object which corresponds to the manipulator
610
    if (PluginFunctions::pickMode() == "Move")
Jan Möbius's avatar
 
Jan Möbius committed
611
      moveObject( mat, objectId );
612
    else if (PluginFunctions::pickMode() == "MoveSelection")
Jan Möbius's avatar
 
Jan Möbius committed
613
614
      moveSelection( mat, objectId );

615
    // move all other targets without manipulator
616
    if(allTargets_) {
617
618
619
      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
620

621
622
623
624
625
          // 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() );
626
627
628
        }
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
629
630
631
632
633
634
635
636
637
638
639
640
641

    lastActiveManipulator_ = objectId;
    updateManipulatorDialog();
  }

  OpenFlipper::Options::redrawDisabled( false );

}


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

/** \brief update object when its manipulator changes position
642
 *
Jan Möbius's avatar
 
Jan Möbius committed
643
644
645
646
647
648
649
 * @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
650
651
652
653
  if ( objectId > 0 ){

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

Dirk Wilden's avatar
Dirk Wilden committed
655
656
657
    // Assume that it has a good position now
    object->manipPlaced( true );
  }
Jan Möbius's avatar
 
Jan Möbius committed
658
659
660
661
662
663
664
665
666
667
668
669
670
671

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

  lastActiveManipulator_ = objectId;
  updateManipulatorDialog();

}


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

/** \brief Place and show the Manipulator
672
 *
Jan Möbius's avatar
 
Jan Möbius committed
673
674
 * @param _event  mouseEvent that occured
 */
675
676
677
678
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
679

680
    bool successfullyPicked = false;
Jan Möbius's avatar
 
Jan Möbius committed
681

682
683
    int data = -1;
    
684
685
686
687
688
689
    /*
     * Snap manipulator to nearest geometry
     * element depending on which selection type is
     * active.
     */
    if (_snap) {
690
691
692
693
694
695
696
697
 
          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
698

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

731
732
733
734
    } 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
735

736
    if (successfullyPicked) {
Jan Möbius's avatar
 
Jan Möbius committed
737

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

740
741
        if (data != -1)
          object->manipulatorNode()->setData( data );
Jan Möbius's avatar
 
Jan Möbius committed
742

743
744
745
746
747
748
749
        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
750

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

753
754
755
756
757
758
759
760
        // 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.
761
762
763
764
765
766
767
768
769
        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();
770
771
772
773
774
775
776
777
778
779
780
       
        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() );
781
782
783
784

    } else {
        //emit log(LOGWARN, tr("Picking failed"));
    }
Jan Möbius's avatar
 
Jan Möbius committed
785
786
787
788
789
790
}


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

/** \brief Checks if the manipulators should be visible or not
791
 *
Jan Möbius's avatar
 
Jan Möbius committed
792
793
794
 */
void MovePlugin::showManipulators( )
{
Dirk Wilden's avatar
Dirk Wilden committed
795

796
  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
Dirk Wilden's avatar
Dirk Wilden committed
797
                                || (PluginFunctions::pickMode() == "MoveSelection"))) {
798
    
799
800
801
802
803
804
805
806
807
808
    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());
809
      }
810
    }
Jan Möbius's avatar
 
Jan Möbius committed
811

812
  } else {
813
814
815
816
817
818
819
820
821
822
823
    
    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());
      }
824
825
826
827
    }
  }

  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
828
829
830

}

831
//------------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
832

833
/** \brief Get Dialog Widget that contains the button
834
 *
835
836
837
838
839
840
841
 * @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
842
843
844
//------------------------------------------------------------------------------

/** \brief Position of manipulator in tab changed
845
 *
Jan Möbius's avatar
 
Jan Möbius committed
846
847
 */
void MovePlugin::slotSetPosition() {
848

849
850
851
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
852

853
    TriMesh::Point newpos;
854

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

863
864
865
866
867
868
869
    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
870
871
872
873
874
875
}


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

/** \brief Toggle the first axis for changing direction in tab
876
 *
Jan Möbius's avatar
 
Jan Möbius committed
877
878
 */
void MovePlugin::slotToggleAxisA() {
879

880
881
882
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
883
884

    axisA_ = (axisA_ + 1) % 3;
885

886
887
    if (axisA_ == axisB_)
	axisA_ = (axisA_ + 1) % 3;
888

889
    switch(axisA_){
Jan Möbius's avatar
Jan Möbius committed
890
891
892
	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;
893
894
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
895
896
897
898
899
900
}


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

/** \brief Toggle the second axis for changing direction in tab
901
 *
Jan Möbius's avatar
 
Jan Möbius committed
902
903
 */
void MovePlugin::slotToggleAxisB() {
904

Mike Kremer's avatar