transfuncwindowingeventlistener.cpp 4.05 KB
Newer Older
1
2
3
4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
6
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
11
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
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
// 
// ================================================================================================

25
#include "transfuncwindowingeventlistener.h"
26

27
28
#include "cgt/assert.h"
#include "cgt/event/mouseevent.h"
29
30
31
32
#include "core/classification/abstracttransferfunction.h"
#include "core/properties/transferfunctionproperty.h"

namespace campvis {
33
    const std::string TransFuncWindowingEventListener::loggerCat_ = "CAMPVis.core.eventhandler.TransFuncWindowingEventListener";
34

35
36
    TransFuncWindowingEventListener::TransFuncWindowingEventListener(TransferFunctionProperty* property)
        : tgt::EventListener()
37
        , _prop(property)
38
39
40
        , _mousePressed(false)
        , _mouseDownPosition(0, 0)
        , _originalIntensityDomain(0.f, 1.f)
41
42
43
    {
    }

44
    TransFuncWindowingEventListener::~TransFuncWindowingEventListener() {
45
46
47

    }

48
    void TransFuncWindowingEventListener::onEvent(tgt::Event* e) {
49
50
        if (_prop == nullptr)
            return;
51
52
        if (typeid(*e) != typeid(tgt::MouseEvent))
            return;
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

        // this is only to be executed when the event was accepted, so the static cast is safe.
        tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);
        if (me->action() == tgt::MouseEvent::PRESSED) {
            _mousePressed = true;
            _mouseDownPosition = tgt::ivec2(me->x(), me->y());
            _originalIntensityDomain = _prop->getTF()->getIntensityDomain();
            e->ignore();
        }
        else if (_mousePressed && me->action() == tgt::MouseEvent::RELEASED) {
            _mousePressed = false;
            e->ignore();
        }
        else if (_mousePressed && me->action() == tgt::MouseEvent::MOTION) {
            tgt::ivec2 currentPosition(me->x(), me->y());
            tgt::ivec2 delta = currentPosition - _mouseDownPosition;

            // apply shift
            float shift = static_cast<float>(delta.x) / 1000.f;
            tgt::vec2 newIntesityDomain = _originalIntensityDomain + shift;

            // compute and apply scaling
            float scale = delta.y < 0 ? 1.f + (delta.y / -10.f) : 1.f / (1.f + (delta.y / 10.f));
            float length = newIntesityDomain.y - newIntesityDomain.x;
            float offset = (scale - 1.f) * (length / 2.f);
            // clamp to avoid scaling to empty interval
            offset = tgt::clamp(offset, -length/2.f + 0.001f, length/2.f - 0.001f);

            newIntesityDomain.x -= offset;
            newIntesityDomain.y += offset;

Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
84
85
86
87
            // triple-check for rock solid safety ;)
            if (newIntesityDomain.x > newIntesityDomain.y)
                std::swap(newIntesityDomain.x, newIntesityDomain.y);

88
89
90
91
92
            _prop->getTF()->setIntensityDomain(tgt::clamp(newIntesityDomain, tgt::vec2(0.f), tgt::vec2(1.f)));
            e->ignore();
        }
    }

93
94
95
96
    void TransFuncWindowingEventListener::setTransferFunctionProperty(TransferFunctionProperty* prop) {
        _prop = prop;
    }

97
}