Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

imagedata.h 10.9 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
#ifndef IMAGEDATA_H__
#define IMAGEDATA_H__
schultezub's avatar
schultezub committed
27

28
#include <tbb/concurrent_vector.h>
29
30
#include <tbb/spin_mutex.h>

31
32
#include "cgt/logmanager.h"
#include "cgt/vector.h"
33
34

#include "core/coreapi.h"
schultezub's avatar
schultezub committed
35
#include "core/datastructures/abstractdata.h"
36
#include "core/datastructures/abstractimagerepresentation.h"
schultezub's avatar
schultezub committed
37
#include "core/datastructures/imagemappinginformation.h"
38
#include "core/datastructures/imagerepresentationconverter.h"
39

40
#include <vector>
schultezub's avatar
schultezub committed
41

schultezub's avatar
schultezub committed
42
namespace campvis {
43

schultezub's avatar
schultezub committed
44
45
    /**
     * Stores basic information about one (semantic) image of arbitrary dimension.
46
     * Different representations (e.g. local memory, OpenGL texture) are
schultezub's avatar
schultezub committed
47
48
     * to be defined by inheritance.
     */
49
    class CAMPVIS_CORE_API ImageData : public AbstractData, public IHasWorldBounds {
50
51
52
    // friend so that it can add itself as representation
    friend class AbstractImageRepresentation;

schultezub's avatar
schultezub committed
53
    public:
54
55
56
57
58
59
        /**
         * Creates a new ImageData instance with the given parameters.
         * \param dimensionality    Dimensionality of this image
         * \param size              Size of this image (number of elements per dimension)
         * \param numChannels       Number of channels per element
         */
60
        explicit ImageData(size_t dimensionality, const cgt::svec3& size, size_t numChannels);
schultezub's avatar
schultezub committed
61

62
        /// Destructor
schultezub's avatar
schultezub committed
63
64
        virtual ~ImageData();

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
        /**
         * Prototype - clone method, some people call this virtual constructor...
         * \note    Deep-copies all contained representations!
         * \return  A copy of this object.
         */
        virtual ImageData* clone() const;

        /**
         * Returns the local memory footprint of the data in bytes.
         * \return  Number of bytes occupied in local memory by the data.
         */
        virtual size_t getLocalMemoryFootprint() const;

        /**
         * Returns the video memory footprint of the data in bytes.
         * \return  Number of bytes occupied in video memory by the data.
         */
        virtual size_t getVideoMemoryFootprint() const;

84
85
86
87
88
89
        /**
         * Returns a human readable representation of the data type that can be used for the GUI.
         * \return  A string with the type name to be used for the GUI.
         */
        virtual std::string getTypeAsString() const;

schultezub's avatar
schultezub committed
90
91
92
93
94
95
96
97
98
99
        /**
         * Dimensionality of this image.
         * \return _dimensionality
         */
        size_t getDimensionality() const;

        /**
         * Size of this image (number of elements per dimension).
         * \return _size
         */
100
        const cgt::svec3& getSize() const;
schultezub's avatar
schultezub committed
101

102
103
104
105
106
107
        /**
         * Returns the number of channels per element.
         * \return  _numChannels
         */
        size_t getNumChannels() const;

108
        /**
109
         * Returns the number of elements (= cgt::hmul(getSize())).
110
111
112
113
         * \return  _numElements
         */
        size_t getNumElements() const;

schultezub's avatar
schultezub committed
114
115
116
117
118
119
        /**
         * Mapping information of this image
         * \return _mappingInformation
         */
        const ImageMappingInformation& getMappingInformation() const;

120
121
122
123
124
125
        /**
         * Sets the mapping information for this image to \a imi.
         * \param   imi The new ImageMappingInformation for this image.
         */
        void setMappingInformation(const ImageMappingInformation& imi);

schultezub's avatar
schultezub committed
126
        /**
127
128
         * Returns the image extent in world coordinates.
         * \return  The image extent in world coordinates.
schultezub's avatar
schultezub committed
129
         */
130
        virtual cgt::Bounds getWorldBounds() const;
schultezub's avatar
schultezub committed
131

schultezub's avatar
schultezub committed
132
133
134
135
136
137
        /**
         * Returns the image extent in world coordinates for the given voxel coordinates.
         * \param   llf     Lower-left-front in voxel coordinates.
         * \param   urb     Upper-right-back in voxel coordinates.
         * \return  The image extent in world coordinates for the given voxel coordinates.
         */
138
        cgt::Bounds getWorldBounds(const cgt::svec3& llf, const cgt::svec3& urb) const;
schultezub's avatar
schultezub committed
139

140
141
142
143
144
145
146
        /**
         * Transforms a vector based position to the corresponding array index.
         * \note    Caution, this method might return wrong results for non-continuous storage.
         *          In this case you should provide an appropriate overload.
         * \param   position    Vector based image coordinates
         * \return  Array index when image is stored continuously.
         */
147
        size_t positionToIndex(const cgt::svec3& position) const;
148

149
150
151
152
153
154
155
        /**
         * Transforms an array index to the corresponding vector based position.
         * \note    Caution, this method might return wrong results for non-continuous storage.
         *          In this case you should provide an appropriate overload.
         * \param   index   Array index when image is stored continuously.
         * \return  Vector based image coordinates.
         */
156
        cgt::svec3 indexToPosition(size_t index) const;
157
158
159

        /**
         * Returns a representation of this image of type \a T.
160
         * Looks, whether such a representations already exists, if not and \a performConversion is 
161
         * set, the method tries to create it via T::tryConvertFrom(). Returns 0 on failure.
162
163
         * \note    You do \b NOT have ownership of the returned pointer!
         *          The returned pointer is valid as long as this ImageData object exists.
164
         * \note    If \a T is OpenGL related, make sure to call this method from a valid and locked OpenGL context.
165
166
167
         * \param   performConversion   Flag whether to perform representation conversion if necessary.
         * \return  A pointer to a representation of type \a T, you do NOT have ownership, valid as long 
         *          as this ImageData object exists. 0 if no such representation could be created.
168
169
         */
        template<typename T>
170
        const T* getRepresentation(bool performConversion = true) const;
171

172
    protected:
173
174
175
        template<typename T>
        const T* tryPerformConversion() const;

176
177
178
179
180
181
182
183
184
185
186
187
188
189
        /**
         * Adds the given representation to the list of representations.
         * \note    Since this is non-publich method, no sanity checks are performed!
         * \param   representation  representation to add, must not be 0.
         */
        void addRepresentation(const AbstractImageRepresentation* representation);

        /**
         * Sets the initial representation of this ImageData.
         * \note    Removes and deletes all existing representations.
         * \param   representation  Initial representation of this image.
         */
        void setInitialRepresentation(const AbstractImageRepresentation* representation);

190
191
192
        /**
         * Clears all representations from the vector and frees the memory.
         * \note    Make sure to call this method only when nobody else holds pointers to the
193
         *          representations as they will be invalidated. This method is \b not thread-safe!
194
195
196
197
         */
        void clearRepresentations();

        /// List of all representations of this image. Mutable to allow lazy instantiation of new representations.
198
        mutable tbb::concurrent_vector<const AbstractImageRepresentation*> _representations;
199

200
        const size_t _dimensionality;                   ///< Dimensionality of this image
201
        const cgt::svec3 _size;                         ///< Size of this image (number of elements per dimension)
202
        const size_t _numChannels;                      ///< Number of channels per element
203
        const size_t _numElements;                      ///< number of elements (= cgt::hmul(size))
schultezub's avatar
schultezub committed
204
205
        ImageMappingInformation _mappingInformation;    ///< Mapping information of this image

206
207
208
        /// Mutex protecting the representation conversions to ensure that there is only one conversion happening at a time.
        mutable tbb::spin_mutex _conversionMutex;

schultezub's avatar
schultezub committed
209
210
211
        static const std::string loggerCat_;
    };

212
213
214
215

// = Template definition ==========================================================================

    template<typename T>
216
    const T* campvis::ImageData::getRepresentation(bool performConversion) const {
217
        // look, whether we already have a suitable representation
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
218
        for (auto it = _representations.begin(); it != _representations.end(); ++it) {
219
220
            if (const T* tester = dynamic_cast<const T*>(*it)) {
                return tester;
221
            }
222
223
        }

224
        // no representation found, create a new one
225
        if (performConversion) {
226
227
228
            tbb::spin_mutex::scoped_lock lock(_conversionMutex);

            // in the meantime, there something might have changed, so check again whether there is a new rep.
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
229
            for (auto it = _representations.begin(); it != _representations.end(); ++it) {
230
231
232
233
234
                if (const T* tester = dynamic_cast<const T*>(*it)) {
                    return tester;
                }
            }

235
236
            return tryPerformConversion<T>();
        }
237

238
239
240
241
242
        return 0;
    }

    template<typename T>
    const T* campvis::ImageData::tryPerformConversion() const {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
243
        for (auto it = _representations.begin(); it != _representations.end(); ++it) {
244
            const T* tester = ImageRepresentationConverter::getRef().tryConvertFrom<T>(*it);
245
            if (tester != 0) {
246
                //LDEBUG("Performed a image representation conversion from " + std::string(typeid(**it).name()) + " to " + std::string(typeid(T).name()) + ".");
247
248
                return tester;
            }
249
250
        }

251
        // could not create a suitable representation
252
        LWARNING("Could not create a " + std::string(typeid(T).name()) + " representation.");
253
254
        return 0;
    }
255

schultezub's avatar
schultezub committed
256
257
}

schultezub's avatar
schultezub committed
258
#endif // IMAGEDATA_H__