File: BoxWidget.cpp

package info (click to toggle)
camitk 5.2.0-5
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 358,388 kB
  • sloc: cpp: 86,984; xml: 1,295; sh: 1,280; ansic: 142; makefile: 112; perl: 84; sed: 20
file content (135 lines) | stat: -rw-r--r-- 5,744 bytes parent folder | download
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
125
126
127
128
129
130
131
132
133
134
135
/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2024 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * 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 <InteractiveGeometryViewer.h>
#include <ActionWidget.h>
#include <Property.h>
#include <Log.h>

// disable warning generated by clang about the surrounded headers
#include <CamiTKDisableWarnings>
#include <vtkBoxWidget.h>
#include <vtkRenderWindow.h>
#include <CamiTKReEnableWarnings>

#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>");
    setComponentClassName(""); // 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() {
}

// --------------- getWidget -------------------
QWidget* BoxWidget::getWidget() {
    if (boxWidget == nullptr) {
        InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));

        if (default3DViewer == nullptr) {
            CAMITK_WARNING(tr("Cannot find \"3D Viewer\". This viewer is mandatory for running this action."))
        }
        else {
#if VTK_MAJOR_VERSION < 9
            vtkRenderWindowInteractor* iren = default3DViewer->getRendererWidget()->GetRenderWindow()->GetInteractor();
#else
            vtkRenderWindowInteractor* iren = default3DViewer->getRendererWidget()->renderWindow()->GetInteractor();
#endif

            // 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];
            default3DViewer->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();
}