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->angleDelta().y() / 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 
399 void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
400  if (((PluginFunctions::pickMode() == ("Move"))
401  || (PluginFunctions::pickMode() == ("MoveSelection")))
402  && PluginFunctions::actionMode() == Viewer::PickingMode) {
403 
404  if (_event->type() == QEvent::MouseButtonDblClick || (_event->type() == QEvent::MouseButtonPress
405  && _event->button() == Qt::LeftButton && (placeAction_->isChecked() || placeMode_))) {
406 
407  bool snap = (placeMode_ && (PluginFunctions::pickMode() == ("MoveSelection")));
408 
409  placeManip(_event, snap);
410  placeAction_->setChecked(false);
412 
413  if (placeMode_) {
414  manMode_ = QtTranslationManipulatorNode::TranslationRotation;
415 
417  if (o_it->manipPlaced())
418  o_it->manipulatorNode()->setMode(manMode_);
419 
420  resizeAction_->setChecked(false);
421  rotateManipAction_->setChecked(false);
422  rotateTranslateAction_->setChecked(true);
423  placeAndSnapAction_->setChecked(false);
424  }
425 
426  placeMode_ = false;
427  return;
428 
429  } else if (placeMode_) {
430 
431  /*
432  * Move manipulator along with cursor if placeAndSnap mode
433  * is active. Snap to nearest geometry element (vertex, line, face center)
434  * depending on which selection type is active.
435  *
436  */
437 
438  placeManip(_event, (PluginFunctions::pickMode() != ("Move")));
440  return;
441  }
442 
443  // interaction
446 
447  if (_event->buttons() == Qt::LeftButton)
448  emit nodeVisibilityChanged(-1);
449 
450  }
451 }
452 
453 /*******************************************************************************
454  KeyInterface implementation
455  *******************************************************************************/
456 
457 void MovePlugin::slotKeyEvent (QKeyEvent* _event)
458 {
459  if ((_event->key() == Qt::Key_Control) && _event->modifiers() != Qt::ShiftModifier) {
460  setManipMode (QtTranslationManipulatorNode::Resize);
461  return;
462  } else if ((_event->key () == Qt::Key_Shift) && _event->modifiers() != Qt::ControlModifier) {
463  setManipMode (QtTranslationManipulatorNode::LocalRotation);
464  return;
465  }
466 
467  // Return to normal mode if Ctrl + Shift is pressed since this
468  // is used in translation manipulator node for rotation rasterization
469  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
470 }
471 
472 //------------------------------------------------------------------------------
473 
475 {
476  PluginFunctions::pickMode("MoveSelection");
477 }
478 
479 //------------------------------------------------------------------------------
481 {
483 }
484 //------------------------------------------------------------------------------
485 
486 void MovePlugin::slotKeyReleaseEvent (QKeyEvent* _event)
487 {
488  if ((_event->key() == Qt::Key_Control && manMode_ == QtTranslationManipulatorNode::Resize) ||
489  (_event->key() == Qt::Key_Shift && manMode_ == QtTranslationManipulatorNode::LocalRotation))
490  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
491 }
492 
493 void MovePlugin::setPickModeProps(movePropsWidget* _pW, const std::string &_pickmode)
494 {
495  if (_pickmode == "Move")
496  {
497  _pW->objectRadioButton->setChecked(true);
498  }
499  else if (_pickmode == "MoveSelection")
500  {
501  _pW->selectionRadioButton->setChecked(true);
502  }
503  else
504  {
505  //not supported, so deselect all radio buttons
506  _pW->objectRadioButton->setAutoExclusive(false);
507  _pW->selectionRadioButton->setAutoExclusive(false);
508  _pW->objectRadioButton->setChecked(false);
509  _pW->selectionRadioButton->setChecked(false);
510  _pW->objectRadioButton->setAutoExclusive(true);
511  _pW->selectionRadioButton->setAutoExclusive(true);
512  }
513 }
514 
515 /*******************************************************************************
516  PickingInterface implementation
517  *******************************************************************************/
518 
523 void MovePlugin::slotPickModeChanged( const std::string& _mode)
524 {
525  moveAction_->setChecked(_mode == "Move");
526  moveSelectionAction_->setChecked(_mode == "MoveSelection");
527 
528  hide_ = !(_mode == "Move" || _mode == "MoveSelection");
529 
531 
532  if (!hide_)
533  {
534  switch (manMode_)
535  {
536  case QtTranslationManipulatorNode::Rotation:
538  break;
539  case QtTranslationManipulatorNode::Resize:
541  break;
542  case QtTranslationManipulatorNode::LocalRotation:
544  break;
545  case QtTranslationManipulatorNode::Place:
547  break;
548  case QtTranslationManipulatorNode::TranslationRotation:
550  break;
551  }
552  }
553  else
555 
556  //change the selection mode in propety widget
557  for (int i = 0; i < propsWindows_.size(); ++i)
558  setPickModeProps(propsWindows_[i], _mode);
559 
560 }
561 
562 
563 /*******************************************************************************
564  MovePlugin implementation
565  *******************************************************************************/
566 
573  BaseObjectData* object;
574  if ( ! PluginFunctions::getObject(_id,object) )
575  return;
576 
577  if ( mat.is_identity() )
578  return;
579 
580  if ( object->dataType() == DATA_TRIANGLE_MESH ) {
581  transformMesh(mat , *PluginFunctions::triMesh(object) );
582  } else if ( object->dataType() == DATA_POLY_MESH ) {
583  transformMesh(mat , *PluginFunctions::polyMesh(object) );
584 #ifdef ENABLE_TSPLINEMESH_SUPPORT
585  } else if ( object->dataType() == DATA_TSPLINE_MESH ) {
586  transformMesh(mat , *PluginFunctions::tsplineMesh(object) );
587 #endif
588 #ifdef ENABLE_POLYLINE_SUPPORT
589  } else if ( object->dataType() == DATA_POLY_LINE ) {
590  transformPolyLine(mat , *PluginFunctions::polyLine(object) );
591 #endif
592 #ifdef ENABLE_SKELETON_SUPPORT
593  } else if ( object->dataType() == DATA_SKELETON ) {
594  transformSkeleton(mat , *PluginFunctions::skeleton(object) );
595 #endif
596 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
597  } else if ( object->dataType() == DATA_HEXAHEDRAL_MESH ) {
599  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
600 #endif
601 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
602  } else if ( object->dataType() == DATA_TETRAHEDRAL_MESH ) {
604  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
605 #endif
606 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
607  } else if ( object->dataType() == DATA_POLYHEDRAL_MESH ) {
609  transformVolumeMesh(mat , *obj->mesh() , obj->normals() );
610 #endif
611  } else if ( object->dataType() == DATA_PLANE ) {
612  PluginFunctions::plane(object)->transform(mat);
613  } else {
614 
615  emit log(LOGERR,tr("moveObject called for unsupported Object Type"));
616  return;
617  }
618 
619  emit updatedObject(_id, UPDATE_GEOMETRY);
620  emit createBackup(_id, "Move Object", UPDATE_GEOMETRY);
621 }
622 
623 
624 //------------------------------------------------------------------------------
625 
636 void MovePlugin::moveSelection(ACG::Matrix4x4d _mat, int _id, QEvent::Type _type) {
637  // Get currently active primitive type
639 
640  if ( !_mat.is_identity() ){
641  if (selectionType_ & VERTEX) {
643  }
644  if (selectionType_ & FACE) {
646  }
647  if (selectionType_ & EDGE) {
649  }
650  if (selectionType_ & CELL) {
652  }
653 
654  emit updatedObject(_id, UPDATE_GEOMETRY);
655  }
656 
657  //only create backups on mouseRelease and something has to have been selected and transformed
658  if ( _type == QEvent::MouseButtonRelease && transformedSelected_ )
659  emit createBackup(_id,"Move Selection", UPDATE_GEOMETRY);
660 
661 }
662 
663 //------------------------------------------------------------------------------
664 
670 {
671  if (_mode != manMode_)
672  {
673  manMode_ = _mode;
674 
675  // Iterate over all objects that have a placed manip and set their mode
677  if ( o_it->manipPlaced() )
678  o_it->manipulatorNode()->setMode (_mode);
679 
680 
681  if (!hide_) {
682  switch (manMode_)
683  {
684  case QtTranslationManipulatorNode::Rotation:
686  placeMode_ = false;
687  break;
688  case QtTranslationManipulatorNode::Resize:
690  placeMode_ = false;
691  break;
692  case QtTranslationManipulatorNode::LocalRotation:
694  placeMode_ = false;
695  break;
696  case QtTranslationManipulatorNode::Place:
698  placeMode_ = true;
699  break;
700  case QtTranslationManipulatorNode::TranslationRotation:
702  placeMode_ = false;
703  break;
704  }
705  }
706 
707  // Update the toolbar icons
708  switch (manMode_)
709  {
710  case QtTranslationManipulatorNode::Resize:
711  resizeAction_->setChecked (true);
712  rotateManipAction_->setChecked (false);
713  rotateTranslateAction_->setChecked (false);
714  placeAndSnapAction_->setChecked (false);
715  break;
716  case QtTranslationManipulatorNode::LocalRotation:
717  resizeAction_->setChecked (false);
718  rotateManipAction_->setChecked (true);
719  rotateTranslateAction_->setChecked (false);
720  placeAndSnapAction_->setChecked (false);
721  break;
722  case QtTranslationManipulatorNode::TranslationRotation:
723  resizeAction_->setChecked (false);
724  rotateManipAction_->setChecked (false);
725  rotateTranslateAction_->setChecked (true);
726  placeAndSnapAction_->setChecked (false);
727  break;
728  case QtTranslationManipulatorNode::Place:
729  resizeAction_->setChecked (false);
730  rotateManipAction_->setChecked (false);
731  rotateTranslateAction_->setChecked (false);
732  placeAndSnapAction_->setChecked (true);
733  break;
734  case QtTranslationManipulatorNode::Rotation:
735  resizeAction_->setChecked(false);
736  rotateManipAction_->setChecked(true);
737  rotateTranslateAction_->setChecked(false);
738  placeAndSnapAction_->setChecked(false);
739  break;
740  }
741  }
742 }
743 
744 //------------------------------------------------------------------------------
745 
746 
752 
754 
755  if (node == 0)
756  return;
757 
758  if (node->className() != "QtTranslationManipulatorNode") {
759  contextAction_->setVisible(false);
760  } else {
761  contextAction_->setVisible(true);
762  }
763 }
764 
765 //------------------------------------------------------------------------------
766 
772 void MovePlugin::manipulatorMoved( QtTranslationManipulatorNode* _node , QMouseEvent* _event) {
773 
774  // React on event only in move mode
775  if ( PluginFunctions::pickMode() != "Move"
776  && PluginFunctions::pickMode() != "MoveSelection" )
777  return;
778 
779  OpenFlipper::Options::redrawDisabled( true );
780 
781  // Apply changes only on Release for moveMode and after every movement in MoveSelection Mode
782  if ( !placeMode_ && ((_event->type() == QEvent::MouseButtonRelease) ||
783  (PluginFunctions::pickMode() != "Move" && _event->buttons() != Qt::NoButton)) ) {
784 
785  int objectId = _node->getIdentifier();
786 
787  ACG::Matrix4x4d mat;
788  mat.identity();
789  mat = _node->matrix();
790 
791  // Reset Node
792  _node->loadIdentity();
793  _node->set_center(mat.transform_point(_node->center()));
794 
795  // move the object which corresponds to the manipulator
796  if (PluginFunctions::pickMode() == "Move")
797  moveObject( mat, objectId );
798  else if (PluginFunctions::pickMode() == "MoveSelection")
799  moveSelection( mat, objectId, _event->type() );
800 
801  // move all other targets without manipulator
802  if(allTargets_) {
804  if ((o_it->id() != objectId) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
805 
806  // move the object which corresponds to the manipulator
807  if (PluginFunctions::pickMode() == "Move")
808  moveObject( mat, o_it->id() );
809  else if (PluginFunctions::pickMode() == "MoveSelection")
810  moveSelection( mat, o_it->id(), _event->type() );
811  }
812  }
813  }
814 
815  lastActiveManipulator_ = objectId;
817  }
818 
819  OpenFlipper::Options::redrawDisabled( false );
820 }
821 
822 
823 //------------------------------------------------------------------------------
824 
830 
831  // Position has been changed of the manipulator by a direct function
832  int objectId = _node->getIdentifier();
833 
834  if ( objectId > 0 ){
835 
836  BaseObjectData* object;
837  PluginFunctions::getObject(objectId,object);
838 
839  // Assume that it has a good position now
840  object->manipPlaced( true );
841  }
842 
843  // Show manipulator only if in Move mode
844  if ( PluginFunctions::pickMode() == "Move" )
845  _node->show();
846 
847  lastActiveManipulator_ = objectId;
849 
850 }
851 
852 
853 //------------------------------------------------------------------------------
854 
860 void MovePlugin::placeManip(QMouseEvent * _event, bool _snap) {
861  size_t node_idx, target_idx;
862  OpenMesh::Vec3d hitPoint;
863  BaseObjectData* object;
864 
865  bool successfullyPicked = false;
866 
867 
868 
869  /*
870  * Snap manipulator to nearest geometry
871  * element depending on which selection type is
872  * active.
873  */
874  if (_snap) {
875 
876  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx,
877  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
878 
879  if(!successfullyPicked) {
880  //emit log(LOGWARN, tr("Picking failed"));
881  return;
882  }
883 
884  if (selectionType_ == VERTEX) {
885  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
886  hitPoint = getNearestVertex(PluginFunctions::triMesh(object), target_idx, hitPoint);
887  } else if ( object->dataType(DATA_POLY_MESH) ) {
888  hitPoint = getNearestVertex(PluginFunctions::polyMesh(object), target_idx, hitPoint);
889 #ifdef ENABLE_TSPLINEMESH_SUPPORT
890  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
891  hitPoint = getNearestVertex(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
892 #endif
893  }
894  } else if (selectionType_ == EDGE) {
895  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
896  hitPoint = getNearestEdge(PluginFunctions::triMesh(object), target_idx, hitPoint);
897  } else if ( object->dataType(DATA_POLY_MESH) ) {
898  hitPoint = getNearestEdge(PluginFunctions::polyMesh(object), target_idx, hitPoint);
899 #ifdef ENABLE_TSPLINEMESH_SUPPORT
900  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
901  hitPoint = getNearestEdge(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
902 #endif
903  }
904  } else if (selectionType_ == FACE) {
905  if ( object->dataType(DATA_TRIANGLE_MESH) ) {
906  hitPoint = getNearestFace(PluginFunctions::triMesh(object), target_idx, hitPoint);
907  } else if ( object->dataType(DATA_POLY_MESH) ) {
908  hitPoint = getNearestFace(PluginFunctions::polyMesh(object), target_idx, hitPoint);
909 #ifdef ENABLE_TSPLINEMESH_SUPPORT
910  } else if ( object->dataType(DATA_TSPLINE_MESH) ) {
911  hitPoint = getNearestFace(PluginFunctions::tsplineMesh(object), target_idx, hitPoint);
912 #endif
913  }
914  }
915 
916  } else {
917  successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
918  target_idx, &hitPoint) && PluginFunctions::getPickedObject(node_idx, object);
919  }
920 
921  if (successfullyPicked) {
922 
923  object->manipPlaced(true);
924 
925  object->manipulatorNode()->loadIdentity();
926  object->manipulatorNode()->set_center(hitPoint);
927  object->manipulatorNode()->set_draw_cylinder(true);
928  object->manipulatorNode()->set_autosize(QtTranslationManipulatorNode::Once);
929  object->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
930  object->manipulatorNode()->setMode(manMode_);
931  object->manipulatorNode()->show();
932 
933  object->manipulatorNode()->apply_transformation(PluginFunctions::pickMode() == "Move");
934 
935  // Disconnect a previously connected Signal
936  disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
937  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
938 
939  disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
941 
942  // Reconnect the signals.
943  connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
944  this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
945 
946  connect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
948 
949  lastActiveManipulator_ = object->id();
950 
951  emit updateView();
952 
953  bool found = false;
954 
955  for (uint i=0; i < activeManipulators_.size(); i++)
956  if ( activeManipulators_[i] == object->id() ){
957  found = true;
958  break;
959  }
960 
961  if ( !found )
962  activeManipulators_.push_back( object->id() );
963 
964  } else {
965  //emit log(LOGWARN, tr("Picking failed"));
966  }
967 }
968 
969 
970 //------------------------------------------------------------------------------
971 
976 {
977 
978  if (!hide_ && (toolboxActive_ || (PluginFunctions::pickMode() == "Move")
979  || (PluginFunctions::pickMode() == "MoveSelection"))) {
980 
981  for (uint i=0; i < activeManipulators_.size(); i++){
982 
983  BaseObjectData* obj = 0;
984 
986 
987  if (obj != 0 && obj->manipPlaced()) {
988  obj->manipulatorNode()->show();
989  obj->manipulatorNode()->apply_transformation( PluginFunctions::pickMode() == "Move" );
990  emit nodeVisibilityChanged(obj->id());
991  }
992  }
993 
994  } else {
995 
996  for (uint i=0; i < activeManipulators_.size(); i++){
997 
998  BaseObjectData* obj = 0;
999 
1001 
1002  if ( obj != 0 ) {
1003  obj->manipulatorNode()->hide();
1004  emit nodeVisibilityChanged(obj->id());
1005  }
1006  }
1007  }
1008 
1009  emit updateView();
1010 
1011 }
1012 
1013 //------------------------------------------------------------------------------
1014 
1020 
1021  if(_but == 0) return 0;
1022  return dynamic_cast<movePropsWidget*>((((_but->parentWidget())->parentWidget())->parentWidget()));
1023 }
1024 //------------------------------------------------------------------------------
1025 
1030 
1031  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1033  if(pW == 0) return;
1034 
1035  TriMesh::Point newpos;
1036 
1037  bool ok = false;
1038  newpos[0] = (pW->nposx->text()).toDouble(&ok);
1039  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1040  newpos[1] = (pW->nposy->text()).toDouble(&ok);
1041  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1042  newpos[2] = (pW->nposz->text()).toDouble(&ok);
1043  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1044 
1045  BaseObjectData* object;
1047  if ( object->manipulatorNode()->visible() ) {
1048  // Compute translation vector
1049  ACG::Vec3d translation = newpos;
1050  translation -= object->manipulatorNode()->center();
1051  object->manipulatorNode()->set_center(newpos);
1052  // Stuff it into transformation matrix
1053  ACG::GLMatrixd m;
1054  m.identity();
1055  m.translate(translation);
1056  if (PluginFunctions::pickMode() == "Move")
1057  {
1058  // ...and transform mesh
1059  if(object->dataType() == DATA_TRIANGLE_MESH)
1061  else if(object->dataType() == DATA_POLY_MESH)
1063 
1064  // Create backup
1065  emit createBackup(object->id(), "Object Translation");
1066 
1067  }
1068  else if (PluginFunctions::pickMode() == "MoveSelection")
1069  {
1071  if (selectionType_ & VERTEX) {
1072  transformVertexSelection(object->id(), m);
1073  }
1074  if (selectionType_ & FACE) {
1075  transformFaceSelection(object->id(), m);
1076  }
1077  if (selectionType_ & EDGE) {
1078  transformEdgeSelection(object->id(), m);
1079  }
1080 
1081  // Create backup
1082  emit createBackup(object->id(), "Translation of selection");
1083  }
1084 
1085 
1086  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1087  }
1089  emit updateView();
1090  }
1091 }
1092 
1093 
1094 //------------------------------------------------------------------------------
1095 
1100 
1101  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1103  if(pW == 0) return;
1104 
1105  axisA_ = (axisA_ + 1) % 3;
1106 
1107  if (axisA_ == axisB_)
1108  axisA_ = (axisA_ + 1) % 3;
1109 
1110  switch(axisA_){
1111  case 0: pW->axisAButton->setText(tr("X Direction")); break;
1112  case 1: pW->axisAButton->setText(tr("Y Direction")); break;
1113  case 2: pW->axisAButton->setText(tr("Z Direction")); break;
1114  default: break;
1115  }
1116 }
1117 
1118 
1119 //------------------------------------------------------------------------------
1120 
1125 
1126  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1128  if(pW == 0) return;
1129 
1130  axisB_ = (axisB_ + 1) % 3;
1131 
1132  if (axisA_ == axisB_)
1133  axisB_ = (axisB_ + 1) % 3;
1134 
1135  switch(axisB_){
1136  case 0: pW->axisBButton->setText(tr("X Direction")); break;
1137  case 1: pW->axisBButton->setText(tr("Y Direction")); break;
1138  case 2: pW->axisBButton->setText(tr("Z Direction")); break;
1139  default: break;
1140  }
1141 }
1142 
1143 
1144 //------------------------------------------------------------------------------
1145 
1150 
1151  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1153  if(pW == 0) return;
1154 
1155  ACG::Vec3d newdirA,newdirB;
1156  ACG::Vec3d dirX,dirY;
1157  ACG::Vec3d dirZ(0.0,0.0,0.0);
1158 
1159  bool ok = false;
1160  newdirA[0] = (pW->ndirAx->text()).toDouble(&ok);
1161  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1162  newdirA[1] = (pW->ndirAy->text()).toDouble(&ok);
1163  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1164  newdirA[2] = (pW->ndirAz->text()).toDouble(&ok);
1165  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1166 
1167  newdirB[0] = (pW->ndirBx->text()).toDouble(&ok);
1168  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1169  newdirB[1] = (pW->ndirBy->text()).toDouble(&ok);
1170  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1171  newdirB[2] = (pW->ndirBz->text()).toDouble(&ok);
1172  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1173 
1174  bool xAxis = false;
1175  bool yAxis = false;
1176 
1177  switch(axisA_){
1178  case 0: dirX = newdirA; xAxis = true; break;
1179  case 1: dirY = newdirA; yAxis = true; break;
1180  default: dirZ = newdirA; break;
1181  }
1182 
1183  switch(axisB_){
1184  case 0: dirX = newdirB; xAxis = true; break;
1185  case 1: dirY = newdirB; yAxis = true; break;
1186  default: dirZ = newdirB; break;
1187  }
1188 
1189  if (!xAxis)
1190  dirX = dirY % dirZ;
1191 
1192  if (!yAxis)
1193  dirY = dirX % dirZ;
1194 
1195 
1196  if ( (dirX | dirY) != 0.0){
1197  emit log(LOGERR,tr("The axes of the new direction have to be orthogonal"));
1198  return;
1199  }
1200 
1201 // // Apply to All Target Objects
1202 // if ( pW->targetObjects->isChecked() ) {
1203 // for (auto* o_it : PluginFunctions::objects(PluginFunctions::TARGET_OBJECTS) ) {
1204 // o_it->manipulatorNode()->set_direction( dirX, dirY );
1205 // }
1206 // }
1207 
1208 
1209  BaseObjectData* object = 0;
1210  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1211  if ( object != 0 ) {
1212  if ( object->manipulatorNode()->visible() ){
1213 
1214  object->manipulatorNode()->set_direction( dirX, dirY );
1215  }
1216  } else return;
1217 
1219  emit updateView();
1220 }
1221 
1222 
1223 //------------------------------------------------------------------------------
1224 
1229 
1230  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1232  if(pW == 0) return;
1233 
1234  ACG::Vec3d translation;
1235 
1236  bool ok = false;
1237  translation[0] = (pW->translationX->text()).toDouble(&ok);
1238  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1239  translation[1] = (pW->translationY->text()).toDouble(&ok);
1240  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1241  translation[2] = (pW->translationZ->text()).toDouble(&ok);
1242  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1243 
1244  BaseObjectData* object = 0;
1245  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1246 
1247  if (object != 0) {
1248  if (object->manipulatorNode()->visible()) {
1249 
1250  object->manipulatorNode()->set_center(
1251  object->manipulatorNode()->center() + translation);
1252 
1253  if (PluginFunctions::pickMode() == "Move")
1254  {
1255 
1256  translate(object->id(), translation);
1257 
1258  // Create backup
1259  emit createBackup(object->id(), "Translation of Object");
1260 
1261  }
1262  else if (PluginFunctions::pickMode() == "MoveSelection")
1263  {
1265  if (selectionType_ & VERTEX) {
1266  translateVertexSelection(object->id(), translation);
1267  }
1268  if (selectionType_ & FACE) {
1269  translateFaceSelection(object->id(), translation);
1270  }
1271  if (selectionType_ & EDGE) {
1272  translateEdgeSelection(object->id(), translation);
1273  }
1274  emit createBackup(object->id(), "Translation of selection");
1275  }
1276 
1277 
1278 
1279  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1280 
1281 
1282  // move all other targets without manipulator
1283  if(allTargets_) {
1284 
1286  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1287  if (PluginFunctions::pickMode() == "Move") {
1288 
1289  translate(o_it->id(), translation);
1290 
1291  // Create backup
1292  emit createBackup(o_it->id(), "Translation of object");
1293 
1294  } else if (PluginFunctions::pickMode() == "MoveSelection") {
1296  if (selectionType_ & VERTEX) {
1297  translateVertexSelection(o_it->id(), translation);
1298  }
1299  if (selectionType_ & FACE) {
1300  translateFaceSelection(o_it->id(), translation);
1301  }
1302  if (selectionType_ & EDGE) {
1303  translateEdgeSelection(o_it->id(), translation);
1304  }
1305 
1306  emit createBackup(o_it->id(), "Translation of selection");
1307  }
1308 
1309 
1310  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1311  }
1312  }
1313 
1314  }
1315  }
1316  } else {
1317  return;
1318  }
1319 
1320 
1322  emit scriptInfo(QString("slotTranslation()"));
1323  emit updateView();
1324 }
1325 
1326 
1327 //------------------------------------------------------------------------------
1328 
1333 
1334  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1336  if(pW == 0) return;
1337 
1338  if ( allTargets_ ) {
1339  emit log(LOGWARN,tr("TODO Project for multiple targets"));
1340  return;
1341  } else {
1342  emit log(LOGWARN,tr("TODO Project for one target"));
1343  return;
1344  }
1345 
1346 }
1347 
1348 
1349 //------------------------------------------------------------------------------
1350 
1355 
1356  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1358  if(pW == 0) return;
1359 
1360 
1361 // if ( pW->targetObjects->isChecked() ) {
1362 // for (auto* o_it : PluginFunctions::objects(PluginFunctions::TARGET_OBJECTS) ) {
1363 // if ( o_it->manipulatorNode()->hidden() )
1364 // continue;
1365 //
1366 // if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1367 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::triMesh(*o_it) ) );
1368 // else if ( o_it->dataType( DATA_POLY_MESH ) )
1369 // o_it->manipulatorNode()->set_center( MeshInfo::cog(*PluginFunctions::polyMesh(*o_it)) );
1370 //
1371 // updateManipulatorDialog();
1372 // o_it->manipulatorNode()->loadIdentity();
1373 // }
1374 // } else {
1375 
1376  BaseObjectData* object = 0;
1377  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1378  if ( object != 0 ) {
1379  if ( object->manipulatorNode()->visible() ){
1380 
1381  if ( object->dataType( DATA_TRIANGLE_MESH ) )
1382  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::triMesh(object)) );
1383  else if ( object->dataType( DATA_POLY_MESH ) )
1384  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::polyMesh(object)) );
1385 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1386  else if ( object->dataType( DATA_TSPLINE_MESH ) )
1387  object->manipulatorNode()->set_center( MeshInfo::cog(PluginFunctions::tsplineMesh(object)) );
1388 #endif
1389 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1390  else if ( object->dataType( DATA_HEXAHEDRAL_MESH ) )
1391  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::hexahedralMesh(object)) );
1392 #endif
1393 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1394  else if ( object->dataType( DATA_TETRAHEDRAL_MESH ) )
1395  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::tetrahedralMesh(object)) );
1396 #endif
1397 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1398  else if ( object->dataType( DATA_POLYHEDRAL_MESH ) )
1399  object->manipulatorNode()->set_center( cogVolumeMesh(*PluginFunctions::polyhedralMesh(object)) );
1400 #endif
1401 
1403  object->manipulatorNode()->loadIdentity();
1404  }
1405  }
1406 
1407  emit updateView();
1408 }
1409 
1410 
1411 //------------------------------------------------------------------------------
1412 
1417 
1418  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1420  if(pW == 0) return;
1421 
1422  TriMesh::Point axis;
1423  double angle;
1424 
1425  bool ok = false;
1426  axis[0] = (pW->rotx->text()).toDouble(&ok);
1427  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for X Coordinate")); return; }
1428  axis[1] = (pW->roty->text()).toDouble(&ok);
1429  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Y Coordinate")); return; }
1430  axis[2] = (pW->rotz->text()).toDouble(&ok);
1431  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Z Coordinate")); return; }
1432 
1433  angle = (pW->rotAngle->text()).toDouble(&ok);
1434  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for Angle")); return; }
1435 
1436  BaseObjectData* object = 0;
1437  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1438  if (object != 0) {
1439  if (object->manipulatorNode()->visible() && (object->target() || !allTargets_)) {
1440 
1441  object->manipulatorNode()->rotate(angle, axis);
1442 
1444 
1445  if (PluginFunctions::pickMode() == "Move")
1446  {
1447  if (object->dataType(DATA_TRIANGLE_MESH))
1448  transformMesh(m, (*PluginFunctions::triMesh(object)));
1449 
1450  if (object->dataType(DATA_POLY_MESH))
1452 
1453  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1454  if (object->dataType(DATA_TSPLINE_MESH))
1455  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1456  #endif
1457  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1458  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1459  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1460  #endif
1461  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1462  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1463  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1464  #endif
1465  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1466  if (object->dataType(DATA_POLYHEDRAL_MESH))
1467  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1468  #endif
1469 
1470  // Create backup
1471  emit createBackup(object->id(), "Rotation of object");
1472 
1473  }
1474  else if (PluginFunctions::pickMode() == "MoveSelection")
1475  {
1477  if (selectionType_ & VERTEX) {
1478  transformVertexSelection(object->id(), m);
1479  }
1480  if (selectionType_ & FACE) {
1481  transformFaceSelection(object->id(), m);
1482  }
1483  if (selectionType_ & EDGE) {
1484  transformEdgeSelection(object->id(), m);
1485  }
1486  if (selectionType_ & CELL) {
1487  transformCellSelection(object->id(), m);
1488  }
1489 
1490  // Create backup
1491  emit createBackup(object->id(), "Rotation of selection");
1492  }
1493 
1494  // move all other targets without manipulator
1495  if(allTargets_) {
1496 
1498 
1499  // If it has its own manipulator active, don't move it
1500  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) {
1501 
1502  if (PluginFunctions::pickMode() == "Move")
1503  {
1504  if (o_it->dataType(DATA_TRIANGLE_MESH))
1506 
1507  if (o_it->dataType(DATA_POLY_MESH))
1509  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1510  if (o_it->dataType(DATA_TSPLINE_MESH))
1511  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1512  #endif
1513  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1514  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1515  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1516  #endif
1517  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1518  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1519  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1520  #endif
1521  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1522  if (object->dataType(DATA_POLYHEDRAL_MESH))
1523  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1524  #endif
1525 
1526  // Create backup
1527  emit createBackup(o_it->id(), "Rotation of object");
1528  }
1529  else if (PluginFunctions::pickMode() == "MoveSelection")
1530  {
1532  if (selectionType_ & VERTEX) {
1533  transformVertexSelection(o_it->id(), m);
1534  }
1535  if (selectionType_ & FACE) {
1536  transformFaceSelection(o_it->id(), m);
1537  }
1538  if (selectionType_ & EDGE) {
1539  transformEdgeSelection(o_it->id(), m);
1540  }
1541  if (selectionType_ & CELL) {
1542  transformCellSelection(o_it->id(), m);
1543  }
1544 
1545  // Create backup
1546  emit createBackup(o_it->id(), "Rotation of selection");
1547  }
1548 
1549  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1550  }
1551  }
1552 
1553  }
1554 
1556 
1557  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1558 
1559  }
1560  }
1561 
1562  emit scriptInfo(QString("slotRotate()"));
1563  emit updateView();
1564 }
1565 
1566 
1567 //------------------------------------------------------------------------------
1568 
1573 
1574  QPushButton* but = dynamic_cast<QPushButton*>(QObject::sender());
1576  if(pW == 0) return;
1577 
1578 
1579  TriMesh::Point scale;
1580 
1581  bool ok = false;
1582  scale[0] = (pW->scalex->text()).toDouble(&ok);
1583  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 1")); return; }
1584  scale[1] = (pW->scaley->text()).toDouble(&ok);
1585  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 2")); return; }
1586  scale[2] = (pW->scalez->text()).toDouble(&ok);
1587  if ( !ok ) { emit log(LOGERR,tr("Wrong Format for factor 3")); return; }
1588 
1589  BaseObjectData* object = 0;
1590  PluginFunctions::getObject(pW->getBaseObjectDataId(),object);
1591  if (object != 0) {
1592  if (object->manipulatorNode()->visible() && (object->target()
1593  || !allTargets_)) {
1594 
1595  object->manipulatorNode()->scale(scale);
1596 
1598 
1599  if (PluginFunctions::pickMode() == "Move")
1600  {
1601  if (object->dataType(DATA_TRIANGLE_MESH))
1603  if (object->dataType(DATA_POLY_MESH))
1605  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1606  if (object->dataType(DATA_TSPLINE_MESH))
1607  transformMesh(m, (*PluginFunctions::tsplineMesh(object)));
1608  #endif
1609  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1610  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1611  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1612  #endif
1613  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1614  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1615  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1616  #endif
1617  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1618  if (object->dataType(DATA_POLYHEDRAL_MESH))
1619  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1620  #endif
1621 
1622  // Create backup
1623  emit createBackup(object->id(), "Scaling of object");
1624  }
1625  else if (PluginFunctions::pickMode() == "MoveSelection")
1626  {
1628  if (selectionType_ & VERTEX) {
1629  transformVertexSelection(object->id(), m);
1630  }
1631  if (selectionType_ & FACE) {
1632  transformFaceSelection(object->id(), m);
1633  }
1634  if (selectionType_ & EDGE) {
1635  transformEdgeSelection(object->id(), m);
1636  }
1637  if (selectionType_ & CELL) {
1638  transformCellSelection(object->id(), m);
1639  }
1640 
1641  // Create backup
1642  emit createBackup(object->id(), "Scaling of selection");
1643  }
1644 
1645  // move all other targets without manipulator
1646  if(allTargets_) {
1647 
1649  if ((o_it->id() != object->id()) && !o_it->manipulatorNode()->draw_manipulator()) { // If it has its own manipulator active, dont move it
1650 
1651  if (PluginFunctions::pickMode() == "Move")
1652  {
1653  if (o_it->dataType(DATA_TRIANGLE_MESH))
1655 
1656  if (o_it->dataType(DATA_POLY_MESH))
1658  #ifdef ENABLE_TSPLINEMESH_SUPPORT
1659  if (o_it->dataType(DATA_TSPLINE_MESH))
1660  transformMesh(m, (*PluginFunctions::tsplineMesh(o_it)));
1661  #endif
1662  #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1663  if (object->dataType(DATA_HEXAHEDRAL_MESH))
1664  transformVolumeMesh(m, (*PluginFunctions::hexahedralMesh(object)), (PluginFunctions::hexahedralMeshObject(object)->normals()));
1665  #endif
1666  #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1667  if (object->dataType(DATA_TETRAHEDRAL_MESH))
1668  transformVolumeMesh(m, (*PluginFunctions::tetrahedralMesh(object)), (PluginFunctions::tetrahedralMeshObject(object)->normals()));
1669  #endif
1670  #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1671  if (object->dataType(DATA_POLYHEDRAL_MESH))
1672  transformVolumeMesh(m, (*PluginFunctions::polyhedralMesh(object)), (PluginFunctions::polyhedralMeshObject(object)->normals()));
1673  #endif
1674 
1675  // Create backup
1676  emit createBackup(o_it->id(), "Scaling of object");
1677  }
1678  else if (PluginFunctions::pickMode() == "MoveSelection")
1679  {
1681  if (selectionType_ & VERTEX) {
1682  transformVertexSelection(o_it->id(), m);
1683  }
1684  if (selectionType_ & FACE) {
1685  transformFaceSelection(o_it->id(), m);
1686  }
1687  if (selectionType_ & EDGE) {
1688  transformEdgeSelection(o_it->id(), m);
1689  }
1690  if (selectionType_ & CELL) {
1691  transformCellSelection(o_it->id(), m);
1692  }
1693 
1694  // Create backup
1695  emit createBackup(o_it->id(), "Scaling of selection");
1696  }
1697 
1698  emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
1699  }
1700  }
1701 
1702  }
1703 
1705 
1706  emit createBackup(object->id(), "Scaling");
1707  emit updatedObject(object->id(), UPDATE_GEOMETRY);
1708  }
1709  }
1710 
1711  emit scriptInfo(QString("slotScale()"));
1712  emit updateView();
1713 }
1714 
1715 
1716 //------------------------------------------------------------------------------
1717 
1718 
1723 
1724  bool useCommonCOG = false;
1725  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
1726 
1727  if ( PluginFunctions::targetCount() > 1 ) {
1728  if ( OpenFlipper::Options::gui()) {
1729  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);
1730 
1731 
1732  useCommonCOG = ( button == QMessageBox::Yes );
1733  }
1734 
1735  if ( useCommonCOG ) {
1736 
1737  double vertexCount = 0.0;
1738 
1739  // Compute cog for all objects
1741  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1742  TriMesh* mesh = PluginFunctions::triMesh(o_it);
1743  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1744  vertexCount += double(mesh->n_vertices());
1745  }
1746 
1747  if ( o_it->dataType( DATA_POLY_MESH )) {
1748  PolyMesh* mesh = PluginFunctions::polyMesh(o_it);
1749  cog += MeshInfo::cog(mesh) * double(mesh->n_vertices());
1750  vertexCount += double(mesh->n_vertices());
1751  }
1752 
1753 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1754  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1755  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(o_it);
1756  cog += MeshInfo::cog(mesh) * double(mesh.n_vertices());
1757  vertexCount += double(mesh.n_vertices());
1758  }
1759 #endif
1760 
1761 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1762  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1764  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1765  vertexCount += double(mesh.n_vertices());
1766  }
1767 #endif
1768 
1769 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1770  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1772  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1773  vertexCount += double(mesh.n_vertices());
1774  }
1775 #endif
1776 
1777 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1778  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1780  cog += cogVolumeMesh(mesh) * double(mesh.n_vertices());
1781  vertexCount += double(mesh.n_vertices());
1782  }
1783 #endif
1784  }
1785 
1786  cog = cog / vertexCount;
1787  }
1788 
1789  }
1790 
1792  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1793  TriMesh* mesh = PluginFunctions::triMesh(o_it);
1794 
1795  if ( !useCommonCOG )
1796  cog = MeshInfo::cog(mesh);
1797 
1798  for ( TriMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1799  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1800 
1801  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1802  }
1803 
1804  if ( o_it->dataType( DATA_POLY_MESH )) {
1805  PolyMesh* mesh = PluginFunctions::polyMesh(o_it);
1806 
1807  if ( !useCommonCOG )
1808  cog = MeshInfo::cog(mesh);
1809 
1810  for ( PolyMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1811  mesh->set_point(*v_it , ( mesh->point(*v_it) ) - cog );
1812 
1813  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1814 
1815  }
1816 
1817 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1818  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1819  TSplineMesh* mesh = PluginFunctions::tsplineMesh(o_it);
1820 
1821  if ( !useCommonCOG )
1822  cog = MeshInfo::cog(mesh);
1823 
1824  for ( TSplineMesh::VertexIter v_it = mesh->vertices_begin(); v_it != mesh->vertices_end() ; ++v_it)
1825  mesh->set_point(v_it , ( mesh->point(v_it) ) - cog );
1826 
1827  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1828 
1829  }
1830 #endif
1831 
1832 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1833  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1835 
1836  if ( !useCommonCOG )
1837  cog = cogVolumeMesh(mesh);
1838 
1839  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1840  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1841 
1842  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1843 
1844  }
1845 #endif
1846 
1847 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1848  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1850 
1851  if ( !useCommonCOG )
1852  cog = cogVolumeMesh(mesh);
1853 
1854  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1855  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1856 
1857  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1858 
1859  }
1860 #endif
1861 
1862 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1863  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1865 
1866  if ( !useCommonCOG )
1867  cog = cogVolumeMesh(mesh);
1868 
1869  for ( OpenVolumeMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end() ; ++v_it)
1870  mesh.set_vertex(*v_it , mesh.vertex(*v_it) - cog );
1871 
1872  o_it->manipulatorNode()->set_center( o_it->manipulatorNode()->center() - cog );
1873 
1874  }
1875 #endif
1876 
1877 
1878  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
1879 
1881  o_it->manipulatorNode()->loadIdentity();
1882 
1883  emit createBackup(o_it->id(),"Move to origin");
1884  }
1885 
1886  emit updateView();
1887 }
1888 
1889 
1890 //------------------------------------------------------------------------------
1891 
1896 {
1897  unifyBoundingBox(MovePlugin::DIAGONAL);
1898 }
1899 
1901 {
1902  unifyBoundingBox((MovePlugin::LONGEST_AXIS));
1903 }
1904 
1906 {
1907  unifyBoundingBox(MovePlugin::ALL_AXIS);
1908 }
1909 
1911 {
1912  bool useCommonBB = false;
1913  ACG::Vec3d bb_min = ACG::Vec3d(FLT_MAX,FLT_MAX,FLT_MAX);
1914  ACG::Vec3d bb_max = ACG::Vec3d(FLT_MIN,FLT_MIN,FLT_MIN);
1915 
1916  if ( PluginFunctions::targetCount() > 1 ) {
1917  if ( OpenFlipper::Options::gui()) {
1918  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);
1919 
1920 
1921  useCommonBB = ( button == QMessageBox::Yes );
1922  }
1923 
1924 
1925  if ( useCommonBB ) {
1926 
1927  // Compute cog for all objects
1929  ACG::Vec3d bb_min_tmp(0.0,0.0,0.0);
1930  ACG::Vec3d bb_max_tmp(0.0,0.0,0.0);
1931 
1932  if ( o_it->dataType( DATA_TRIANGLE_MESH )) {
1933  TriMesh& mesh = *PluginFunctions::triMesh(o_it);
1934  getBB(mesh,bb_min_tmp,bb_max_tmp);
1935  bb_min.minimize(bb_min_tmp);
1936  bb_max.maximize(bb_max_tmp);
1937  }
1938 
1939  if ( o_it->dataType( DATA_POLY_MESH )) {
1940  PolyMesh& mesh = *PluginFunctions::polyMesh(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 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1947  if ( o_it->dataType( DATA_TSPLINE_MESH )) {
1948  TSplineMesh& mesh = *PluginFunctions::tsplineMesh(o_it);
1949  getBB(mesh,bb_min_tmp,bb_max_tmp);
1950  bb_min.minimize(bb_min_tmp);
1951  bb_max.maximize(bb_max_tmp);
1952  }
1953 #endif
1954 
1955 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1956  if ( o_it->dataType( DATA_HEXAHEDRAL_MESH )) {
1958  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1959  bb_min.minimize(bb_min_tmp);
1960  bb_max.maximize(bb_max_tmp);
1961  }
1962 #endif
1963 
1964 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
1965  if ( o_it->dataType( DATA_TETRAHEDRAL_MESH )) {
1967  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1968  bb_min.minimize(bb_min_tmp);
1969  bb_max.maximize(bb_max_tmp);
1970  }
1971 #endif
1972 
1973 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
1974  if ( o_it->dataType( DATA_POLYHEDRAL_MESH )) {
1976  getBBVolumeMesh(mesh,bb_min_tmp,bb_max_tmp);
1977  bb_min.minimize(bb_min_tmp);
1978  bb_max.maximize(bb_max_tmp);
1979  }
1980 #endif
1981  }
1982  }
1983 
1984  }
1985 
1987  if ( useCommonBB ) {
1988  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
1989  unifyBB(*PluginFunctions::triMesh(o_it),bb_min,bb_max, u);
1990  else if ( o_it->dataType( DATA_POLY_MESH ) )
1991  unifyBB(*PluginFunctions::polyMesh(o_it),bb_min,bb_max, u);
1992 #ifdef ENABLE_TSPLINEMESH_SUPPORT
1993  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
1994  unifyBB(*PluginFunctions::tsplineMesh(o_it),bb_min,bb_max, u);
1995 #endif
1996 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
1997  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
1998  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(o_it),(PluginFunctions::hexahedralMeshObject(o_it)->normals()),bb_min,bb_max, u);
1999 #endif
2000 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
2001  else if ( o_it->dataType( DATA_TETRAHEDRAL_MESH ) )
2002  unifyBBVolumeMesh(*PluginFunctions::tetrahedralMesh(o_it),(PluginFunctions::tetrahedralMeshObject(o_it)->normals()),bb_min,bb_max, u);
2003 #endif
2004 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
2005  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
2006  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(o_it),(PluginFunctions::polyhedralMeshObject(o_it)->normals()),bb_min,bb_max, u);
2007 #endif
2008  } else {
2009  if ( o_it->dataType( DATA_TRIANGLE_MESH ) )
2010  unifyBB(*PluginFunctions::triMesh(o_it), u);
2011  else if ( o_it->dataType( DATA_POLY_MESH ) )
2013 #ifdef ENABLE_TSPLINEMESH_SUPPORT
2014  else if ( o_it->dataType( DATA_TSPLINE_MESH ) )
2015  unifyBB(*PluginFunctions::tsplineMesh(o_it), u);
2016 #endif
2017 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
2018  else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) )
2019  unifyBBVolumeMesh(*PluginFunctions::hexahedralMesh(o_it),(PluginFunctions::hexahedralMeshObject(o_it)->normals()), u);
2020 #endif
2021 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
2022  else if ( o_it->dataType( DATA_TETRAHEDRAL_MESH ) )
2024 #endif
2025 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
2026  else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) )
2027  unifyBBVolumeMesh(*PluginFunctions::polyhedralMesh(o_it),(PluginFunctions::polyhedralMeshObject(o_it)->normals()), u);
2028 #endif
2029  }
2030 
2031  emit updatedObject( o_it->id(), UPDATE_GEOMETRY );
2032 
2033  }
2034 
2035  emit updateView();
2036 }
2037 
2038 
2039 //------------------------------------------------------------------------------
2040 
2045 
2046  BaseObjectData* object;
2048  return;
2049  }
2050 
2051  if ( object->manipulatorNode()->visible() ) {
2052 
2053  // Get properties widget that corresponds to
2054  // to the last manipulated object
2055  movePropsWidget* pW = getDialogWidget(object);
2056 
2057  // If there's no properties dialog yet...
2058  if(pW == 0) return;
2059 
2060  const TriMesh::Point pos = object->manipulatorNode()->center();
2061 
2062  QString num;
2063 
2064  num = QString::number(pos[0]); pW->posx->setText(num);
2065  num = QString::number(pos[1]); pW->posy->setText(num);
2066  num = QString::number(pos[2]); pW->posz->setText(num);
2067 
2068  TriMesh::Point direction = object->manipulatorNode()->directionX();
2069  num = QString::number(direction[0]); pW->dirxx->setText(num);
2070  num = QString::number(direction[1]); pW->dirxy->setText(num);
2071  num = QString::number(direction[2]); pW->dirxz->setText(num);
2072 
2073  direction = object->manipulatorNode()->directionY();
2074  num = QString::number(direction[0]); pW->diryx->setText(num);
2075  num = QString::number(direction[1]); pW->diryy->setText(num);
2076  num = QString::number(direction[2]); pW->diryz->setText(num);
2077 
2078  direction = object->manipulatorNode()->directionZ();
2079  num = QString::number(direction[0]); pW->dirzx->setText(num);
2080  num = QString::number(direction[1]); pW->dirzy->setText(num);
2081  num = QString::number(direction[2]); pW->dirzz->setText(num);
2082 
2083  }
2084 }
2085 
2086 //------------------------------------------------------------------------------
2087 
2093 
2094  for(QList<movePropsWidget*>::iterator it = propsWindows_.begin();
2095  it != propsWindows_.end(); ++it) {
2096  if ( (*it)->getBaseObjectDataId() == _obj->id() )
2097  return *it;
2098  }
2099  return 0;
2100 }
2101 //------------------------------------------------------------------------------
2102 
2107 void MovePlugin::slotSetMoveMode(QAction* _action) {
2108 
2109  if (_action == moveAction_){
2110  PluginFunctions::actionMode(Viewer::PickingMode);
2111  PluginFunctions::pickMode("Move");
2112 
2113  moveAction_->setChecked( true );
2114  }
2115 
2116  if (_action == moveSelectionAction_){
2117 
2118  PluginFunctions::actionMode(Viewer::PickingMode);
2119  PluginFunctions::pickMode("MoveSelection");
2120 
2121  moveSelectionAction_->setChecked( true );
2122  }
2123 }
2124 
2125 //------------------------------------------------------------------------------
2126 
2133 {
2134 
2135  if (_action == rotateTranslateAction_)
2136  {
2137  setManipMode (QtTranslationManipulatorNode::TranslationRotation);
2138  }
2139 
2140  if (_action == rotateManipAction_)
2141  {
2142  setManipMode (QtTranslationManipulatorNode::LocalRotation);
2143  }
2144 
2145  if (_action == placeAndSnapAction_)
2146  {
2147  setManipMode(QtTranslationManipulatorNode::Place);
2148  }
2149 
2150  if (_action == resizeAction_)
2151  {
2152  setManipMode(QtTranslationManipulatorNode::Resize);
2153  }
2154 
2155  if (_action == biggerManipAction_)
2156  {
2159  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2160  emit nodeVisibilityChanged (-1);
2161  }
2162 
2163  if (_action == smallerManipAction_)
2164  {
2167  o_it->manipulatorNode()->set_size(manip_size_ * manip_size_modifier_);
2168  emit nodeVisibilityChanged (-1);
2169  }
2170 }
2171 
2172 
2173 //------------------------------------------------------------------------------
2174 
2181  ACG::Matrix4x4d matrix;
2182  matrix.identity();
2183 
2184  BaseObjectData* object;
2186  if ( object->manipulatorNode()->visible() ) {
2187  matrix = object->manipulatorNode()->matrix();
2188  if (_reset)
2189  object->manipulatorNode()->loadIdentity();
2190  }
2191  return matrix;
2192 }
2193 
2194 
2195 //------------------------------------------------------------------------------
2196 
2205 template< typename MeshT >
2206 void MovePlugin::transformMesh(ACG::Matrix4x4d _mat , MeshT& _mesh ) {
2207  // Get the inverse matrix of the transformation for the normals
2208  ACG::Matrix4x4d invTranspMat = _mat;
2209 
2210  // Build inverse transposed matrix of _mat
2211  invTranspMat.invert();
2212  invTranspMat.transpose();
2213 
2214  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2215  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2216  for (; v_it!=v_end; ++v_it) {
2217 
2218  // transform the mesh vertex
2219  _mesh.set_point(*v_it,_mat.transform_point(_mesh.point(*v_it)));
2220 
2221  // transform the vertex normal
2222  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*v_it));
2223 
2224  n.normalize();
2225 
2226  _mesh.set_normal(*v_it,n);
2227  }
2228 
2229  typename MeshT::FaceIter f_it = _mesh.faces_begin();
2230  typename MeshT::FaceIter f_end = _mesh.faces_end();
2231  for (; f_it != f_end; ++f_it) {
2232 
2233  // transform the face normal
2234  typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*f_it));
2235 
2236  n.normalize();
2237 
2238  _mesh.set_normal(*f_it,n);
2239  }
2240 }
2241 
2242 
2243 //------------------------------------------------------------------------------
2244 
2245 #ifdef ENABLE_POLYLINE_SUPPORT
2246 
2252 template< class PolyLineT >
2253 void MovePlugin::transformPolyLine( ACG::Matrix4x4d _mat , PolyLineT& _polyLine ) {
2254  #ifdef USE_OPENMP
2255  #pragma omp parallel for
2256  #endif
2257  for ( int i = 0 ; i < (int)_polyLine.n_vertices(); ++i )
2258  _polyLine.point(i) = _mat.transform_point( _polyLine.point(i) );
2259 }
2260 
2261 #endif
2262 
2263 
2264 //------------------------------------------------------------------------------
2265 
2266 #ifdef ENABLE_SKELETON_SUPPORT
2267 
2273 void MovePlugin::transformSkeleton( ACG::Matrix4x4d _mat , Skeleton& _skeleton ) {
2274 
2275  SkeletonTransform transformer(_skeleton);
2276  transformer.transformSkeleton(_mat);
2277 }
2278 
2279 #endif
2280 
2281 #if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
2282 
2291 template< typename VolumeMeshT >
2292 void MovePlugin::transformVolumeMesh(ACG::Matrix4x4d _mat , VolumeMeshT& _mesh , OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib )
2293 {
2294  // Get the inverse matrix of the transformation for the normals
2295  ACG::Matrix4x4d invTranspMat = _mat;
2296 
2297  // Build inverse transposed matrix of _mat
2298  invTranspMat.invert();
2299  invTranspMat.transpose();
2300 
2301  OpenVolumeMesh::VertexIter v_begin = _mesh.vertices_begin();
2302  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2303 
2304  // transform the mesh vertices
2305  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2306  _mesh.set_vertex(*v_it, _mat.transform_point(_mesh.vertex(*v_it)));
2307 
2308  // transform the vertex normals
2309  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
2310  _normalAttrib[*v_it] = invTranspMat.transform_vector(_normalAttrib[*v_it]).normalized();
2311 
2312 
2313  // transform the face normals
2314  OpenVolumeMesh::FaceIter f_begin = _mesh.faces_begin();
2315  OpenVolumeMesh::FaceIter f_end = _mesh.faces_end();
2316  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
2317  _normalAttrib[*f_it] = invTranspMat.transform_vector(_normalAttrib[*f_it]).normalized();
2318 }
2319 
2320 //------------------------------------------------------------------------------
2321 
2326 template< typename VolumeMeshT >
2327 ACG::Vec3d MovePlugin::cogVolumeMesh( VolumeMeshT& _mesh )
2328 {
2329  ACG::Vec3d cog = ACG::Vec3d(0.0,0.0,0.0);
2330  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2331  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2332  for (; v_it!=v_end; ++v_it)
2333  cog += _mesh.vertex(*v_it);
2334 
2335  return cog/(double)_mesh.n_vertices();
2336 }
2337 
2338 //------------------------------------------------------------------------------
2339 
2346 template< typename VolumeMeshT >
2347 void MovePlugin::getBBVolumeMesh( VolumeMeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max)
2348 {
2349  OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin();
2350  OpenVolumeMesh::VertexIter v_end = _mesh.vertices_end();
2351 
2352  // no vertices?
2353  if( v_it == v_end) return;
2354 
2355  _bb_min = _mesh.vertex(*v_it);
2356  _bb_max = _mesh.vertex(*v_it);
2357 
2358  for(; v_it!=v_end; ++v_it)
2359  {
2360  _bb_min.minimize( _mesh.vertex(*v_it));
2361  _bb_max.maximize( _mesh.vertex(*v_it));
2362  }
2363 }
2364 
2365 //------------------------------------------------------------------------------
2366 
2372 template< typename VolumeMeshT >
2373 void MovePlugin::unifyBBVolumeMesh(VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, Unificationtype u)
2374 {
2375  // no vertices?
2376  if( _mesh.n_vertices() == 0) return;
2377 
2378  ACG::Vec3d bb_min, bb_max;
2379  getBBVolumeMesh( _mesh, bb_min, bb_max );
2380 
2381  unifyBBVolumeMesh( _mesh, _normalAttrib, bb_min, bb_max, u );
2382 }
2383 
2384 //------------------------------------------------------------------------------
2385 
2394 template< typename VolumeMeshT >
2395 void MovePlugin::unifyBBVolumeMesh( VolumeMeshT& _mesh, OpenVolumeMesh::NormalAttrib<VolumeMeshT>& _normalAttrib, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max, Unificationtype u)
2396 {
2397  ACG::Vec3d bb_center = 0.5 * (_bb_min + _bb_max) ;
2398  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2399  double bb_longestAxis = bb_diagonal.max();
2400 
2401  ACG::Vec3d scale;
2402  switch(u)
2403  {
2404  case MovePlugin::DIAGONAL :
2405  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2406  break;
2407  case MovePlugin::LONGEST_AXIS :
2408  scale = ACG::Vec3d(1.0/(bb_longestAxis));
2409  break;
2410  case MovePlugin::ALL_AXIS :
2411  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2412  break;
2413  default:
2414  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2415  }
2416 
2417 
2418  for( OpenVolumeMesh::VertexIter v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2419  _mesh.set_vertex(*v_it, (_mesh.vertex(*v_it) - bb_center) * scale + bb_center);
2420 
2421  _normalAttrib.update_vertex_normals();
2422 }
2423 
2424 #endif
2425 
2426 //------------------------------------------------------------------------------
2427 
2433 template< typename MeshT >
2434 void MovePlugin::unifyBB(MeshT& _mesh , Unificationtype u)
2435 {
2436  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2437  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2438 
2439  // no vertices?
2440  if( v_it == v_end) return;
2441 
2442  typename MeshT::Point bb_min = _mesh.point(*v_it);
2443  typename MeshT::Point bb_max = _mesh.point(*v_it);
2444 
2445  for(; v_it!=v_end; ++v_it)
2446  {
2447  bb_min.minimize( _mesh.point(*v_it));
2448  bb_max.maximize( _mesh.point(*v_it));
2449  }
2450 
2451  typename MeshT::Point bb_center = 0.5 * (bb_min + bb_max) ;
2452  ACG::Vec3d bb_diagonal = bb_max-bb_min;
2453  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2454 
2455  ACG::Vec3d scale;
2456  switch(u)
2457  {
2458  case MovePlugin::DIAGONAL :
2459  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2460  break;
2461  case MovePlugin::LONGEST_AXIS :
2462  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2463  break;
2464  case MovePlugin::ALL_AXIS :
2465  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2466  break;
2467  default:
2468  scale = ACG::Vec3d(1.0/(bb_max-bb_min).norm());
2469  }
2470 
2471  for( v_it = _mesh.vertices_begin(); v_it!=v_end; ++v_it)
2472  {
2473 
2474  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2475  }
2476 
2477  _mesh.update_normals();
2478 
2479 }
2480 
2487 template< typename MeshT >
2488 void MovePlugin::getBB( MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max )
2489 {
2490  typename MeshT::VertexIter v_it = _mesh.vertices_begin();
2491  typename MeshT::VertexIter v_end = _mesh.vertices_end();
2492 
2493  // no vertices?
2494  if( v_it == v_end) return;
2495 
2496  _bb_min = _mesh.point(*v_it);
2497  _bb_max = _mesh.point(*v_it);
2498 
2499  for(; v_it!=v_end; ++v_it)
2500  {
2501  _bb_min.minimize( _mesh.point(*v_it));
2502  _bb_max.maximize( _mesh.point(*v_it));
2503  }
2504 
2505 
2506 }
2507 
2515 template< typename MeshT >
2516 void MovePlugin::unifyBB(MeshT& _mesh, ACG::Vec3d& _bb_min, ACG::Vec3d& _bb_max , Unificationtype u)
2517 {
2518 
2519  typename MeshT::Point bb_center = 0.5 * (_bb_min + _bb_max) ;
2520  ACG::Vec3d bb_diagonal = _bb_max-_bb_min;
2521  typename MeshT::Scalar bb_longestAxis = bb_diagonal.max();
2522  ACG::Vec3d scale;
2523  switch(u)
2524  {
2525  case MovePlugin::DIAGONAL :
2526  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2527  break;
2528  case MovePlugin::LONGEST_AXIS :
2529  scale = ACG::Vec3d(1.0 / bb_longestAxis);
2530  break;
2531  case MovePlugin::ALL_AXIS :
2532  scale = ACG::Vec3d(ACG::Vec3d(1.0)/bb_diagonal);
2533  break;
2534  default:
2535  scale = ACG::Vec3d(1.0/(_bb_max-_bb_min).norm());
2536  }
2537 
2538  typename MeshT::VertexIter v_it;
2539 
2540  for( v_it = _mesh.vertices_begin(); v_it!=_mesh.vertices_end(); ++v_it)
2541  _mesh.point(*v_it) = (_mesh.point(*v_it) - bb_center) * scale + bb_center;
2542 
2543  _mesh.update_normals();
2544 
2545 }
2546 
2547 
2548 //------------------------------------------------------------------------------
2549 
2554 
2555  bool functionExistsMeshV;
2556  emit functionExists("meshobjectselection", "vertexTypeActive()", functionExistsMeshV);
2557  bool functionExistsMeshE;
2558  emit functionExists("meshobjectselection", "edgeTypeActive()", functionExistsMeshE);
2559  bool functionExistsMeshF;
2560  emit functionExists("meshobjectselection", "faceTypeActive()", functionExistsMeshF);
2561 
2562  bool connected = false;
2563  selectionType_ = 0u;
2564 
2565  if(functionExistsMeshV && functionExistsMeshE && functionExistsMeshF) {
2566 
2567  connected = true;
2568 
2569  // Make RPC call
2570  if(RPC::callFunctionValue<bool>("meshobjectselection", "vertexTypeActive")) {
2571  selectionType_ |= VERTEX;
2572  }
2573  if(RPC::callFunctionValue<bool>("meshobjectselection", "edgeTypeActive")) {
2574  selectionType_ |= EDGE;
2575  }
2576  if(RPC::callFunctionValue<bool>("meshobjectselection", "faceTypeActive")) {
2577  selectionType_ |= FACE;
2578  }
2579 
2580  }
2581 
2582 #if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
2583  bool functionExistsVolumeMeshV;
2584  emit functionExists("volumemeshselection", "vertexTypeActive()", functionExistsVolumeMeshV);
2585  bool functionExistsVolumeMeshE;
2586  emit functionExists("volumemeshselection", "edgeTypeActive()", functionExistsVolumeMeshE);
2587  bool functionExistsVolumeMeshF;
2588  emit functionExists("volumemeshselection", "faceTypeActive()", functionExistsVolumeMeshF);
2589  bool functionExistsVolumeMeshC;
2590  emit functionExists("volumemeshselection", "cellTypeActive()", functionExistsVolumeMeshC);
2591 
2592  if ( functionExistsVolumeMeshV && functionExistsVolumeMeshE && functionExistsVolumeMeshF && functionExistsVolumeMeshC) {
2593 
2594  connected = true;
2595 
2596  // Make RPC call
2597  if(RPC::callFunctionValue<bool>("volumemeshselection", "vertexTypeActive")) {
2598  selectionType_ |= VERTEX;
2599  }
2600  if(RPC::callFunctionValue<bool>("volumemeshselection", "edgeTypeActive")) {
2601  selectionType_ |= EDGE;
2602  }
2603  if(RPC::callFunctionValue<bool>("volumemeshselection", "faceTypeActive")) {
2604  selectionType_ |= FACE;
2605  }
2606  if(RPC::callFunctionValue<bool>("volumemeshselection", "cellTypeActive")) {
2607  selectionType_ |= CELL;
2608  }
2609  }
2610 #endif
2611 
2612  if (!connected) {
2613  emit log(LOGWARN, tr("Unable to connect to Selection-Plugin. MoveSelection will work on vertices only."));
2614  selectionType_ = VERTEX;
2615  }
2616 }
2617 
2618 //------------------------------------------------------------------------------
2619 
2625 void MovePlugin::setAllTargets(bool _state) {
2626  allTargets_ = _state;
2627 }
2628 
2629 //--------------------------------------------------------------------------------
2630 
2634 template< typename MeshType >
2635 OpenMesh::Vec3d MovePlugin::getNearestVertex(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2636 
2637  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2638 
2639  if ( !fh.is_valid() )
2640  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2641 
2642  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2643  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2644  typename MeshType::Scalar shortest_distance = (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2645  typename MeshType::VertexHandle vh = *fv_it;
2646 
2647  for (; fv_it.is_valid(); ++fv_it) {
2648 
2649  typename MeshType::Scalar tmpdist =
2650  (_mesh->point(*fv_it) - hitPointP).sqrnorm();
2651 
2652  if(tmpdist < shortest_distance) {
2653  shortest_distance = tmpdist;
2654  vh = *fv_it;
2655  }
2656  }
2657 
2658  return (OpenMesh::Vec3d)_mesh->point(vh);
2659 }
2660 
2661 //--------------------------------------------------------------------------------
2662 
2666 template< typename MeshType >
2667 OpenMesh::Vec3d MovePlugin::getNearestEdge(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2668 
2669  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2670 
2671  if (!fh.is_valid())
2672  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2673 
2674  typename MeshType::FaceEdgeIter fe_it(*_mesh, fh);
2675  typename MeshType::Point hitPointP = (typename MeshType::Point) _hitPoint;
2676 
2677  typename MeshType::Point center;
2678  typename MeshType::Scalar closest_dist(-1);
2679 
2680  for (; fe_it.is_valid(); ++fe_it) {
2681 
2682  typename MeshType::HalfedgeHandle heh0 = _mesh->halfedge_handle(*fe_it, 0);
2683  typename MeshType::HalfedgeHandle heh1 = _mesh->halfedge_handle(*fe_it, 1);
2684 
2685  typename MeshType::Point lp0 = _mesh->point(_mesh->to_vertex_handle(heh0));
2686  typename MeshType::Point lp1 = _mesh->point(_mesh->to_vertex_handle(heh1));
2687 
2688  double dist_new = ACG::Geometry::distPointLineSquared( hitPointP, lp0, lp1);
2689 
2690  /*typename MeshType::Point b(hitPointP - lp0), a(((lp1 - lp0).sqrnorm()));
2691  typename MeshType::Scalar d = b|a;
2692  typename MeshType::Point x = lp0 + a * d;
2693  double dist_new = (hitPointP - x).length();*/
2694 
2695  if (dist_new < closest_dist || closest_dist == -1) {
2696  // save closest Edge
2697  closest_dist = dist_new;
2698  center = lp0 + (lp1 - lp0) * .5;
2699 
2700  }
2701  }
2702 
2703  return (OpenMesh::Vec3d)center;
2704 }
2705 
2706 //--------------------------------------------------------------------------------
2707 
2711 template< typename MeshType >
2712 OpenMesh::Vec3d MovePlugin::getNearestFace(MeshType* _mesh, uint _fh, OpenMesh::Vec3d &_hitPoint) {
2713 
2714  typename MeshType::FaceHandle fh = _mesh->face_handle(_fh);
2715 
2716  if ( !fh.is_valid() )
2717  return OpenMesh::Vec3d(0.0, 0.0, 0.0);
2718 
2719  typename MeshType::FaceVertexIter fv_it(*_mesh, fh);
2720 
2721  typename MeshType::Point cog(0.0,0.0,0.0);
2722  uint count = 0;
2723 
2724  for (; fv_it.is_valid(); ++fv_it) {
2725 
2726  cog += _mesh->point(*fv_it);
2727  ++count;
2728  }
2729 
2730  return (OpenMesh::Vec3d)cog/count;
2731 }
2732 
2733 //--------------------------------------------------------------------------------
2734 
2735 void MovePlugin::slotAllCleared(){
2736  activeManipulators_.clear();
2737 }
2738 
2739 //--------------------------------------------------------------------------------
2740 
2741 void MovePlugin::objectDeleted( int _id ){
2742 
2743  for (uint i=0; i < activeManipulators_.size(); i++)
2744  if ( activeManipulators_[i] == _id ){
2745  activeManipulators_.erase( activeManipulators_.begin() + i );
2746  return;
2747  }
2748 }
2749 
2750 //--------------------------------------------------------------------------------
2751 
2752 
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
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
SelectionType selectionType_
Current SelectionType of SelectionPlugin.
Definition: MovePlugin.hh:435
#define DATA_POLYHEDRAL_MESH
PolyLine * polyLine(BaseObjectData *_object)
Get a poly Line from an object.
TetrahedralMeshObject * tetrahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an TetrahedralMeshObject if possible.
QMenu * contextMenuManipControl_
Additional Context Menu replicating the toolbar stuff.
Definition: MovePlugin.hh:488
QAction * toAllTargets_
Checked if transformation should be applied to all target objs.
Definition: MovePlugin.hh:485
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
double manip_size_modifier_
Modifier for the Size (changed by Mousewheel Events)
Definition: MovePlugin.hh:403
void slotPickModeChanged(const std::string &_mode)
slot is called when the pickMode changed
Definition: MovePlugin.cc:523
QActionGroup * pickToolBarActions_
Called by pick Toolbar.
Definition: MovePlugin.hh:307
QAction * contextMenuManipControlsAction_
Action holding the context menu for toolbar replication.
Definition: MovePlugin.hh:491
void translate(int _objectId, Vector _vector)
translate an Object by a given vector
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
void slotToggleAxisB()
Toggle the second axis for changing direction in tab.
Definition: MovePlugin.cc:1124
const Vec3d & center() const
get center
void translateEdgeSelection(int _objectId, Vector _vector)
translate current edge selection of an Object by a given vector
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
void pluginsInitialized()
Initialization of the plugin when it is loaded by the core.
Definition: MovePlugin.cc:156
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
int lastActiveManipulator_
Stores the last manipulator which has been clicked ( used for the toolbox dialog) ...
Definition: MovePlugin.hh:406
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
void slotUnifyBoundingBoxDiagonal()
Scale Boundingbox Diagonal to unit size.
Definition: MovePlugin.cc:1895
void moveObject(ACG::Matrix4x4d mat, int _id)
Move an object with given id.
Definition: MovePlugin.cc:572
const GLMatrixd & matrix() const
Returns a const reference to the current transformation matrix.
void transpose()
transpose matrix
bool is_identity() const
check if the matrix is the identity ( up to an epsilon )
Definition: Matrix4x4T.hh:214
void slotMouseEvent(QMouseEvent *_event)
MousePress event occured.
Definition: MovePlugin.cc:399
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
QToolBar * pickToolbar_
Called by pick Toolbar.
Definition: MovePlugin.hh:291
#define DATA_TETRAHEDRAL_MESH
void slotTranslation()
perform a translation for Manipulator in tab
Definition: MovePlugin.cc:1228
#define DATA_HEXAHEDRAL_MESH
#define DATA_SKELETON
Definition: Skeleton.hh:64
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void setPickModeProps(movePropsWidget *_pW, const std::string &_pickmode)
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.cc:493
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void unifyBB(MeshT &_mesh, Unificationtype u=MovePlugin::DIAGONAL)
scale mesh to have a boundingboxdiagonal of one
Definition: MovePlugin.cc:2434
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
void identity()
setup an identity matrix
void translateVertexSelection(int _objectId, Vector _vector)
translate current vertex selection of an Object by a given vector
const QStringList ALL_OBJECTS
Iterable object range.
void ManipulatorPositionChanged(QtTranslationManipulatorNode *_node)
update object when its manipulator changes position
Definition: MovePlugin.cc:829
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:587
void showManipulators()
Checks if the manipulators should be visible or not.
Definition: MovePlugin.cc:975
void slotUpdateContextMenuNode(int _nodeId)
Hide context menu entry when right clicking on node other than manipulator node.
Definition: MovePlugin.cc:751
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)
QAction * rotateManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:295
void transform(const ACG::Matrix4x4d &_mat)
Transform the plane with given matrix.
Definition: PlaneType.cc:89
QAction * moveAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:271
QAction * resizeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:296
int id() const
Definition: BaseObject.cc:190
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
#define DATA_POLY_LINE
Definition: PolyLine.hh:64
Unificationtype
stores the current axes in the tool
Definition: MovePlugin.hh:198
void slotMoveManipToCOG()
Move the current manipulator to the cog of the object.
Definition: MovePlugin.cc:1354
void slotSetPosition()
Position of manipulator in tab changed.
Definition: MovePlugin.cc:1029
QtTranslationManipulatorNode * manipulatorNode()
std::vector< int > activeManipulators_
Size for the manipulators.
Definition: MovePlugin.hh:323
bool invert()
matrix inversion (returns true on success)
Skeleton transformation class.
QToolBar * toolbar_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:276
Scalar max() const
return the maximal component
Definition: Vector11T.hh:517
void slotUnifyBoundingBoxLongestAxis()
Scale Boundingbox longest axis to unit size (keeps aspect ratio)
Definition: MovePlugin.cc:1900
OpenMesh::Vec3d getNearestFace(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest face to hitpoint.
Definition: MovePlugin.cc:2712
moveToolbarWidget * tool_
Widget for Toolbox.
Definition: MovePlugin.hh:259
void setAllTargets(bool _state)
Sets whether all targets should be affected or not.
Definition: MovePlugin.cc:2625
Viewer::ActionMode actionMode()
Get the current Action mode.
void setViewObjectMarker(ViewObjectMarker *_marker)
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:559
void slotMoveToOrigin()
Move target Meshes cog to the origin.
Definition: MovePlugin.cc:1722
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 slotEnableObjectMode()
stores the current axes in the tool
Definition: MovePlugin.cc:480
void slotToggleAxisA()
Toggle the first axis for changing direction in tab.
Definition: MovePlugin.cc:1099
int targetCount()
Get the number of target objects.
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:77
void hideManipulator()
Hide the manipulator( Called via context for picking. Get the picked id from the Qvariant attached to...
double manip_size_
Size for the manipulators.
Definition: MovePlugin.hh:400
bool transformVertexSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
QAction * rotateTranslateAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:294
void placeManip(QMouseEvent *_event, bool _snap=false)
Place and show the Manipulator.
Definition: MovePlugin.cc:860
bool transformCellSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
QAction * moveSelectionAction_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:272
QAction * smallerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:299
void traverse(ACG::SceneGraph::MouseEventAction &_action)
void slotPickToolbarAction(QAction *_action)
Called by pick Toolbar.
Definition: MovePlugin.cc:2132
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
const std::string pickMode()
Get the current Picking mode.
QActionGroup * toolBarActions_
Called by Toolbar to enable move mode.
Definition: MovePlugin.hh:274
void update_vertex_normals()
A simple heuristic to estimate the vertex normals.
int getIdentifier()
Get an identifier for that manipulator.
int axisA_
stores the current axes in the tool
Definition: MovePlugin.hh:195
void set_vertex(const VertexHandle &_vh, const VecT &_p)
Set the coordinates of point _vh.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
QAction * contextAction_
Context menu entry for showing per manipulator settings.
Definition: MovePlugin.hh:479
bool transformedSelected_
stores if any selected elements where transformed
Definition: MovePlugin.hh:617
void unifyBoundingBox(Unificationtype u)
Size for the manipulators.
Definition: MovePlugin.cc:1910
MoveObjectMarker objectMarker_
Object marker to dimm Objects during manipulator transformation.
Definition: MovePlugin.hh:418
ObjectRange objects(IteratorRestriction _restriction, DataType _dataType)
Iterable object range.
void showProps()
Show properties of move manipulator in a dialog ( Called via context for picking. Get the picked id f...
void slotProjectToTangentPlane()
Project the current manipulator onto the tangent plane of the object.
Definition: MovePlugin.cc:1332
virtual const std::string & className() const =0
Return class name (implemented by the ACG_CLASSNAME macro)
~MovePlugin()
Destructor.
Definition: MovePlugin.cc:125
void transformMesh(ACG::Matrix4x4d _mat, MeshT &_mesh)
Transform a mesh with the given transformation matrix.
Definition: MovePlugin.cc:2206
bool toolboxActive_
True if the toolbox widget is active.
Definition: MovePlugin.hh:256
QtTranslationManipulatorNode::ManipulatorMode manMode_
Holds the current manipulator mode.
Definition: MovePlugin.hh:423
QAction * biggerManipAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:298
bool manipPlaced()
Check if the manipulator has been placed.
Plane * plane(BaseObjectData *_object)
Get a Plane from an object.
const VecT & vertex(const VertexHandle &_vh) const
Get point _vh&#39;s coordinates.
ACG::Matrix4x4d getLastManipulatorMatrix(bool _reset=true)
Get the Matrix of the last active Manipulator ( Identity if not found or hidden Manipulator ) ...
Definition: MovePlugin.cc:2180
void slotRotate()
Rotate Manipulator (with values from Tab)
Definition: MovePlugin.cc:1416
ManipulatorMode
enum to define the manipulator mode
void manipulatorMoved(QtTranslationManipulatorNode *_node, QMouseEvent *_event)
move the object when its manipulator moves
Definition: MovePlugin.cc:772
bool visible()
Is node visible (status == Active)?
Definition: BaseNode.hh:409
ViewObjectMarker * defaultViewObjectMarker()
Get the default ViewObjectMarker.
QIcon * toolIcon_
stores the current axes in the tool
Definition: MovePlugin.hh:261
const NormalAttrib & normals() const
return a pointer to the mesh
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
QList< movePropsWidget * > propsWindows_
List of properties dialogs (each corresponding to one manipulator)
Definition: MovePlugin.hh:476
QString generateLink(const QString &_ref="", const QString &_site="index.html") const
generates a clickable link to the documentation for whatsThis Messages
HexahedralMeshObject * hexahedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an HexahedralMeshObject if possible.
void slotEnableSelectionMode()
stores the current axes in the tool
Definition: MovePlugin.cc:474
#define DATA_PLANE
Definition: Plane.hh:58
MeshT * mesh()
return a pointer to the mesh
MovePlugin()
Default Constructor.
Definition: MovePlugin.cc:82
bool transformFaceSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
QAction * placeAndSnapAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:305
void slotScale()
Scale (with values from Tab)
Definition: MovePlugin.cc:1572
The Menu will be shown when a node was picked.
void updateManipulatorDialog()
Update the Dialog with the last clicked manipulator.
Definition: MovePlugin.cc:2044
void translateFaceSelection(int _objectId, Vector _vector)
translate current face selection of an Object by a given vector
void updateSelectionType()
Get current primitive selection.
Definition: MovePlugin.cc:2553
void setDescriptions()
Set Descriptions for scriptable functions.
movePropsWidget * getDialogWidget(BaseObjectData *_obj)
Get properties dialog widget that is attached to BaseDataObject obj.
Definition: MovePlugin.cc:2092
void setManipMode(QtTranslationManipulatorNode::ManipulatorMode _mode)
Set the manipulator manipulation mode.
Definition: MovePlugin.cc:669
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
void slotUnifyBoundingBoxAllAxis()
Scale all Boundingbox axis to unit size.
Definition: MovePlugin.cc:1905
OpenMesh::Vec3d getNearestEdge(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest edge to hitpoint.
Definition: MovePlugin.cc:2667
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
QAction * contextActionHide_
Context menu entry to hide a manipulator.
Definition: MovePlugin.hh:482
int axisB_
stores the current axes in the tool
Definition: MovePlugin.hh:196
QAction * placeAction_
Called by pick Toolbar.
Definition: MovePlugin.hh:293
void slotSetMoveMode(QAction *_action)
Called by Toolbar to enable move mode.
Definition: MovePlugin.cc:2107
void moveSelection(ACG::Matrix4x4d mat, int _id, QEvent::Type _type)
Move selection on an object with given id.
Definition: MovePlugin.cc:636
OpenMesh::Vec3d getNearestVertex(MeshType *_mesh, uint _fh, OpenMesh::Vec3d &_hitPoint)
Get closest vertex to hitpoint.
Definition: MovePlugin.cc:2635
void getBB(MeshT &_mesh, ACG::Vec3d &_bb_min, ACG::Vec3d &_bb_max)
get bounding box diagonal of a mesh
Definition: MovePlugin.cc:2488
void transformSkeleton(Matrix4x4 _transformation, Skeleton::Pose *_pose=0)
transform the skeleton
bool transformEdgeSelection(int _objectId, Matrix4x4 _matrix)
transform current selection of an Object by a given matrix
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void slotSetDirection()
Set Direction of manipulator in tab changed.
Definition: MovePlugin.cc:1149
movePropsWidget * getDialogFromButton(QPushButton *_but)
Get parent properties dialog widget of QPushButton but.
Definition: MovePlugin.cc:1019