1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/*****************************************************************************
* $CAMITK_LICENCE_BEGIN$
*
* CamiTK - Computer Assisted Medical Intervention ToolKit
* (c) 2001-2018 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
*
* Visit http://camitk.imag.fr for more information
*
* This file is part of CamiTK.
*
* CamiTK is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* CamiTK is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with CamiTK. If not, see <http://www.gnu.org/licenses/>.
*
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "BoxWidget.h"
#include "BoxWidgetVtkCommand.h"
#include <InteractiveViewer.h>
#include <ActionWidget.h>
#include <Property.h>
#include <Log.h>
#include <vtkBoxWidget.h>
#include <vtkRenderWindow.h>
#include <QVector3D>
using namespace camitk;
// -------------------- constructor --------------------
BoxWidget::BoxWidget(ActionExtension* extension) : Action(extension) {
setName("Box Widget");
setDescription("Add a VTK 3D Widget to the 3D viewer.<br/>Mouse interaction<ul><li>Left button: grab on the six face handles → slide the faces</li><li>Left button: grab the center handle → move the entire box</li><li>Shift+Left button: inside the widget → Translation</li><li>Right button: inside the widget → up/down scaling</li><li>Left mouse: pick a face (not a face handle) → rotate (if <i>Rotation Enabled</i> is ticked)</li></ul>");
setComponent(""); // nothing needed
setFamily("VTK Widget");
addTag("Demo");
addTag("3D Interaction");
setProperty("Translation Enabled", QVariant(true));
setProperty("Scaling Enabled", QVariant(true));
setProperty("Rotation Enabled", QVariant(false));
// Read-only parameter
Property* readOnlyProperty = new Property("Bottom Corner", QVector3D(0.0, 0.0, 0.0), "Bottom corner coordinates, automatically updated when the box widget is modified", "");
readOnlyProperty->setReadOnly(true);
addParameter(readOnlyProperty);
readOnlyProperty = new Property("Top Corner", QVector3D(1.0, 1.0, 1.0), "Top corner coordinates, automatically updated when the box widget is modified", "");
readOnlyProperty->setReadOnly(true);
addParameter(readOnlyProperty);
boxWidget = nullptr;
boxWidgetCommand = nullptr;
}
// --------------- destructor -------------------
BoxWidget::~BoxWidget() {
// CAMITK_INFO_IF((boxWidget!=nullptr),tr("pointer=%1, reference count=%2").arg(QString("0x%1").arg((quintptr)boxWidget.GetPointer(),
// QT_POINTER_SIZE * 2, 16, QChar('0')),QString::number(boxWidget->GetReferenceCount())))
}
// --------------- getWidget -------------------
QWidget* BoxWidget::getWidget() {
if (boxWidget == nullptr) {
vtkRenderWindowInteractor* iren = InteractiveViewer::get3DViewer()->getRendererWidget()->GetRenderWindow()->GetInteractor();
// Configure the box widget including callbacks
boxWidget = vtkSmartPointer<vtkBoxWidget>::New();
boxWidget->SetInteractor(iren);
boxWidget->InsideOutOff();
boxWidget->SetPlaceFactor(1);
// Initialize the dimension using the current bounding box
double bounds[6];
InteractiveViewer::get3DViewer()->getBounds(bounds);
boxWidget->PlaceWidget(bounds);
// Set box possible interactions
boxWidget->SetTranslationEnabled(property("Translation Enabled").toBool());
boxWidget->SetScalingEnabled(property("Scaling Enabled").toBool());
boxWidget->SetRotationEnabled(property("Rotation Enabled").toBool());
// add the call back
boxWidgetCommand = new BoxWidgetVtkCommand(this);
boxWidget->AddObserver(vtkCommand::EndInteractionEvent, boxWidgetCommand);
// Activate the box
boxWidget->EnabledOn();
}
return Action::getWidget();
}
// --------------- apply -------------------
Action::ApplyStatus BoxWidget::apply() {
// nothing is needed here, just check the user modifications for the possible interactions
boxWidget->SetTranslationEnabled(property("Translation Enabled").toBool());
boxWidget->SetScalingEnabled(property("Scaling Enabled").toBool());
boxWidget->SetRotationEnabled(property("Rotation Enabled").toBool());
return SUCCESS;
}
// --------------- updateWidget -------------------
void BoxWidget::updateWidget() {
// update action's widget from modified property (this is not the "usual" way, normally
// the user modify some property in the widget and the action gets the value to do
// something. In this case, the action's property is modified by some external
// mechanism (not the user), e.g. here the vtkBoxWidget, therefore the action's widget has
// to be updated
dynamic_cast<camitk::ActionWidget*>(Action::getWidget())->update();
}
|