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