abstracttransferfunction.h 7.87 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, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
8
9
//      Chair for Computer Aided Medical Procedures
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
schultezub's avatar
schultezub committed
10
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

30
31
32
33
34
35
36
37
#ifndef ABSTRACTTRANSFERFUNCTION_H__
#define ABSTRACTTRANSFERFUNCTION_H__

#include "sigslot/sigslot.h"
#include "tgt/vector.h"
#include "tbb/include/tbb/atomic.h"
#include "tbb/include/tbb/mutex.h"

38
39
40
#include "core/datastructures/datahandle.h"
#include "core/tools/concurrenthistogram.h"

41
42
43
44
#include <string>

namespace tgt {
    class Shader;
45
    class Texture;
46
47
48
    class TextureUnit;
}

schultezub's avatar
schultezub committed
49
namespace campvis {
50
51
52
53
54
55
56
57
58
59
60
61
62
63

    /**
     * Abstract base class for transfer functions.
     * 
     * The granularity of the transfer function is determined by its size which is directly mapped to 
     * the OpenGL texture size. During classification the transfer function is mapped to the intensity 
     * domain.
     * 
     * \note    Transfer function objects are supposed to be thread-safe as follows:
     *          a) Access to non-OpenGL internals is protected by the local mutex.
     *          b) All OpenGL-related methods must be called by a thread with a valid and locked OpenGL
     *             context. Even though other internals might be changed meanwhile, this ensures that
     *             the OpenGL stuff (e.g. the texture) stays valid for this time.
     * 
64
     * \todo    Check thread-safety, the private local lock is probably not the best design.
65
66
67
     */
    class AbstractTransferFunction {
    public:
68
69
        typedef ConcurrentGenericHistogramND<float, 1> IntensityHistogramType;

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
        /**
         * Creates a new AbstractTransferFunction.
         * \param   size            Size of the transfer function texture
         * \param   intensityDomain Intensity Domain where the transfer function is mapped to during classification
         */
        AbstractTransferFunction(const tgt::svec3& size, const tgt::vec2& intensityDomain = tgt::vec2(0.f, 1.f));

        /**
         * Destructor, make sure to delete the OpenGL texture beforehand by calling deinit() with a valid OpenGL context!
         */
        virtual ~AbstractTransferFunction();

        /**
         * Deletes the OpenGL texture, hence, this methods has to be called from a thread with a valid OpenGL context!
         */
        virtual void deinit();

        /**
         * Returns the dimensionality of the transfer function.
         * \return  The dimensionality of the transfer function.
         */
        virtual size_t getDimensionality() const = 0;

        /**
         * Binds the transfer function OpenGL texture to the given texture and sets up uniforms.
         * \note    Calling thread must have a valid OpenGL context.
         * \param   shader                      Shader used for rendering
         * \param   texUnit                     Texture unit to bind texture to
98
         * \param   transFuncUniform            Uniform name to store the TF struct
99
         */
100
        void bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& transFuncUniform = "_transferFunction");
101
102
103
104
105
106
        
        /**
         * Creates the OpenGL texture.
         * \note    Calling thread must have a valid OpenGL context.
         */
        void uploadTexture();
107
108

        /**
109
         * Sets the intensity domain where the transfer function is mapped to during classification.
110
111
112
113
         * \param   newDomain   new intensity domain
         */
        void setIntensityDomain(const tgt::vec2& newDomain);

114
115
116
117
118
119
        /**
         * Returns the intensity domain where the transfer function is mapped to during classification.
         * \return _intensityDomain
         */
        const tgt::vec2& getIntensityDomain() const;

120
121
122
123
124
125
126
        /**
         * Gets the OpenGL lookup texture storing the TF.
         * \note    Calling thread must have a valid OpenGL context.
         * \return  _texture
         */
        const tgt::Texture* getTexture();

127
128
129
130
        /**
         * Returns a DataHandle to the image for this transfer function, may be 0.
         * \return  _imageHandle, may be 0!
         */
131
        DataHandle getImageHandle() const;
132
133
134
135

        /**
         * Sets the DataHandle for this transfer function, may be 0.
         * \note    This method makes a copy of \a imageHandle, hence does not take ownership.
136
         * \param   imageHandle     The new DataHandle for this transfer function
137
         */
138
        void setImageHandle(const DataHandle& imageHandle);
139
140
141
142
143
144
145
146

        /**
         * Returns the intensity histogram
         * \todo    This is NOT thread-safe!
         * \return  _intensityHistogram
         */
        const IntensityHistogramType* getIntensityHistogram() const;

147
        /// Signal emitted when transfer function has changed.
schultezub's avatar
schultezub committed
148
        sigslot::signal0<> s_changed;
149

150
151
152
        /// Signal emitted when the image DataHandle for this TF has changed.
        sigslot::signal0<> s_imageHandleChanged;

153
    protected:
154
155
156
157
158
        /**
         * Computes the intensity histogram;
         */
        void computeIntensityHistogram() const;

159
160
161
162
163
164
        /**
         * Creates the texture and uploads it to OpenGL.
         * Gets called by bind() with the local mutex already acquired.
         */
        virtual void createTexture() = 0;

165
166
167
168
169
        tgt::svec3 _size;                   ///< Size of the transfer function texture
        tgt::vec2 _intensityDomain;         ///< Intensity Domain where the transfer function is mapped to during classification
        tgt::Texture* _texture;             ///< OpenGL lookup texture storing the TF
        tbb::atomic<bool> _dirtyTexture;    ///< Flag whether the OpenGL texture has to be updated

170
        DataHandle _imageHandle;                                ///< DataHandle to the image for this transfer function. May be 0.
171
        mutable IntensityHistogramType* _intensityHistogram;    ///< Intensity histogram of the intensity in _imageHandle for the current _intensityDomain
172
        mutable tbb::atomic<bool> _dirtyHistogram;              ///< Flag whether the intensity histogram has to be updated.
173
174
175
176
177
178
179
180
181
182

        mutable tbb::mutex _localMutex; ///< mutex protecting the local members

        static const std::string loggerCat_;

    };

}

#endif // ABSTRACTTRANSFERFUNCTION_H__