datacontainerinspectorcanvas.cpp 27.5 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-2013, 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 Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, 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
25
26
27
28
// 
// ================================================================================================

#include "datacontainerinspectorcanvas.h"

#include "tgt/assert.h"
#include "tgt/shadermanager.h"
29
30
#include "tgt/textureunit.h"

31
32
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/datahandle.h"
33
#include "core/datastructures/renderdata.h"
34
#include "core/datastructures/imagerepresentationgl.h"
35
#include "core/datastructures/facegeometry.h"
36
#include "core/datastructures/geometrydatafactory.h"
37
#include "core/tools/job.h"
38
39
#include "core/classification/tfgeometry1d.h"
#include "core/classification/geometry1dtransferfunction.h"
40

41
42
#include "datacontainerinspectorwidget.h"

43
44
#include "ext/tgt/navigation/trackball.h"

45

schultezub's avatar
schultezub committed
46
namespace campvis {
47
48
49

    DataContainerInspectorCanvas::DataContainerInspectorCanvas(QWidget* parent /*= 0*/) 
        : tgt::QtThreadedCanvas("DataContainer Inspector", tgt::ivec2(640, 480), tgt::GLCanvas::RGBA_BUFFER, parent, true)
50
        , p_currentSlice("CurrentSlice", "Slice", -1, -1, -1)
51
        , p_meshSolidColor("MeshSolidColor", "Mesh Solid Color", tgt::vec4(.5f, .75f, .5f, 1), tgt::vec4(0.0f), tgt::vec4(1.0f))
52
        , p_transferFunction("TransferFunction", "Transfer Function", new Geometry1DTransferFunction(256, tgt::vec2(0.f, 1.f)))
53
54
55
56
        , p_renderRChannel("RenderRChannel", "Render Red Channel", true)
        , p_renderGChannel("RenderGChannel", "Render Green Channel", true)
        , p_renderBChannel("RenderBChannel", "Render Blue Channel", true)
        , p_renderAChannel("RenderAChannel", "Render Alpha Channel", true)
57
58
        , _dataContainer(0)
        , _paintShader(0)
59
        , _quad(0)
60
61
62
63
        , _numTiles(0, 0)
        , _quadSize(0, 0)
        , _selectedTexture(0)
        , _renderFullscreen(false)
64
        , _currentSlice(-1)
65
        , _color(0.0f, 0.0f, 0.0f, 0.0f)
66
        , _meshGeomTexturesDirty(false)
67
    {
68
        static_cast<Geometry1DTransferFunction*>(p_transferFunction.getTF())->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 255), tgt::col4(255, 255, 255, 255)));
69
70
71
72
73
74
75
76
77
78

        makeCurrent();
        // Init GLEW for this context
        GLenum err = glewInit();
        if (err != GLEW_OK) {
            // Problem: glewInit failed, something is seriously wrong.
            tgtAssert(false, "glewInit failed");
            std::cerr << "glewInit failed, error: " << glewGetErrorString(err) << std::endl;
            exit(EXIT_FAILURE);
        }
79
        
80
81
        addProperty(&p_currentSlice);
        addProperty(&p_transferFunction);
82
        addProperty(&p_meshSolidColor);
83
84
85
86
        addProperty(&p_renderRChannel);
        addProperty(&p_renderGChannel);
        addProperty(&p_renderBChannel);
        addProperty(&p_renderAChannel);
87
88
89
90
91
92
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

93
    void DataContainerInspectorCanvas::init(DataContainerInspectorWidget* _pWidget) {
schultezub's avatar
schultezub committed
94
95
        initAllProperties();

96
        _widget = _pWidget;
97

98
        GLJobProc.registerContext(this);
99
100
        _paintShader = ShdrMgr.load("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "");
        _geometryRenderingShader = ShdrMgr.load("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector_geometryrenderer.frag", "");
101

102
103
        _paintShader->setAttributeLocation(0, "in_Position");
        _paintShader->setAttributeLocation(1, "in_TexCoords");
104

105
106
        createQuad();

107
        // set this as painter to get notified when window size changes
108
        setPainter(this, false);
109
        getEventHandler()->addEventListenerToFront(this);
110
111
112

        _frameBuffer = new tgt::FramebufferObject();
        _depthBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);		//, _renderingWndSize(tgt::ivec2(400, 100))
113
114
115
    }

    void DataContainerInspectorCanvas::deinit() {
schultezub's avatar
schultezub committed
116
117
        deinitAllProperties();

118
119
120
121
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

122
        _handles.clear();
123
        GLJobProc.deregisterContext(this);
124
        ShdrMgr.dispose(_paintShader);
125
        ShdrMgr.dispose(_geometryRenderingShader);
126
        delete _quad;
127
128
        delete _frameBuffer;
        delete _depthBuffer;
mostajab's avatar
mostajab committed
129
130
131
132

        resetContent();
    }

133
    void DataContainerInspectorCanvas::resetContent() {
mostajab's avatar
mostajab committed
134
135
136
        /// Clear the textures Array and geometry textures indicies array
        _textures.clear();

137
        /// Clear the trackball navigation event listener array
mostajab's avatar
mostajab committed
138
        /// - First delete the data that it contains
139
140
141
142
143
        std::vector<TrackballNavigationEventListener*>::iterator trackballNavEHIterator = _trackballEHs.begin();
        for(; trackballNavEHIterator != _trackballEHs.end(); trackballNavEHIterator++) {
            delete (*trackballNavEHIterator);
        }
        _trackballEHs.clear();
mostajab's avatar
mostajab committed
144
145
146
147

        /// Clear the Camera properties related to the trackballs array
        /// - First delete the data that it contains
        std::vector<campvis::CameraProperty*>::iterator camPropertyIterator = _trackballCameraProperties.begin();
148
149
150
        for(; camPropertyIterator != _trackballCameraProperties.end(); camPropertyIterator++) {
            delete (*camPropertyIterator);
        }
mostajab's avatar
mostajab committed
151
152
        _trackballCameraProperties.clear();

153
154
155
156
157
        std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
        for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
            (*geomTexInfoIter).destroy();
        }
        _geomTextureInfos.clear();
158
159
160
161
162
163
164
165
    }

    QSize DataContainerInspectorCanvas::sizeHint() const {
        return QSize(640, 480);
    }


    void DataContainerInspectorCanvas::paint() {
166
167

        /// if the window is resized, change the depth buffer size, also!
168
        if(!_depthBuffer || _depthBuffer->getWidth() != width() || _depthBuffer->getHeight() != height()) {
169
170
171
            delete _depthBuffer;
            _depthBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);		//, _renderingWndSize(tgt::ivec2(400, 100))
            _texturesDirty = true;
172
        }
173
        
174

175
        LGL_ERROR;
176
        tbb::mutex::scoped_lock lock(_localMutex);
177
178
179
        if (_texturesDirty)
            updateTextures();

180
181
        if (_textures.empty())
            return;
182
183

        glPushAttrib(GL_ALL_ATTRIB_BITS);
184
        glViewport(0, 0, size_.x, size_.y);
185
186
187
188
189
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
190
191
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
192
        _quadSize = size_ / _numTiles;
193
194
195
196
197
198

        _paintShader->activate();

        tgt::mat4 projection = tgt::mat4::createOrtho(0, size_.x, 0, size_.y, -1, 1);
        _paintShader->setUniform("_projectionMatrix", projection);

199
200
        tgt::TextureUnit tfUnit, unit2d, unit3d;
        p_transferFunction.getTF()->bind(_paintShader, tfUnit);
201
202
        _paintShader->setUniform("_texture2d", unit2d.getUnitNumber());
        _paintShader->setUniform("_texture3d", unit3d.getUnitNumber());
203

204
205
206
207
208
        _paintShader->setUniform("_renderRChannel", p_renderRChannel.getValue());
        _paintShader->setUniform("_renderGChannel", p_renderGChannel.getValue());
        _paintShader->setUniform("_renderBChannel", p_renderBChannel.getValue());
        _paintShader->setUniform("_renderAChannel", p_renderAChannel.getValue());

209
210
211
212
213
214
215
216
217
218
        for (int y = 0; y < _numTiles.y; ++y) {
            for (int x = 0; x < _numTiles.x; ++x) {
                int index = (_numTiles.x * y) + x;
                if (index >= static_cast<int>(_textures.size()))
                    break;

                tgt::mat4 scaleMatrix = tgt::mat4::createScale(tgt::vec3(_quadSize, 1.f));
                tgt::mat4 translation = tgt::mat4::createTranslation(tgt::vec3(_quadSize.x * x, _quadSize.y * y, 0.f));
                _paintShader->setUniform("_modelMatrix", translation * scaleMatrix);
                paintTexture(_textures[index], unit2d, unit3d);
219
220
221
            }
        }

222
        _paintShader->deactivate();
223
224
225
226
        LGL_ERROR;
        glPopAttrib();
    }

227
    void DataContainerInspectorCanvas::paintMeshGeomTextures() {
228
229
230
        LGL_ERROR;
        tbb::mutex::scoped_lock lock(_localMutex);
        if (_meshGeomTexturesDirty)
231
            updateMeshGeomRenderedTextures();
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

        if (_textures.empty())
            return;

        glPushAttrib(GL_ALL_ATTRIB_BITS);
        glViewport(0, 0, size_.x, size_.y);
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
        _quadSize = size_ / _numTiles;

        _paintShader->activate();

        tgt::mat4 projection = tgt::mat4::createOrtho(0, size_.x, 0, size_.y, -1, 1);
        _paintShader->setUniform("_projectionMatrix", projection);

        tgt::TextureUnit tfUnit, unit2d, unit3d;
        p_transferFunction.getTF()->bind(_paintShader, tfUnit);
        _paintShader->setUniform("_texture2d", unit2d.getUnitNumber());
        _paintShader->setUniform("_texture3d", unit3d.getUnitNumber());

        for (int y = 0; y < _numTiles.y; ++y) {
            for (int x = 0; x < _numTiles.x; ++x) {
                int index = (_numTiles.x * y) + x;
                if (index >= static_cast<int>(_textures.size()))
                    break;

                tgt::mat4 scaleMatrix = tgt::mat4::createScale(tgt::vec3(_quadSize, 1.f));
                tgt::mat4 translation = tgt::mat4::createTranslation(tgt::vec3(_quadSize.x * x, _quadSize.y * y, 0.f));
                _paintShader->setUniform("_modelMatrix", translation * scaleMatrix);
                paintTexture(_textures[index], unit2d, unit3d);
            }
        }

        _paintShader->deactivate();
        LGL_ERROR;
        glPopAttrib();
    }

275
    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d) {
276
277

        _paintShader->setIgnoreUniformLocationError(true);
278
279
280
281
        if (texture->getDimensions().z == 1) {
            unit2d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", false);
282
            _paintShader->setUniform("_isDepthTexture", texture->isDepthTexture());
283
284
285
            _paintShader->setUniform("_2dTextureParams._size", tgt::vec2(texture->getDimensions().xy()));
            _paintShader->setUniform("_2dTextureParams._sizeRCP", tgt::vec2(1.f) / tgt::vec2(texture->getDimensions().xy()));
            _paintShader->setUniform("_2dTextureParams._numChannels", static_cast<int>(texture->getNumChannels()));
286
287
        }
        else {
288
289
290
            // clamp current slice to texture size, since this can't be done in event handler:
            _currentSlice = tgt::clamp(_currentSlice, -1, texture->getDimensions().z);

291
292
293
            unit3d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", true);
294
            _paintShader->setUniform("_sliceNumber", p_currentSlice.getValue());
295
296
297
            _paintShader->setUniform("_3dTextureParams._size", tgt::vec3(texture->getDimensions()));
            _paintShader->setUniform("_3dTextureParams._sizeRCP", tgt::vec3(1.f) / tgt::vec3(texture->getDimensions()));
            _paintShader->setUniform("_3dTextureParams._numChannels", static_cast<int>(texture->getNumChannels()));
298
        }
299
300
        _paintShader->setIgnoreUniformLocationError(false);

301
        _quad->render(GL_POLYGON);
302
303
304
        LGL_ERROR;
    }

305
    void DataContainerInspectorCanvas::drawGeomteryData(const campvis::GeometryData* mg, tgt::Texture* colorBuffer, const int& trackballndx) {
306
307
308
309
        // avoid FRAMEBUFFER_INCOMPLETE_DIMENSIONS error
        if (colorBuffer->getDimensions() != _depthBuffer->getDimensions())
            return;

310
311
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        
mostajab's avatar
mostajab committed
312
313
        /// Activate the shader for geometry Rendering.
        _geometryRenderingShader->activate();
314
315
316
317
318
319
        _geometryRenderingShader->setIgnoreUniformLocationError(true);
        
        _trackballEHs[trackballndx]->setSceneBounds(mg->getWorldBounds());
        
        _geometryRenderingShader->setUniform("_projectionMatrix", _trackballEHs[trackballndx]->getTrackball()->getCamera()->getProjectionMatrix()/*_trackballCameraProperty->getValue().getProjectionMatrix()*/);
        _geometryRenderingShader->setUniform("_viewMatrix", _trackballEHs[trackballndx]->getTrackball()->getCamera()->getViewMatrix());
320

mostajab's avatar
mostajab committed
321
        // The color that will be used for rendering the object
322
        _geometryRenderingShader->setUniform("_color", p_meshSolidColor.getValue());
323
324
325
326
327
        _geometryRenderingShader->setIgnoreUniformLocationError(false);
        
        _frameBuffer->activate();
        // Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
328

329
        colorBuffer->uploadTexture();
330
331
332
333
334
335
336
337
338
339
340
341
342
343
        colorBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);

        _depthBuffer->uploadTexture();
        _depthBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
        
        _frameBuffer->attachTexture(colorBuffer, GL_COLOR_ATTACHMENT0);
        _frameBuffer->attachTexture(_depthBuffer, GL_DEPTH_ATTACHMENT);
        _frameBuffer->isComplete();

        glViewport(0, 0, width(), height());
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glClearDepth(1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
344
        
mostajab's avatar
mostajab committed
345
        // render the geometry into a polygon mesh.
346
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
347
        mg->render(GL_POLYGON);
348

349

mostajab's avatar
mostajab committed
350
        // change the color to white for the wireframe.
351
        _geometryRenderingShader->setUniform("_color", 1.0f, 1.0f, 1.0f, 1.0f);
mostajab's avatar
mostajab committed
352
353

        // Render wireframe around the geometry.
354
355
356
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        mg->render(GL_POLYGON);

357
358
359
        colorBuffer->downloadTexture();
        _frameBuffer->deactivate();
        _geometryRenderingShader->deactivate();
360
361

        glPopAttrib();
362
        LGL_ERROR;
363
364
365
    }

    void DataContainerInspectorCanvas::invalidate() {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
366
367
368
        // only if inited
        if (_quad != 0 && _paintShader != 0)
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
369
370
    }

371
    void DataContainerInspectorCanvas::invalidateMeshGeomTextures() {
372
373
        // only if inited
        if (_quad != 0 && _paintShader != 0)
374
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paintMeshGeomTextures), OpenGLJobProcessor::PaintJob);
375
376
    }

377
    void DataContainerInspectorCanvas::createQuad() {
378
        delete _quad;
379
        _quad = 0;
380
        _quad = GeometryDataFactory::createQuad(tgt::vec3(0.f), tgt::vec3(1.f), tgt::vec3(0.f, 1.f, 0.f), tgt::vec3(1.f, 0.f, 0.f));
381
382
    }

383
384
385
386
    void DataContainerInspectorCanvas::repaint() {
        invalidate();
    }

387
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2& size) {
388
389
390
        invalidate();
    }

391
392
393
394
395
396
397
398
399
    void DataContainerInspectorCanvas::mouseDoubleClickEvent(tgt::MouseEvent* e) {
        if (_renderFullscreen) {
            _renderFullscreen = false;
        }
        else {
            tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
            _selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;
            _renderFullscreen = true;
        }
400
        e->ignore();
401
402
403
        invalidate();
    }

404
405
    void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
    {
406
        if (e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT) {
407
408
409
410
411
412
413
414
415
416
            tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);

            tgt::MouseEvent adjustedMe(
                me->x(),
                me->y(),
                me->action(),
                me->modifiers(),
                me->button(),
                me->viewport() 
                );
417

418
419
420
            
            if(_selectedTrackball >= 0) {
                _trackballEHs[_selectedTrackball]->onEvent(&adjustedMe);
421

422
423
424
                _meshGeomTexturesDirty = true;
                invalidateMeshGeomTextures();
            }
425
            
426
        }
427
428

        {
429
430
431
432
433
434
435
436
437
438
            tgt::ivec2 dimCanvas = tgt::ivec2(_quadSize.x * _numTiles.x, _quadSize.y * _numTiles.y);    
            if(e->x() >= dimCanvas.x || e->y() >= dimCanvas.y || e->x() < 0 || e->y() < 0)
                return;

            int texIndx = (e->y() / _quadSize.y) * _numTiles.x + (e->x() / _quadSize.x);
            const tgt::Texture* texturePtr = _textures[texIndx];
            const int texWidth  = texturePtr->getWidth();
            const int texHeight = texturePtr->getHeight();
            int cursorPosX = static_cast<int>(static_cast<float>(e->x() % _quadSize.x) / _quadSize.x * texWidth);
            int cursorPosY = static_cast<int>(static_cast<float>(e->y() % _quadSize.y) / _quadSize.y * texHeight);
439

440
441
442
443
444
445
            float f = 0.0;
            if(_textures[texIndx]->isDepthTexture()) {
                _depth = _textures[texIndx]->depthAsFloat(cursorPosX, texHeight - cursorPosY - 1);
                _widget->updateDepth();
            }
            else {
446
447
448
449
450
451
452
453
454
455
                if (_textures[texIndx]->getDimensions().z != 1) {
                    if (p_currentSlice.getValue() >= 0 && p_currentSlice.getValue() < _textures[texIndx]->getDimensions().z) {
                        _color = _textures[texIndx]->texelAsFloat(cursorPosX, texHeight - cursorPosY - 1, p_currentSlice.getValue());
                        _widget->updateColor();
                    }
                }
                else if (_textures[texIndx]->getDimensions().y != 1) {
                    _color = _textures[texIndx]->texelAsFloat(cursorPosX, texHeight - cursorPosY - 1);
                    _widget->updateColor();
                }
456
            }      
457
        }
458
459
    }

460
461
462
463
464
465
466
467
468
469
470
471
    void DataContainerInspectorCanvas::wheelEvent(tgt::MouseEvent* e) {
        if (_renderFullscreen) {
            switch (e->button()) {
                case tgt::MouseEvent::MOUSE_WHEEL_UP:
                    ++_currentSlice; // we cant clamp the value here to the number of slices - we do this during rendering
                    e->ignore();
                    break;
                case tgt::MouseEvent::MOUSE_WHEEL_DOWN:
                    if (_currentSlice >= -1)
                        --_currentSlice;
                    e->ignore();
                    break;
472
473
                default:
                    break;
474
475
476
477
478
            }
            invalidate();
        }
    }

479
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
480
481
482
        tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
        _selectedTrackball = -1;
        std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
483

484
485
486
        switch (e->button()) {
        case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
            _selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;
487
                
488
489
490
491
            for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
                if((*geomTexInfoIter)._trackballIndx == _selectedTexture) {
                    _selectedTrackball = (*geomTexInfoIter)._trackballIndx;
                    break;
492
                }
493
            }
494

495
496
497
            if(_selectedTrackball >= 0)
                _trackballEHs[_selectedTrackball]->getTrackball()->mousePressEvent(e);
                break;
498
                
499
500
501
            default:
                break;
        }
502
503
504
505
506
507
    }

    void DataContainerInspectorCanvas::mouseReleaseEvent(tgt::MouseEvent* e) {
        if (_renderFullscreen) {
            switch (e->button()) {
            case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
508
                if(_selectedTrackball >= 0)
509
                _trackballEHs[_selectedTrackball]->getTrackball()->mouseReleaseEvent(e);
510
511
512
513
514
515
516
517
                    break;
                
                default:
                    break;
            }
        }
    }

518
519
520
521
522
523
524
525
526
527
528
529
530
    void DataContainerInspectorCanvas::onDataContainerChanged(const QString& key, QtDataHandle dh) {
        {
            tbb::mutex::scoped_lock lock(_localMutex);

            // check whether DataHandle is already existing
            std::map<QString, QtDataHandle>::iterator lb = _handles.lower_bound(key);
            if (lb == _handles.end() || lb->first != key) {
                // not existant -> do nothing
            }
            else {
                // existant -> replace
                lb->second = QtDataHandle(dh);
                // update _textures array
531
                _texturesDirty = true;
532
533
            }
        }
534
535
536

        if (_texturesDirty)
            invalidate();
537
538
539
540
541
542
543
544
545
    }

    void DataContainerInspectorCanvas::setDataHandles(const std::vector< std::pair<QString, QtDataHandle> >& handles) {
        {
            tbb::mutex::scoped_lock lock(_localMutex);
            _handles.clear();
            for (std::vector< std::pair<QString, QtDataHandle> >::const_iterator it = handles.begin(); it != handles.end(); ++it)
                _handles.insert(*it);

546
            _texturesDirty = true;
547
548
549
550
551
        }

        invalidate();
    }

552
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor() {
553
554
        return _color;
    }
555

556
    const float& DataContainerInspectorCanvas::getCapturedDepth() {
557
558
559
        return _depth;
    }

560
    void DataContainerInspectorCanvas::updateTextures() {
561

mostajab's avatar
mostajab committed
562
563
        /// Reset the content of the Canvas.
        resetContent();
564

565
        /// Calculate the maximum slices of the textures and fill the textures array
566
        int maxSlices = 1;
567
        unsigned int nMeshGeometry = 0;
568
569
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
570
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
571
                    imgGL->downloadTexture();
572
                    _textures.push_back(imgGL->getTexture());
573
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
574
575
                }
            }
576
577
578
            else if (const RenderData* rd = dynamic_cast<const RenderData*>(it->second.getData())) {
                for (size_t i = 0; i < rd->getNumColorTextures(); ++i) {
                    const ImageRepresentationGL* imgGL = rd->getColorTexture(i)->getRepresentation<ImageRepresentationGL>();
579
                    if (imgGL) {
580
                        imgGL->downloadTexture();
581
                        _textures.push_back(imgGL->getTexture());
582
                    }
583
584
585
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
586
                    if (imgGL) {
587
                        imgGL->downloadTexture();
588
                        _textures.push_back(imgGL->getTexture());
589
                    }
590
591
592

                }
            }
593
            else if(const campvis::GeometryData* gd = dynamic_cast<const campvis::GeometryData*>(it->second.getData())) {
594
                
595
                LGL_ERROR;
596

597
598
599
600
601
602
                GeometryTextureInfo geomTexInfo;
                geomTexInfo._geomData = it->second;
                geomTexInfo._trackballIndx = nMeshGeometry;
                              
                campvis::CameraProperty* cameraProperty = new CameraProperty("camera", "Camera");
                _trackballCameraProperties.push_back(cameraProperty);
603

mostajab's avatar
mostajab committed
604
                /// re-initialize the trackball navigation event listener to reset the object's pose
605
606
607
608
                TrackballNavigationEventListener* trackballEH = new TrackballNavigationEventListener(cameraProperty, new IVec2Property("QuadSize", "Size", tgt::ivec2(width(), height()), tgt::ivec2(0), tgt::ivec2(1024)) );
                float dist = 3 * fabs(gd->getWorldBounds().getLLF().z - gd->getWorldBounds().getURB().z);
                trackballEH->reinitializeCamera(gd->getWorldBounds());
                trackballEH->getTrackball()->moveCameraBackward(dist);
mostajab's avatar
mostajab committed
609
                LGL_ERROR;
610
                                
mostajab's avatar
mostajab committed
611
                /// store the trackball in the vector
612
613
                _trackballEHs.push_back(trackballEH);
                
mostajab's avatar
mostajab committed
614
                /// create color buffer and depth buffer.
615
                tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
616

mostajab's avatar
mostajab committed
617
                /// Render the object on the buffers.
618
                drawGeomteryData(gd, colorBuffer, nMeshGeometry++);
mostajab's avatar
mostajab committed
619

620
621
                geomTexInfo._texture = colorBuffer;

mostajab's avatar
mostajab committed
622
                /// Store the buffers into array.
623
624
                _geomTextureInfos.push_back(geomTexInfo);
                
mostajab's avatar
mostajab committed
625
626

                /// Store the rendered texture in textures.
627
628
                _textures.push_back(colorBuffer);
            }
629
        }
630
631
632
633

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
634
        _meshGeomTexturesDirty = false;
635
        _texturesDirty = false;
636
637
    }

638
    void DataContainerInspectorCanvas::updateMeshGeomRenderedTextures() {
639
        
640
641
642
        std::vector<GeometryTextureInfo>::iterator geomTexInfosIter = _geomTextureInfos.begin();
        for(;geomTexInfosIter != _geomTextureInfos.end(); geomTexInfosIter++) {
            drawGeomteryData(dynamic_cast<const campvis::GeometryData*>((*geomTexInfosIter)._geomData.getData()), (*geomTexInfosIter)._texture, (*geomTexInfosIter)._trackballIndx);
643
        }
644

645
        _meshGeomTexturesDirty = false;
646
647
648
649
650
    }

    void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
        invalidate();

651
652
        /// if the Mesh Solid Color property is changed, update the mesh's color
        const std::string propertyName = (prop)->getName();
653
        if(propertyName == "MeshSolidColor") {
654
655
656
            _meshGeomTexturesDirty = true;
            invalidateMeshGeomTextures();
        }        
657
    }
658
}