2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

transferfunctionpropertywidget.cpp 7.25 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
26
#include "transferfunctionpropertywidget.h"

schultezub's avatar
schultezub committed
27
28
#include "application/gui/properties/abstracttransferfunctioneditor.h"
#include "application/gui/properties/transferfunctioneditorfactory.h"
29
#include "application/campvisapplication.h"
30
#include "core/datastructures/imagerepresentationlocal.h"
31

schultezub's avatar
schultezub committed
32
33
34
35
36
#include <QDockWidget>
#include <QDoubleSpinBox>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
37
#include <QCheckBox>
schultezub's avatar
schultezub committed
38

schultezub's avatar
schultezub committed
39
namespace campvis {
40
41
    TransferFunctionPropertyWidget::TransferFunctionPropertyWidget(TransferFunctionProperty* property, DataContainer* dataContainer /*= nullptr*/, QWidget* parent /*= 0*/)
        : AbstractPropertyWidget(property, true, dataContainer, parent)
schultezub's avatar
schultezub committed
42
43
44
45
46
        , _widget(0)
        , _gridLayout(0)
        , _lblDomain(0)
        , _spinDomainLeft(0)
        , _spinDomainRight(0)
47
48
        , _cbAutoFitDomainToImage(0)
        , _btnFitDomainToImage(0)
schultezub's avatar
schultezub committed
49
        , _btnEditTF(0)
schultezub's avatar
schultezub committed
50
        , _dockWidget(0)
schultezub's avatar
schultezub committed
51
        , _editor(0)
schultezub's avatar
schultezub committed
52
53
54
55
56
    {
        _widget = new QWidget(this);
        _gridLayout = new QGridLayout(_widget);
        _widget->setLayout(_gridLayout);

57
        _lblDomain = new QLabel("Window:", _widget);
schultezub's avatar
schultezub committed
58
59
60
61
        _gridLayout->addWidget(_lblDomain, 0, 0);


        _spinDomainLeft = new QDoubleSpinBox(_widget);
62
        _spinDomainLeft->setMinimum(-10000);
schultezub's avatar
schultezub committed
63
64
65
66
67
        _spinDomainLeft->setDecimals(2);
        _spinDomainLeft->setSingleStep(0.01);
        _gridLayout->addWidget(_spinDomainLeft, 0, 1);

        _spinDomainRight = new QDoubleSpinBox(_widget);
68
        _spinDomainRight->setMaximum(10000);
schultezub's avatar
schultezub committed
69
70
71
72
        _spinDomainRight->setDecimals(2);
        _spinDomainRight->setSingleStep(0.01);
        _gridLayout->addWidget(_spinDomainRight, 0, 2);

73
74
        _btnFitDomainToImage = new QPushButton("Fit", _widget);
        _gridLayout->addWidget(_btnFitDomainToImage, 0, 3);
75

76
77
78
        _cbAutoFitDomainToImage = new QCheckBox("Auto", _widget);
        _gridLayout->addWidget(_cbAutoFitDomainToImage, 0, 4);

schultezub's avatar
schultezub committed
79
        _btnEditTF = new QPushButton("Edit Transfer Function", _widget);
80
        _gridLayout->addWidget(_btnEditTF, 1, 1, 1, 4);
schultezub's avatar
schultezub committed
81
82
83

        addWidget(_widget);

84
        updateWidgetFromProperty();
85

schultezub's avatar
schultezub committed
86
87
88
        connect(_spinDomainLeft, SIGNAL(valueChanged(double)), this, SLOT(onDomainChanged(double)));
        connect(_spinDomainRight, SIGNAL(valueChanged(double)), this, SLOT(onDomainChanged(double)));
        connect(_btnEditTF, SIGNAL(clicked(bool)), this, SLOT(onEditClicked(bool)));
89
        connect(_btnFitDomainToImage, SIGNAL(clicked(bool)), this, SLOT(onFitClicked(bool)));
90
91
92
        connect(_cbAutoFitDomainToImage, SIGNAL(stateChanged(int)), this, SLOT(onAutoFitDomainToImageChanged(int)));

        property->s_autoFitWindowToDataChanged.connect(this, &TransferFunctionPropertyWidget::onTransferFunctionAutoFitWindowToDataChanged);
schultezub's avatar
schultezub committed
93
94
95
    }

    TransferFunctionPropertyWidget::~TransferFunctionPropertyWidget() {
96
        static_cast<TransferFunctionProperty*>(_property)->s_autoFitWindowToDataChanged.disconnect(this);
schultezub's avatar
schultezub committed
97
        delete _dockWidget;
schultezub's avatar
schultezub committed
98
99
100
101
102
103
104
105
    }

    void TransferFunctionPropertyWidget::updateWidgetFromProperty() {
        TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
        AbstractTransferFunction* tf = prop->getTF();
        const tgt::vec2& domain = tf->getIntensityDomain();

        _spinDomainLeft->blockSignals(true);
106
        _spinDomainLeft->setMaximum(domain.y);
schultezub's avatar
schultezub committed
107
108
109
110
        _spinDomainLeft->setValue(domain.x);
        _spinDomainLeft->blockSignals(false);

        _spinDomainRight->blockSignals(true);
111
        _spinDomainRight->setMinimum(domain.x);
schultezub's avatar
schultezub committed
112
113
        _spinDomainRight->setValue(domain.y);
        _spinDomainRight->blockSignals(false);
114
115
116
117

        _cbAutoFitDomainToImage->blockSignals(true);
        _cbAutoFitDomainToImage->setChecked(prop->getAutoFitWindowToData());
        _cbAutoFitDomainToImage->blockSignals(false);
schultezub's avatar
schultezub committed
118
119
120
121
    }

    void TransferFunctionPropertyWidget::onDomainChanged(double value) {
        TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
schultezub's avatar
schultezub committed
122
        ++_ignorePropertyUpdates;
123
124
        _spinDomainLeft->setMaximum(_spinDomainRight->value());
        _spinDomainRight->setMinimum(_spinDomainLeft->value());
schultezub's avatar
schultezub committed
125
126
        tgt::vec2 newDomain(static_cast<float>(_spinDomainLeft->value()), static_cast<float>(_spinDomainRight->value()));
        prop->getTF()->setIntensityDomain(newDomain);
schultezub's avatar
schultezub committed
127
        --_ignorePropertyUpdates;
schultezub's avatar
schultezub committed
128
129
130
    }

    void TransferFunctionPropertyWidget::onEditClicked(bool checked) {
schultezub's avatar
schultezub committed
131
132
        if (_editor == 0) {
            TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
133
            _editor = TransferFunctionEditorFactory::createEditor(prop);
schultezub's avatar
schultezub committed
134
135
136
137

            _dockWidget = new QDockWidget("Transfer Function Editor");
            _dockWidget->setWidget(_editor);

138
139
140
141
            static_cast<CampVisApplication*>(qApp)->registerDockWidget(Qt::BottomDockWidgetArea, _dockWidget);
        } else {
          _dockWidget->setVisible(true);
        }
schultezub's avatar
schultezub committed
142
143
    }

144
145
146
147
    void TransferFunctionPropertyWidget::onFitClicked(bool checked) {
        TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
        AbstractTransferFunction* tf = prop->getTF();

148
        DataHandle dh = prop->getImageHandle();
149
        if (dh.getData() != 0) {
150
            const ImageRepresentationLocal* idl = static_cast<const ImageData*>(dh.getData())->getRepresentation<ImageRepresentationLocal>();
151
152
153
154
155
156
157
            if (idl != 0) {
                Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
                tf->setIntensityDomain(tgt::vec2(intensityInterval.getLeft(), intensityInterval.getRight()));
            }
        }
    }

158
159
160
161
162
163
164
165
166
    void TransferFunctionPropertyWidget::onAutoFitDomainToImageChanged(int state) {
        TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
        prop->setAutoFitWindowToData(state != Qt::Unchecked);
    }

    void TransferFunctionPropertyWidget::onTransferFunctionAutoFitWindowToDataChanged() {
        emit s_propertyChanged(_property);
    }

schultezub's avatar
schultezub committed
167
168

}