MovePlugin.cc 74.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
 *      Copyright (C) 2001-2009 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/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
38 39 40 41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
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),
78 79
    placeMode_(false),
    recursiveJointTransformation_(true)
Jan Möbius's avatar
 
Jan Möbius committed
80 81 82 83 84 85 86 87 88
{
    manip_size_          = 1.0;
    manip_size_modifier_ = 1.0;

    selectionType_ = VERTEX;
    selectionConnected_ = false;

    axisA_ = 0;
    axisB_ = 1;
89 90

    hide_ = true;
91
    allTargets_ = false;
Jan Möbius's avatar
 
Jan Möbius committed
92 93
}

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
/** \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
116 117 118 119 120 121

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

/** \brief Initialization of the plugin when it is loaded by the core
122
 *
Jan Möbius's avatar
 
Jan Möbius committed
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);
132 133 134 135 136
  
#ifdef ENABLE_SKELETON_SUPPORT
  emit addHiddenPickMode("MoveSkeleton");
  emit setPickModeMouseTracking ("MoveSkeleton", true);
#endif
Jan Möbius's avatar
 
Jan Möbius committed
137

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
138
  //KEYS
Jan Möbius's avatar
Jan Möbius committed
139 140 141 142
  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
143

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

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

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

163 164
  emit addContextMenuItem(toAllTargets_      , CONTEXTNODEMENU );
  emit addContextMenuItem(contextAction_     , CONTEXTNODEMENU );
165
  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
166

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

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

  toolBarActions_ = new QActionGroup(toolbar_);

176
  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
Jan Möbius's avatar
 
Jan Möbius committed
177 178 179 180 181
  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_);

182
  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
183 184 185 186 187
  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_);

188 189 190 191 192 193 194 195 196
  
#ifdef ENABLE_SKELETON_SUPPORT
  moveSkeletonAction_ = new QAction(tr("<B>Move Skeleton</B><br>Move joints of a skeleton"), toolBarActions_);
  moveSkeletonAction_->setStatusTip(tr("Move joints of a skeleton."));
  moveSkeletonAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-skeleton.png") );
  moveSkeletonAction_->setCheckable(true);
  toolbar_->addAction(moveSkeletonAction_);
#endif
  
Jan Möbius's avatar
 
Jan Möbius committed
197 198 199
  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );

  emit addToolbar(toolbar_);
200

Jan Möbius's avatar
Jan Möbius committed
201
  pickToolbar_ = new QToolBar(tr("Transform and Move"));
202
  pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
203 204 205 206 207
  pickToolBarActions_ = new QActionGroup(pickToolbar_);
  pickToolBarActions_->setExclusive (false);

  placeAction_ = new QAction(tr("Place manipulator"), pickToolBarActions_);
  placeAction_->setStatusTip(tr("Place manipulator on object. <Doubleclick>"));
208
  placeAction_->setToolTip(tr("Place manipulator on object. <Doubleclick>"));
209 210 211 212 213 214
  placeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-place.png") );
  placeAction_->setCheckable(true);
  pickToolbar_->addAction(placeAction_);

  pickToolbar_->addSeparator ();

215 216
  rotateTranslateAction_ = new QAction(tr("Rotate/Translate object"), pickToolBarActions_);
  rotateTranslateAction_->setStatusTip(tr("Rotate/Translate object."));
217
  rotateTranslateAction_->setToolTip(tr("Rotate/Translate object."));
218 219 220 221
  rotateTranslateAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-translaterotate.png") );
  rotateTranslateAction_->setCheckable(true);
  rotateTranslateAction_->setChecked(true);
  pickToolbar_->addAction(rotateTranslateAction_);
222 223 224

  resizeAction_ = new QAction(tr("Resize object"), pickToolBarActions_);
  resizeAction_->setStatusTip(tr("Resize object. <Control>"));
225
  resizeAction_->setToolTip(tr("Resize object. <Control>"));
226 227 228 229 230 231
  resizeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-resize.png") );
  resizeAction_->setCheckable(true);
  pickToolbar_->addAction(resizeAction_);

  pickToolbar_->addSeparator ();

232 233
  rotateManipAction_ = new QAction(tr("Rotate manipulator"), pickToolBarActions_);
  rotateManipAction_->setStatusTip(tr("Rotate manipulator. <Shift>"));
234
  rotateManipAction_->setToolTip(tr("Rotate manipulator. <Shift>"));
235 236 237
  rotateManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-maniprotate.png") );
  rotateManipAction_->setCheckable(true);
  pickToolbar_->addAction(rotateManipAction_);
238

239 240
  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
241
  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
242 243 244
  placeAndSnapAction_->setCheckable(true);
  pickToolbar_->addAction(placeAndSnapAction_);

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

259 260 261 262 263 264 265 266 267 268 269
#ifdef ENABLE_SKELETON_SUPPORT
  pickToolbar_->addSeparator();
  fixChildManipAction_ = new QAction(tr("Keep child joints fixed"), pickToolBarActions_);
  fixChildManipAction_->setStatusTip(tr("Do not apply transformations to all child joints"));
  fixChildManipAction_->setToolTip(tr("Do not apply transformations to all child joints"));
  fixChildManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipfix.png") );
  fixChildManipAction_->setCheckable(true);
  fixChildManipAction_->setChecked(recursiveJointTransformation_);
  pickToolbar_->addAction(fixChildManipAction_);
#endif
  
270 271 272 273
  connect(pickToolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotPickToolbarAction(QAction*)) );

  emit setPickModeToolbar ("Move", pickToolbar_);
  emit setPickModeToolbar ("MoveSelection", pickToolbar_);
274 275 276 277 278
  
#ifdef ENABLE_SKELETON_SUPPORT
  emit setPickModeToolbar ("MoveSkeleton", pickToolbar_);
#endif
  
Jan Möbius's avatar
 
Jan Möbius committed
279 280 281 282 283 284 285
}


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

Jan Möbius's avatar
Jan Möbius committed
286
void MovePlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
{
   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;

Jan Möbius's avatar
Jan Möbius committed
302
   emit addToolbox( tr("Move") , tool_ );
Jan Möbius's avatar
 
Jan Möbius committed
303 304 305 306 307 308 309 310
}


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

/** \brief MouseWheel event occured
311
 *
Jan Möbius's avatar
 
Jan Möbius committed
312 313 314 315
 * @param _event the event that occured
 */
void MovePlugin::slotMouseWheelEvent(QWheelEvent * _event, const std::string & /*_mode*/)
{
316
  // Skip execution if this is not our pick mode
317 318 319 320
  if( ( (PluginFunctions::pickMode() != "Move")
     && (PluginFunctions::pickMode() != "MoveSelection")
     && (PluginFunctions::pickMode() != "MoveSkeleton") )
    || PluginFunctions::actionMode() != Viewer::PickingMode)
321 322 323 324 325 326 327 328 329 330 331
    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
332 333 334 335 336 337
}


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

/** \brief MousePress event occured
338
 *
Jan Möbius's avatar
 
Jan Möbius committed
339 340
 * @param _event the event that occured
 */
341
void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
342 343 344
    if (((PluginFunctions::pickMode() == ("Move"))
      || (PluginFunctions::pickMode() == ("MoveSelection"))
      || (PluginFunctions::pickMode() == ("MoveSkeleton")))
345
            && PluginFunctions::actionMode() == Viewer::PickingMode) {
Jan Möbius's avatar
 
Jan Möbius committed
346

347 348
        if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
                && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
349 350 351
          
            bool snap = (placeMode_ && (PluginFunctions::pickMode() == ("MoveSelection")))
                      || (PluginFunctions::pickMode() == ("MoveSkeleton"));
Jan Möbius's avatar
 
Jan Möbius committed
352

353
            placeManip(_event, snap);
354 355
            placeAction_->setChecked(false);
            updateManipulatorDialog();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
356

357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
            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.
380 381 382
             *
             * For skeletons always snap to nearest joint
             *
383 384
             */

385
            placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
386 387 388 389 390
            updateManipulatorDialog();
            return;
        }

        // interaction
391
        ACG::SceneGraph::MouseEventAction action(_event,PluginFunctions::viewerProperties().glState());
392 393 394
        PluginFunctions::traverse(action);

        if (_event->buttons() == Qt::LeftButton)
395
          emit nodeVisibilityChanged(-1);
396 397

    }
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
398 399 400 401 402 403 404 405 406
}

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

void MovePlugin::slotKeyEvent (QKeyEvent* _event)
{
  if (_event->key() == Qt::Key_Control)
407
    setManipMode (QtTranslationManipulatorNode::Resize);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
408
  else if (_event->key () == Qt::Key_Shift)
409
    setManipMode (QtTranslationManipulatorNode::LocalRotation);
Jan Möbius's avatar
 
Jan Möbius committed
410 411
}

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
412 413 414 415 416 417
//------------------------------------------------------------------------------

void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
{
  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
      (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
418
    setManipMode (QtTranslationManipulatorNode::TranslationRotation);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
419
}
Jan Möbius's avatar
 
Jan Möbius committed
420 421 422 423 424 425

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

/** \brief slot is called when the pickMode changed
426
 *
Jan Möbius's avatar
 
Jan Möbius committed
427 428 429 430
 * @param _mode new pickMode
 */
void MovePlugin::slotPickModeChanged( const std::string& _mode)
{
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
431 432
  moveAction_->setChecked(_mode == "Move");
  moveSelectionAction_->setChecked(_mode == "MoveSelection");
433

434 435 436 437 438 439
#ifdef ENABLE_SKELETON_SUPPORT
  moveSkeletonAction_->setChecked(_mode == "MoveSkeleton");
  fixChildManipAction_->setVisible(_mode == "MoveSkeleton");
#endif

  hide_ = !(_mode == "Move" || _mode == "MoveSelection" || _mode == "MoveSkeleton");
Jan Möbius's avatar
 
Jan Möbius committed
440

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
441 442 443 444 445 446 447 448 449 450 451 452
  showManipulators();

  if (!hide_)
  {
    switch (manMode_)
    {
      case QtTranslationManipulatorNode::Resize:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        PluginFunctions::setViewObjectMarker (&objectMarker_);
        break;
453 454 455
      case QtTranslationManipulatorNode::Place:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
456 457 458 459 460 461 462
      case QtTranslationManipulatorNode::TranslationRotation:
        PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
        break;
    }
  }
  else
    PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
Jan Möbius's avatar
 
Jan Möbius committed
463 464 465 466 467 468 469 470
}


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

/** \brief Move object with given transformation matrix
471
 *
Jan Möbius's avatar
 
Jan Möbius committed
472 473 474 475 476
 * @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
477
  if ( ! PluginFunctions::getObject(_id,object) )
Jan Möbius's avatar
 
Jan Möbius committed
478 479
    return;

480 481 482 483
  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
484 485 486 487
#ifdef ENABLE_TSPLINEMESH_SUPPORT
  } else  if  ( object->dataType()  == DATA_TSPLINE_MESH ) {
    transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
#endif
488
#ifdef ENABLE_POLYLINE_SUPPORT
489 490
  } else  if  ( object->dataType()  == DATA_POLY_LINE ) {
    transformPolyLine(mat , *PluginFunctions::polyLine(object) );
491 492 493 494 495
#endif
#ifdef ENABLE_SKELETON_SUPPORT
  } else  if  ( object->dataType()  == DATA_SKELETON ) {
    transformSkeleton(mat , *PluginFunctions::skeleton(object) );
#endif
Dirk Wilden's avatar
Dirk Wilden committed
496 497
  } else  if  ( object->dataType()  == DATA_PLANE ) {
    PluginFunctions::planeNode(object)->transform(mat);
498 499
  } else {

Jan Möbius's avatar
Jan Möbius committed
500
    emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
501
    return;
Jan Möbius's avatar
 
Jan Möbius committed
502 503
  }

504
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
505 506 507 508 509 510 511
  emit createBackup(_id,"Move");
}


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

/** \brief Move selection on an object with given transformation matrix
512
 *
Jan Möbius's avatar
 
Jan Möbius committed
513 514 515 516
 * 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.
 *
517 518
 * @param mat
 * @param _id
Jan Möbius's avatar
 
Jan Möbius committed
519 520 521 522 523 524 525 526 527 528
 */
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 );

529
  emit updatedObject(_id, UPDATE_GEOMETRY);
Jan Möbius's avatar
 
Jan Möbius committed
530 531 532
//   emit createBackup(_id,"MoveSelection");
}

533 534
//------------------------------------------------------------------------------

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
#ifdef ENABLE_SKELETON_SUPPORT
/** \brief Move joint of a skeleton with given transformation matrix
 *
 * @param mat the transformation matrix
 * @param _id id of the skeleton
 */
void MovePlugin::moveSkeletonJoint(ACG::Matrix4x4d mat, int _id) {

  transformSkeletonJoint( _id , mat );

  emit updatedObject(_id, UPDATE_GEOMETRY);
//   emit createBackup(_id,"MoveSkeleton");
}
#endif

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

552 553 554 555 556 557 558 559 560 561
/** \brief Set the manipulator manipulation mode
 *
 * @param _mode Mode
 */

void MovePlugin::setManipMode (QtTranslationManipulatorNode::ManipulatorMode _mode)
{
  if (_mode != manMode_)
  {
    manMode_ = _mode;
562 563
    if ((PluginFunctions::pickMode() == "Move" ) || (PluginFunctions::pickMode() == "MoveSelection" )
                                                 || (PluginFunctions::pickMode() == "MoveSkeleton" )) {
564 565 566 567
        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
568 569 570 571 572
      if (!hide_)
        switch (manMode_)
        {
          case QtTranslationManipulatorNode::Resize:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
573
            placeMode_ = false;
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
574 575 576
            break;
          case QtTranslationManipulatorNode::LocalRotation:
            PluginFunctions::setViewObjectMarker (&objectMarker_);
577 578 579 580 581
            placeMode_ = false;
            break;
          case QtTranslationManipulatorNode::Place:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
            placeMode_ = true;
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
582 583 584
            break;
          case QtTranslationManipulatorNode::TranslationRotation:
            PluginFunctions::setViewObjectMarker (PluginFunctions::defaultViewObjectMarker ());
585
            placeMode_ = false;
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
586 587
            break;
        }
588 589 590 591 592
    }
    switch (manMode_)
    {
      case QtTranslationManipulatorNode::Resize:
        resizeAction_->setChecked (true);
593 594
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
595
        placeAndSnapAction_->setChecked (false);
596 597 598
        break;
      case QtTranslationManipulatorNode::LocalRotation:
        resizeAction_->setChecked (false);
599 600
        rotateManipAction_->setChecked (true);
        rotateTranslateAction_->setChecked (false);
601
        placeAndSnapAction_->setChecked (false);
602 603 604
        break;
      case QtTranslationManipulatorNode::TranslationRotation:
        resizeAction_->setChecked (false);
605 606
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (true);
607 608 609 610 611 612 613
        placeAndSnapAction_->setChecked (false);
        break;
      case QtTranslationManipulatorNode::Place:
        resizeAction_->setChecked (false);
        rotateManipAction_->setChecked (false);
        rotateTranslateAction_->setChecked (false);
        placeAndSnapAction_->setChecked (true);
614 615 616 617 618 619 620
        break;
    }
  }
}

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

621
/** \brief Hide context menu entry when right clicking on node other than manipulator node
622
 *
623 624
 * @param _nodeId Identifier of node that has been clicked
 */
625
void MovePlugin::slotUpdateContextMenuNode(int _nodeId) {
626

627
    ACG::SceneGraph::BaseNode* node = ACG::SceneGraph::find_node(PluginFunctions::getSceneGraphRootNode(), _nodeId);
628

629 630
    if (node == 0)
        return;
631

632 633 634 635
    if (node->className() != "QtTranslationManipulatorNode") {
        contextAction_->setVisible(false);
    } else {
        contextAction_->setVisible(true);
636 637
    }
}
Jan Möbius's avatar
 
Jan Möbius committed
638 639 640 641

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

/** \brief move the object when its manipulator moves
642
 *
Jan Möbius's avatar
 
Jan Möbius committed
643 644 645 646 647 648
 * @param _node the manipulator node
 * @param _event the mouse event
 */
void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {

  // React on event only in move mode
649 650 651
  if ( PluginFunctions::pickMode() != "Move"
    && PluginFunctions::pickMode() != "MoveSelection"
    && PluginFunctions::pickMode() != "MoveSkeleton" )
Jan Möbius's avatar
 
Jan Möbius committed
652 653 654 655
    return;

  OpenFlipper::Options::redrawDisabled( true );

656 657
  // Apply changes only on Release for moveMode and after every movement in MoveSelection/MoveSkeleton Mode
  if ( ((_event->type() == QEvent::MouseButtonRelease) || (PluginFunctions::pickMode() != "Move")) && !placeMode_) {
Jan Möbius's avatar
 
Jan Möbius committed
658 659 660 661 662 663 664 665 666 667 668

    int objectId = _node->getIdentifier();

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

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

669
    // move the object which corresponds to the manipulator
670
    if (PluginFunctions::pickMode() == "Move")
Jan Möbius's avatar
 
Jan Möbius committed
671
      moveObject( mat, objectId );
672
    else if (PluginFunctions::pickMode() == "MoveSelection")
Jan Möbius's avatar
 
Jan Möbius committed
673
      moveSelection( mat, objectId );
674 675 676 677 678
    
    #ifdef ENABLE_SKELETON_SUPPORT
    else if (PluginFunctions::pickMode() == "MoveSkeleton")
      moveSkeletonJoint( mat, objectId );
    #endif
Jan Möbius's avatar
 
Jan Möbius committed
679

680
    // move all other targets without manipulator
681
    if(allTargets_) {
682 683 684
      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
685 686 687 688 689 690 691 692 693 694 695
          
          // 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() );
          
          #ifdef ENABLE_SKELETON_SUPPORT
          else if (PluginFunctions::pickMode() == "MoveSkeleton")
            moveSkeletonJoint( mat, o_it->id() );
          #endif
696 697 698
        }
      }
    }
Jan Möbius's avatar
 
Jan Möbius committed
699 700 701 702 703 704 705 706 707 708 709 710 711

    lastActiveManipulator_ = objectId;
    updateManipulatorDialog();
  }

  OpenFlipper::Options::redrawDisabled( false );

}


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

/** \brief update object when its manipulator changes position
712
 *
Jan Möbius's avatar
 
Jan Möbius committed
713 714 715 716 717 718 719
 * @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
720 721 722 723
  if ( objectId > 0 ){

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

Dirk Wilden's avatar
Dirk Wilden committed
725 726 727
    // Assume that it has a good position now
    object->manipPlaced( true );
  }
Jan Möbius's avatar
 
Jan Möbius committed
728 729 730 731 732 733 734 735 736 737 738 739 740 741

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

  lastActiveManipulator_ = objectId;
  updateManipulatorDialog();

}


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

/** \brief Place and show the Manipulator
742
 *
Jan Möbius's avatar
 
Jan Möbius committed
743 744
 * @param _event  mouseEvent that occured
 */
745 746 747 748
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
749

750
    bool successfullyPicked = false;
Jan Möbius's avatar
 
Jan Möbius committed
751

752 753 754 755 756 757
    /*
     * Snap manipulator to nearest geometry
     * element depending on which selection type is
     * active.
     */
    if (_snap) {
758 759 760 761 762
      
        #ifdef ENABLE_SKELETON_SUPPORT
        //first pick anything and check if we hit a skeleton
          
        successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
763
                target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
764 765
        
        if ( object->dataType(DATA_SKELETON) ) {
Jan Möbius's avatar
 
Jan Möbius committed
766

767 768 769 770
          hitPoint = getNearestJoint(PluginFunctions::skeleton(object), hitPoint);
          
        } else {
          successfullyPicked = false;
771
        }
772 773 774 775 776 777 778 779 780 781 782
        #endif
      
        if (!successfullyPicked){
 
          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
783

784 785 786 787 788
          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
789
#ifdef ENABLE_TSPLINEMESH_SUPPORT
790 791
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
792
#endif
793 794 795 796 797 798
              }
          } 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
799
#ifdef ENABLE_TSPLINEMESH_SUPPORT
800 801
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
802
#endif
803 804 805 806 807 808
              }
          } 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
809
#ifdef ENABLE_TSPLINEMESH_SUPPORT
810 811
              } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
                  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
Henrik Zimmer's avatar
Henrik Zimmer committed
812
#endif
813 814
              }
          }
815
        }
Jan Möbius's avatar
 
Jan Möbius committed
816

817 818 819 820
    } 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
821

822
    if (successfullyPicked) {
Jan Möbius's avatar
 
Jan Möbius committed
823

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

826 827 828
        /*if (!object->picked(node_idx)) {
            emit log(LOGWARN, tr("Picking failed"));
        }*/
Jan Möbius's avatar
 
Jan Möbius committed
829

830 831 832 833 834 835 836
        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
837

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

840 841 842 843 844 845 846 847
        // 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.
848 849 850 851 852 853 854 855 856
        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();
857 858 859 860 861 862 863 864 865 866 867
       
        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() );
868 869 870 871

    } else {
        //emit log(LOGWARN, tr("Picking failed"));
    }
Jan Möbius's avatar
 
Jan Möbius committed
872 873 874 875 876 877
}


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

/** \brief Checks if the manipulators should be visible or not
878
 *
Jan Möbius's avatar
 
Jan Möbius committed
879 880 881
 */
void MovePlugin::showManipulators( )
{
Dirk Wilden's avatar
Dirk Wilden committed
882

883 884 885
  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
                                || (PluginFunctions::pickMode() == "MoveSelection")
                                || (PluginFunctions::pickMode() == "MoveSkeleton"))) {
886
    
887 888 889 890 891 892 893
    for (uint i=0; i < activeManipulators_.size(); i++){
      
      BaseObjectData* obj = 0;
      
      PluginFunctions::getObject( activeManipulators_[i], obj );
      
      if (obj != 0 && obj->manipPlaced()) {
894 895 896 897 898 899
        
        #ifdef ENABLE_SKELETON_SUPPORT
        if ( obj->dataType(DATA_SKELETON) )
          moveManipulatorOnSkeleton(obj);
        #endif
        
900 901 902
        obj->manipulatorNode()->show();
        obj->manipulatorNode()->apply_transformation( PluginFunctions::pickMode() == "Move" );
        emit nodeVisibilityChanged(obj->id());
903
      }
904
    }
Jan Möbius's avatar
 
Jan Möbius committed
905

906
  } else {
907 908 909 910 911 912 913 914 915 916 917
    
    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());
      }
918 919 920 921
    }
  }

  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
922 923 924

}

925
//------------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
926

927
/** \brief Get Dialog Widget that contains the button
928
 *
929 930 931 932 933 934 935
 * @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
936 937 938
//------------------------------------------------------------------------------

/** \brief Position of manipulator in tab changed
939
 *
Jan Möbius's avatar
 
Jan Möbius committed
940 941
 */
void MovePlugin::slotSetPosition() {
942

943 944 945
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
946

947
    TriMesh::Point newpos;
948

949 950
    bool ok = false;
    newpos[0] =  (pW->nposx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
951
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
952
    newpos[1] =  (pW->nposy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
953
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
954
    newpos[2] =  (pW->nposz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
955
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
956

957 958 959 960 961 962 963
    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
964 965 966 967 968 969
}


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

/** \brief Toggle the first axis for changing direction in tab
970
 *
Jan Möbius's avatar
 
Jan Möbius committed
971 972
 */
void MovePlugin::slotToggleAxisA() {
973

974 975 976
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
977 978

    axisA_ = (axisA_ + 1) % 3;
979

980 981
    if (axisA_ == axisB_)
	axisA_ = (axisA_ + 1) % 3;
982

983
    switch(axisA_){
Jan Möbius's avatar
Jan Möbius committed
984 985 986
	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;
987 988
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
989 990 991 992 993 994
}


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

/** \brief Toggle the second axis for changing direction in tab
995
 *
Jan Möbius's avatar
 
Jan Möbius committed
996 997
 */
void MovePlugin::slotToggleAxisB() {
998

999 1000 1001
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1002 1003

    axisB_ = (axisB_ + 1) % 3;
1004

1005 1006
    if (axisA_ == axisB_)
	axisB_ = (axisB_ + 1) % 3;
1007

1008
    switch(axisB_){
Jan Möbius's avatar
Jan Möbius committed
1009 1010 1011
	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;
1012 1013
	default: break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
1014 1015 1016 1017 1018 1019
}


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

/** \brief Set Direction of manipulator in tab changed
1020
 *
Jan Möbius's avatar
 
Jan Möbius committed
1021 1022
 */
void MovePlugin::slotSetDirection() {
1023

1024 1025 1026
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1027

1028 1029 1030
    ACG::Vec3d newdirA,newdirB;
    ACG::Vec3d dirX,dirY;
    ACG::Vec3d dirZ(0.0,0.0,0.0);
1031

1032 1033
    bool ok = false;
    newdirA[0] =  (pW->ndirAx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1034
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate"));  return; }
1035
    newdirA[1] =  (pW->ndirAy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1036
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1037
    newdirA[2] =  (pW->ndirAz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1038
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1039

1040
    newdirB[0] =  (pW->ndirBx->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1041
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate"));  return; }
1042
    newdirB[1] =  (pW->ndirBy->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1043
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1044
    newdirB[2] =  (pW->ndirBz->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1045
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1046

1047 1048
    bool xAxis = false;
    bool yAxis = false;
1049

1050 1051 1052 1053 1054
    switch(axisA_){
	case  0: dirX = newdirA; xAxis = true; break;
	case  1: dirY = newdirA; yAxis = true; break;
	default: dirZ = newdirA; break;
    }
1055

1056 1057 1058 1059 1060
    switch(axisB_){
	case  0: dirX = newdirB; xAxis = true; break;
	case  1: dirY = newdirB; yAxis = true; break;
	default: dirZ = newdirB; break;
    }
1061

1062 1063
    if (!xAxis)
	dirX = dirY % dirZ;
1064

1065 1066
    if (!yAxis)
	dirY = dirX % dirZ;
1067 1068


1069
    if ( (dirX | dirY) != 0.0){
Jan Möbius's avatar
Jan Möbius committed
1070
	emit log(LOGERR,tr("The axes of the new direction have to be orthogonal"));
1071 1072
	return;
    }
1073

Jan Möbius's avatar
Jan Möbius committed
1074 1075 1076 1077 1078 1079 1080 1081 1082
//    // Apply to All Target Objects
//     if ( pW->targetObjects->isChecked() ) {
// 	for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ;
//              o_it PluginFunctions::objectsEnd(); ++o_it){
//
// 	    o_it->manipulatorNode()->set_direction( dirX, dirY );
// 	}
//     }

1083 1084 1085
    
    BaseObjectData* object = 0;
    PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1086 1087
    if ( object != 0 ) {
        if (  object->manipulatorNode()->visible() ){
Jan Möbius's avatar
 
Jan Möbius committed
1088 1089

            object->manipulatorNode()->set_direction( dirX, dirY );
1090 1091
	}
    } else return;
1092

1093 1094
    updateManipulatorDialog();
    emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
1095 1096 1097 1098 1099 1100
}


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

/** \brief perform a translation for Manipulator in tab
1101
 *
Jan Möbius's avatar
 
Jan Möbius committed
1102 1103
 */
void MovePlugin::slotTranslation() {
1104

1105 1106 1107
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;
Jan Möbius's avatar
 
Jan Möbius committed
1108

1109
    ACG::Vec3d translation;
1110

1111 1112
    bool ok = false;
    translation[0] =  (pW->translationX->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1113
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate"));  return; }
1114
    translation[1] =  (pW->translationY->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1115
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1116
    translation[2] =  (pW->translationZ->text()).toDouble(&ok);
Jan Möbius's avatar
Jan Möbius committed
1117
    if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1118

Jan Möbius's avatar
Jan Möbius committed
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
//	// Apply to All Target Objects
//	if ( pW->targetObjects->isChecked() ) {
//
//		int manipcount = 0; // Check how many of the target meshes have an visible manipulator
//		int targets = 0; // Count the number of target meshes
//		for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS); o_it != PluginFunctions::objectsEnd(); ++o_it) {
//			++targets;
//			if ( ! o_it->manipulatorNode()->hidden() ) {
//				++ manipcount;
//			}
//		}
//
//		if (manipcount == 0 ) // No manipulator -> no translation
//		return;
//
//		for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DataType( DATA_TRIANGLE_MESH | DATA_POLY_MESH ));
//				o_it != PluginFunctions::objectsEnd(); ++o_it) {
//			if ( manipcount > 1 ) { // Use manipulator direction for each target mesh
//				if ( o_it->manipulatorNode()->hidden() )
//				continue;
//			}
//
//			translate( o_it->id() , translation );
//
//			o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() + translation );
//			emit createBackup(o_it->id(),"Translation");
//			emit updatedObject(o_it->id());
//		}
//
//	}

1150 1151 1152
        BaseObjectData* object = 0;
        PluginFunctions::getObject(pW->getBaseObjectDataId(),object);

1153
	if (object != 0) {
1154
		if (object->manipulatorNode()->visible()) {
Jan Möbius's avatar
 
Jan Möbius committed
1155

1156
			translate(object->id(), translation);
1157

1158 1159 1160
			object->manipulatorNode()->set_center(
					object->manipulatorNode()->center() + translation);
			emit createBackup(object->id(), "Translation");
1161
			emit updatedObject(object->id(), UPDATE_GEOMETRY);
1162 1163 1164
		}
	} else {
		return;
1165
	}
Jan Möbius's avatar
 
Jan Möbius committed
1166

Jan Möbius's avatar
Jan Möbius committed
1167

1168 1169 1170
    updateManipulatorDialog();
    emit scriptInfo(QString("slotTranslation()"));
    emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
1171 1172 1173 1174 1175 1176
}


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

/** \brief Project the current manipulator onto the tangent plane of the object
1177
 *
Jan Möbius's avatar
 
Jan Möbius committed
1178 1179
 */
void MovePlugin::slotProjectToTangentPlane() {
1180

1181 1182 1183 1184
    QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
    movePropsWidget* pW = getDialogFromButton(but);
    if(pW == 0) return;

1185
    if ( allTargets_ ) {
Jan Möbius's avatar
Jan Möbius committed
1186
    	emit log(LOGWARN,tr("TODO Project for multiple targets"));
1187
    	return;
1188
    } else {
Jan Möbius's avatar
Jan Möbius committed
1189
    	emit log(LOGWARN,tr("TODO Project for one target"));
1190
    	return;
1191
    }
Jan Möbius's avatar
 
Jan Möbius committed
1192 1193 1194 1195 1196 1197 1198

}


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

/** \brief Move the current manipulator to the cog of the object
1199
 *
Jan Möbius's avatar
 
Jan Möbius committed
1200 1201
 */
void MovePlugin::slotMoveManipToCOG() {
1202