Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MovePlugin.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 #include "MovePlugin.hh"
52 
53 #include <MeshTools/MeshInfoT.hh>
54 
55 #ifdef USE_OPENMP
56 #endif
57 
58 #if QT_VERSION >= 0x050000
59 #else
60 #include <QtGui>
61 #endif
62 
63 #ifdef ENABLE_POLYLINE_SUPPORT
65 #endif
66 
67 #ifdef ENABLE_TSPLINEMESH_SUPPORT
68 #include <ObjectTypes/TSplineMesh/TSplineMesh.hh>
69 #endif
70 
71 #ifdef ENABLE_SKELETON_SUPPORT
72 #include <ObjectTypes/Skeleton/Helper/SkeletonTransform.hh>
73 #endif
74 
75 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
77 #endif
78 
79 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
81 #endif
82 
87 axisA_(0),
88 axisB_(1),
89 toolboxActive_(false),
90 tool_(0),
91 toolIcon_(0),
92 moveAction_(0),
93 moveSelectionAction_(0),
94 toolBarActions_(0),
95 toolbar_(0),
96 pickToolbar_(0),
97 placeAction_(0),
98 rotateTranslateAction_(0),
99 rotateManipAction_(0),
100 resizeAction_(0),
101 biggerManipAction_(0),
102 smallerManipAction_(0),
103 fixChildManipAction_(0),
104 transformRefPoseManipAction_(0),
105 currentPoseManipAction_(0),
106 placeAndSnapAction_(0),
107 pickToolBarActions_(0),
108 manip_size_(1.0),
109 manip_size_modifier_(1.0),
110 lastActiveManipulator_(-1),
111 manMode_(QtTranslationManipulatorNode::TranslationRotation),
112 selectionType_(VERTEX),
113 contextAction_(0),
114 contextActionHide_(0),
115 toAllTargets_(0),
116 contextMenuManipControl_(0),
117 contextMenuManipControlsAction_(0),
118 hide_(true),
119 allTargets_(false),
120 placeMode_(false),
121 transformedSelected_(false)
122 {
123 
124 }
125 
130 
131  if(contextAction_) {
132  delete contextAction_;
133  }
134 
135  if(contextActionHide_) {
136  delete contextActionHide_;
137  }
138 
139  if(toAllTargets_) {
140  delete toAllTargets_;
141  }
142 
143  for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
144  it != propsWindows_.end(); ++it) {
145 
146  if(*it) {
147  delete *it;
148  }
149  }
150 }
151 
152 
153 /*******************************************************************************
154  BaseInterface implementation
155  *******************************************************************************/
156 
161 
162  //PICKMODES
163  emit addPickMode("Separator");
164  emit addHiddenPickMode("Move");
165  emit setPickModeMouseTracking ("Move", true);
166  emit addHiddenPickMode("MoveSelection");
167  emit setPickModeMouseTracking ("MoveSelection", true);
168 
169  //KEYS
170  emit registerKey (Qt::Key_Shift, Qt::NoModifier, tr("Manipulator rotation"), true);
171  emit registerKey (Qt::Key_Shift, Qt::ShiftModifier, tr("Manipulator rotation"), true);
172  emit registerKey (Qt::Key_Shift, Qt::ControlModifier | Qt::ShiftModifier, tr("Manipulator rotation"), true);
173  emit registerKey (Qt::Key_Control, Qt::NoModifier, tr("Resize"), true);
174  emit registerKey (Qt::Key_Control, Qt::ControlModifier, tr("Resize"), true);
175  emit registerKey (Qt::Key_Control, Qt::ShiftModifier | Qt::ControlModifier, tr("Resize"), true);
176 
177  //SCRIPTING SLOT DESCRIPTIONS
178  setDescriptions();
179 
180  // ==================================
181  // Toolbar
182  // ==================================
183 
184  WhatsThisGenerator whatsThis("Move");
185  WhatsThisGenerator whatsThisUser("user");
186 
187  toolbar_ = new QToolBar(tr("Transform and Move"));
188  toolbar_->setObjectName("TransformAndMoveToolBar");
189 
190  toolBarActions_ = new QActionGroup(toolbar_);
191 
192  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
193  moveAction_->setStatusTip(tr("Move object in 3D."));
194  moveAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-objects.png") );
195  moveAction_->setCheckable(true);
196  whatsThis.setWhatsThis(moveAction_,tr("Move the whole object."));
197  toolbar_->addAction(moveAction_);
198 
199  moveSelectionAction_ = new QAction(tr("<B>Move Selection</B><br>Move a selection on an object"), toolBarActions_);
200  moveSelectionAction_->setStatusTip(tr("Move selections in 3D."));
201  moveSelectionAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-selections.png") );
202  moveSelectionAction_->setCheckable(true);
203  whatsThis.setWhatsThis(moveSelectionAction_,tr("Move only a selection."));
204  toolbar_->addAction(moveSelectionAction_);
205 
206  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );
207 
208  emit addToolbar(toolbar_);
209 
210  // ==================================
211  // Pick Toolbar
212  // ==================================
213 
214  pickToolbar_ = new QToolBar(tr("Transform and Move PickTool bar"));
215  pickToolbar_->setObjectName("TransformAndMovePickToolBar");
216 
217  pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
218  pickToolBarActions_ = new QActionGroup(pickToolbar_);
219  pickToolBarActions_->setExclusive (false);
220 
221  placeAction_ = new QAction(tr("Place manipulator"), pickToolBarActions_);
222  placeAction_->setStatusTip(tr("Place manipulator on object. <Doubleclick>"));
223  placeAction_->setToolTip(tr("Place manipulator on object. <Doubleclick>"));
224  placeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-place.png") );
225  whatsThisUser.setWhatsThis(placeAction_,tr("Place the manipulator."),"obj_man","manipulator.html");
226  placeAction_->setCheckable(true);
227  pickToolbar_->addAction(placeAction_);
228 
229  pickToolbar_->addSeparator ();
230 
231  rotateTranslateAction_ = new QAction(tr("Rotate/Translate object"), pickToolBarActions_);
232  rotateTranslateAction_->setStatusTip(tr("Rotate/Translate object."));
233  rotateTranslateAction_->setToolTip(tr("Rotate/Translate object."));
234  rotateTranslateAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-translaterotate.png") );
235  rotateTranslateAction_->setCheckable(true);
236  rotateTranslateAction_->setChecked(true);
237  whatsThisUser.setWhatsThis(rotateTranslateAction_,tr("Rotate or translate an object or selection."),"obj_translation","manipulator.html");
239 
240  resizeAction_ = new QAction(tr("Resize object"), pickToolBarActions_);
241  resizeAction_->setStatusTip(tr("Resize object. <Control>"));
242  resizeAction_->setToolTip(tr("Resize object. <Control>"));
243  resizeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-resize.png") );
244  whatsThisUser.setWhatsThis(resizeAction_,tr("Resize object or selection."),"obj_resizing","manipulator.html");
245  resizeAction_->setCheckable(true);
246  pickToolbar_->addAction(resizeAction_);
247 
248  pickToolbar_->addSeparator ();
249 
250  rotateManipAction_ = new QAction(tr("Rotate manipulator"), pickToolBarActions_);
251  rotateManipAction_->setStatusTip(tr("Rotate manipulator. <Shift>"));
252  rotateManipAction_->setToolTip(tr("Rotate manipulator. <Shift>"));
253  rotateManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-maniprotate.png") );
254  whatsThisUser.setWhatsThis(rotateManipAction_,tr("Rotate only the Manipulator."),"man_rotating","manipulator.html");
255  rotateManipAction_->setCheckable(true);
256  pickToolbar_->addAction(rotateManipAction_);
257 
258  placeAndSnapAction_ = new QAction(tr("Locally translate manipulator"), pickToolBarActions_);
259  placeAndSnapAction_->setStatusTip(tr("Locally translate manipulator. Press and hold <Alt> for snapping."));
260  whatsThisUser.setWhatsThis(placeAndSnapAction_,tr("Translate only the Manipulator."),"man_translation","manipulator.html");
261  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
262  placeAndSnapAction_->setCheckable(true);
263  pickToolbar_->addAction(placeAndSnapAction_);
264 
265  smallerManipAction_ = new QAction(tr("Decrease size of manipulator"), pickToolBarActions_);
266  smallerManipAction_->setStatusTip(tr("Make manipulator smaller. <Mouse wheel up>"));
267  smallerManipAction_->setToolTip(tr("Make manipulator smaller. <Mouse wheel up>"));
268  whatsThisUser.setWhatsThis(smallerManipAction_,tr("Resize the Manipulator to a smaller one."),"man_resizing","manipulator.html");
269  smallerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipsmall.png") );
270  smallerManipAction_->setCheckable(false);
271  pickToolbar_->addAction(smallerManipAction_);
272 
273  biggerManipAction_ = new QAction(tr("Increase size of manipulator"), pickToolBarActions_);
274  biggerManipAction_->setStatusTip(tr("Make manipulator bigger. <Mouse wheel down>"));
275  biggerManipAction_->setToolTip(tr("Make manipulator bigger. <Mouse wheel down>"));
276  whatsThisUser.setWhatsThis(biggerManipAction_,tr("Resize the Manipulator to a bigger one."),"man_resizing","manipulator.html");
277  biggerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipbig.png") );
278  biggerManipAction_->setCheckable(false);
279  pickToolbar_->addAction(biggerManipAction_);
280 
281  connect(pickToolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotPickToolbarAction(QAction*)) );
282 
283  emit setPickModeToolbar ("Move", pickToolbar_);
284  emit setPickModeToolbar ("MoveSelection", pickToolbar_);
285 
286  // ==================================
287  // CONTEXT MENU
288  // ==================================
289  toAllTargets_ = new QAction(tr("Apply to all targets"), this);
290  toAllTargets_->setCheckable(true);
291  toAllTargets_->setToolTip(tr("Apply transformation to all target objects"));
292  toAllTargets_->setStatusTip( toAllTargets_->toolTip() );
293 
294  contextAction_ = new QAction(tr("Set properties"), this);
295  contextAction_->setToolTip(tr("Set properties"));
296  contextAction_->setStatusTip( contextAction_->toolTip() );
297  contextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-properties.png") );
298 
299  contextActionHide_ = new QAction(tr("Hide Manipulator"), this);
300  contextActionHide_->setToolTip(tr("Hide Manipulator"));
301  contextActionHide_->setStatusTip( contextActionHide_->toolTip() );
302  contextActionHide_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-hide.png") );
303 
304  // QMenu replicating the relevant pick toolbar actions
305  contextMenuManipControl_ = new QMenu(tr("Manipulator Controls"));
312 
313 
315 
316  emit addContextMenuItem(toAllTargets_ , CONTEXTNODEMENU );
317  emit addContextMenuItem(contextAction_ , CONTEXTNODEMENU );
318  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
319  emit addContextMenuItem(contextMenuManipControlsAction_ , CONTEXTNODEMENU );
320 
321  connect( toAllTargets_ , SIGNAL(toggled(bool) ), this, SLOT(setAllTargets(bool)));
322  connect( contextAction_ , SIGNAL( triggered() ), this, SLOT(showProps()) );
323  connect( contextActionHide_ , SIGNAL( triggered() ), this, SLOT(hideManipulator()) );
324 }
325 
326 
327 /*******************************************************************************
328  ToolBoxInterface implementation
329  *******************************************************************************/
330 
331 void MovePlugin::initializePlugin()
332 {
333  toolboxActive_ = false;
334  tool_ = new moveToolbarWidget();
335 
336  connect(tool_->moveToOrigin,SIGNAL(clicked() ),this,SLOT(slotMoveToOrigin()));
337 
338  tool_->moveToOrigin->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "moveToCOG.png") );
339  tool_->moveToOrigin->setIconSize(QSize(48,48));
340  WhatsThisGenerator whatsThis("Move");
341  tool_->moveToOrigin->setWhatsThis(QString(tr("Moves the selected objects such that their center of gravity is at the origin."))
342  +whatsThis.generateLink("move_cog"));
343 
344  connect(tool_->unifyBoundingBoxDiagonal,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxDiagonal()));
345  tool_->unifyBoundingBoxDiagonal->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB.png") );
346  tool_->unifyBoundingBoxDiagonal->setIconSize(QSize(48,48));
347  tool_->unifyBoundingBoxDiagonal->setWhatsThis(QString(tr("Rescale objects such that its bounding box diagonal has length one."))
348  +whatsThis.generateLink("unifyBB"));
349 
350  connect(tool_->unifyBoundingBoxLongest,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxLongestAxis()));
351  tool_->unifyBoundingBoxLongest->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB_longest.png") );
352  tool_->unifyBoundingBoxLongest->setIconSize(QSize(48,48));
353 
354  connect(tool_->unifyBoundingBoxAll,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxAllAxis()));
355  tool_->unifyBoundingBoxAll->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB_all.png") );
356  tool_->unifyBoundingBoxAll->setIconSize(QSize(48,48));
357 
359 
360  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-toolBox.png");
361  emit addToolbox( tr("Move") , tool_, toolIcon_ );
362 }
363 
364 
365 /*******************************************************************************
366  MouseInterface implementation
367  *******************************************************************************/
368 
369 void MovePlugin::slotMouseWheelEvent(QWheelEvent * _event, const std::string & /*_mode*/)
370 {
371  // Skip execution if this is not our pick mode
372  if( ( (PluginFunctions::pickMode() != "Move")
373  && (PluginFunctions::pickMode() != "MoveSelection") )
374  || PluginFunctions::actionMode() != Viewer::PickingMode)
375  return;
376 
377  // compute the manipulator size modifier based on the mouse wheel change
378  manip_size_modifier_ = manip_size_modifier_ - (float)_event->delta() / 120.0 * 0.1;
379 
380  //dont scroll into negative sizes
381  if (manip_size_modifier_ < 0.0)
382  manip_size_modifier_ = 0.0;
383 
384  // Resize all manipulators based on the modifier on all objects
386  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
387 
388  // Redraw scene with updated manipulators
389  emit updateView();
390 }
391 
392 
393 //------------------------------------------------------------------------------
394 
399 void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
400  if (((PluginFunctions::pickMode() == ("Move"))
401  || (PluginFunctions::pickMode() == ("MoveSelection")))
402  && PluginFunctions::actionMode() == Viewer::PickingMode) {
403 
404  if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
405  && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
406 
407  bool snap = (placeMode_ && (PluginFunctions::pickMode() == ("MoveSelection")));
408 
409  placeManip(_event, snap);
410  placeAction_->setChecked(false);
412 
413  if (placeMode_) {
414  manMode_ = QtTranslationManipulatorNode::TranslationRotation;
415 
417  != PluginFunctions::objectsEnd(); ++o_it)
418  if (o_it->manipPlaced())
419  o_it->manipulatorNode()->setMode(manMode_);
420 
421  resizeAction_->setChecked(false);
422  rotateManipAction_->setChecked(false);
423  rotateTranslateAction_->setChecked(true);
424  placeAndSnapAction_->setChecked(false);
425  }
426 
427  placeMode_ = false;
428  return;
429 
430  } else if (placeMode_) {
431 
432  /*
433  * Move manipulator along with cursor if placeAndSnap mode
434  * is active. Snap to nearest geometry element (vertex, line, face center)
435  * depending on which selection type is active.
436  *
437  */
438 
439  placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
441  return;
442  }
443 
444  // interaction
447 
448  if (_event->buttons() == Qt::LeftButton)
449  emit nodeVisibilityChanged(-1);
450 
451  }
452 }
453 
454 /*******************************************************************************
455  KeyInterface implementation
456  *******************************************************************************/
457 
458 void MovePlugin::slotKeyEvent (QKeyEvent* _event)
459 {
460  if ((_event->key() == Qt::Key_Control) && _event->modifiers() != Qt::ShiftModifier) {
461  setManipMode (QtTranslationManipulatorNode::Resize);
462  return;
463  } else if ((_event->key () == Qt::Key_Shift) && _event->modifiers() != Qt::ControlModifier) {
464  setManipMode (QtTranslationManipulatorNode::LocalRotation);
465  return;
466  }
467 
468  // Return to normal mode if Ctrl + Shift is pressed since this
469  // is used in translation manipulator node for rotation rasterization
470  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
471 }
472 
473 //------------------------------------------------------------------------------
474 
476 {
477  PluginFunctions::pickMode("MoveSelection");
478 }
479 
480 //------------------------------------------------------------------------------
482 {
484 }
485 //------------------------------------------------------------------------------
486 
487 void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
488 {
489  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
490  (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
491  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
492 }
493 
494 void MovePlugin::setPickModeProps(movePropsWidget* _pW, const std::string &_pickmode)
495 {
496  if (_pickmode == "Move")
497  {
498  _pW->objectRadioButton->setChecked(true);
499  }
500  else if (_pickmode == "MoveSelection")
501  {
502  _pW->selectionRadioButton->setChecked(true);
503  }
504  else
505  {
506  //not supported, so deselect all radio buttons
507  _pW->objectRadioButton->setAutoExclusive(false);
508  _pW->selectionRadioButton->setAutoExclusive(false);
509  _pW->objectRadioButton->setChecked(false);
510  _pW->selectionRadioButton->setChecked(false);
511  _pW->objectRadioButton->setAutoExclusive(true);
512  _pW->selectionRadioButton->setAutoExclusive(true);
513  }
514 }
515 
516 /*******************************************************************************
517  PickingInterface implementation
518  *******************************************************************************/
519 
524 void MovePlugin::slotPickModeChanged( const std::string& _mode)
525 {
526  moveAction_->setChecked(_mode == "Move");
527  moveSelectionAction_->setChecked(_mode == "MoveSelection");
528 
529  hide_ = !(_mode == "Move" || _mode == "MoveSelection");
530 
532 
533  if (!hide_)
534  {
535  switch (manMode_)
536  {
537  case QtTranslationManipulatorNode::Rotation:
539  break;
540  case QtTranslationManipulatorNode::Resize:
542  break;
543  case QtTranslationManipulatorNode::LocalRotation:
545  break;
546  case QtTranslationManipulatorNode::Place:
548  break;
549  case QtTranslationManipulatorNode::TranslationRotation:
551  break;
552  }
553  }
554  else
556 
557  //change the selection mode in propety widget
558  for (int i = 0; i < propsWindows_.size(); ++i)
559  setPickModeProps(propsWindows_[i], _mode);
560 
561 }
562 
563 
564 /*******************************************************************************
565  MovePlugin implementation
566  *******************************************************************************/
567 
574  BaseObjectData* object;
575  if ( ! PluginFunctions::getObject(_id,object) )
576  return;
577 
578  if ( mat.is_identity() )
579  return;
580 
581  if ( object->dataType() == DATA_TRIANGLE_MESH ) {
582  transformMesh(mat , *PluginFunctions::triMesh(object) );
583  } else if ( object->dataType() == DATA_POLY_MESH ) {
584  transformMesh(mat , *PluginFunctions::polyMesh(object) );
585 #ifdef ENABLE_TSPLINEMESH_SUPPORT
586  } else if ( object->dataType() == DATA_TSPLINE_MESH ) {
587  transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
588 #endif
589 #ifdef ENABLE_POLYLINE_SUPPORT
590  } else if ( object->dataType() == DATA_POLY_LINE ) {
591  transformPolyLine(mat , *PluginFunctions::polyLine(object) );
592 #endif
593 #ifdef ENABLE_SKELETON_SUPPORT
594  } else if ( object->dataType() == DATA_SKELETON ) {
595  transformSkeleton(mat , *PluginFunctions::skeleton(object) );
596 #endif
597 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
598  } else if ( object->dataType() == DATA_HEXAHEDRAL_MESH ) {
600  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
601 #endif
602 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
603  } else if ( object->dataType() == DATA_POLYHEDRAL_MESH ) {
605  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
606 #endif
607  } else if ( object->dataType() == DATA_PLANE ) {
608  PluginFunctions::plane(object)->transform(mat);
609  } else {
610 
611  emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
612  return;
613  }
614 
615  emit updatedObject(_id, UPDATE_GEOMETRY);
616  emit createBackup(_id, "Move Object", UPDATE_GEOMETRY);
617 }
618 
619 
620 //------------------------------------------------------------------------------
621 
632 void MovePlugin::moveSelection(ACG::Matrix4x4d _mat, int _id, QEvent::Type _type) {
633  // Get currently active primitive type
635 
636  if ( !_mat.is_identity() ){
637  if (selectionType_ & VERTEX) {
639  }
640  if (selectionType_ & FACE) {
642  }
643  if (selectionType_ & EDGE) {
645  }
646  if (selectionType_ & CELL) {
648  }
649 
650  emit updatedObject(_id, UPDATE_GEOMETRY);
651  }
652 
653  //only create backups on mouseRelease and something has to have been selected and transformed
654  if ( _type == QEvent::MouseButtonRelease && transformedSelected_ )
655  emit createBackup(_id,"Move Selection", UPDATE_GEOMETRY);
656 
657 }
658 
659 //------------------------------------------------------------------------------
660 
666 {
667  if (_mode != manMode_)
668  {
669  manMode_ = _mode;
670 
671  // Iterate over all objects that have a placed manip and set their mode
673  if ( o_it->manipPlaced() )
674  o_it->manipulatorNode()->setMode (_mode);
675 
676 
677  if (!hide_) {
678  switch (manMode_)
679  {
680  case QtTranslationManipulatorNode::Rotation:
682  placeMode_ = false;
683  break;
684  case QtTranslationManipulatorNode::Resize:
686  placeMode_ = false;
687  break;
688  case QtTranslationManipulatorNode::LocalRotation:
690  placeMode_ = false;
691  break;
692  case QtTranslationManipulatorNode::Place:
694  placeMode_ = true;
695  break;
696  case QtTranslationManipulatorNode::TranslationRotation:
698  placeMode_ = false;
699  break;
700  }
701  }
702 
703  // Update the toolbar icons
704  switch (manMode_)
705  {
706  case QtTranslationManipulatorNode::Resize:
707  resizeAction_->setChecked (true);
708  rotateManipAction_->setChecked (false);
709  rotateTranslateAction_->setChecked (false);
710  placeAndSnapAction_->setChecked (false);
711  break;
712  case QtTranslationManipulatorNode::LocalRotation:
713  resizeAction_->setChecked (false);
714  rotateManipAction_->setChecked (true);
715  rotateTranslateAction_->setChecked (false);
716  placeAndSnapAction_->setChecked (false);
717  break;
718  case QtTranslationManipulatorNode::TranslationRotation:
719  resizeAction_->setChecked (false);
720  rotateManipAction_->setChecked (false);
721  rotateTranslateAction_->setChecked (true);
722  placeAndSnapAction_->setChecked (false);
723  break;
724  case QtTranslationManipulatorNode::Place:
725  resizeAction_->setChecked (false);
726  rotateManipAction_->setChecked (false);
727  rotateTranslateAction_->setChecked (false);
728  placeAndSnapAction_->setChecked (true);
729  break;
730  case QtTranslationManipulatorNode::Rotation:
731  resizeAction_->setChecked(false);
732  rotateManipAction_->setChecked(true);
733  rotateTranslateAction_->setChecked(false);
734  placeAndSnapAction_->setChecked(false);
735  break;
736  }
737  }
738 }
739 
740 //------------------------------------------------------------------------------
741 
747 
749 
750  if (node == 0)
751  return;
752 
753  if (node->className() != "QtTranslationManipulatorNode") {
754  contextAction_->setVisible(false);
755  } else {
756  contextAction_->setVisible(true);
757  }
758 }
759 
760 //------------------------------------------------------------------------------
761 
767 void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {
768 
769  // React on event only in move mode
770  if ( PluginFunctions::pickMode() != "Move"
771  && PluginFunctions::pickMode() != "MoveSelection" )
772  return;
773 
774  OpenFlipper::Options::redrawDisabled( true );
775 
776  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
777  if ( !placeMode_ && ((_event->type() == QEvent::MouseButtonRelease) ||
778  (PluginFunctions::pickMode() != "Move" && _event->buttons() != Qt::NoButton)) ) {
779 
780  int objectId = _node->getIdentifier();
781 
782  ACG::Matrix4x4d mat;
783  mat.identity();
784  mat = _node->matrix();
785 
786  // Reset Node
787  _node->loadIdentity();
788  _node->set_center(mat.transform_point(_node->center()));
789 
790  // move the object which corresponds to the manipulator
791  if (PluginFunctions::pickMode() == "Move")
792  moveObject( mat, objectId );
793  else if (PluginFunctions::pickMode() == "MoveSelection")
794  moveSelection( mat, objectId, _event->type() );
795 
796  // move all other targets without manipulator
797  if(allTargets_) {
799  != PluginFunctions::objectsEnd(); ++o_it) {
800  if ((o_it->id() != objectId) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
801 
802  // move the object which corresponds to the manipulator
803  if (PluginFunctions::pickMode() == "Move")
804  moveObject( mat, o_it->id() );
805  else if (PluginFunctions::pickMode() == "MoveSelection")
806  moveSelection( mat, o_it->id(), _event->type() );
807  }
808  }
809  }
810 
811  lastActiveManipulator_ = objectId;
813  }
814 
815  OpenFlipper::Options::redrawDisabled( false );
816 }
817 
818 
819 //------------------------------------------------------------------------------
820 
826 
827  // Position has been changed of the manipulator by a direct function
828  int objectId = _node->getIdentifier();
829 
830  if ( objectId > 0 ){
831 
832  BaseObjectData* object;
833  PluginFunctions::getObject(objectId,object);
834 
835  // Assume that it has a good position now
836  object->manipPlaced( true );
837  }
838 
839  // Show manipulator only if in Move mode
840  if ( PluginFunctions::pickMode() == "Move" )
841  _node->show();
842 
843  lastActiveManipulator_ = objectId;
845 
846 }
847 
848 
849 //------------------------------------------------------------------------------
850 
856 void MovePlugin::placeManip(QMouseEvent * _event, bool _snap) {
857  unsigned int node_idx, target_idx;
858  OpenMesh::Vec3d hitPoint;
859  BaseObjectData* object;
860 
861  bool successfullyPicked = false;
862 
863 
864 
865  /*
866  * Snap manipulator to nearest geometry
867  * element depending on which selection type is
868  * active.
869  */
870  if (_snap) {
871 
872  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx,
873  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
874 
875  if(!successfullyPicked) {
876  //emit log(LOGWARN, tr("Picking failed"));
877  return;
878  }
879 
880  if (selectionType_ == VERTEX) {
881  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
882  hitPoint = getNearestVertex(PluginFunctions::triMesh(object), target_idx, hitPoint);
883  } else if ( object->dataType(DATA_POLY_MESH) ) {
884  hitPoint = getNearestVertex(PluginFunctions::polyMesh(object), target_idx, hitPoint);
885 #ifdef ENABLE_TSPLINEMESH_SUPPORT
886  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
887  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
888 #endif
889  }
890  } else if (selectionType_ == EDGE) {
891  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
892  hitPoint = getNearestEdge(PluginFunctions::triMesh(object), target_idx, hitPoint);
893  } else if ( object->dataType(DATA_POLY_MESH) ) {
894  hitPoint = getNearestEdge(PluginFunctions::polyMesh(object), target_idx, hitPoint);
895 #ifdef ENABLE_TSPLINEMESH_SUPPORT
896  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
897  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
898 #endif
899  }
900  } else if (selectionType_ == FACE) {
901  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
902  hitPoint = getNearestFace(PluginFunctions::triMesh(object), target_idx, hitPoint);
903  } else if ( object->dataType(DATA_POLY_MESH) ) {
904  hitPoint = getNearestFace(PluginFunctions::polyMesh(object), target_idx, hitPoint);
905 #ifdef ENABLE_TSPLINEMESH_SUPPORT
906  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
907  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
908 #endif
909  }
910  }
911 
912  } else {
913  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
914  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
915  }
916 
917  if (successfullyPicked) {
918 
919  object->manipPlaced(true);
920 
922  int data = -1;
923  if (data != -1)
924  object->manipulatorNode()->setData( data );
925 
926  object->manipulatorNode()->loadIdentity();
927  object->manipulatorNode()->set_center(hitPoint);
928  object->manipulatorNode()->set_draw_cylinder(true);
929  object->manipulatorNode()->set_autosize(QtTranslationManipulatorNode::Once);
930  object->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
931  object->manipulatorNode()->setMode(manMode_);
932  object->manipulatorNode()->show();
933 
934  object->manipulatorNode()->apply_transformation(PluginFunctions::pickMode() == "Move");
935 
936  // Disconnect a previously connected Signal
937  disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
938  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
939 
940  disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
942 
943  // Reconnect the signals.
944  connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
945  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
946 
947  connect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
949 
950  lastActiveManipulator_ = object->id();
951 
952  emit updateView();
953 
954  bool found = false;
955 
956  for (uint i=0; i < activeManipulators_.size(); i++)
957  if ( activeManipulators_[i] == object->id() ){
958  found = true;
959  break;
960  }
961 
962  if ( !found )
963  activeManipulators_.push_back( object->id() );
964 
965  } else {
966  //emit log(LOGWARN, tr("Picking failed"));
967  }
968 }
969 
970 
971 //------------------------------------------------------------------------------
972 
977 {
978 
979  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
980  || (PluginFunctions::pickMode() == "MoveSelection"))) {
981 
982  for (uint i=0; i < activeManipulators_.size(); i++){
983 
984  BaseObjectData* obj = 0;
985 
987 
988  if (obj != 0 && obj->manipPlaced()) {
989  obj->manipulatorNode()->show();
990  obj->manipulatorNode()->apply_transformation( PluginFunctions::pickMode() == "Move" );
991  emit nodeVisibilityChanged(obj->id());
992  }
993  }
994 
995  } else {
996 
997  for (uint i=0; i < activeManipulators_.size(); i++){
998 
999  BaseObjectData* obj = 0;
1000 
1002 
1003  if ( obj != 0 ) {
1004  obj->manipulatorNode()->hide();
1005  emit nodeVisibilityChanged(obj->id());
1006  }
1007  }
1008  }
1009 
1010  emit updateView();
1011 
1012 }
1013 
1014 //------------------------------------------------------------------------------
1015 
1021 
1022  if(_but == 0) return 0;
1023  return dynamic_cast<movePropsWidget*>((((_but->parentWidget())->parentWidget())->parentWidget()));
1024 }
1025 //------------------------------------------------------------------------------
1026 
1031 
1032  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1034  if(pW == 0) return;
1035 
1036  TriMesh::Point newpos;
1037 
1038  bool ok = false;
1039  newpos[0] = (pW->nposx->text()).toDouble(&ok);
1040  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1041  newpos[1] = (pW->nposy->text()).toDouble(&ok);
1042  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1043  newpos[2] = (pW->nposz->text()).toDouble(&ok);
1044  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1045 
1046  BaseObjectData* object;
1048  if ( object->manipulatorNode()->visible() ) {
1049  // Compute translation vector
1050  ACG::Vec3d translation = newpos;
1051  translation -= object->manipulatorNode()->center();
1052  object->manipulatorNode()->set_center(newpos);
1053  // Stuff it into transformation matrix
1054  ACG::GLMatrixd m;
1055  m.identity();
1056  m.translate(translation);
1057  if (PluginFunctions::pickMode() == "Move")
1058  {
1059  // ...and transform mesh
1060  if(object->dataType() == DATA_TRIANGLE_MESH)
1062  else if(object->dataType() == DATA_POLY_MESH)
1064 
1065  // Create backup
1066  emit createBackup(object->id(), "Object Translation");
1067 
1068  }
1069  else if (PluginFunctions::pickMode() == "MoveSelection")
1070  {
1072  if (selectionType_ & VERTEX) {
1073  transformVertexSelection(object->id(), m);
1074  }
1075  if (selectionType_ & FACE) {
1076  transformFaceSelection(object->id(), m);
1077  }
1078  if (selectionType_ & EDGE) {
1079  transformEdgeSelection(object->id(), m);
1080  }
1081 
1082  // Create backup
1083  emit createBackup(object->id(), "Translation of selection");
1084  }
1085 
1086 
1087  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1088  }
1090  emit updateView();
1091  }
1092 }
1093 
1094 
1095 //------------------------------------------------------------------------------
1096 
1101 
1102  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1104  if(pW == 0) return;
1105 
1106  axisA_ = (axisA_ + 1) % 3;
1107 
1108  if (axisA_ == axisB_)
1109  axisA_ = (axisA_ + 1) % 3;
1110 
1111  switch(axisA_){
1112  case 0: pW->axisAButton->setText(tr("X Direction")); break;
1113  case 1: pW->axisAButton->setText(tr("Y Direction")); break;
1114  case 2: pW->axisAButton->setText(tr("Z Direction")); break;
1115  default: break;
1116  }
1117 }
1118 
1119 
1120 //------------------------------------------------------------------------------
1121 
1126 
1127  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1129  if(pW == 0) return;
1130 
1131  axisB_ = (axisB_ + 1) % 3;
1132 
1133  if (axisA_ == axisB_)
1134  axisB_ = (axisB_ + 1) % 3;
1135 
1136  switch(axisB_){
1137  case 0: pW->axisBButton->setText(tr("X Direction")); break;
1138  case 1: pW->axisBButton->setText(tr("Y Direction")); break;
1139  case 2: pW->axisBButton->setText(tr("Z Direction")); break;
1140  default: break;
1141  }
1142 }
1143 
1144 
1145 //------------------------------------------------------------------------------
1146 
1151 
1152  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1154  if(pW == 0) return;
1155 
1156  ACG::Vec3d newdirA,newdirB;
1157  ACG::Vec3d dirX,dirY;
1158  ACG::Vec3d dirZ(0.0,0.0,0.0);
1159 
1160  bool ok = false;
1161  newdirA[0] = (pW->ndirAx->text()).toDouble(&ok);
1162  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1163  newdirA[1] = (pW->ndirAy->text()).toDouble(&ok);
1164  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1165  newdirA[2] = (pW->ndirAz->text()).toDouble(&ok);
1166  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1167 
1168  newdirB[0] = (pW->ndirBx->text()).toDouble(&ok);
1169  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1170  newdirB[1] = (pW->ndirBy->text()).toDouble(&ok);
1171  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1172  newdirB[2] = (pW->ndirBz->text()).toDouble(&ok);
1173  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1174 
1175  bool xAxis = false;
1176  bool yAxis = false;
1177 
1178  switch(axisA_){
1179  case 0: dirX = newdirA; xAxis = true; break;
1180  case 1: dirY = newdirA; yAxis = true; break;
1181  default: dirZ = newdirA; break;
1182  }
1183 
1184  switch(axisB_){
1185  case 0: dirX = newdirB; xAxis = true; break;
1186  case 1: dirY = newdirB; yAxis = true; break;
1187  default: dirZ = newdirB; break;
1188  }
1189 
1190  if (!xAxis)
1191  dirX = dirY % dirZ;
1192 
1193  if (!yAxis)
1194  dirY = dirX % dirZ;
1195 
1196 
1197  if ( (dirX | dirY) != 0.0){
1198  emit log(LOGERR,tr("The axes of the new direction have to be orthogonal"));
1199  return;
1200  }
1201 
1202 // // Apply to All Target Objects
1203 // if ( pW->targetObjects->isChecked() ) {
1204 // for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ;
1205 // o_it PluginFunctions::objectsEnd(); ++o_it){
1206 //
1207 // o_it->manipulatorNode()->set_direction( dirX, dirY );
1208 // }
1209 // }
1210 
1211 
1212  BaseObjectData* object = 0;
1213  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1214  if ( object != 0 ) {
1215  if ( object->manipulatorNode()->visible() ){
1216 
1217  object->manipulatorNode()->set_direction( dirX, dirY );
1218  }
1219  } else return;
1220 
1222  emit updateView();
1223 }
1224 
1225 
1226 //------------------------------------------------------------------------------
1227 
1232 
1233  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1235  if(pW == 0) return;
1236 
1237  ACG::Vec3d translation;
1238 
1239  bool ok = false;
1240  translation[0] = (pW->translationX->text()).toDouble(&ok);
1241  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1242  translation[1] = (pW->translationY->text()).toDouble(&ok);
1243  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1244  translation[2] = (pW->translationZ->text()).toDouble(&ok);
1245  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1246 
1247  BaseObjectData* object = 0;
1248  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1249 
1250  if (object != 0) {
1251  if (object->manipulatorNode()->visible()) {
1252 
1253  object->manipulatorNode()->set_center(
1254  object->manipulatorNode()->center() + translation);
1255 
1256  if (PluginFunctions::pickMode() == "Move")
1257  {
1258 
1259  translate(object->id(), translation);
1260 
1261  // Create backup
1262  emit createBackup(object->id(), "Translation of Object");
1263 
1264  }
1265  else if (PluginFunctions::pickMode() == "MoveSelection")
1266  {
1268  if (selectionType_ & VERTEX) {
1269  translateVertexSelection(object->id(), translation);
1270  }
1271  if (selectionType_ & FACE) {
1272  translateFaceSelection(object->id(), translation);
1273  }
1274  if (selectionType_ & EDGE) {
1275  translateEdgeSelection(object->id(), translation);
1276  }
1277  emit createBackup(object->id(), "Translation of selection");
1278  }
1279 
1280 
1281 
1282  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1283 
1284 
1285  // move all other targets without manipulator
1286  if(allTargets_) {
1287 
1289  != PluginFunctions::objectsEnd(); ++o_it) {
1290  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1291  if (PluginFunctions::pickMode() == "Move") {
1292 
1293  translate(o_it->id(), translation);
1294 
1295  // Create backup
1296  emit createBackup(o_it->id(), "Translation of object");
1297 
1298  } else if (PluginFunctions::pickMode() == "MoveSelection") {
1300  if (selectionType_ & VERTEX) {
1301  translateVertexSelection(o_it->id(), translation);
1302  }
1303  if (selectionType_ & FACE) {
1304  translateFaceSelection(o_it->id(), translation);
1305  }
1306  if (selectionType_ & EDGE) {
1307  translateEdgeSelection(o_it->id(), translation);
1308  }
1309 
1310  emit createBackup(o_it->id(), "Translation of selection");
1311  }
1312 
1313 
1314  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1315  }
1316  }
1317 
1318  }
1319  }
1320  } else {
1321  return;
1322  }
1323 
1324 
1326  emit scriptInfo(QString("slotTranslation()"));
1327  emit updateView();
1328 }
1329 
1330 
1331 //------------------------------------------------------------------------------
1332 
1337 
1338  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1340  if(pW == 0) return;
1341 
1342  if ( allTargets_ ) {
1343  emit log(LOGWARN,tr("TODO Project for multiple targets"));
1344  return;
1345  } else {
1346  emit log(LOGWARN,tr("TODO Project for one target"));
1347  return;
1348  }
1349 
1350 }
1351 
1352 
1353 //------------------------------------------------------------------------------
1354 
1359 
1360  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1362  if(pW == 0) return;
1363 
1364 
1365 // if ( pW->targetObjects->isChecked() ) {
1366 // for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) {
1367 // if ( o_it->manipulatorNode()->hidden() )
1368 // continue;
1369 //
1370 // if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1371 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::triMesh(*o_it) ) );
1372 // else if ( o_it->dataType( DATA_POLY_MESH ) )
1373 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::polyMesh(*o_it)) );
1374 //
1375 // updateManipulatorDialog();
1376 // o_it->manipulatorNode()->loadIdentity();
1377 // }
1378 // } else {
1379 
1380  BaseObjectData* object = 0;
1381  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1382  if ( object != 0 ) {
1383  if ( object->manipulatorNode()->visible() ){
1384 
1385  if ( object->dataType( DATA_TRIANGLE_MESH ) )
1386  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::triMesh(object)) );
1387  else if ( object->dataType( DATA_POLY_MESH ) )
1388  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::polyMesh(object)) );
1389 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1390  else if ( object->dataType( DATA_TSPLINE_MESH ) )
1391  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::tsplineMesh(object)) );
1392 #endif
1393 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1394  else if ( object->dataType( DATA_HEXAHEDRAL_MESH ) )
1395  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::hexahedralMesh(object)) );
1396 #endif
1397 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1398  else if ( object->dataType( DATA_POLYHEDRAL_MESH ) )
1399  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::polyhedralMesh(object)) );
1400 #endif
1401 
1403  object->manipulatorNode()->loadIdentity();
1404  }
1405  }
1406 
1407  emit updateView();
1408 }
1409 
1410 
1411 //------------------------------------------------------------------------------
1412 
1417 
1418  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1420  if(pW == 0) return;
1421 
1422  TriMesh::Point axis;
1423  double angle;
1424 
1425  bool ok = false;
1426  axis[0] = (pW->rotx->text()).toDouble(&ok);
1427  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1428  axis[1] = (pW->roty->text()).toDouble(&ok);
1429  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1430  axis[2] = (pW->rotz->text()).toDouble(&ok);
1431  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1432 
1433  angle = (pW->rotAngle->text()).toDouble(&ok);
1434  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Angle")); return; }
1435 
1436  BaseObjectData* object = 0;
1437  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1438  if (object != 0) {
1439  if (object->manipulatorNode()->visible() && (object->target() || !allTargets_)) {
1440 
1441  object->manipulatorNode()->rotate(angle, axis);
1442 
1444 
1445  if (PluginFunctions::pickMode() == "Move")
1446  {
1447  if (object->dataType(DATA_TRIANGLE_MESH))
1448  transformMesh(m, (*PluginFunctions::triMesh(object)));
1449 
1450  if (object->dataType(DATA_POLY_MESH))
1452 
1453  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1454  if (object->dataType(DATA_TSPLINE_MESH))
1455  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1456  #endif
1457  #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1458  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1459  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1460  #endif
1461  #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1462  if (object->dataType(DATA_POLYHEDRAL_MESH))
1463  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1464  #endif
1465 
1466  // Create backup
1467  emit createBackup(object->id(), "Rotation of object");
1468 
1469  }
1470  else if (PluginFunctions::pickMode() == "MoveSelection")
1471  {
1473  if (selectionType_ & VERTEX) {
1474  transformVertexSelection(object->id(), m);
1475  }
1476  if (selectionType_ & FACE) {
1477  transformFaceSelection(object->id(), m);
1478  }
1479  if (selectionType_ & EDGE) {
1480  transformEdgeSelection(object->id(), m);
1481  }
1482  if (selectionType_ & CELL) {
1483  transformCellSelection(object->id(), m);
1484  }
1485 
1486  // Create backup
1487  emit createBackup(object->id(), "Rotation of selection");
1488  }
1489 
1490  // move all other targets without manipulator
1491  if(allTargets_) {
1492 
1494 
1495  // If it has its own manipulator active, don't move it
1496  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) {
1497 
1498  if (PluginFunctions::pickMode() == "Move")
1499  {
1500  if (o_it->dataType(DATA_TRIANGLE_MESH))
1502 
1503  if (o_it->dataType(DATA_POLY_MESH))
1505  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1506  if (o_it->dataType(DATA_TSPLINE_MESH))
1507  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1508  #endif
1509  #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1510  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1511  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1512  #endif
1513  #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1514  if (object->dataType(DATA_POLYHEDRAL_MESH))
1515  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1516  #endif
1517 
1518  // Create backup
1519  emit createBackup(o_it->id(), "Rotation of object");
1520  }
1521  else if (PluginFunctions::pickMode() == "MoveSelection")
1522  {
1524  if (selectionType_ & VERTEX) {
1525  transformVertexSelection(o_it->id(), m);
1526  }
1527  if (selectionType_ & FACE) {
1528  transformFaceSelection(o_it->id(), m);
1529  }
1530  if (selectionType_ & EDGE) {
1531  transformEdgeSelection(o_it->id(), m);
1532  }
1533  if (selectionType_ & CELL) {
1534  transformCellSelection(o_it->id(), m);
1535  }
1536 
1537  // Create backup
1538  emit createBackup(o_it->id(), "Rotation of selection");
1539  }
1540 
1541  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1542  }
1543  }
1544 
1545  }
1546 
1548 
1549  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1550 
1551  }
1552  }
1553 
1554  emit scriptInfo(QString("slotRotate()"));
1555  emit updateView();
1556 }
1557 
1558 
1559 //------------------------------------------------------------------------------
1560 
1565 
1566  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1568  if(pW == 0) return;
1569 
1570 
1571  TriMesh::Point scale;
1572 
1573  bool ok = false;
1574  scale[0] = (pW->scalex->text()).toDouble(&ok);
1575  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 1")); return; }
1576  scale[1] = (pW->scaley->text()).toDouble(&ok);
1577  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 2")); return; }
1578  scale[2] = (pW->scalez->text()).toDouble(&ok);
1579  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 3")); return; }
1580 
1581  BaseObjectData* object = 0;
1582  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1583  if (object != 0) {
1584  if (object->manipulatorNode()->visible() && (object->target()
1585  || !allTargets_)) {
1586 
1587  object->manipulatorNode()->scale(scale);
1588 
1590 
1591  if (PluginFunctions::pickMode() == "Move")
1592  {
1593  if (object->dataType(DATA_TRIANGLE_MESH))
1595  if (object->dataType(DATA_POLY_MESH))
1597  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1598  if (object->dataType(DATA_TSPLINE_MESH))
1599  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1600  #endif
1601  #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1602  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1603  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1604  #endif
1605  #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1606  if (object->dataType(DATA_POLYHEDRAL_MESH))
1607  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1608  #endif
1609 
1610  // Create backup
1611  emit createBackup(object->id(), "Scaling of object");
1612  }
1613  else if (PluginFunctions::pickMode() == "MoveSelection")
1614  {
1616  if (selectionType_ & VERTEX) {
1617  transformVertexSelection(object->id(), m);
1618  }
1619  if (selectionType_ & FACE) {
1620  transformFaceSelection(object->id(), m);
1621  }
1622  if (selectionType_ & EDGE) {
1623  transformEdgeSelection(object->id(), m);
1624  }
1625  if (selectionType_ & CELL) {
1626  transformCellSelection(object->id(), m);
1627  }
1628 
1629  // Create backup
1630  emit createBackup(object->id(), "Scaling of selection");
1631  }
1632 
1633  // move all other targets without manipulator
1634  if(allTargets_) {
1635 
1637  != PluginFunctions::objectsEnd(); ++o_it) {
1638  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1639 
1640  if (PluginFunctions::pickMode() == "Move")
1641  {
1642  if (o_it->dataType(DATA_TRIANGLE_MESH))
1644 
1645  if (o_it->dataType(DATA_POLY_MESH))
1647  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1648  if (o_it->dataType(DATA_TSPLINE_MESH))
1649  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1650  #endif
1651  #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1652  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1653  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1654  #endif
1655  #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1656  if (object->dataType(DATA_POLYHEDRAL_MESH))
1657  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1658  #endif
1659 
1660  // Create backup
1661  emit createBackup(o_it->id(), "Scaling of object");
1662  }
1663  else if (PluginFunctions::pickMode() == "MoveSelection")
1664  {
1666  if (selectionType_ & VERTEX) {
1667  transformVertexSelection(o_it->id(), m);
1668  }
1669  if (selectionType_ & FACE) {
1670  transformFaceSelection(o_it->id(), m);
1671  }
1672  if (selectionType_ & EDGE) {
1673  transformEdgeSelection(o_it->id(), m);
1674  }
1675  if (selectionType_ & CELL) {
1676  transformCellSelection(o_it->id(), m);
1677  }
1678 
1679  // Create backup
1680  emit createBackup(o_it->id(), "Scaling of selection");
1681  }
1682 
1683  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1684  }
1685  }
1686 
1687  }
1688 
1690 
1691  emit createBackup(object->id(), "Scaling");
1692  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1693  }
1694  }
1695 
1696  emit scriptInfo(QString("slotScale()"));
1697  emit updateView();
1698 }
1699 
1700 
1701 //------------------------------------------------------------------------------
1702 
1703 
1708 
1709  bool useCommonCOG = false;
1710  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
1711 
1712  if ( PluginFunctions::targetCount() > 1 ) {
1713  if ( OpenFlipper::Options::gui()) {
1714  QMessageBox::StandardButton button = QMessageBox::question( 0, tr("Use common COG?"), tr("Should the targets be moved depending on their common cog?"),QMessageBox::Yes|QMessageBox::No);
1715 
1716 
1717  useCommonCOG = ( button == QMessageBox::Yes );
1718  }
1719 
1720  if ( useCommonCOG ) {
1721 
1722  double vertexCount = 0.0;
1723 
1724  // Compute cog for all objects
1726  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1727  TriMesh* mesh = PluginFunctions::triMesh(*o_it);
1728  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1729  vertexCount += double(mesh->n_vertices());
1730  }
1731 
1732  if ( o_it->dataType( DATA_POLY_MESH )) {
1733  PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
1734  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1735  vertexCount += double(mesh->n_vertices());
1736  }
1737 
1738 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1739  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1740  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(*o_it);
1741  cog += MeshInfo::cog(mesh) * double(mesh.n_vertices());
1742  vertexCount += double(mesh.n_vertices());
1743  }
1744 #endif
1745 
1746 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1747  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1749  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1750  vertexCount += double(mesh.n_vertices());
1751  }
1752 #endif
1753 
1754 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1755  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1757  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1758  vertexCount += double(mesh.n_vertices());
1759  }
1760 #endif
1761  }
1762 
1763  cog = cog / vertexCount;
1764  }
1765 
1766  }
1767 
1769  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1770  TriMesh* mesh = PluginFunctions::triMesh(*o_it);
1771 
1772  if ( !useCommonCOG )
1773  cog = MeshInfo::cog(mesh);
1774 
1775  for ( TriMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1776  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1777 
1778  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1779  }
1780 
1781  if ( o_it->dataType( DATA_POLY_MESH )) {
1782  PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
1783 
1784  if ( !useCommonCOG )
1785  cog = MeshInfo::cog(mesh);
1786 
1787  for ( PolyMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1788  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1789 
1790  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1791 
1792  }
1793 
1794 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1795  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1796  TSplineMesh* mesh = PluginFunctions::tsplineMesh(*o_it);
1797 
1798  if ( !useCommonCOG )
1799  cog = MeshInfo::cog(mesh);
1800 
1801  for ( TSplineMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1802  mesh->set_point(v_it , ( mesh->point(v_it) ) - cog );
1803 
1804  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1805 
1806  }
1807 #endif
1808 
1809 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1810  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1812 
1813  if ( !useCommonCOG )
1814  cog = cogVolumeMesh(mesh);
1815 
1816  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1817  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1818 
1819  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1820 
1821  }
1822 #endif
1823 
1824 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1825  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1827 
1828  if ( !useCommonCOG )
1829  cog = cogVolumeMesh(mesh);
1830 
1831  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1832  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1833 
1834  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1835 
1836  }
1837 #endif
1838 
1839 
1840  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
1841 
1843  o_it->manipulatorNode()->loadIdentity();
1844 
1845  emit createBackup(o_it->id(),"Move to origin");
1846  }
1847 
1848  emit updateView();
1849 }
1850 
1851 
1852 //------------------------------------------------------------------------------
1853 
1858 {
1859  unifyBoundingBox(MovePlugin::DIAGONAL);
1860 }
1861 
1863 {
1864  unifyBoundingBox((MovePlugin::LONGEST_AXIS));
1865 }
1866 
1868 {
1869  unifyBoundingBox(MovePlugin::ALL_AXIS);
1870 }
1871 
1873 {
1874  bool useCommonBB = false;
1875  ACG::Vec3d bb_min = ACG::Vec3d(FLT_MAX,FLT_MAX,FLT_MAX);
1876  ACG::Vec3d bb_max = ACG::Vec3d(FLT_MIN,FLT_MIN,FLT_MIN);
1877 
1878  if ( PluginFunctions::targetCount() > 1 ) {
1879  if ( OpenFlipper::Options::gui()) {
1880  QMessageBox::StandardButton button = QMessageBox::question( 0, tr("Use common BB?"), tr("Should the targets be scaled depending on their common Bounding Box?"),QMessageBox::Yes|QMessageBox::No);
1881 
1882 
1883  useCommonBB = ( button == QMessageBox::Yes );
1884  }
1885 
1886 
1887  if ( useCommonBB ) {
1888 
1889  // Compute cog for all objects
1891  ACG::Vec3d bb_min_tmp(0.0,0.0,0.0);
1892  ACG::Vec3d bb_max_tmp(0.0,0.0,0.0);
1893 
1894  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1895  TriMesh& mesh = *PluginFunctions::triMesh(*o_it);
1896  getBB(mesh,bb_min_tmp,bb_max_tmp);
1897  bb_min.minimize(bb_min_tmp);
1898  bb_max.maximize(bb_max_tmp);
1899  }
1900 
1901  if ( o_it->dataType( DATA_POLY_MESH )) {
1902  PolyMesh& mesh = *PluginFunctions::polyMesh(*o_it);
1903  getBB(mesh,bb_min_tmp,bb_max_tmp);
1904  bb_min.minimize(bb_min_tmp);
1905  bb_max.maximize(bb_max_tmp);
1906  }
1907 
1908 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1909  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1910  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(*o_it);
1911  getBB(mesh,bb_min_tmp,bb_max_tmp);
1912  bb_min.minimize(bb_min_tmp);
1913  bb_max.maximize(bb_max_tmp);
1914  }
1915 #endif
1916 
1917 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1918  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1920  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1921  bb_min.minimize(bb_min_tmp);
1922  bb_max.maximize(bb_max_tmp);
1923  }
1924 #endif
1925 
1926 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1927  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1929  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1930  bb_min.minimize(bb_min_tmp);
1931  bb_max.maximize(bb_max_tmp);
1932  }
1933 #endif
1934  }
1935  }
1936 
1937  }
1938 
1940  if ( useCommonBB ) {
1941  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1942  unifyBB(*PluginFunctions::triMesh(*o_it),bb_min,bb_max, u);
1943  else if ( o_it->dataType( DATA_POLY_MESH ) )
1944  unifyBB(*PluginFunctions::polyMesh(*o_it),bb_min,bb_max, u);
1945 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1946  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
1947  unifyBB(*PluginFunctions::tsplineMesh(*o_it),bb_min,bb_max, u);
1948 #endif
1949 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1950  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
1951  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(*o_it),(PluginFunctions::hexahedralMeshObject(*o_it)->normals()),bb_min,bb_max, u);
1952 #endif
1953 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1954  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
1955  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(*o_it),(PluginFunctions::polyhedralMeshObject(*o_it)->normals()),bb_min,bb_max, u);
1956 #endif
1957  } else {
1958  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1959  unifyBB(*PluginFunctions::triMesh(*o_it), u);
1960  else if ( o_it->dataType( DATA_POLY_MESH ) )
1961  unifyBB(*PluginFunctions::polyMesh(*o_it), u);
1962 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1963  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
1964  unifyBB(*PluginFunctions::tsplineMesh(*o_it), u);
1965 #endif
1966 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1967  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
1968  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(*o_it),(PluginFunctions::hexahedralMeshObject(*o_it)->normals()), u);
1969 #endif
1970 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1971  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
1972  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(*o_it),(PluginFunctions::polyhedralMeshObject(*o_it)->normals()), u);
1973 #endif
1974  }
1975 
1976  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
1977 
1978  }
1979 
1980  emit updateView();
1981 }
1982 
1983 
1984 //------------------------------------------------------------------------------
1985 
1990 
1991  BaseObjectData* object;
1993  return;
1994  }
1995 
1996  if ( object->manipulatorNode()->visible() ) {
1997 
1998  // Get properties widget that corresponds to
1999  // to the last manipulated object
2000  movePropsWidget* pW = getDialogWidget(object);
2001 
2002  // If there's no properties dialog yet...
2003  if(pW == 0) return;
2004 
2005  const TriMesh::Point pos = object->manipulatorNode()->center();
2006 
2007  QString num;
2008 
2009  num = QString::number(pos[0]); pW->posx->setText(num);
2010  num = QString::number(pos[1]); pW->posy->setText(num);
2011  num = QString::number(pos[2]); pW->posz->setText(num);
2012 
2013  TriMesh::Point direction = object->manipulatorNode()->directionX();
2014  num = QString::number(direction[0]); pW->dirxx->setText(num);
2015  num = QString::number(direction[1]); pW->dirxy->setText(num);
2016  num = QString::number(direction[2]); pW->dirxz->setText(num);
2017 
2018  direction = object->manipulatorNode()->directionY();
2019  num = QString::number(direction[0]); pW->diryx->setText(num);
2020  num = QString::number(direction[1]); pW->diryy->setText(num);
2021  num = QString::number(direction[2]); pW->diryz->setText(num);
2022 
2023  direction = object->manipulatorNode()->directionZ();
2024  num = QString::number(direction[0]); pW->dirzx->setText(num);
2025  num = QString::number(direction[1]); pW->dirzy->setText(num);
2026  num = QString::number(direction[2]); pW->dirzz->setText(num);
2027 
2028  }
2029 }
2030 
2031 //------------------------------------------------------------------------------
2032 
2038 
2039  for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
2040  it != propsWindows_.end(); ++it) {
2041  if ( (*it)->getBaseObjectDataId() == _obj->id() )
2042  return *it;
2043  }
2044  return 0;
2045 }
2046 //------------------------------------------------------------------------------
2047 
2052 void MovePlugin::slotSetMoveMode(QAction* _action) {
2053 
2054  if (_action == moveAction_){
2055  PluginFunctions::actionMode(Viewer::PickingMode);
2056  PluginFunctions::pickMode("Move");
2057 
2058  moveAction_->setChecked( true );
2059  }
2060 
2061  if (_action == moveSelectionAction_){
2062 
2063  PluginFunctions::actionMode(Viewer::PickingMode);
2064  PluginFunctions::pickMode("MoveSelection");
2065 
2066  moveSelectionAction_->setChecked( true );
2067  }
2068 }
2069 
2070 //------------------------------------------------------------------------------
2071 
2078 {
2079 
2080  if (_action == rotateTranslateAction_)
2081  {
2082  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
2083  }
2084 
2085  if (_action == rotateManipAction_)
2086  {
2087  setManipMode (QtTranslationManipulatorNode::LocalRotation);
2088  }
2089 
2090  if (_action == placeAndSnapAction_)
2091  {
2092  setManipMode(QtTranslationManipulatorNode::Place);
2093  }
2094 
2095  if (_action == resizeAction_)
2096  {
2097  setManipMode(QtTranslationManipulatorNode::Resize);
2098  }
2099 
2100  if (_action == biggerManipAction_)
2101  {
2104  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2105  emit nodeVisibilityChanged (-1);
2106  }
2107 
2108  if (_action == smallerManipAction_)
2109  {
2112  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2113  emit nodeVisibilityChanged (-1);
2114  }
2115 }
2116 
2117 
2118 //------------------------------------------------------------------------------
2119 
2126  ACG::Matrix4x4d matrix;
2127  matrix.identity();
2128 
2129  BaseObjectData* object;
2131  if ( object->manipulatorNode()->visible() ) {
2132  matrix = object->manipulatorNode()->matrix();
2133  if (_reset)
2134  object->manipulatorNode()->loadIdentity();
2135  }
2136  return matrix;
2137 }
2138 
2139 
2140 //------------------------------------------------------------------------------
2141 
2150 template< typename MeshT >
2151 void MovePlugin::transformMesh(ACG::Matrix4x4d _mat , MeshT& _mesh ) {
2152  // Get the inverse matrix of the transformation for the normals
2153  ACG::Matrix4x4d invTranspMat = _mat;
2154 
2155  // Build inverse transposed matrix of _mat
2156  invTranspMat.invert();
2157  invTranspMat.transpose();
2158 
2159  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2160  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2161  for (; v_it!=v_end; ++v_it) {
2162 
2163  // transform the mesh vertex
2164  _mesh.set_point(*v_it,_mat.transform_point(_mesh.point(*v_it)));
2165 
2166  // transform the vertex normal
2167  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*v_it));
2168 
2169  n.normalize();
2170 
2171  _mesh.set_normal(*v_it,n);
2172  }
2173 
2174  typename MeshT::FaceIter f_it = _mesh.faces_begin();
2175  typename MeshT::FaceIter f_end = _mesh.faces_end();
2176  for (; f_it != f_end; ++f_it) {
2177 
2178  // transform the face normal
2179  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*f_it));
2180 
2181  n.normalize();
2182 
2183  _mesh.set_normal(*f_it,n);
2184  }
2185 }
2186 
2187 
2188 //------------------------------------------------------------------------------
2189 
2190 #ifdef ENABLE_POLYLINE_SUPPORT
2191 
2197 template< class PolyLineT >
2198 void MovePlugin::transformPolyLine( ACG::Matrix4x4d _mat , PolyLineT& _polyLine ) {
2199  #ifdef USE_OPENMP
2200  #pragma omp parallel for
2201  #endif
2202  for ( int i = 0 ; i < (int)_polyLine.n_vertices(); ++i )
2203  _polyLine.point(i) = _mat.transform_point( _polyLine.point(i) );
2204 }
2205 
2206 #endif
2207 
2208 
2209 //------------------------------------------------------------------------------
2210 
2211 #ifdef ENABLE_SKELETON_SUPPORT
2212 
2218 void MovePlugin::transformSkeleton( ACG::Matrix4x4d _mat , Skeleton& _skeleton ) {
2219 
2220  SkeletonTransform transformer(_skeleton);
2221  transformer.transformSkeleton(_mat);
2222 }
2223 
2224 #endif
2225 
2226 #ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
2227 
2236 template< typename VolumeMeshT >
2237 void MovePlugin::transformVolumeMesh(ACG::Matrix4x4d _mat , VolumeMeshT& _mesh , OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib )
2238 {
2239  // Get the inverse matrix of the transformation for the normals
2240  ACG::Matrix4x4d invTranspMat = _mat;
2241 
2242  // Build inverse transposed matrix of _mat
2243  invTranspMat.invert();
2244  invTranspMat.transpose();
2245 
2246  OpenVolumeMesh::VertexIter v_begin = _mesh.vertices_begin();
2247  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2248 
2249  // transform the mesh vertices
2250  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2251  _mesh.set_vertex(*v_it, _mat.transform_point(_mesh.vertex(*v_it)));
2252 
2253  // transform the vertex normals
2254  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2255  _normalAttrib[*v_it] = invTranspMat.transform_vector(_normalAttrib[*v_it]).normalized();
2256 
2257 
2258  // transform the face normals
2259  OpenVolumeMesh::FaceIter f_begin = _mesh.faces_begin();
2260  OpenVolumeMesh::FaceIter f_end = _mesh.faces_end();
2261  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
2262  _normalAttrib[*f_it] = invTranspMat.transform_vector(_normalAttrib[*f_it]).normalized();
2263 }
2264 
2265 //------------------------------------------------------------------------------
2266 
2271 template< typename VolumeMeshT >
2272 ACG::Vec3d MovePlugin::cogVolumeMesh( VolumeMeshT& _mesh )
2273 {
2274  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
2275  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2276  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2277  for (; v_it!=v_end; ++v_it)
2278  cog += _mesh.vertex(*v_it);
2279 
2280  return cog/(double)_mesh.n_vertices();
2281 }
2282 
2283 //------------------------------------------------------------------------------
2284 
2291 template< typename VolumeMeshT >
2292 void MovePlugin::getBBVolumeMesh( VolumeMeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max)
2293 {
2294  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2295  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2296 
2297  // no vertices?
2298  if( v_it == v_end) return;
2299 
2300  _bb_min = _mesh.vertex(*v_it);
2301  _bb_max = _mesh.vertex(*v_it);
2302 
2303  for(; v_it!=v_end; ++v_it)
2304  {
2305  _bb_min.minimize( _mesh.vertex(*v_it));
2306  _bb_max.maximize( _mesh.vertex(*v_it));
2307  }
2308 }
2309 
2310 //------------------------------------------------------------------------------
2311 
2317 template< typename VolumeMeshT >
2318 void MovePlugin::unifyBBVolumeMesh(VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, Unificationtype u)
2319 {
2320  // no vertices?
2321  if( _mesh.n_vertices() == 0) return;
2322 
2323  ACG::Vec3d bb_min, bb_max;
2324  getBBVolumeMesh( _mesh, bb_min, bb_max );
2325 
2326  unifyBBVolumeMesh( _mesh, _normalAttrib, bb_min, bb_max, u );
2327 }
2328 
2329 //------------------------------------------------------------------------------
2330 
2339 template< typename VolumeMeshT >
2340 void MovePlugin::unifyBBVolumeMesh( VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max, Unificationtype u)
2341 {
2342  ACG::Vec3d bb_center = 0.5 * (_bb_min + _bb_max) ;
2343  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2344  double bb_longestAxis = bb_diagonal.max();
2345 
2346  ACG::Vec3d scale;
2347  switch(u)
2348  {
2349  case MovePlugin::DIAGONAL :
2350  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2351  break;
2352  case MovePlugin::LONGEST_AXIS :
2353  scale = ACG::Vec3d(1.0/(bb_longestAxis));
2354  break;
2355  case MovePlugin::ALL_AXIS :
2356  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2357  break;
2358  default:
2359  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2360  }
2361 
2362 
2363  for( OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2364  _mesh.set_vertex(*v_it, (_mesh.vertex(*v_it) - bb_center) * scale + bb_center);
2365 
2366  _normalAttrib.update_vertex_normals();
2367 }
2368 
2369 #endif
2370 
2371 //------------------------------------------------------------------------------
2372 
2378 template< typename MeshT >
2379 void MovePlugin::unifyBB(MeshT& _mesh , Unificationtype u)
2380 {
2381  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2382  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2383 
2384  // no vertices?
2385  if( v_it == v_end) return;
2386 
2387  typename MeshT::Point bb_min = _mesh.point(*v_it);
2388  typename MeshT::Point bb_max = _mesh.point(*v_it);
2389 
2390  for(; v_it!=v_end; ++v_it)
2391  {
2392  bb_min.minimize( _mesh.point(*v_it));
2393  bb_max.maximize( _mesh.point(*v_it));
2394  }
2395 
2396  typename MeshT::Point bb_center = 0.5 * (bb_min + bb_max) ;
2397  ACG::Vec3d bb_diagonal = bb_max-bb_min;
2398  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2399 
2400  ACG::Vec3d scale;
2401  switch(u)
2402  {
2403  case MovePlugin::DIAGONAL :
2404  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2405  break;
2406  case MovePlugin::LONGEST_AXIS :
2407  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2408  break;
2409  case MovePlugin::ALL_AXIS :
2410  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2411  break;
2412  default:
2413  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2414  }
2415 
2416  for( v_it = _mesh.vertices_begin(); v_it!=v_end; ++v_it)
2417  {
2418 
2419  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2420  }
2421 
2422  _mesh.update_normals();
2423 
2424 }
2425 
2432 template< typename MeshT >
2433 void MovePlugin::getBB( MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max )
2434 {
2435  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2436  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2437 
2438  // no vertices?
2439  if( v_it == v_end) return;
2440 
2441  _bb_min = _mesh.point(*v_it);
2442  _bb_max = _mesh.point(*v_it);
2443 
2444  for(; v_it!=v_end; ++v_it)
2445  {
2446  _bb_min.minimize( _mesh.point(*v_it));
2447  _bb_max.maximize( _mesh.point(*v_it));
2448  }
2449 
2450 
2451 }
2452 
2460 template< typename MeshT >
2461 void MovePlugin::unifyBB(MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max , Unificationtype u)
2462 {
2463 
2464  typename MeshT::Point bb_center = 0.5 * (_bb_min + _bb_max) ;
2465  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2466  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2467  ACG::Vec3d scale;
2468  switch(u)
2469  {
2470  case MovePlugin::DIAGONAL :
2471  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2472  break;
2473  case MovePlugin::LONGEST_AXIS :
2474  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2475  break;
2476  case MovePlugin::ALL_AXIS :
2477  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2478  break;
2479  default:
2480  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2481  }
2482 
2483  typename MeshT::VertexIter v_it;
2484 
2485  for( v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2486  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2487 
2488  _mesh.update_normals();
2489 
2490 }
2491 
2492 
2493 //------------------------------------------------------------------------------
2494 
2499 
2500  bool functionExistsMeshV;
2501  emit functionExists("meshobjectselection", "vertexTypeActive()", functionExistsMeshV);
2502  bool functionExistsMeshE;
2503  emit functionExists("meshobjectselection", "edgeTypeActive()", functionExistsMeshE);
2504  bool functionExistsMeshF;
2505  emit functionExists("meshobjectselection", "faceTypeActive()", functionExistsMeshF);
2506 
2507  bool connected = false;
2508  selectionType_ = 0u;
2509 
2510  if(functionExistsMeshV && functionExistsMeshE && functionExistsMeshF) {
2511 
2512  connected = true;
2513 
2514  // Make RPC call
2515  if(RPC::callFunctionValue<bool>("meshobjectselection", "vertexTypeActive")) {
2516  selectionType_ |= VERTEX;
2517  }
2518  if(RPC::callFunctionValue<bool>("meshobjectselection", "edgeTypeActive")) {
2519  selectionType_ |= EDGE;
2520  }
2521  if(RPC::callFunctionValue<bool>("meshobjectselection", "faceTypeActive")) {
2522  selectionType_ |= FACE;
2523  }
2524 
2525  }
2526 
2527 #ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
2528  bool functionExistsVolumeMeshV;
2529  emit functionExists("volumemeshselection", "vertexTypeActive()", functionExistsVolumeMeshV);
2530  bool functionExistsVolumeMeshE;
2531  emit functionExists("volumemeshselection", "edgeTypeActive()", functionExistsVolumeMeshE);
2532  bool functionExistsVolumeMeshF;
2533  emit functionExists("volumemeshselection", "faceTypeActive()", functionExistsVolumeMeshF);
2534  bool functionExistsVolumeMeshC;
2535  emit functionExists("volumemeshselection", "cellTypeActive()", functionExistsVolumeMeshC);
2536 
2537  if ( functionExistsVolumeMeshV && functionExistsVolumeMeshE && functionExistsVolumeMeshF && functionExistsVolumeMeshC) {
2538 
2539  connected = true;
2540 
2541  // Make RPC call
2542  if(RPC::callFunctionValue<bool>("volumemeshselection", "vertexTypeActive")) {
2543  selectionType_ |= VERTEX;
2544  }
2545  if(RPC::callFunctionValue<bool>("volumemeshselection", "edgeTypeActive")) {
2546  selectionType_ |= EDGE;
2547  }
2548  if(RPC::callFunctionValue<bool>("volumemeshselection", "faceTypeActive")) {
2549  selectionType_ |= FACE;
2550  }
2551  if(RPC::callFunctionValue<bool>("volumemeshselection", "cellTypeActive")) {
2552  selectionType_ |= CELL;
2553  }
2554  }
2555 #endif
2556 
2557  if (!connected) {
2558  emit log(LOGWARN, tr("Unable to connect to Selection-Plugin. MoveSelection will work on vertices only."));
2559  selectionType_ = VERTEX;
2560  }
2561 }
2562 
2563 //------------------------------------------------------------------------------
2564 
2570 void MovePlugin::setAllTargets(bool _state) {
2571  allTargets_ = _state;
2572 }
2573 
2574 //--------------------------------------------------------------------------------
2575 
2579 template< typename MeshType >
2580 OpenMesh::Vec3d MovePlugin::getNearestVertex(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2581 
2582  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2583 
2584  if ( !fh.is_valid() )
2585  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2586 
2587  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2588  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2589  typename MeshType::Scalar shortest_distance = (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2590  typename MeshType::VertexHandle vh = *fv_it;
2591 
2592  for (; fv_it.is_valid(); ++fv_it) {
2593 
2594  typename MeshType::Scalar tmpdist =
2595  (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2596 
2597  if(tmpdist < shortest_distance) {
2598  shortest_distance = tmpdist;
2599  vh = *fv_it;
2600  }
2601  }
2602 
2603  return (OpenMesh::Vec3d)_mesh->point(vh);
2604 }
2605 
2606 //--------------------------------------------------------------------------------
2607 
2611 template< typename MeshType >
2612 OpenMesh::Vec3d MovePlugin::getNearestEdge(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2613 
2614  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2615 
2616  if (!fh.is_valid())
2617  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2618 
2619  typename MeshType::FaceEdgeIter fe_it(*_mesh, fh);
2620  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2621 
2622  typename MeshType::Point center;
2623  typename MeshType::Scalar closest_dist(-1);
2624 
2625  for (; fe_it.is_valid(); ++fe_it) {
2626 
2627  typename MeshType::HalfedgeHandle heh0 = _mesh->halfedge_handle(*fe_it, 0);
2628  typename MeshType::HalfedgeHandle heh1 = _mesh->halfedge_handle(*fe_it, 1);
2629 
2630  typename MeshType::Point lp0 = _mesh->point(_mesh->to_vertex_handle(heh0));
2631  typename MeshType::Point lp1 = _mesh->point(_mesh->to_vertex_handle(heh1));
2632 
2633  double dist_new = ACG::Geometry::distPointLineSquared( hitPointP, lp0, lp1);
2634 
2635  /*typename MeshType::Point b(hitPointP - lp0), a(((lp1 - lp0).sqrnorm()));
2636  typename MeshType::Scalar d = b|a;
2637  typename MeshType::Point x = lp0 + a * d;
2638  double dist_new = (hitPointP - x).length();*/
2639 
2640  if (dist_new < closest_dist || closest_dist == -1) {
2641  // save closest Edge
2642  closest_dist = dist_new;
2643  center = lp0 + (lp1 - lp0) * .5;
2644 
2645  }
2646  }
2647 
2648  return (OpenMesh::Vec3d)center;
2649 }
2650 
2651 //--------------------------------------------------------------------------------
2652 
2656 template< typename MeshType >
2657 OpenMesh::Vec3d MovePlugin::getNearestFace(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2658 
2659  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2660 
2661  if ( !fh.is_valid() )
2662  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2663 
2664  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2665 
2666  typename MeshType::Point cog(0.0,0.0,0.0);
2667  uint count = 0;
2668 
2669  for (; fv_it.is_valid(); ++fv_it) {
2670 
2671  cog += _mesh->point(*fv_it);
2672  ++count;
2673  }
2674 
2675  return (OpenMesh::Vec3d)cog/count;
2676 }
2677 
2678 //--------------------------------------------------------------------------------
2679 
2680 void MovePlugin::slotAllCleared(){
2681  activeManipulators_.clear();
2682 }
2683 
2684 //--------------------------------------------------------------------------------
2685 
2686 void MovePlugin::objectDeleted( int _id ){
2687 
2688  for (uint i=0; i < activeManipulators_.size(); i++)
2689  if ( activeManipulators_[i] == _id ){
2690  activeManipulators_.erase( activeManipulators_.begin() + i );
2691  return;
2692  }
2693 }
2694 
2695 //--------------------------------------------------------------------------------
2696 
2697 #if QT_VERSION < 0x050000
2698  Q_EXPORT_PLUGIN2( moveplugin , MovePlugin );
2699 #endif
2700 
QAction * moveSelectionAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:279
QAction * placeAndSnapAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:312
void transform(const ACG::Matrix4x4d &_mat)
Transform the plane with given matrix.
Definition: PlaneType.cc:97
#define DATA_PLANE
Definition: Plane.hh:64
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool is_identity() const
check if the matrix is the identity ( up to an epsilon )
Definition: Matrix4x4T.hh:220
MeshT * mesh()
return a pointer to the mesh
const QStringList ALL_OBJECTS
Iterable object range.
void setViewObjectMarker(ViewObjectMarker *_marker)
void slotSetDirection()
Set Direction of manipulator in tab changed.
Definition: MovePlugin.cc:1150
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
void slotMoveToOrigin()
Move target Meshes cog to the origin.
Definition: MovePlugin.cc:1707
SelectionType selectionType_
Current SelectionType of SelectionPlugin.
Definition: MovePlugin.hh:442
QActionGroup * toolBarActions_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:281
QToolBar * pickToolbar_
Called by pick Toolbar.
Definition: MovePlugin.hh:298
bool manipPlaced()
Check if the manipulator has been placed.
#define DATA_POLY_LINE
Definition: PolyLine.hh:70
void slotMoveManipToCOG()
Move the current manipulator to the cog of the object.
Definition: MovePlugin.cc:1358
void translateEdgeSelection(int _objectId, Vector _vector)
translate current edge selection of an Object by a given vector
PolyLine * polyLine(BaseObjectData *_object)
Get a poly Line from an object.
bool visible()
Is node visible (status == Active)?
Definition: MeshNode2T.cc:385
void slotPickModeChanged(const std::string &_mode)
slot is called when the pickMode changed
Definition: MovePlugin.cc:524
int targetCount()
Get the number of target objects.
picks faces (should be implemented for all nodes)
Definition: BaseNode.hh:104
bool transformFaceSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
QtTranslationManipulatorNode * manipulatorNode()
#define DATA_POLYHEDRAL_MESH
void slotUnifyBoundingBoxAllAxis()
Scale all Boundingbox axis to unit size.
Definition: MovePlugin.cc:1867
bool getObject(int _identifier, BSplineCurveObject *&_object)
Skeleton transformation class.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
void slotPickToolbarAction(QAction *_action)
Called by pick Toolbar.
Definition: MovePlugin.cc:2077
void slotTranslation()
perform a translation for Manipulator in tab
Definition: MovePlugin.cc:1231
void updateManipulatorDialog()
Update the Dialog with the last clicked manipulator.
Definition: MovePlugin.cc:1989
void placeManip(QMouseEvent *_event, bool _snap=false)
Place and show the Manipulator.
Definition: MovePlugin.cc:856
bool transformEdgeSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
ViewObjectMarker * defaultViewObjectMarker()
Get the default ViewObjectMarker.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
Definition: MovePlugin.cc:160
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
Definition: Matrix4x4T.cc:225
void setPickModeProps(movePropsWidget *_pW, const std::string &_pickmode)
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.cc:494
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void ManipulatorPositionChanged(QtTranslationManipulatorNode *_node)
update object when its manipulator changes position
Definition: MovePlugin.cc:825
const QStringList TARGET_OBJECTS("target")
Iterable object range.
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
QList< movePropsWidget * > propsWindows_
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.hh:483
bool transformedSelected_
stores if any selected elements where transformed
Definition: MovePlugin.hh:624
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
QAction * rotateManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:302
const Vec3d & center() const
get center
QAction * contextActionHide_
Context menu entry to hide a manipulator.
Definition: MovePlugin.hh:489
QAction * placeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:300
MovePlugin()
Default Constructor.
Definition: MovePlugin.cc:86
QAction * contextAction_
Context menu entry for showing per manipulator settings.
Definition: MovePlugin.hh:486
virtual const std::string & className() const =0
Return class name (implemented by the ACG_CLASSNAME macro)
QAction * moveAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:278
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
movePropsWidget * getDialogWidget(BaseObjectData *_obj)
Get properties dialog widget that is attached to BaseDataObject obj.
Definition: MovePlugin.cc:2037
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
Definition: GLMatrixT.cc:102
const std::string pickMode()
Get the current Picking mode.
int axisA_
stores the current axes in the tool
Definition: MovePlugin.hh:202
void slotUnifyBoundingBoxLongestAxis()
Scale Boundingbox longest axis to unit size (keeps aspect ratio)
Definition: MovePlugin.cc:1862
void setAllTargets(bool _state)
Sets whether all targets should be affected or not.
Definition: MovePlugin.cc:2570
QAction * toAllTargets_
Checked if transformation should be applied to all target objs.
Definition: MovePlugin.hh:492
int lastActiveManipulator_
Stores the last manipulator which has been clicked ( used for the toolbox dialog) ...
Definition: MovePlugin.hh:413
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
int axisB_
stores the current axes in the tool
Definition: MovePlugin.hh:203
OpenMesh::Vec3d getNearestFace(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest face to hitpoint.
Definition: MovePlugin.cc:2657
OpenMesh::Vec3d getNearestEdge(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest edge to hitpoint.
Definition: MovePlugin.cc:2612
const VecT & vertex(const VertexHandle &_vh) const
Get point _vh's coordinates.
void translateFaceSelection(int _objectId, Vector _vector)
translate current face selection of an Object by a given vector
QAction * rotateTranslateAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:301
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
QToolBar * toolbar_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:283
QMenu * contextMenuManipControl_
Additional Context Menu replicating the toolbar stuff.
Definition: MovePlugin.hh:495
bool transformVertexSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
QAction * resizeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:303
void updateSelectionType()
Get current primitive selection.
Definition: MovePlugin.cc:2498
void slotMouseEvent(QMouseEvent *_event)
MousePress event occured.
Definition: MovePlugin.cc:399
void setManipMode(QtTranslationManipulatorNode::ManipulatorMode _mode)
Set the manipulator manipulation mode.
Definition: MovePlugin.cc:665
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
QAction * biggerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:305
void slotEnableSelectionMode()
stores the current axes in the tool
Definition: MovePlugin.cc:475
void showManipulators()
Checks if the manipulators should be visible or not.
Definition: MovePlugin.cc:976
const GLMatrixd & matrix() const
Returns a const reference to the current transformation matrix.
void moveObject(ACG::Matrix4x4d mat, int _id)
Move an object with given id.
Definition: MovePlugin.cc:573
void slotScale()
Scale (with values from Tab)
Definition: MovePlugin.cc:1564
void slotToggleAxisB()
Toggle the second axis for changing direction in tab.
Definition: MovePlugin.cc:1125
OpenMesh::Vec3d getNearestVertex(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest vertex to hitpoint.
Definition: MovePlugin.cc:2580
void slotUnifyBoundingBoxDiagonal()
Scale Boundingbox Diagonal to unit size.
Definition: MovePlugin.cc:1857
void update_vertex_normals()
A simple heuristic to estimate the vertex normals.
void showProps()
Show properties of move manipulator in a dialog ( Called via context for picking. Get the picked id f...
void slotSetPosition()
Position of manipulator in tab changed.
Definition: MovePlugin.cc:1030
void slotSetMoveMode(QAction *_action)
Called by Toolbar to enable move mode.
Definition: MovePlugin.cc:2052
ACG::Matrix4x4d getLastManipulatorMatrix(bool _reset=true)
Get the Matrix of the last active Manipulator ( Identity if not found or hidden Manipulator ) ...
Definition: MovePlugin.cc:2125
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
void translateVertexSelection(int _objectId, Vector _vector)
translate current vertex selection of an Object by a given vector
moveToolbarWidget * tool_
Widget for Toolbox.
Definition: MovePlugin.hh:266
void identity()
setup an identity matrix
Definition: Matrix4x4T.cc:256
const NormalAttrib & normals() const
return a pointer to the mesh
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
Plane * plane(BaseObjectData *_object)
Get a Plane from an object.
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:83
void slotProjectToTangentPlane()
Project the current manipulator onto the tangent plane of the object.
Definition: MovePlugin.cc:1336
The Menu will be shown when a node was picked.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void manipulatorMoved(QtTranslationManipulatorNode *_node, QMouseEvent *_event)
move the object when its manipulator moves
Definition: MovePlugin.cc:767
#define DATA_HEXAHEDRAL_MESH
double manip_size_modifier_
Modifier for the Size (changed by Mousewheel Events)
Definition: MovePlugin.hh:410
void transpose()
transpose matrix
Definition: Matrix4x4T.cc:272
void setWhatsThis(QAction *_action, const QString &_msg, const QString &_ref="", const QString &_site="index.html") const
sets a whatsThis Message plus link to the doc for the given QAction
bool toolboxActive_
True if the toolbox widget is active.
Definition: MovePlugin.hh:263
void slotEnableObjectMode()
stores the current axes in the tool
Definition: MovePlugin.cc:481
double manip_size_
Size for the manipulators.
Definition: MovePlugin.hh:407
Viewer::ActionMode actionMode()
Get the current Action mode.
QActionGroup * pickToolBarActions_
Called by pick Toolbar.
Definition: MovePlugin.hh:314
void moveSelection(ACG::Matrix4x4d mat, int _id, QEvent::Type _type)
Move selection on an object with given id.
Definition: MovePlugin.cc:632
void slotRotate()
Rotate Manipulator (with values from Tab)
Definition: MovePlugin.cc:1416
#define DATA_SKELETON
Definition: Skeleton.hh:70
std::vector< int > activeManipulators_
Size for the manipulators.
Definition: MovePlugin.hh:330
void slotUpdateContextMenuNode(int _nodeId)
Hide context menu entry when right clicking on node other than manipulator node.
Definition: MovePlugin.cc:746
void hideManipulator()
Hide the manipulator( Called via context for picking. Get the picked id from the Qvariant attached to...
void getBB(MeshT &_mesh, ACG::Vec3d &_bb_min, ACG::Vec3d &_bb_max)
get bounding box diagonal of a mesh
Definition: MovePlugin.cc:2433
bool getPickedObject(const unsigned int _node_idx, BaseObjectData *&_object)
Get the picked mesh.
QAction * contextMenuManipControlsAction_
Action holding the context menu for toolbar replication.
Definition: MovePlugin.hh:498
bool transformCellSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
void setDescriptions()
Set Descriptions for scriptable functions.
bool invert()
matrix inversion (returns true on success)
Definition: Matrix4x4T.cc:297
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
void slotToggleAxisA()
Toggle the first axis for changing direction in tab.
Definition: MovePlugin.cc:1100
QtTranslationManipulatorNode::ManipulatorMode manMode_
Holds the current manipulator mode.
Definition: MovePlugin.hh:430
movePropsWidget * getDialogFromButton(QPushButton *_but)
Get parent properties dialog widget of QPushButton but.
Definition: MovePlugin.cc:1020
ManipulatorMode
enum to define the manipulator mode
MoveObjectMarker objectMarker_
Object marker to dimm Objects during manipulator transformation.
Definition: MovePlugin.hh:425
int getIdentifier()
Get an identifier for that manipulator.
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
void unifyBB(MeshT &_mesh, Unificationtype u=MovePlugin::DIAGONAL)
scale mesh to have a boundingboxdiagonal of one
Definition: MovePlugin.cc:2379
QIcon * toolIcon_
stores the current axes in the tool
Definition: MovePlugin.hh:268
Vec::value_type distPointLineSquared(const Vec &_p, const Vec &_v0, const Vec &_v1, Vec *_min_v)
squared distance from point _p to line segment (_v0,_v1)
Definition: Algorithms.cc:300
~MovePlugin()
Destructor.
Definition: MovePlugin.cc:129
void translate(int _objectId, Vector _vector)
translate an Object by a given vector
void unifyBoundingBox(Unificationtype u)
Size for the manipulators.
Definition: MovePlugin.cc:1872
void transformMesh(ACG::Matrix4x4d _mat, MeshT &_mesh)
Transform a mesh with the given transformation matrix.
Definition: MovePlugin.cc:2151
QAction * smallerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:306
int id() const
Definition: BaseObject.cc:201
void traverse(ACG::SceneGraph::MouseEventAction &_action)
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
Unificationtype
stores the current axes in the tool
Definition: MovePlugin.hh:205
void set_vertex(const VertexHandle &_vh, const VecT &_p)
Set the coordinates of point _vh.