Developer Documentation
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 #include "MovePlugin.hh"
44 
45 #include <MeshTools/MeshInfoT.hh>
46 #include <OpenFlipper/BasePlugin/WhatsThisGenerator.hh>
47 
48 #ifdef USE_OPENMP
49 #endif
50 
51 
52 #ifdef ENABLE_POLYLINE_SUPPORT
54 #endif
55 
56 #ifdef ENABLE_TSPLINEMESH_SUPPORT
57 #include <ObjectTypes/TSplineMesh/TSplineMesh.hh>
58 #endif
59 
60 #ifdef ENABLE_SKELETON_SUPPORT
61 #include <ObjectTypes/Skeleton/Helper/SkeletonTransform.hh>
62 #endif
63 
64 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
66 #endif
67 
68 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
70 #endif
71 
72 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
74 #endif
75 
76 #include <QMessageBox>
77 
78 
83 axisA_(0),
84 axisB_(1),
85 toolboxActive_(false),
86 tool_(0),
87 toolIcon_(0),
88 moveAction_(0),
89 moveSelectionAction_(0),
90 toolBarActions_(0),
91 toolbar_(0),
92 pickToolbar_(0),
93 placeAction_(0),
94 rotateTranslateAction_(0),
95 rotateManipAction_(0),
96 resizeAction_(0),
97 biggerManipAction_(0),
98 smallerManipAction_(0),
99 fixChildManipAction_(0),
100 transformRefPoseManipAction_(0),
101 currentPoseManipAction_(0),
102 placeAndSnapAction_(0),
103 pickToolBarActions_(0),
104 manip_size_(1.0),
105 manip_size_modifier_(1.0),
106 lastActiveManipulator_(-1),
107 manMode_(QtTranslationManipulatorNode::TranslationRotation),
108 selectionType_(VERTEX),
109 contextAction_(0),
110 contextActionHide_(0),
111 toAllTargets_(0),
112 contextMenuManipControl_(0),
113 contextMenuManipControlsAction_(0),
114 hide_(true),
115 allTargets_(false),
116 placeMode_(false),
117 transformedSelected_(false)
118 {
119 
120 }
121 
126 
127  if(contextAction_) {
128  delete contextAction_;
129  }
130 
131  if(contextActionHide_) {
132  delete contextActionHide_;
133  }
134 
135  if(toAllTargets_) {
136  delete toAllTargets_;
137  }
138 
139  for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
140  it != propsWindows_.end(); ++it) {
141 
142  if(*it) {
143  delete *it;
144  }
145  }
146 }
147 
148 
149 /*******************************************************************************
150  BaseInterface implementation
151  *******************************************************************************/
152 
157 
158  //PICKMODES
159  emit addPickMode("Separator");
160  emit addHiddenPickMode("Move");
161  emit setPickModeMouseTracking ("Move", true);
162  emit addHiddenPickMode("MoveSelection");
163  emit setPickModeMouseTracking ("MoveSelection", true);
164 
165  //KEYS
166  emit registerKey (Qt::Key_Shift, Qt::NoModifier, tr("Manipulator rotation"), true);
167  emit registerKey (Qt::Key_Shift, Qt::ShiftModifier, tr("Manipulator rotation"), true);
168  emit registerKey (Qt::Key_Shift, Qt::ControlModifier | Qt::ShiftModifier, tr("Manipulator rotation"), true);
169  emit registerKey (Qt::Key_Control, Qt::NoModifier, tr("Resize"), true);
170  emit registerKey (Qt::Key_Control, Qt::ControlModifier, tr("Resize"), true);
171  emit registerKey (Qt::Key_Control, Qt::ShiftModifier | Qt::ControlModifier, tr("Resize"), true);
172 
173  //SCRIPTING SLOT DESCRIPTIONS
174  setDescriptions();
175 
176  // ==================================
177  // Toolbar
178  // ==================================
179 
180  WhatsThisGenerator whatsThis("Move");
181  WhatsThisGenerator whatsThisUser("user");
182 
183  toolbar_ = new QToolBar(tr("Transform and Move"));
184  toolbar_->setObjectName("TransformAndMoveToolBar");
185 
186  toolBarActions_ = new QActionGroup(toolbar_);
187 
188  moveAction_ = new QAction(tr("<B>Move Object</B><br>Move an object in 3D"), toolBarActions_);
189  moveAction_->setStatusTip(tr("Move object in 3D."));
190  moveAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-objects.png") );
191  moveAction_->setCheckable(true);
192  whatsThis.setWhatsThis(moveAction_,tr("Move the whole object."));
193  toolbar_->addAction(moveAction_);
194 
195  moveSelectionAction_ = new QAction(tr("<B>Move Selection</B><br>Move a selection on an object"), toolBarActions_);
196  moveSelectionAction_->setStatusTip(tr("Move selections in 3D."));
197  moveSelectionAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-selections.png") );
198  moveSelectionAction_->setCheckable(true);
199  whatsThis.setWhatsThis(moveSelectionAction_,tr("Move only a selection."));
200  toolbar_->addAction(moveSelectionAction_);
201 
202  connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetMoveMode(QAction*)) );
203 
204  emit addToolbar(toolbar_);
205 
206  // ==================================
207  // Pick Toolbar
208  // ==================================
209 
210  pickToolbar_ = new QToolBar(tr("Transform and Move PickTool bar"));
211  pickToolbar_->setObjectName("TransformAndMovePickToolBar");
212 
213  pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
214  pickToolBarActions_ = new QActionGroup(pickToolbar_);
215  pickToolBarActions_->setExclusive (false);
216 
217  placeAction_ = new QAction(tr("Place manipulator"), pickToolBarActions_);
218  placeAction_->setStatusTip(tr("Place manipulator on object. <Doubleclick>"));
219  placeAction_->setToolTip(tr("Place manipulator on object. <Doubleclick>"));
220  placeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-place.png") );
221  whatsThisUser.setWhatsThis(placeAction_,tr("Place the manipulator."),"obj_man","manipulator.html");
222  placeAction_->setCheckable(true);
223  pickToolbar_->addAction(placeAction_);
224 
225  pickToolbar_->addSeparator ();
226 
227  rotateTranslateAction_ = new QAction(tr("Rotate/Translate object"), pickToolBarActions_);
228  rotateTranslateAction_->setStatusTip(tr("Rotate/Translate object."));
229  rotateTranslateAction_->setToolTip(tr("Rotate/Translate object."));
230  rotateTranslateAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-translaterotate.png") );
231  rotateTranslateAction_->setCheckable(true);
232  rotateTranslateAction_->setChecked(true);
233  whatsThisUser.setWhatsThis(rotateTranslateAction_,tr("Rotate or translate an object or selection."),"obj_translation","manipulator.html");
235 
236  resizeAction_ = new QAction(tr("Resize object"), pickToolBarActions_);
237  resizeAction_->setStatusTip(tr("Resize object. <Control>"));
238  resizeAction_->setToolTip(tr("Resize object. <Control>"));
239  resizeAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-resize.png") );
240  whatsThisUser.setWhatsThis(resizeAction_,tr("Resize object or selection."),"obj_resizing","manipulator.html");
241  resizeAction_->setCheckable(true);
242  pickToolbar_->addAction(resizeAction_);
243 
244  pickToolbar_->addSeparator ();
245 
246  rotateManipAction_ = new QAction(tr("Rotate manipulator"), pickToolBarActions_);
247  rotateManipAction_->setStatusTip(tr("Rotate manipulator. <Shift>"));
248  rotateManipAction_->setToolTip(tr("Rotate manipulator. <Shift>"));
249  rotateManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-maniprotate.png") );
250  whatsThisUser.setWhatsThis(rotateManipAction_,tr("Rotate only the Manipulator."),"man_rotating","manipulator.html");
251  rotateManipAction_->setCheckable(true);
252  pickToolbar_->addAction(rotateManipAction_);
253 
254  placeAndSnapAction_ = new QAction(tr("Locally translate manipulator"), pickToolBarActions_);
255  placeAndSnapAction_->setStatusTip(tr("Locally translate manipulator. Press and hold <Alt> for snapping."));
256  whatsThisUser.setWhatsThis(placeAndSnapAction_,tr("Translate only the Manipulator."),"man_translation","manipulator.html");
257  placeAndSnapAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-placeandsnap.png") );
258  placeAndSnapAction_->setCheckable(true);
259  pickToolbar_->addAction(placeAndSnapAction_);
260 
261  smallerManipAction_ = new QAction(tr("Decrease size of manipulator"), pickToolBarActions_);
262  smallerManipAction_->setStatusTip(tr("Make manipulator smaller. <Mouse wheel up>"));
263  smallerManipAction_->setToolTip(tr("Make manipulator smaller. <Mouse wheel up>"));
264  whatsThisUser.setWhatsThis(smallerManipAction_,tr("Resize the Manipulator to a smaller one."),"man_resizing","manipulator.html");
265  smallerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipsmall.png") );
266  smallerManipAction_->setCheckable(false);
267  pickToolbar_->addAction(smallerManipAction_);
268 
269  biggerManipAction_ = new QAction(tr("Increase size of manipulator"), pickToolBarActions_);
270  biggerManipAction_->setStatusTip(tr("Make manipulator bigger. <Mouse wheel down>"));
271  biggerManipAction_->setToolTip(tr("Make manipulator bigger. <Mouse wheel down>"));
272  whatsThisUser.setWhatsThis(biggerManipAction_,tr("Resize the Manipulator to a bigger one."),"man_resizing","manipulator.html");
273  biggerManipAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-manipbig.png") );
274  biggerManipAction_->setCheckable(false);
275  pickToolbar_->addAction(biggerManipAction_);
276 
277  connect(pickToolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotPickToolbarAction(QAction*)) );
278 #if defined(ARCH_DARWIN)
279  // Workaround for QPainter using an unsupported rendering backend on core profiles
280  // See https://bugreports.qt.io/browse/QTBUG-32639
281  // setting opacity to a value smaller than 1 forces rasterizer engine
282  pickToolbar_->setWindowOpacity(0.99);
283 #endif
284  emit setPickModeToolbar ("Move", pickToolbar_);
285  emit setPickModeToolbar ("MoveSelection", pickToolbar_);
286 
287  // ==================================
288  // CONTEXT MENU
289  // ==================================
290  toAllTargets_ = new QAction(tr("Apply to all targets"), this);
291  toAllTargets_->setCheckable(true);
292  toAllTargets_->setToolTip(tr("Apply transformation to all target objects"));
293  toAllTargets_->setStatusTip( toAllTargets_->toolTip() );
294 
295  contextAction_ = new QAction(tr("Set properties"), this);
296  contextAction_->setToolTip(tr("Set properties"));
297  contextAction_->setStatusTip( contextAction_->toolTip() );
298  contextAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-properties.png") );
299 
300  contextActionHide_ = new QAction(tr("Hide Manipulator"), this);
301  contextActionHide_->setToolTip(tr("Hide Manipulator"));
302  contextActionHide_->setStatusTip( contextActionHide_->toolTip() );
303  contextActionHide_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-hide.png") );
304 
305  // QMenu replicating the relevant pick toolbar actions
306  contextMenuManipControl_ = new QMenu(tr("Manipulator Controls"));
313 
314 
316 
317  emit addContextMenuItem(toAllTargets_ , CONTEXTNODEMENU );
318  emit addContextMenuItem(contextAction_ , CONTEXTNODEMENU );
319  emit addContextMenuItem(contextActionHide_ , CONTEXTNODEMENU );
320  emit addContextMenuItem(contextMenuManipControlsAction_ , CONTEXTNODEMENU );
321 
322  connect( toAllTargets_ , SIGNAL(toggled(bool) ), this, SLOT(setAllTargets(bool)));
323  connect( contextAction_ , SIGNAL( triggered() ), this, SLOT(showProps()) );
324  connect( contextActionHide_ , SIGNAL( triggered() ), this, SLOT(hideManipulator()) );
325 }
326 
327 
328 /*******************************************************************************
329  ToolBoxInterface implementation
330  *******************************************************************************/
331 
332 void MovePlugin::initializePlugin()
333 {
334  toolboxActive_ = false;
335  tool_ = new moveToolbarWidget();
336 
337  connect(tool_->moveToOrigin,SIGNAL(clicked() ),this,SLOT(slotMoveToOrigin()));
338 
339  tool_->moveToOrigin->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "moveToCOG.png") );
340  tool_->moveToOrigin->setIconSize(QSize(48,48));
341  WhatsThisGenerator whatsThis("Move");
342  tool_->moveToOrigin->setWhatsThis(QString(tr("Moves the selected objects such that their center of gravity is at the origin."))
343  +whatsThis.generateLink("move_cog"));
344 
345  connect(tool_->unifyBoundingBoxDiagonal,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxDiagonal()));
346  tool_->unifyBoundingBoxDiagonal->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB.png") );
347  tool_->unifyBoundingBoxDiagonal->setIconSize(QSize(48,48));
348  tool_->unifyBoundingBoxDiagonal->setWhatsThis(QString(tr("Rescale objects such that its bounding box diagonal has length one."))
349  +whatsThis.generateLink("unifyBB"));
350 
351  connect(tool_->unifyBoundingBoxLongest,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxLongestAxis()));
352  tool_->unifyBoundingBoxLongest->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB_longest.png") );
353  tool_->unifyBoundingBoxLongest->setIconSize(QSize(48,48));
354 
355  connect(tool_->unifyBoundingBoxAll,SIGNAL(clicked() ),this,SLOT(slotUnifyBoundingBoxAllAxis()));
356  tool_->unifyBoundingBoxAll->setIcon( QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "unifyBB_all.png") );
357  tool_->unifyBoundingBoxAll->setIconSize(QSize(48,48));
358 
360 
361  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"move-toolBox.png");
362  emit addToolbox( tr("Move") , tool_, toolIcon_ );
363 }
364 
365 
366 /*******************************************************************************
367  MouseInterface implementation
368  *******************************************************************************/
369 
370 void MovePlugin::slotMouseWheelEvent(QWheelEvent * _event, const std::string & /*_mode*/)
371 {
372  // Skip execution if this is not our pick mode
373  if( ( (PluginFunctions::pickMode() != "Move")
374  && (PluginFunctions::pickMode() != "MoveSelection") )
375  || PluginFunctions::actionMode() != Viewer::PickingMode)
376  return;
377 
378  // compute the manipulator size modifier based on the mouse wheel change
379  manip_size_modifier_ = manip_size_modifier_ - (float)_event->delta() / 120.0 * 0.1;
380 
381  //dont scroll into negative sizes
382  if (manip_size_modifier_ < 0.0)
383  manip_size_modifier_ = 0.0;
384 
385  // Resize all manipulators based on the modifier on all objects
387  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
388 
389  // Redraw scene with updated manipulators
390  emit updateView();
391 }
392 
393 
394 //------------------------------------------------------------------------------
395 
400 void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
401  if (((PluginFunctions::pickMode() == ("Move"))
402  || (PluginFunctions::pickMode() == ("MoveSelection")))
403  && PluginFunctions::actionMode() == Viewer::PickingMode) {
404 
405  if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
406  && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
407 
408  bool snap = (placeMode_ && (PluginFunctions::pickMode() == ("MoveSelection")));
409 
410  placeManip(_event, snap);
411  placeAction_->setChecked(false);
413 
414  if (placeMode_) {
415  manMode_ = QtTranslationManipulatorNode::TranslationRotation;
416 
418  != PluginFunctions::objectsEnd(); ++o_it)
419  if (o_it->manipPlaced())
420  o_it->manipulatorNode()->setMode(manMode_);
421 
422  resizeAction_->setChecked(false);
423  rotateManipAction_->setChecked(false);
424  rotateTranslateAction_->setChecked(true);
425  placeAndSnapAction_->setChecked(false);
426  }
427 
428  placeMode_ = false;
429  return;
430 
431  } else if (placeMode_) {
432 
433  /*
434  * Move manipulator along with cursor if placeAndSnap mode
435  * is active. Snap to nearest geometry element (vertex, line, face center)
436  * depending on which selection type is active.
437  *
438  */
439 
440  placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
442  return;
443  }
444 
445  // interaction
448 
449  if (_event->buttons() == Qt::LeftButton)
450  emit nodeVisibilityChanged(-1);
451 
452  }
453 }
454 
455 /*******************************************************************************
456  KeyInterface implementation
457  *******************************************************************************/
458 
459 void MovePlugin::slotKeyEvent (QKeyEvent* _event)
460 {
461  if ((_event->key() == Qt::Key_Control) && _event->modifiers() != Qt::ShiftModifier) {
462  setManipMode (QtTranslationManipulatorNode::Resize);
463  return;
464  } else if ((_event->key () == Qt::Key_Shift) && _event->modifiers() != Qt::ControlModifier) {
465  setManipMode (QtTranslationManipulatorNode::LocalRotation);
466  return;
467  }
468 
469  // Return to normal mode if Ctrl + Shift is pressed since this
470  // is used in translation manipulator node for rotation rasterization
471  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
472 }
473 
474 //------------------------------------------------------------------------------
475 
477 {
478  PluginFunctions::pickMode("MoveSelection");
479 }
480 
481 //------------------------------------------------------------------------------
483 {
485 }
486 //------------------------------------------------------------------------------
487 
488 void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
489 {
490  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
491  (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
492  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
493 }
494 
495 void MovePlugin::setPickModeProps(movePropsWidget* _pW, const std::string &_pickmode)
496 {
497  if (_pickmode == "Move")
498  {
499  _pW->objectRadioButton->setChecked(true);
500  }
501  else if (_pickmode == "MoveSelection")
502  {
503  _pW->selectionRadioButton->setChecked(true);
504  }
505  else
506  {
507  //not supported, so deselect all radio buttons
508  _pW->objectRadioButton->setAutoExclusive(false);
509  _pW->selectionRadioButton->setAutoExclusive(false);
510  _pW->objectRadioButton->setChecked(false);
511  _pW->selectionRadioButton->setChecked(false);
512  _pW->objectRadioButton->setAutoExclusive(true);
513  _pW->selectionRadioButton->setAutoExclusive(true);
514  }
515 }
516 
517 /*******************************************************************************
518  PickingInterface implementation
519  *******************************************************************************/
520 
525 void MovePlugin::slotPickModeChanged( const std::string& _mode)
526 {
527  moveAction_->setChecked(_mode == "Move");
528  moveSelectionAction_->setChecked(_mode == "MoveSelection");
529 
530  hide_ = !(_mode == "Move" || _mode == "MoveSelection");
531 
533 
534  if (!hide_)
535  {
536  switch (manMode_)
537  {
538  case QtTranslationManipulatorNode::Rotation:
540  break;
541  case QtTranslationManipulatorNode::Resize:
543  break;
544  case QtTranslationManipulatorNode::LocalRotation:
546  break;
547  case QtTranslationManipulatorNode::Place:
549  break;
550  case QtTranslationManipulatorNode::TranslationRotation:
552  break;
553  }
554  }
555  else
557 
558  //change the selection mode in propety widget
559  for (int i = 0; i < propsWindows_.size(); ++i)
560  setPickModeProps(propsWindows_[i], _mode);
561 
562 }
563 
564 
565 /*******************************************************************************
566  MovePlugin implementation
567  *******************************************************************************/
568 
575  BaseObjectData* object;
576  if ( ! PluginFunctions::getObject(_id,object) )
577  return;
578 
579  if ( mat.is_identity() )
580  return;
581 
582  if ( object->dataType() == DATA_TRIANGLE_MESH ) {
583  transformMesh(mat , *PluginFunctions::triMesh(object) );
584  } else if ( object->dataType() == DATA_POLY_MESH ) {
585  transformMesh(mat , *PluginFunctions::polyMesh(object) );
586 #ifdef ENABLE_TSPLINEMESH_SUPPORT
587  } else if ( object->dataType() == DATA_TSPLINE_MESH ) {
588  transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
589 #endif
590 #ifdef ENABLE_POLYLINE_SUPPORT
591  } else if ( object->dataType() == DATA_POLY_LINE ) {
592  transformPolyLine(mat , *PluginFunctions::polyLine(object) );
593 #endif
594 #ifdef ENABLE_SKELETON_SUPPORT
595  } else if ( object->dataType() == DATA_SKELETON ) {
596  transformSkeleton(mat , *PluginFunctions::skeleton(object) );
597 #endif
598 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
599  } else if ( object->dataType() == DATA_HEXAHEDRAL_MESH ) {
601  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
602 #endif
603 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
604  } else if ( object->dataType() == DATA_TETRAHEDRAL_MESH ) {
606  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
607 #endif
608 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
609  } else if ( object->dataType() == DATA_POLYHEDRAL_MESH ) {
611  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
612 #endif
613  } else if ( object->dataType() == DATA_PLANE ) {
614  PluginFunctions::plane(object)->transform(mat);
615  } else {
616 
617  emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
618  return;
619  }
620 
621  emit updatedObject(_id, UPDATE_GEOMETRY);
622  emit createBackup(_id, "Move Object", UPDATE_GEOMETRY);
623 }
624 
625 
626 //------------------------------------------------------------------------------
627 
638 void MovePlugin::moveSelection(ACG::Matrix4x4d _mat, int _id, QEvent::Type _type) {
639  // Get currently active primitive type
641 
642  if ( !_mat.is_identity() ){
643  if (selectionType_ & VERTEX) {
645  }
646  if (selectionType_ & FACE) {
648  }
649  if (selectionType_ & EDGE) {
651  }
652  if (selectionType_ & CELL) {
654  }
655 
656  emit updatedObject(_id, UPDATE_GEOMETRY);
657  }
658 
659  //only create backups on mouseRelease and something has to have been selected and transformed
660  if ( _type == QEvent::MouseButtonRelease && transformedSelected_ )
661  emit createBackup(_id,"Move Selection", UPDATE_GEOMETRY);
662 
663 }
664 
665 //------------------------------------------------------------------------------
666 
672 {
673  if (_mode != manMode_)
674  {
675  manMode_ = _mode;
676 
677  // Iterate over all objects that have a placed manip and set their mode
679  if ( o_it->manipPlaced() )
680  o_it->manipulatorNode()->setMode (_mode);
681 
682 
683  if (!hide_) {
684  switch (manMode_)
685  {
686  case QtTranslationManipulatorNode::Rotation:
688  placeMode_ = false;
689  break;
690  case QtTranslationManipulatorNode::Resize:
692  placeMode_ = false;
693  break;
694  case QtTranslationManipulatorNode::LocalRotation:
696  placeMode_ = false;
697  break;
698  case QtTranslationManipulatorNode::Place:
700  placeMode_ = true;
701  break;
702  case QtTranslationManipulatorNode::TranslationRotation:
704  placeMode_ = false;
705  break;
706  }
707  }
708 
709  // Update the toolbar icons
710  switch (manMode_)
711  {
712  case QtTranslationManipulatorNode::Resize:
713  resizeAction_->setChecked (true);
714  rotateManipAction_->setChecked (false);
715  rotateTranslateAction_->setChecked (false);
716  placeAndSnapAction_->setChecked (false);
717  break;
718  case QtTranslationManipulatorNode::LocalRotation:
719  resizeAction_->setChecked (false);
720  rotateManipAction_->setChecked (true);
721  rotateTranslateAction_->setChecked (false);
722  placeAndSnapAction_->setChecked (false);
723  break;
724  case QtTranslationManipulatorNode::TranslationRotation:
725  resizeAction_->setChecked (false);
726  rotateManipAction_->setChecked (false);
727  rotateTranslateAction_->setChecked (true);
728  placeAndSnapAction_->setChecked (false);
729  break;
730  case QtTranslationManipulatorNode::Place:
731  resizeAction_->setChecked (false);
732  rotateManipAction_->setChecked (false);
733  rotateTranslateAction_->setChecked (false);
734  placeAndSnapAction_->setChecked (true);
735  break;
736  case QtTranslationManipulatorNode::Rotation:
737  resizeAction_->setChecked(false);
738  rotateManipAction_->setChecked(true);
739  rotateTranslateAction_->setChecked(false);
740  placeAndSnapAction_->setChecked(false);
741  break;
742  }
743  }
744 }
745 
746 //------------------------------------------------------------------------------
747 
748 
754 
756 
757  if (node == 0)
758  return;
759 
760  if (node->className() != "QtTranslationManipulatorNode") {
761  contextAction_->setVisible(false);
762  } else {
763  contextAction_->setVisible(true);
764  }
765 }
766 
767 //------------------------------------------------------------------------------
768 
774 void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {
775 
776  // React on event only in move mode
777  if ( PluginFunctions::pickMode() != "Move"
778  && PluginFunctions::pickMode() != "MoveSelection" )
779  return;
780 
781  OpenFlipper::Options::redrawDisabled( true );
782 
783  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
784  if ( !placeMode_ && ((_event->type() == QEvent::MouseButtonRelease) ||
785  (PluginFunctions::pickMode() != "Move" && _event->buttons() != Qt::NoButton)) ) {
786 
787  int objectId = _node->getIdentifier();
788 
789  ACG::Matrix4x4d mat;
790  mat.identity();
791  mat = _node->matrix();
792 
793  // Reset Node
794  _node->loadIdentity();
795  _node->set_center(mat.transform_point(_node->center()));
796 
797  // move the object which corresponds to the manipulator
798  if (PluginFunctions::pickMode() == "Move")
799  moveObject( mat, objectId );
800  else if (PluginFunctions::pickMode() == "MoveSelection")
801  moveSelection( mat, objectId, _event->type() );
802 
803  // move all other targets without manipulator
804  if(allTargets_) {
806  != PluginFunctions::objectsEnd(); ++o_it) {
807  if ((o_it->id() != objectId) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
808 
809  // move the object which corresponds to the manipulator
810  if (PluginFunctions::pickMode() == "Move")
811  moveObject( mat, o_it->id() );
812  else if (PluginFunctions::pickMode() == "MoveSelection")
813  moveSelection( mat, o_it->id(), _event->type() );
814  }
815  }
816  }
817 
818  lastActiveManipulator_ = objectId;
820  }
821 
822  OpenFlipper::Options::redrawDisabled( false );
823 }
824 
825 
826 //------------------------------------------------------------------------------
827 
833 
834  // Position has been changed of the manipulator by a direct function
835  int objectId = _node->getIdentifier();
836 
837  if ( objectId > 0 ){
838 
839  BaseObjectData* object;
840  PluginFunctions::getObject(objectId,object);
841 
842  // Assume that it has a good position now
843  object->manipPlaced( true );
844  }
845 
846  // Show manipulator only if in Move mode
847  if ( PluginFunctions::pickMode() == "Move" )
848  _node->show();
849 
850  lastActiveManipulator_ = objectId;
852 
853 }
854 
855 
856 //------------------------------------------------------------------------------
857 
863 void MovePlugin::placeManip(QMouseEvent * _event, bool _snap) {
864  size_t node_idx, target_idx;
865  OpenMesh::Vec3d hitPoint;
866  BaseObjectData* object;
867 
868  bool successfullyPicked = false;
869 
870 
871 
872  /*
873  * Snap manipulator to nearest geometry
874  * element depending on which selection type is
875  * active.
876  */
877  if (_snap) {
878 
879  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx,
880  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
881 
882  if(!successfullyPicked) {
883  //emit log(LOGWARN, tr("Picking failed"));
884  return;
885  }
886 
887  if (selectionType_ == VERTEX) {
888  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
889  hitPoint = getNearestVertex(PluginFunctions::triMesh(object), target_idx, hitPoint);
890  } else if ( object->dataType(DATA_POLY_MESH) ) {
891  hitPoint = getNearestVertex(PluginFunctions::polyMesh(object), target_idx, hitPoint);
892 #ifdef ENABLE_TSPLINEMESH_SUPPORT
893  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
894  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
895 #endif
896  }
897  } else if (selectionType_ == EDGE) {
898  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
899  hitPoint = getNearestEdge(PluginFunctions::triMesh(object), target_idx, hitPoint);
900  } else if ( object->dataType(DATA_POLY_MESH) ) {
901  hitPoint = getNearestEdge(PluginFunctions::polyMesh(object), target_idx, hitPoint);
902 #ifdef ENABLE_TSPLINEMESH_SUPPORT
903  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
904  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
905 #endif
906  }
907  } else if (selectionType_ == FACE) {
908  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
909  hitPoint = getNearestFace(PluginFunctions::triMesh(object), target_idx, hitPoint);
910  } else if ( object->dataType(DATA_POLY_MESH) ) {
911  hitPoint = getNearestFace(PluginFunctions::polyMesh(object), target_idx, hitPoint);
912 #ifdef ENABLE_TSPLINEMESH_SUPPORT
913  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
914  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
915 #endif
916  }
917  }
918 
919  } else {
920  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
921  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
922  }
923 
924  if (successfullyPicked) {
925 
926  object->manipPlaced(true);
927 
928  object->manipulatorNode()->loadIdentity();
929  object->manipulatorNode()->set_center(hitPoint);
930  object->manipulatorNode()->set_draw_cylinder(true);
931  object->manipulatorNode()->set_autosize(QtTranslationManipulatorNode::Once);
932  object->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
933  object->manipulatorNode()->setMode(manMode_);
934  object->manipulatorNode()->show();
935 
936  object->manipulatorNode()->apply_transformation(PluginFunctions::pickMode() == "Move");
937 
938  // Disconnect a previously connected Signal
939  disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
940  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
941 
942  disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
944 
945  // Reconnect the signals.
946  connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
947  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
948 
949  connect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
951 
952  lastActiveManipulator_ = object->id();
953 
954  emit updateView();
955 
956  bool found = false;
957 
958  for (uint i=0; i < activeManipulators_.size(); i++)
959  if ( activeManipulators_[i] == object->id() ){
960  found = true;
961  break;
962  }
963 
964  if ( !found )
965  activeManipulators_.push_back( object->id() );
966 
967  } else {
968  //emit log(LOGWARN, tr("Picking failed"));
969  }
970 }
971 
972 
973 //------------------------------------------------------------------------------
974 
979 {
980 
981  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
982  || (PluginFunctions::pickMode() == "MoveSelection"))) {
983 
984  for (uint i=0; i < activeManipulators_.size(); i++){
985 
986  BaseObjectData* obj = 0;
987 
989 
990  if (obj != 0 && obj->manipPlaced()) {
991  obj->manipulatorNode()->show();
992  obj->manipulatorNode()->apply_transformation( PluginFunctions::pickMode() == "Move" );
993  emit nodeVisibilityChanged(obj->id());
994  }
995  }
996 
997  } else {
998 
999  for (uint i=0; i < activeManipulators_.size(); i++){
1000 
1001  BaseObjectData* obj = 0;
1002 
1004 
1005  if ( obj != 0 ) {
1006  obj->manipulatorNode()->hide();
1007  emit nodeVisibilityChanged(obj->id());
1008  }
1009  }
1010  }
1011 
1012  emit updateView();
1013 
1014 }
1015 
1016 //------------------------------------------------------------------------------
1017 
1023 
1024  if(_but == 0) return 0;
1025  return dynamic_cast<movePropsWidget*>((((_but->parentWidget())->parentWidget())->parentWidget()));
1026 }
1027 //------------------------------------------------------------------------------
1028 
1033 
1034  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1036  if(pW == 0) return;
1037 
1038  TriMesh::Point newpos;
1039 
1040  bool ok = false;
1041  newpos[0] = (pW->nposx->text()).toDouble(&ok);
1042  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1043  newpos[1] = (pW->nposy->text()).toDouble(&ok);
1044  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1045  newpos[2] = (pW->nposz->text()).toDouble(&ok);
1046  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1047 
1048  BaseObjectData* object;
1050  if ( object->manipulatorNode()->visible() ) {
1051  // Compute translation vector
1052  ACG::Vec3d translation = newpos;
1053  translation -= object->manipulatorNode()->center();
1054  object->manipulatorNode()->set_center(newpos);
1055  // Stuff it into transformation matrix
1056  ACG::GLMatrixd m;
1057  m.identity();
1058  m.translate(translation);
1059  if (PluginFunctions::pickMode() == "Move")
1060  {
1061  // ...and transform mesh
1062  if(object->dataType() == DATA_TRIANGLE_MESH)
1064  else if(object->dataType() == DATA_POLY_MESH)
1066 
1067  // Create backup
1068  emit createBackup(object->id(), "Object Translation");
1069 
1070  }
1071  else if (PluginFunctions::pickMode() == "MoveSelection")
1072  {
1074  if (selectionType_ & VERTEX) {
1075  transformVertexSelection(object->id(), m);
1076  }
1077  if (selectionType_ & FACE) {
1078  transformFaceSelection(object->id(), m);
1079  }
1080  if (selectionType_ & EDGE) {
1081  transformEdgeSelection(object->id(), m);
1082  }
1083 
1084  // Create backup
1085  emit createBackup(object->id(), "Translation of selection");
1086  }
1087 
1088 
1089  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1090  }
1092  emit updateView();
1093  }
1094 }
1095 
1096 
1097 //------------------------------------------------------------------------------
1098 
1103 
1104  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1106  if(pW == 0) return;
1107 
1108  axisA_ = (axisA_ + 1) % 3;
1109 
1110  if (axisA_ == axisB_)
1111  axisA_ = (axisA_ + 1) % 3;
1112 
1113  switch(axisA_){
1114  case 0: pW->axisAButton->setText(tr("X Direction")); break;
1115  case 1: pW->axisAButton->setText(tr("Y Direction")); break;
1116  case 2: pW->axisAButton->setText(tr("Z Direction")); break;
1117  default: break;
1118  }
1119 }
1120 
1121 
1122 //------------------------------------------------------------------------------
1123 
1128 
1129  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1131  if(pW == 0) return;
1132 
1133  axisB_ = (axisB_ + 1) % 3;
1134 
1135  if (axisA_ == axisB_)
1136  axisB_ = (axisB_ + 1) % 3;
1137 
1138  switch(axisB_){
1139  case 0: pW->axisBButton->setText(tr("X Direction")); break;
1140  case 1: pW->axisBButton->setText(tr("Y Direction")); break;
1141  case 2: pW->axisBButton->setText(tr("Z Direction")); break;
1142  default: break;
1143  }
1144 }
1145 
1146 
1147 //------------------------------------------------------------------------------
1148 
1153 
1154  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1156  if(pW == 0) return;
1157 
1158  ACG::Vec3d newdirA,newdirB;
1159  ACG::Vec3d dirX,dirY;
1160  ACG::Vec3d dirZ(0.0,0.0,0.0);
1161 
1162  bool ok = false;
1163  newdirA[0] = (pW->ndirAx->text()).toDouble(&ok);
1164  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1165  newdirA[1] = (pW->ndirAy->text()).toDouble(&ok);
1166  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1167  newdirA[2] = (pW->ndirAz->text()).toDouble(&ok);
1168  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1169 
1170  newdirB[0] = (pW->ndirBx->text()).toDouble(&ok);
1171  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1172  newdirB[1] = (pW->ndirBy->text()).toDouble(&ok);
1173  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1174  newdirB[2] = (pW->ndirBz->text()).toDouble(&ok);
1175  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1176 
1177  bool xAxis = false;
1178  bool yAxis = false;
1179 
1180  switch(axisA_){
1181  case 0: dirX = newdirA; xAxis = true; break;
1182  case 1: dirY = newdirA; yAxis = true; break;
1183  default: dirZ = newdirA; break;
1184  }
1185 
1186  switch(axisB_){
1187  case 0: dirX = newdirB; xAxis = true; break;
1188  case 1: dirY = newdirB; yAxis = true; break;
1189  default: dirZ = newdirB; break;
1190  }
1191 
1192  if (!xAxis)
1193  dirX = dirY % dirZ;
1194 
1195  if (!yAxis)
1196  dirY = dirX % dirZ;
1197 
1198 
1199  if ( (dirX | dirY) != 0.0){
1200  emit log(LOGERR,tr("The axes of the new direction have to be orthogonal"));
1201  return;
1202  }
1203 
1204 // // Apply to All Target Objects
1205 // if ( pW->targetObjects->isChecked() ) {
1206 // for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ;
1207 // o_it PluginFunctions::objectsEnd(); ++o_it){
1208 //
1209 // o_it->manipulatorNode()->set_direction( dirX, dirY );
1210 // }
1211 // }
1212 
1213 
1214  BaseObjectData* object = 0;
1215  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1216  if ( object != 0 ) {
1217  if ( object->manipulatorNode()->visible() ){
1218 
1219  object->manipulatorNode()->set_direction( dirX, dirY );
1220  }
1221  } else return;
1222 
1224  emit updateView();
1225 }
1226 
1227 
1228 //------------------------------------------------------------------------------
1229 
1234 
1235  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1237  if(pW == 0) return;
1238 
1239  ACG::Vec3d translation;
1240 
1241  bool ok = false;
1242  translation[0] = (pW->translationX->text()).toDouble(&ok);
1243  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1244  translation[1] = (pW->translationY->text()).toDouble(&ok);
1245  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1246  translation[2] = (pW->translationZ->text()).toDouble(&ok);
1247  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1248 
1249  BaseObjectData* object = 0;
1250  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1251 
1252  if (object != 0) {
1253  if (object->manipulatorNode()->visible()) {
1254 
1255  object->manipulatorNode()->set_center(
1256  object->manipulatorNode()->center() + translation);
1257 
1258  if (PluginFunctions::pickMode() == "Move")
1259  {
1260 
1261  translate(object->id(), translation);
1262 
1263  // Create backup
1264  emit createBackup(object->id(), "Translation of Object");
1265 
1266  }
1267  else if (PluginFunctions::pickMode() == "MoveSelection")
1268  {
1270  if (selectionType_ & VERTEX) {
1271  translateVertexSelection(object->id(), translation);
1272  }
1273  if (selectionType_ & FACE) {
1274  translateFaceSelection(object->id(), translation);
1275  }
1276  if (selectionType_ & EDGE) {
1277  translateEdgeSelection(object->id(), translation);
1278  }
1279  emit createBackup(object->id(), "Translation of selection");
1280  }
1281 
1282 
1283 
1284  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1285 
1286 
1287  // move all other targets without manipulator
1288  if(allTargets_) {
1289 
1291  != PluginFunctions::objectsEnd(); ++o_it) {
1292  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1293  if (PluginFunctions::pickMode() == "Move") {
1294 
1295  translate(o_it->id(), translation);
1296 
1297  // Create backup
1298  emit createBackup(o_it->id(), "Translation of object");
1299 
1300  } else if (PluginFunctions::pickMode() == "MoveSelection") {
1302  if (selectionType_ & VERTEX) {
1303  translateVertexSelection(o_it->id(), translation);
1304  }
1305  if (selectionType_ & FACE) {
1306  translateFaceSelection(o_it->id(), translation);
1307  }
1308  if (selectionType_ & EDGE) {
1309  translateEdgeSelection(o_it->id(), translation);
1310  }
1311 
1312  emit createBackup(o_it->id(), "Translation of selection");
1313  }
1314 
1315 
1316  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1317  }
1318  }
1319 
1320  }
1321  }
1322  } else {
1323  return;
1324  }
1325 
1326 
1328  emit scriptInfo(QString("slotTranslation()"));
1329  emit updateView();
1330 }
1331 
1332 
1333 //------------------------------------------------------------------------------
1334 
1339 
1340  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1342  if(pW == 0) return;
1343 
1344  if ( allTargets_ ) {
1345  emit log(LOGWARN,tr("TODO Project for multiple targets"));
1346  return;
1347  } else {
1348  emit log(LOGWARN,tr("TODO Project for one target"));
1349  return;
1350  }
1351 
1352 }
1353 
1354 
1355 //------------------------------------------------------------------------------
1356 
1361 
1362  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1364  if(pW == 0) return;
1365 
1366 
1367 // if ( pW->targetObjects->isChecked() ) {
1368 // for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) {
1369 // if ( o_it->manipulatorNode()->hidden() )
1370 // continue;
1371 //
1372 // if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1373 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::triMesh(*o_it) ) );
1374 // else if ( o_it->dataType( DATA_POLY_MESH ) )
1375 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::polyMesh(*o_it)) );
1376 //
1377 // updateManipulatorDialog();
1378 // o_it->manipulatorNode()->loadIdentity();
1379 // }
1380 // } else {
1381 
1382  BaseObjectData* object = 0;
1383  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1384  if ( object != 0 ) {
1385  if ( object->manipulatorNode()->visible() ){
1386 
1387  if ( object->dataType( DATA_TRIANGLE_MESH ) )
1388  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::triMesh(object)) );
1389  else if ( object->dataType( DATA_POLY_MESH ) )
1390  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::polyMesh(object)) );
1391 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1392  else if ( object->dataType( DATA_TSPLINE_MESH ) )
1393  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::tsplineMesh(object)) );
1394 #endif
1395 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1396  else if ( object->dataType( DATA_HEXAHEDRAL_MESH ) )
1397  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::hexahedralMesh(object)) );
1398 #endif
1399 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1400  else if ( object->dataType( DATA_TETRAHEDRAL_MESH ) )
1401  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::tetrahedralMesh(object)) );
1402 #endif
1403 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1404  else if ( object->dataType( DATA_POLYHEDRAL_MESH ) )
1405  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::polyhedralMesh(object)) );
1406 #endif
1407 
1409  object->manipulatorNode()->loadIdentity();
1410  }
1411  }
1412 
1413  emit updateView();
1414 }
1415 
1416 
1417 //------------------------------------------------------------------------------
1418 
1423 
1424  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1426  if(pW == 0) return;
1427 
1428  TriMesh::Point axis;
1429  double angle;
1430 
1431  bool ok = false;
1432  axis[0] = (pW->rotx->text()).toDouble(&ok);
1433  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1434  axis[1] = (pW->roty->text()).toDouble(&ok);
1435  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1436  axis[2] = (pW->rotz->text()).toDouble(&ok);
1437  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1438 
1439  angle = (pW->rotAngle->text()).toDouble(&ok);
1440  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Angle")); return; }
1441 
1442  BaseObjectData* object = 0;
1443  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1444  if (object != 0) {
1445  if (object->manipulatorNode()->visible() && (object->target() || !allTargets_)) {
1446 
1447  object->manipulatorNode()->rotate(angle, axis);
1448 
1450 
1451  if (PluginFunctions::pickMode() == "Move")
1452  {
1453  if (object->dataType(DATA_TRIANGLE_MESH))
1454  transformMesh(m, (*PluginFunctions::triMesh(object)));
1455 
1456  if (object->dataType(DATA_POLY_MESH))
1458 
1459  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1460  if (object->dataType(DATA_TSPLINE_MESH))
1461  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1462  #endif
1463  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1464  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1465  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1466  #endif
1467  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1468  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1469  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1470  #endif
1471  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1472  if (object->dataType(DATA_POLYHEDRAL_MESH))
1473  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1474  #endif
1475 
1476  // Create backup
1477  emit createBackup(object->id(), "Rotation of object");
1478 
1479  }
1480  else if (PluginFunctions::pickMode() == "MoveSelection")
1481  {
1483  if (selectionType_ & VERTEX) {
1484  transformVertexSelection(object->id(), m);
1485  }
1486  if (selectionType_ & FACE) {
1487  transformFaceSelection(object->id(), m);
1488  }
1489  if (selectionType_ & EDGE) {
1490  transformEdgeSelection(object->id(), m);
1491  }
1492  if (selectionType_ & CELL) {
1493  transformCellSelection(object->id(), m);
1494  }
1495 
1496  // Create backup
1497  emit createBackup(object->id(), "Rotation of selection");
1498  }
1499 
1500  // move all other targets without manipulator
1501  if(allTargets_) {
1502 
1504 
1505  // If it has its own manipulator active, don't move it
1506  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) {
1507 
1508  if (PluginFunctions::pickMode() == "Move")
1509  {
1510  if (o_it->dataType(DATA_TRIANGLE_MESH))
1512 
1513  if (o_it->dataType(DATA_POLY_MESH))
1515  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1516  if (o_it->dataType(DATA_TSPLINE_MESH))
1517  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1518  #endif
1519  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1520  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1521  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1522  #endif
1523  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1524  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1525  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1526  #endif
1527  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1528  if (object->dataType(DATA_POLYHEDRAL_MESH))
1529  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1530  #endif
1531 
1532  // Create backup
1533  emit createBackup(o_it->id(), "Rotation of object");
1534  }
1535  else if (PluginFunctions::pickMode() == "MoveSelection")
1536  {
1538  if (selectionType_ & VERTEX) {
1539  transformVertexSelection(o_it->id(), m);
1540  }
1541  if (selectionType_ & FACE) {
1542  transformFaceSelection(o_it->id(), m);
1543  }
1544  if (selectionType_ & EDGE) {
1545  transformEdgeSelection(o_it->id(), m);
1546  }
1547  if (selectionType_ & CELL) {
1548  transformCellSelection(o_it->id(), m);
1549  }
1550 
1551  // Create backup
1552  emit createBackup(o_it->id(), "Rotation of selection");
1553  }
1554 
1555  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1556  }
1557  }
1558 
1559  }
1560 
1562 
1563  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1564 
1565  }
1566  }
1567 
1568  emit scriptInfo(QString("slotRotate()"));
1569  emit updateView();
1570 }
1571 
1572 
1573 //------------------------------------------------------------------------------
1574 
1579 
1580  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1582  if(pW == 0) return;
1583 
1584 
1585  TriMesh::Point scale;
1586 
1587  bool ok = false;
1588  scale[0] = (pW->scalex->text()).toDouble(&ok);
1589  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 1")); return; }
1590  scale[1] = (pW->scaley->text()).toDouble(&ok);
1591  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 2")); return; }
1592  scale[2] = (pW->scalez->text()).toDouble(&ok);
1593  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 3")); return; }
1594 
1595  BaseObjectData* object = 0;
1596  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1597  if (object != 0) {
1598  if (object->manipulatorNode()->visible() && (object->target()
1599  || !allTargets_)) {
1600 
1601  object->manipulatorNode()->scale(scale);
1602 
1604 
1605  if (PluginFunctions::pickMode() == "Move")
1606  {
1607  if (object->dataType(DATA_TRIANGLE_MESH))
1609  if (object->dataType(DATA_POLY_MESH))
1611  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1612  if (object->dataType(DATA_TSPLINE_MESH))
1613  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1614  #endif
1615  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1616  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1617  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1618  #endif
1619  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1620  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1621  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1622  #endif
1623  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1624  if (object->dataType(DATA_POLYHEDRAL_MESH))
1625  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1626  #endif
1627 
1628  // Create backup
1629  emit createBackup(object->id(), "Scaling of object");
1630  }
1631  else if (PluginFunctions::pickMode() == "MoveSelection")
1632  {
1634  if (selectionType_ & VERTEX) {
1635  transformVertexSelection(object->id(), m);
1636  }
1637  if (selectionType_ & FACE) {
1638  transformFaceSelection(object->id(), m);
1639  }
1640  if (selectionType_ & EDGE) {
1641  transformEdgeSelection(object->id(), m);
1642  }
1643  if (selectionType_ & CELL) {
1644  transformCellSelection(object->id(), m);
1645  }
1646 
1647  // Create backup
1648  emit createBackup(object->id(), "Scaling of selection");
1649  }
1650 
1651  // move all other targets without manipulator
1652  if(allTargets_) {
1653 
1655  != PluginFunctions::objectsEnd(); ++o_it) {
1656  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1657 
1658  if (PluginFunctions::pickMode() == "Move")
1659  {
1660  if (o_it->dataType(DATA_TRIANGLE_MESH))
1662 
1663  if (o_it->dataType(DATA_POLY_MESH))
1665  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1666  if (o_it->dataType(DATA_TSPLINE_MESH))
1667  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1668  #endif
1669  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1670  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1671  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1672  #endif
1673  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1674  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1675  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1676  #endif
1677  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1678  if (object->dataType(DATA_POLYHEDRAL_MESH))
1679  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1680  #endif
1681 
1682  // Create backup
1683  emit createBackup(o_it->id(), "Scaling of object");
1684  }
1685  else if (PluginFunctions::pickMode() == "MoveSelection")
1686  {
1688  if (selectionType_ & VERTEX) {
1689  transformVertexSelection(o_it->id(), m);
1690  }
1691  if (selectionType_ & FACE) {
1692  transformFaceSelection(o_it->id(), m);
1693  }
1694  if (selectionType_ & EDGE) {
1695  transformEdgeSelection(o_it->id(), m);
1696  }
1697  if (selectionType_ & CELL) {
1698  transformCellSelection(o_it->id(), m);
1699  }
1700 
1701  // Create backup
1702  emit createBackup(o_it->id(), "Scaling of selection");
1703  }
1704 
1705  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1706  }
1707  }
1708 
1709  }
1710 
1712 
1713  emit createBackup(object->id(), "Scaling");
1714  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1715  }
1716  }
1717 
1718  emit scriptInfo(QString("slotScale()"));
1719  emit updateView();
1720 }
1721 
1722 
1723 //------------------------------------------------------------------------------
1724 
1725 
1730 
1731  bool useCommonCOG = false;
1732  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
1733 
1734  if ( PluginFunctions::targetCount() > 1 ) {
1735  if ( OpenFlipper::Options::gui()) {
1736  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);
1737 
1738 
1739  useCommonCOG = ( button == QMessageBox::Yes );
1740  }
1741 
1742  if ( useCommonCOG ) {
1743 
1744  double vertexCount = 0.0;
1745 
1746  // Compute cog for all objects
1748  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1749  TriMesh* mesh = PluginFunctions::triMesh(*o_it);
1750  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1751  vertexCount += double(mesh->n_vertices());
1752  }
1753 
1754  if ( o_it->dataType( DATA_POLY_MESH )) {
1755  PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
1756  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1757  vertexCount += double(mesh->n_vertices());
1758  }
1759 
1760 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1761  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1762  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(*o_it);
1763  cog += MeshInfo::cog(mesh) * double(mesh.n_vertices());
1764  vertexCount += double(mesh.n_vertices());
1765  }
1766 #endif
1767 
1768 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1769  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1771  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1772  vertexCount += double(mesh.n_vertices());
1773  }
1774 #endif
1775 
1776 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1777  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1779  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1780  vertexCount += double(mesh.n_vertices());
1781  }
1782 #endif
1783 
1784 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1785  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1787  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1788  vertexCount += double(mesh.n_vertices());
1789  }
1790 #endif
1791  }
1792 
1793  cog = cog / vertexCount;
1794  }
1795 
1796  }
1797 
1799  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1800  TriMesh* mesh = PluginFunctions::triMesh(*o_it);
1801 
1802  if ( !useCommonCOG )
1803  cog = MeshInfo::cog(mesh);
1804 
1805  for ( TriMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1806  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1807 
1808  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1809  }
1810 
1811  if ( o_it->dataType( DATA_POLY_MESH )) {
1812  PolyMesh* mesh = PluginFunctions::polyMesh(*o_it);
1813 
1814  if ( !useCommonCOG )
1815  cog = MeshInfo::cog(mesh);
1816 
1817  for ( PolyMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1818  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1819 
1820  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1821 
1822  }
1823 
1824 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1825  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1826  TSplineMesh* mesh = PluginFunctions::tsplineMesh(*o_it);
1827 
1828  if ( !useCommonCOG )
1829  cog = MeshInfo::cog(mesh);
1830 
1831  for ( TSplineMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1832  mesh->set_point(v_it , ( mesh->point(v_it) ) - cog );
1833 
1834  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1835 
1836  }
1837 #endif
1838 
1839 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1840  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1842 
1843  if ( !useCommonCOG )
1844  cog = cogVolumeMesh(mesh);
1845 
1846  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1847  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1848 
1849  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1850 
1851  }
1852 #endif
1853 
1854 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1855  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1857 
1858  if ( !useCommonCOG )
1859  cog = cogVolumeMesh(mesh);
1860 
1861  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1862  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1863 
1864  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1865 
1866  }
1867 #endif
1868 
1869 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1870  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1872 
1873  if ( !useCommonCOG )
1874  cog = cogVolumeMesh(mesh);
1875 
1876  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1877  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1878 
1879  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1880 
1881  }
1882 #endif
1883 
1884 
1885  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
1886 
1888  o_it->manipulatorNode()->loadIdentity();
1889 
1890  emit createBackup(o_it->id(),"Move to origin");
1891  }
1892 
1893  emit updateView();
1894 }
1895 
1896 
1897 //------------------------------------------------------------------------------
1898 
1903 {
1904  unifyBoundingBox(MovePlugin::DIAGONAL);
1905 }
1906 
1908 {
1909  unifyBoundingBox((MovePlugin::LONGEST_AXIS));
1910 }
1911 
1913 {
1914  unifyBoundingBox(MovePlugin::ALL_AXIS);
1915 }
1916 
1918 {
1919  bool useCommonBB = false;
1920  ACG::Vec3d bb_min = ACG::Vec3d(FLT_MAX,FLT_MAX,FLT_MAX);
1921  ACG::Vec3d bb_max = ACG::Vec3d(FLT_MIN,FLT_MIN,FLT_MIN);
1922 
1923  if ( PluginFunctions::targetCount() > 1 ) {
1924  if ( OpenFlipper::Options::gui()) {
1925  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);
1926 
1927 
1928  useCommonBB = ( button == QMessageBox::Yes );
1929  }
1930 
1931 
1932  if ( useCommonBB ) {
1933 
1934  // Compute cog for all objects
1936  ACG::Vec3d bb_min_tmp(0.0,0.0,0.0);
1937  ACG::Vec3d bb_max_tmp(0.0,0.0,0.0);
1938 
1939  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1940  TriMesh& mesh = *PluginFunctions::triMesh(*o_it);
1941  getBB(mesh,bb_min_tmp,bb_max_tmp);
1942  bb_min.minimize(bb_min_tmp);
1943  bb_max.maximize(bb_max_tmp);
1944  }
1945 
1946  if ( o_it->dataType( DATA_POLY_MESH )) {
1947  PolyMesh& mesh = *PluginFunctions::polyMesh(*o_it);
1948  getBB(mesh,bb_min_tmp,bb_max_tmp);
1949  bb_min.minimize(bb_min_tmp);
1950  bb_max.maximize(bb_max_tmp);
1951  }
1952 
1953 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1954  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1955  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(*o_it);
1956  getBB(mesh,bb_min_tmp,bb_max_tmp);
1957  bb_min.minimize(bb_min_tmp);
1958  bb_max.maximize(bb_max_tmp);
1959  }
1960 #endif
1961 
1962 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1963  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1965  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1966  bb_min.minimize(bb_min_tmp);
1967  bb_max.maximize(bb_max_tmp);
1968  }
1969 #endif
1970 
1971 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1972  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1974  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1975  bb_min.minimize(bb_min_tmp);
1976  bb_max.maximize(bb_max_tmp);
1977  }
1978 #endif
1979 
1980 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1981  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1983  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1984  bb_min.minimize(bb_min_tmp);
1985  bb_max.maximize(bb_max_tmp);
1986  }
1987 #endif
1988  }
1989  }
1990 
1991  }
1992 
1994  if ( useCommonBB ) {
1995  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1996  unifyBB(*PluginFunctions::triMesh(*o_it),bb_min,bb_max, u);
1997  else if ( o_it->dataType( DATA_POLY_MESH ) )
1998  unifyBB(*PluginFunctions::polyMesh(*o_it),bb_min,bb_max, u);
1999 #ifdef ENABLE_TSPLINEMESH_SUPPORT
2000  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
2001  unifyBB(*PluginFunctions::tsplineMesh(*o_it),bb_min,bb_max, u);
2002 #endif
2003 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
2004  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
2005  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(*o_it),(PluginFunctions::hexahedralMeshObject(*o_it)->normals()),bb_min,bb_max, u);
2006 #endif
2007 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
2008  else if ( o_it->dataType( DATA_TETRAHEDRAL_MESH ) )
2009  unifyBBVolumeMesh(*PluginFunctions::tetrahedralMesh(*o_it),(PluginFunctions::tetrahedralMeshObject(*o_it)->normals()),bb_min,bb_max, u);
2010 #endif
2011 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
2012  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
2013  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(*o_it),(PluginFunctions::polyhedralMeshObject(*o_it)->normals()),bb_min,bb_max, u);
2014 #endif
2015  } else {
2016  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
2017  unifyBB(*PluginFunctions::triMesh(*o_it), u);
2018  else if ( o_it->dataType( DATA_POLY_MESH ) )
2019  unifyBB(*PluginFunctions::polyMesh(*o_it), u);
2020 #ifdef ENABLE_TSPLINEMESH_SUPPORT
2021  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
2022  unifyBB(*PluginFunctions::tsplineMesh(*o_it), u);
2023 #endif
2024 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
2025  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
2026  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(*o_it),(PluginFunctions::hexahedralMeshObject(*o_it)->normals()), u);
2027 #endif
2028 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
2029  else if ( o_it->dataType( DATA_TETRAHEDRAL_MESH ) )
2030  unifyBBVolumeMesh(*PluginFunctions::tetrahedralMesh(*o_it),(PluginFunctions::tetrahedralMeshObject(*o_it)->normals()), u);
2031 #endif
2032 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
2033  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
2034  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(*o_it),(PluginFunctions::polyhedralMeshObject(*o_it)->normals()), u);
2035 #endif
2036  }
2037 
2038  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
2039 
2040  }
2041 
2042  emit updateView();
2043 }
2044 
2045 
2046 //------------------------------------------------------------------------------
2047 
2052 
2053  BaseObjectData* object;
2055  return;
2056  }
2057 
2058  if ( object->manipulatorNode()->visible() ) {
2059 
2060  // Get properties widget that corresponds to
2061  // to the last manipulated object
2062  movePropsWidget* pW = getDialogWidget(object);
2063 
2064  // If there's no properties dialog yet...
2065  if(pW == 0) return;
2066 
2067  const TriMesh::Point pos = object->manipulatorNode()->center();
2068 
2069  QString num;
2070 
2071  num = QString::number(pos[0]); pW->posx->setText(num);
2072  num = QString::number(pos[1]); pW->posy->setText(num);
2073  num = QString::number(pos[2]); pW->posz->setText(num);
2074 
2075  TriMesh::Point direction = object->manipulatorNode()->directionX();
2076  num = QString::number(direction[0]); pW->dirxx->setText(num);
2077  num = QString::number(direction[1]); pW->dirxy->setText(num);
2078  num = QString::number(direction[2]); pW->dirxz->setText(num);
2079 
2080  direction = object->manipulatorNode()->directionY();
2081  num = QString::number(direction[0]); pW->diryx->setText(num);
2082  num = QString::number(direction[1]); pW->diryy->setText(num);
2083  num = QString::number(direction[2]); pW->diryz->setText(num);
2084 
2085  direction = object->manipulatorNode()->directionZ();
2086  num = QString::number(direction[0]); pW->dirzx->setText(num);
2087  num = QString::number(direction[1]); pW->dirzy->setText(num);
2088  num = QString::number(direction[2]); pW->dirzz->setText(num);
2089 
2090  }
2091 }
2092 
2093 //------------------------------------------------------------------------------
2094 
2100 
2101  for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
2102  it != propsWindows_.end(); ++it) {
2103  if ( (*it)->getBaseObjectDataId() == _obj->id() )
2104  return *it;
2105  }
2106  return 0;
2107 }
2108 //------------------------------------------------------------------------------
2109 
2114 void MovePlugin::slotSetMoveMode(QAction* _action) {
2115 
2116  if (_action == moveAction_){
2117  PluginFunctions::actionMode(Viewer::PickingMode);
2118  PluginFunctions::pickMode("Move");
2119 
2120  moveAction_->setChecked( true );
2121  }
2122 
2123  if (_action == moveSelectionAction_){
2124 
2125  PluginFunctions::actionMode(Viewer::PickingMode);
2126  PluginFunctions::pickMode("MoveSelection");
2127 
2128  moveSelectionAction_->setChecked( true );
2129  }
2130 }
2131 
2132 //------------------------------------------------------------------------------
2133 
2140 {
2141 
2142  if (_action == rotateTranslateAction_)
2143  {
2144  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
2145  }
2146 
2147  if (_action == rotateManipAction_)
2148  {
2149  setManipMode (QtTranslationManipulatorNode::LocalRotation);
2150  }
2151 
2152  if (_action == placeAndSnapAction_)
2153  {
2154  setManipMode(QtTranslationManipulatorNode::Place);
2155  }
2156 
2157  if (_action == resizeAction_)
2158  {
2159  setManipMode(QtTranslationManipulatorNode::Resize);
2160  }
2161 
2162  if (_action == biggerManipAction_)
2163  {
2166  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2167  emit nodeVisibilityChanged (-1);
2168  }
2169 
2170  if (_action == smallerManipAction_)
2171  {
2174  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2175  emit nodeVisibilityChanged (-1);
2176  }
2177 }
2178 
2179 
2180 //------------------------------------------------------------------------------
2181 
2188  ACG::Matrix4x4d matrix;
2189  matrix.identity();
2190 
2191  BaseObjectData* object;
2193  if ( object->manipulatorNode()->visible() ) {
2194  matrix = object->manipulatorNode()->matrix();
2195  if (_reset)
2196  object->manipulatorNode()->loadIdentity();
2197  }
2198  return matrix;
2199 }
2200 
2201 
2202 //------------------------------------------------------------------------------
2203 
2212 template< typename MeshT >
2213 void MovePlugin::transformMesh(ACG::Matrix4x4d _mat , MeshT& _mesh ) {
2214  // Get the inverse matrix of the transformation for the normals
2215  ACG::Matrix4x4d invTranspMat = _mat;
2216 
2217  // Build inverse transposed matrix of _mat
2218  invTranspMat.invert();
2219  invTranspMat.transpose();
2220 
2221  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2222  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2223  for (; v_it!=v_end; ++v_it) {
2224 
2225  // transform the mesh vertex
2226  _mesh.set_point(*v_it,_mat.transform_point(_mesh.point(*v_it)));
2227 
2228  // transform the vertex normal
2229  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*v_it));
2230 
2231  n.normalize();
2232 
2233  _mesh.set_normal(*v_it,n);
2234  }
2235 
2236  typename MeshT::FaceIter f_it = _mesh.faces_begin();
2237  typename MeshT::FaceIter f_end = _mesh.faces_end();
2238  for (; f_it != f_end; ++f_it) {
2239 
2240  // transform the face normal
2241  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*f_it));
2242 
2243  n.normalize();
2244 
2245  _mesh.set_normal(*f_it,n);
2246  }
2247 }
2248 
2249 
2250 //------------------------------------------------------------------------------
2251 
2252 #ifdef ENABLE_POLYLINE_SUPPORT
2253 
2259 template< class PolyLineT >
2260 void MovePlugin::transformPolyLine( ACG::Matrix4x4d _mat , PolyLineT& _polyLine ) {
2261  #ifdef USE_OPENMP
2262  #pragma omp parallel for
2263  #endif
2264  for ( int i = 0 ; i < (int)_polyLine.n_vertices(); ++i )
2265  _polyLine.point(i) = _mat.transform_point( _polyLine.point(i) );
2266 }
2267 
2268 #endif
2269 
2270 
2271 //------------------------------------------------------------------------------
2272 
2273 #ifdef ENABLE_SKELETON_SUPPORT
2274 
2280 void MovePlugin::transformSkeleton( ACG::Matrix4x4d _mat , Skeleton& _skeleton ) {
2281 
2282  SkeletonTransform transformer(_skeleton);
2283  transformer.transformSkeleton(_mat);
2284 }
2285 
2286 #endif
2287 
2288 #if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
2289 
2298 template< typename VolumeMeshT >
2299 void MovePlugin::transformVolumeMesh(ACG::Matrix4x4d _mat , VolumeMeshT& _mesh , OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib )
2300 {
2301  // Get the inverse matrix of the transformation for the normals
2302  ACG::Matrix4x4d invTranspMat = _mat;
2303 
2304  // Build inverse transposed matrix of _mat
2305  invTranspMat.invert();
2306  invTranspMat.transpose();
2307 
2308  OpenVolumeMesh::VertexIter v_begin = _mesh.vertices_begin();
2309  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2310 
2311  // transform the mesh vertices
2312  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2313  _mesh.set_vertex(*v_it, _mat.transform_point(_mesh.vertex(*v_it)));
2314 
2315  // transform the vertex normals
2316  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2317  _normalAttrib[*v_it] = invTranspMat.transform_vector(_normalAttrib[*v_it]).normalized();
2318 
2319 
2320  // transform the face normals
2321  OpenVolumeMesh::FaceIter f_begin = _mesh.faces_begin();
2322  OpenVolumeMesh::FaceIter f_end = _mesh.faces_end();
2323  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
2324  _normalAttrib[*f_it] = invTranspMat.transform_vector(_normalAttrib[*f_it]).normalized();
2325 }
2326 
2327 //------------------------------------------------------------------------------
2328 
2333 template< typename VolumeMeshT >
2334 ACG::Vec3d MovePlugin::cogVolumeMesh( VolumeMeshT& _mesh )
2335 {
2336  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
2337  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2338  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2339  for (; v_it!=v_end; ++v_it)
2340  cog += _mesh.vertex(*v_it);
2341 
2342  return cog/(double)_mesh.n_vertices();
2343 }
2344 
2345 //------------------------------------------------------------------------------
2346 
2353 template< typename VolumeMeshT >
2354 void MovePlugin::getBBVolumeMesh( VolumeMeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max)
2355 {
2356  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2357  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2358 
2359  // no vertices?
2360  if( v_it == v_end) return;
2361 
2362  _bb_min = _mesh.vertex(*v_it);
2363  _bb_max = _mesh.vertex(*v_it);
2364 
2365  for(; v_it!=v_end; ++v_it)
2366  {
2367  _bb_min.minimize( _mesh.vertex(*v_it));
2368  _bb_max.maximize( _mesh.vertex(*v_it));
2369  }
2370 }
2371 
2372 //------------------------------------------------------------------------------
2373 
2379 template< typename VolumeMeshT >
2380 void MovePlugin::unifyBBVolumeMesh(VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, Unificationtype u)
2381 {
2382  // no vertices?
2383  if( _mesh.n_vertices() == 0) return;
2384 
2385  ACG::Vec3d bb_min, bb_max;
2386  getBBVolumeMesh( _mesh, bb_min, bb_max );
2387 
2388  unifyBBVolumeMesh( _mesh, _normalAttrib, bb_min, bb_max, u );
2389 }
2390 
2391 //------------------------------------------------------------------------------
2392 
2401 template< typename VolumeMeshT >
2402 void MovePlugin::unifyBBVolumeMesh( VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max, Unificationtype u)
2403 {
2404  ACG::Vec3d bb_center = 0.5 * (_bb_min + _bb_max) ;
2405  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2406  double bb_longestAxis = bb_diagonal.max();
2407 
2408  ACG::Vec3d scale;
2409  switch(u)
2410  {
2411  case MovePlugin::DIAGONAL :
2412  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2413  break;
2414  case MovePlugin::LONGEST_AXIS :
2415  scale = ACG::Vec3d(1.0/(bb_longestAxis));
2416  break;
2417  case MovePlugin::ALL_AXIS :
2418  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2419  break;
2420  default:
2421  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2422  }
2423 
2424 
2425  for( OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2426  _mesh.set_vertex(*v_it, (_mesh.vertex(*v_it) - bb_center) * scale + bb_center);
2427 
2428  _normalAttrib.update_vertex_normals();
2429 }
2430 
2431 #endif
2432 
2433 //------------------------------------------------------------------------------
2434 
2440 template< typename MeshT >
2441 void MovePlugin::unifyBB(MeshT& _mesh , Unificationtype u)
2442 {
2443  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2444  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2445 
2446  // no vertices?
2447  if( v_it == v_end) return;
2448 
2449  typename MeshT::Point bb_min = _mesh.point(*v_it);
2450  typename MeshT::Point bb_max = _mesh.point(*v_it);
2451 
2452  for(; v_it!=v_end; ++v_it)
2453  {
2454  bb_min.minimize( _mesh.point(*v_it));
2455  bb_max.maximize( _mesh.point(*v_it));
2456  }
2457 
2458  typename MeshT::Point bb_center = 0.5 * (bb_min + bb_max) ;
2459  ACG::Vec3d bb_diagonal = bb_max-bb_min;
2460  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2461 
2462  ACG::Vec3d scale;
2463  switch(u)
2464  {
2465  case MovePlugin::DIAGONAL :
2466  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2467  break;
2468  case MovePlugin::LONGEST_AXIS :
2469  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2470  break;
2471  case MovePlugin::ALL_AXIS :
2472  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2473  break;
2474  default:
2475  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2476  }
2477 
2478  for( v_it = _mesh.vertices_begin(); v_it!=v_end; ++v_it)
2479  {
2480 
2481  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2482  }
2483 
2484  _mesh.update_normals();
2485 
2486 }
2487 
2494 template< typename MeshT >
2495 void MovePlugin::getBB( MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max )
2496 {
2497  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2498  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2499 
2500  // no vertices?
2501  if( v_it == v_end) return;
2502 
2503  _bb_min = _mesh.point(*v_it);
2504  _bb_max = _mesh.point(*v_it);
2505 
2506  for(; v_it!=v_end; ++v_it)
2507  {
2508  _bb_min.minimize( _mesh.point(*v_it));
2509  _bb_max.maximize( _mesh.point(*v_it));
2510  }
2511 
2512 
2513 }
2514 
2522 template< typename MeshT >
2523 void MovePlugin::unifyBB(MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max , Unificationtype u)
2524 {
2525 
2526  typename MeshT::Point bb_center = 0.5 * (_bb_min + _bb_max) ;
2527  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2528  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2529  ACG::Vec3d scale;
2530  switch(u)
2531  {
2532  case MovePlugin::DIAGONAL :
2533  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2534  break;
2535  case MovePlugin::LONGEST_AXIS :
2536  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2537  break;
2538  case MovePlugin::ALL_AXIS :
2539  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2540  break;
2541  default:
2542  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2543  }
2544 
2545  typename MeshT::VertexIter v_it;
2546 
2547  for( v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2548  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2549 
2550  _mesh.update_normals();
2551 
2552 }
2553 
2554 
2555 //------------------------------------------------------------------------------
2556 
2561 
2562  bool functionExistsMeshV;
2563  emit functionExists("meshobjectselection", "vertexTypeActive()", functionExistsMeshV);
2564  bool functionExistsMeshE;
2565  emit functionExists("meshobjectselection", "edgeTypeActive()", functionExistsMeshE);
2566  bool functionExistsMeshF;
2567  emit functionExists("meshobjectselection", "faceTypeActive()", functionExistsMeshF);
2568 
2569  bool connected = false;
2570  selectionType_ = 0u;
2571 
2572  if(functionExistsMeshV && functionExistsMeshE && functionExistsMeshF) {
2573 
2574  connected = true;
2575 
2576  // Make RPC call
2577  if(RPC::callFunctionValue<bool>("meshobjectselection", "vertexTypeActive")) {
2578  selectionType_ |= VERTEX;
2579  }
2580  if(RPC::callFunctionValue<bool>("meshobjectselection", "edgeTypeActive")) {
2581  selectionType_ |= EDGE;
2582  }
2583  if(RPC::callFunctionValue<bool>("meshobjectselection", "faceTypeActive")) {
2584  selectionType_ |= FACE;
2585  }
2586 
2587  }
2588 
2589 #if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
2590  bool functionExistsVolumeMeshV;
2591  emit functionExists("volumemeshselection", "vertexTypeActive()", functionExistsVolumeMeshV);
2592  bool functionExistsVolumeMeshE;
2593  emit functionExists("volumemeshselection", "edgeTypeActive()", functionExistsVolumeMeshE);
2594  bool functionExistsVolumeMeshF;
2595  emit functionExists("volumemeshselection", "faceTypeActive()", functionExistsVolumeMeshF);
2596  bool functionExistsVolumeMeshC;
2597  emit functionExists("volumemeshselection", "cellTypeActive()", functionExistsVolumeMeshC);
2598 
2599  if ( functionExistsVolumeMeshV && functionExistsVolumeMeshE && functionExistsVolumeMeshF && functionExistsVolumeMeshC) {
2600 
2601  connected = true;
2602 
2603  // Make RPC call
2604  if(RPC::callFunctionValue<bool>("volumemeshselection", "vertexTypeActive")) {
2605  selectionType_ |= VERTEX;
2606  }
2607  if(RPC::callFunctionValue<bool>("volumemeshselection", "edgeTypeActive")) {
2608  selectionType_ |= EDGE;
2609  }
2610  if(RPC::callFunctionValue<bool>("volumemeshselection", "faceTypeActive")) {
2611  selectionType_ |= FACE;
2612  }
2613  if(RPC::callFunctionValue<bool>("volumemeshselection", "cellTypeActive")) {
2614  selectionType_ |= CELL;
2615  }
2616  }
2617 #endif
2618 
2619  if (!connected) {
2620  emit log(LOGWARN, tr("Unable to connect to Selection-Plugin. MoveSelection will work on vertices only."));
2621  selectionType_ = VERTEX;
2622  }
2623 }
2624 
2625 //------------------------------------------------------------------------------
2626 
2632 void MovePlugin::setAllTargets(bool _state) {
2633  allTargets_ = _state;
2634 }
2635 
2636 //--------------------------------------------------------------------------------
2637 
2641 template< typename MeshType >
2642 OpenMesh::Vec3d MovePlugin::getNearestVertex(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2643 
2644  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2645 
2646  if ( !fh.is_valid() )
2647  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2648 
2649  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2650  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2651  typename MeshType::Scalar shortest_distance = (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2652  typename MeshType::VertexHandle vh = *fv_it;
2653 
2654  for (; fv_it.is_valid(); ++fv_it) {
2655 
2656  typename MeshType::Scalar tmpdist =
2657  (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2658 
2659  if(tmpdist < shortest_distance) {
2660  shortest_distance = tmpdist;
2661  vh = *fv_it;
2662  }
2663  }
2664 
2665  return (OpenMesh::Vec3d)_mesh->point(vh);
2666 }
2667 
2668 //--------------------------------------------------------------------------------
2669 
2673 template< typename MeshType >
2674 OpenMesh::Vec3d MovePlugin::getNearestEdge(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2675 
2676  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2677 
2678  if (!fh.is_valid())
2679  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2680 
2681  typename MeshType::FaceEdgeIter fe_it(*_mesh, fh);
2682  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2683 
2684  typename MeshType::Point center;
2685  typename MeshType::Scalar closest_dist(-1);
2686 
2687  for (; fe_it.is_valid(); ++fe_it) {
2688 
2689  typename MeshType::HalfedgeHandle heh0 = _mesh->halfedge_handle(*fe_it, 0);
2690  typename MeshType::HalfedgeHandle heh1 = _mesh->halfedge_handle(*fe_it, 1);
2691 
2692  typename MeshType::Point lp0 = _mesh->point(_mesh->to_vertex_handle(heh0));
2693  typename MeshType::Point lp1 = _mesh->point(_mesh->to_vertex_handle(heh1));
2694 
2695  double dist_new = ACG::Geometry::distPointLineSquared( hitPointP, lp0, lp1);
2696 
2697  /*typename MeshType::Point b(hitPointP - lp0), a(((lp1 - lp0).sqrnorm()));
2698  typename MeshType::Scalar d = b|a;
2699  typename MeshType::Point x = lp0 + a * d;
2700  double dist_new = (hitPointP - x).length();*/
2701 
2702  if (dist_new < closest_dist || closest_dist == -1) {
2703  // save closest Edge
2704  closest_dist = dist_new;
2705  center = lp0 + (lp1 - lp0) * .5;
2706 
2707  }
2708  }
2709 
2710  return (OpenMesh::Vec3d)center;
2711 }
2712 
2713 //--------------------------------------------------------------------------------
2714 
2718 template< typename MeshType >
2719 OpenMesh::Vec3d MovePlugin::getNearestFace(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2720 
2721  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2722 
2723  if ( !fh.is_valid() )
2724  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2725 
2726  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2727 
2728  typename MeshType::Point cog(0.0,0.0,0.0);
2729  uint count = 0;
2730 
2731  for (; fv_it.is_valid(); ++fv_it) {
2732 
2733  cog += _mesh->point(*fv_it);
2734  ++count;
2735  }
2736 
2737  return (OpenMesh::Vec3d)cog/count;
2738 }
2739 
2740 //--------------------------------------------------------------------------------
2741 
2742 void MovePlugin::slotAllCleared(){
2743  activeManipulators_.clear();
2744 }
2745 
2746 //--------------------------------------------------------------------------------
2747 
2748 void MovePlugin::objectDeleted( int _id ){
2749 
2750  for (uint i=0; i < activeManipulators_.size(); i++)
2751  if ( activeManipulators_[i] == _id ){
2752  activeManipulators_.erase( activeManipulators_.begin() + i );
2753  return;
2754  }
2755 }
2756 
2757 //--------------------------------------------------------------------------------
2758 
2759 
bool invert()
matrix inversion (returns true on success)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:563
bool toolboxActive_
True if the toolbox widget is active.
Definition: MovePlugin.hh:256
bool is_identity() const
check if the matrix is the identity ( up to an epsilon )
Definition: Matrix4x4T.hh:214
void placeManip(QMouseEvent *_event, bool _snap=false)
Place and show the Manipulator.
Definition: MovePlugin.cc:863
Plane * plane(BaseObjectData *_object)
Get a Plane from an object.
bool transformCellSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
bool transformFaceSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
ViewObjectMarker * defaultViewObjectMarker()
Get the default ViewObjectMarker.
QAction * resizeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:296
void slotEnableSelectionMode()
stores the current axes in the tool
Definition: MovePlugin.cc:476
int axisB_
stores the current axes in the tool
Definition: MovePlugin.hh:196
QAction * biggerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:298
#define DATA_SKELETON
Definition: Skeleton.hh:64
QString generateLink(const QString &_ref="", const QString &_site="index.html") const
generates a clickable link to the documentation for whatsThis Messages
void slotToggleAxisB()
Toggle the second axis for changing direction in tab.
Definition: MovePlugin.cc:1127
void setDescriptions()
Set Descriptions for scriptable functions.
virtual const std::string & className() const =0
Return class name (implemented by the ACG_CLASSNAME macro)
void updateSelectionType()
Get current primitive selection.
Definition: MovePlugin.cc:2560
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
QActionGroup * pickToolBarActions_
Called by pick Toolbar.
Definition: MovePlugin.hh:307
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
bool visible()
Is node visible (status == Active)?
QAction * placeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:293
QAction * contextMenuManipControlsAction_
Action holding the context menu for toolbar replication.
Definition: MovePlugin.hh:491
bool manipPlaced()
Check if the manipulator has been placed.
int id() const
Definition: BaseObject.cc:190
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void transformSkeleton(Matrix4x4 _transformation, Skeleton::Pose *_pose=0)
transform the skeleton
void updateManipulatorDialog()
Update the Dialog with the last clicked manipulator.
Definition: MovePlugin.cc:2051
ManipulatorMode
enum to define the manipulator mode
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
void setPickModeProps(movePropsWidget *_pW, const std::string &_pickmode)
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.cc:495
void moveSelection(ACG::Matrix4x4d mat, int _id, QEvent::Type _type)
Move selection on an object with given id.
Definition: MovePlugin.cc:638
moveToolbarWidget * tool_
Widget for Toolbox.
Definition: MovePlugin.hh:259
void slotSetPosition()
Position of manipulator in tab changed.
Definition: MovePlugin.cc:1032
MovePlugin()
Default Constructor.
Definition: MovePlugin.cc:82
void slotToggleAxisA()
Toggle the first axis for changing direction in tab.
Definition: MovePlugin.cc:1102
Unificationtype
stores the current axes in the tool
Definition: MovePlugin.hh:198
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
TetrahedralMeshObject * tetrahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an TetrahedralMeshObject if possible.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x&#39;,y&#39;,z&#39;,1) = M * (x,y,z,1)
movePropsWidget * getDialogWidget(BaseObjectData *_obj)
Get properties dialog widget that is attached to BaseDataObject obj.
Definition: MovePlugin.cc:2099
QtTranslationManipulatorNode::ManipulatorMode manMode_
Holds the current manipulator mode.
Definition: MovePlugin.hh:423
void translate(int _objectId, Vector _vector)
translate an Object by a given vector
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
void transpose()
transpose matrix
const QStringList ALL_OBJECTS
Iterable object range.
void showManipulators()
Checks if the manipulators should be visible or not.
Definition: MovePlugin.cc:978
void setManipMode(QtTranslationManipulatorNode::ManipulatorMode _mode)
Set the manipulator manipulation mode.
Definition: MovePlugin.cc:671
void showProps()
Show properties of move manipulator in a dialog ( Called via context for picking. Get the picked id f...
void slotSetDirection()
Set Direction of manipulator in tab changed.
Definition: MovePlugin.cc:1152
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:290
double manip_size_
Size for the manipulators.
Definition: MovePlugin.hh:400
QToolBar * pickToolbar_
Called by pick Toolbar.
Definition: MovePlugin.hh:291
bool transformedSelected_
stores if any selected elements where transformed
Definition: MovePlugin.hh:617
#define DATA_TETRAHEDRAL_MESH
QList< movePropsWidget * > propsWindows_
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.hh:476
QAction * moveAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:271
OpenMesh::Vec3d getNearestFace(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest face to hitpoint.
Definition: MovePlugin.cc:2719
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
int axisA_
stores the current axes in the tool
Definition: MovePlugin.hh:195
#define DATA_PLANE
Definition: Plane.hh:58
void slotMoveToOrigin()
Move target Meshes cog to the origin.
Definition: MovePlugin.cc:1729
MoveObjectMarker objectMarker_
Object marker to dimm Objects during manipulator transformation.
Definition: MovePlugin.hh:418
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
void transformMesh(ACG::Matrix4x4d _mat, MeshT &_mesh)
Transform a mesh with the given transformation matrix.
Definition: MovePlugin.cc:2213
Skeleton transformation class.
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void getBB(MeshT &_mesh, ACG::Vec3d &_bb_min, ACG::Vec3d &_bb_max)
get bounding box diagonal of a mesh
Definition: MovePlugin.cc:2495
void update_vertex_normals()
A simple heuristic to estimate the vertex normals.
QActionGroup * toolBarActions_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:274
const NormalAttrib & normals() const
return a pointer to the mesh
void slotScale()
Scale (with values from Tab)
Definition: MovePlugin.cc:1578
void transform(const ACG::Matrix4x4d &_mat)
Transform the plane with given matrix.
Definition: PlaneType.cc:89
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
QAction * toAllTargets_
Checked if transformation should be applied to all target objs.
Definition: MovePlugin.hh:485
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void slotProjectToTangentPlane()
Project the current manipulator onto the tangent plane of the object.
Definition: MovePlugin.cc:1338
QAction * placeAndSnapAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:305
void slotEnableObjectMode()
stores the current axes in the tool
Definition: MovePlugin.cc:482
QAction * contextAction_
Context menu entry for showing per manipulator settings.
Definition: MovePlugin.hh:479
const GLMatrixd & matrix() const
Returns a const reference to the current transformation matrix.
void unifyBB(MeshT &_mesh, Unificationtype u=MovePlugin::DIAGONAL)
scale mesh to have a boundingboxdiagonal of one
Definition: MovePlugin.cc:2441
void moveObject(ACG::Matrix4x4d mat, int _id)
Move an object with given id.
Definition: MovePlugin.cc:574
QAction * rotateTranslateAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:294
#define DATA_HEXAHEDRAL_MESH
bool transformVertexSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
#define DATA_POLY_LINE
Definition: PolyLine.hh:64
QAction * smallerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:299
void slotUnifyBoundingBoxLongestAxis()
Scale Boundingbox longest axis to unit size (keeps aspect ratio)
Definition: MovePlugin.cc:1907
QAction * contextActionHide_
Context menu entry to hide a manipulator.
Definition: MovePlugin.hh:482
void ManipulatorPositionChanged(QtTranslationManipulatorNode *_node)
update object when its manipulator changes position
Definition: MovePlugin.cc:832
The Menu will be shown when a node was picked.
void slotTranslation()
perform a translation for Manipulator in tab
Definition: MovePlugin.cc:1233
QAction * rotateManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:295
bool transformEdgeSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
QIcon * toolIcon_
stores the current axes in the tool
Definition: MovePlugin.hh:261
const VecT & vertex(const VertexHandle &_vh) const
Get point _vh&#39;s coordinates.
int getIdentifier()
Get an identifier for that manipulator.
void translateFaceSelection(int _objectId, Vector _vector)
translate current face selection of an Object by a given vector
~MovePlugin()
Destructor.
Definition: MovePlugin.cc:125
void manipulatorMoved(QtTranslationManipulatorNode *_node, QMouseEvent *_event)
move the object when its manipulator moves
Definition: MovePlugin.cc:774
void slotMoveManipToCOG()
Move the current manipulator to the cog of the object.
Definition: MovePlugin.cc:1360
movePropsWidget * getDialogFromButton(QPushButton *_but)
Get parent properties dialog widget of QPushButton but.
Definition: MovePlugin.cc:1022
QToolBar * toolbar_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:276
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:535
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
double manip_size_modifier_
Modifier for the Size (changed by Mousewheel Events)
Definition: MovePlugin.hh:403
void identity()
setup an identity matrix
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:77
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
#define DATA_POLYHEDRAL_MESH
void hideManipulator()
Hide the manipulator( Called via context for picking. Get the picked id from the Qvariant attached to...
PolyLine * polyLine(BaseObjectData *_object)
Get a poly Line from an object.
void setViewObjectMarker(ViewObjectMarker *_marker)
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
void setAllTargets(bool _state)
Sets whether all targets should be affected or not.
Definition: MovePlugin.cc:2632
OpenMesh::Vec3d getNearestEdge(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest edge to hitpoint.
Definition: MovePlugin.cc:2674
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
void slotPickToolbarAction(QAction *_action)
Called by pick Toolbar.
Definition: MovePlugin.cc:2139
void slotUnifyBoundingBoxDiagonal()
Scale Boundingbox Diagonal to unit size.
Definition: MovePlugin.cc:1902
Viewer::ActionMode actionMode()
Get the current Action mode.
SelectionType selectionType_
Current SelectionType of SelectionPlugin.
Definition: MovePlugin.hh:435
ACG::Matrix4x4d getLastManipulatorMatrix(bool _reset=true)
Get the Matrix of the last active Manipulator ( Identity if not found or hidden Manipulator ) ...
Definition: MovePlugin.cc:2187
OpenMesh::Vec3d getNearestVertex(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest vertex to hitpoint.
Definition: MovePlugin.cc:2642
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
void slotUpdateContextMenuNode(int _nodeId)
Hide context menu entry when right clicking on node other than manipulator node.
Definition: MovePlugin.cc:753
std::vector< int > activeManipulators_
Size for the manipulators.
Definition: MovePlugin.hh:323
void translateEdgeSelection(int _objectId, Vector _vector)
translate current edge selection of an Object by a given vector
int lastActiveManipulator_
Stores the last manipulator which has been clicked ( used for the toolbox dialog) ...
Definition: MovePlugin.hh:406
int targetCount()
Get the number of target objects.
void slotSetMoveMode(QAction *_action)
Called by Toolbar to enable move mode.
Definition: MovePlugin.cc:2114
MeshT * mesh()
return a pointer to the mesh
void slotRotate()
Rotate Manipulator (with values from Tab)
Definition: MovePlugin.cc:1422
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x&#39;,y&#39;,z&#39;,0) = A * (x,y,z,0)
void set_vertex(const VertexHandle &_vh, const VecT &_p)
Set the coordinates of point _vh.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
const Vec3d & center() const
get center
void traverse(ACG::SceneGraph::MouseEventAction &_action)
void unifyBoundingBox(Unificationtype u)
Size for the manipulators.
Definition: MovePlugin.cc:1917
void translateVertexSelection(int _objectId, Vector _vector)
translate current vertex selection of an Object by a given vector
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
void slotPickModeChanged(const std::string &_mode)
slot is called when the pickMode changed
Definition: MovePlugin.cc:525
void slotMouseEvent(QMouseEvent *_event)
MousePress event occured.
Definition: MovePlugin.cc:400
QtTranslationManipulatorNode * manipulatorNode()
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
QMenu * contextMenuManipControl_
Additional Context Menu replicating the toolbar stuff.
Definition: MovePlugin.hh:488
const std::string pickMode()
Get the current Picking mode.
void slotUnifyBoundingBoxAllAxis()
Scale all Boundingbox axis to unit size.
Definition: MovePlugin.cc:1912
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
Definition: MovePlugin.cc:156
Scalar max() const
return the maximal component
Definition: Vector11T.hh:493
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
QAction * moveSelectionAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:272