datacontainerinspectorcanvas.cpp 26.1 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
        , _dataContainer(0)
        , _paintShader(0)
55
        , _quad(0)
56
57
58
59
        , _numTiles(0, 0)
        , _quadSize(0, 0)
        , _selectedTexture(0)
        , _renderFullscreen(false)
60
        , _currentSlice(-1)
61
        , _color(0.0f, 0.0f, 0.0f, 0.0f)
62
        , _meshGeomTexturesDirty(false)
63
    {
64
        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)));
65
66
67
68
69
70
71
72
73
74

        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);
        }
75
        
76
77
        addProperty(&p_currentSlice);
        addProperty(&p_transferFunction);
78
        addProperty(&p_meshSolidColor);
79
80
81
82
83
84
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

85
    void DataContainerInspectorCanvas::init(DataContainerInspectorWidget* _pWidget) {
schultezub's avatar
schultezub committed
86
87
        initAllProperties();

88
        _widget = _pWidget;
89

90
91
        GLJobProc.registerContext(this);
        _paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
92
        _geometryRenderingShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector_geometryrenderer.frag", "", false);
93

94
95
        _paintShader->setAttributeLocation(0, "in_Position");
        _paintShader->setAttributeLocation(1, "in_TexCoords");
96

97
98
        createQuad();

99
        // set this as painter to get notified when window size changes
100
        setPainter(this, false);
101
        getEventHandler()->addEventListenerToFront(this);
102
103
104

        _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))
105
106
107
    }

    void DataContainerInspectorCanvas::deinit() {
schultezub's avatar
schultezub committed
108
109
        deinitAllProperties();

110
111
112
113
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

114
        _handles.clear();
115
        GLJobProc.deregisterContext(this);
116
        ShdrMgr.dispose(_paintShader);
117
        ShdrMgr.dispose(_geometryRenderingShader);
118
        delete _quad;
119
120
        delete _frameBuffer;
        delete _depthBuffer;
mostajab's avatar
mostajab committed
121
122
123
124

        resetContent();
    }

125
    void DataContainerInspectorCanvas::resetContent() {
mostajab's avatar
mostajab committed
126
127
128
        /// Clear the textures Array and geometry textures indicies array
        _textures.clear();

129
        /// Clear the trackball navigation event listener array
mostajab's avatar
mostajab committed
130
        /// - First delete the data that it contains
131
132
133
134
135
        std::vector<TrackballNavigationEventListener*>::iterator trackballNavEHIterator = _trackballEHs.begin();
        for(; trackballNavEHIterator != _trackballEHs.end(); trackballNavEHIterator++) {
            delete (*trackballNavEHIterator);
        }
        _trackballEHs.clear();
mostajab's avatar
mostajab committed
136
137
138
139

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

145
146
147
148
149
        std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
        for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
            (*geomTexInfoIter).destroy();
        }
        _geomTextureInfos.clear();
150
151
152
153
154
155
156
157
    }

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


    void DataContainerInspectorCanvas::paint() {
158
159

        /// if the window is resized, change the depth buffer size, also!
160
        if(!_depthBuffer || _depthBuffer->getWidth() != width() || _depthBuffer->getHeight() != height()) {
161
162
163
            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;
164
        }
165
        
166

167
        LGL_ERROR;
168
        tbb::mutex::scoped_lock lock(_localMutex);
169
170
171
        if (_texturesDirty)
            updateTextures();

172
173
        if (_textures.empty())
            return;
174
175

        glPushAttrib(GL_ALL_ATTRIB_BITS);
176
        glViewport(0, 0, size_.x, size_.y);
177
178
179
180
181
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
182
183
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
184
        _quadSize = size_ / _numTiles;
185
186
187
188
189
190

        _paintShader->activate();

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

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

196
197
198
199
200
201
202
203
204
205
        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);
206
207
208
            }
        }

209
        _paintShader->deactivate();
210
211
212
213
        LGL_ERROR;
        glPopAttrib();
    }

214
    void DataContainerInspectorCanvas::paintMeshGeomTextures() {
215
216
217
        LGL_ERROR;
        tbb::mutex::scoped_lock lock(_localMutex);
        if (_meshGeomTexturesDirty)
218
            updateMeshGeomRenderedTextures();
219
220
221
222
223
224
225
226
227
228
229
230
231
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

        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();
    }

262
    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d) {
263
264

        _paintShader->setIgnoreUniformLocationError(true);
265
266
267
268
        if (texture->getDimensions().z == 1) {
            unit2d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", false);
269
            _paintShader->setUniform("_isDepthTexture", texture->isDepthTexture());
270
271
272
            _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()));
273
274
        }
        else {
275
276
277
            // clamp current slice to texture size, since this can't be done in event handler:
            _currentSlice = tgt::clamp(_currentSlice, -1, texture->getDimensions().z);

278
279
280
            unit3d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", true);
281
            _paintShader->setUniform("_sliceNumber", p_currentSlice.getValue());
282
283
284
            _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()));
285
        }
286
287
        _paintShader->setIgnoreUniformLocationError(false);

288
        _quad->render(GL_POLYGON);
289
290
291
        LGL_ERROR;
    }

292
293
294
    void DataContainerInspectorCanvas::drawGeomteryData(const campvis::GeometryData* mg, tgt::Texture* colorBuffer, const int& trackballndx) {
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        
mostajab's avatar
mostajab committed
295
296
        /// Activate the shader for geometry Rendering.
        _geometryRenderingShader->activate();
297
298
299
300
301
302
        _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());
303

mostajab's avatar
mostajab committed
304
        // The color that will be used for rendering the object
305
        _geometryRenderingShader->setUniform("_color", p_meshSolidColor.getValue());
306
307
308
309
310
        _geometryRenderingShader->setIgnoreUniformLocationError(false);
        
        _frameBuffer->activate();
        // Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
311

312
        colorBuffer->uploadTexture();
313
314
315
316
317
318
319
320
321
322
323
324
325
326
        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);
327
        
mostajab's avatar
mostajab committed
328
        // render the geometry into a polygon mesh.
329
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
330
        mg->render(GL_POLYGON);
331

332

mostajab's avatar
mostajab committed
333
        // change the color to white for the wireframe.
334
        _geometryRenderingShader->setUniform("_color", 1.0f, 1.0f, 1.0f, 1.0f);
mostajab's avatar
mostajab committed
335
336

        // Render wireframe around the geometry.
337
338
339
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        mg->render(GL_POLYGON);

340
341
342
        colorBuffer->downloadTexture();
        _frameBuffer->deactivate();
        _geometryRenderingShader->deactivate();
343
344

        glPopAttrib();
345
        LGL_ERROR;
346
347
348
    }

    void DataContainerInspectorCanvas::invalidate() {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
349
350
351
        // only if inited
        if (_quad != 0 && _paintShader != 0)
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
352
353
    }

354
    void DataContainerInspectorCanvas::invalidateMeshGeomTextures() {
355
356
        // only if inited
        if (_quad != 0 && _paintShader != 0)
357
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paintMeshGeomTextures), OpenGLJobProcessor::PaintJob);
358
359
    }

360
    void DataContainerInspectorCanvas::createQuad() {
361
        delete _quad;
362
        _quad = 0;
363
        _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));
364
365
    }

366
367
368
369
    void DataContainerInspectorCanvas::repaint() {
        invalidate();
    }

370
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2& size) {
371
372
373
        invalidate();
    }

374
375
376
377
378
379
380
381
382
    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;
        }
383
        e->ignore();
384
385
386
        invalidate();
    }

387
388
    void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
    {
389
        if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT) {
390
391
392
393
394
395
396
397
398
399
            tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);

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

401
402
403
            
            if(_selectedTrackball >= 0) {
                _trackballEHs[_selectedTrackball]->onEvent(&adjustedMe);
404

405
406
407
                _meshGeomTexturesDirty = true;
                invalidateMeshGeomTextures();
            }
408
            
409
        }
410
        else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT) {
411
412
413
414
415
416
417
418
419
420
            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);
421

422
423
424
425
426
427
428
429
430
            float f = 0.0;
            if(_textures[texIndx]->isDepthTexture()) {
                _depth = _textures[texIndx]->depthAsFloat(cursorPosX, texHeight - cursorPosY - 1);
                _widget->updateDepth();
            }
            else {
                _color = _textures[texIndx]->texelAsFloat(cursorPosX, texHeight - cursorPosY - 1);
                _widget->updateColor();
            }      
431
        }
432
433
    }

434
435
436
437
438
439
440
441
442
443
444
445
    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;
446
447
                default:
                    break;
448
449
450
451
452
            }
            invalidate();
        }
    }

453
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
454
455
456
        tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
        _selectedTrackball = -1;
        std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
457

458
459
460
        switch (e->button()) {
        case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
            _selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;
461
                
462
463
464
465
            for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
                if((*geomTexInfoIter)._trackballIndx == _selectedTexture) {
                    _selectedTrackball = (*geomTexInfoIter)._trackballIndx;
                    break;
466
                }
467
            }
468

469
470
471
            if(_selectedTrackball >= 0)
                _trackballEHs[_selectedTrackball]->getTrackball()->mousePressEvent(e);
                break;
472
                
473
474
475
            default:
                break;
        }
476
477
478
479
480
481
    }

    void DataContainerInspectorCanvas::mouseReleaseEvent(tgt::MouseEvent* e) {
        if (_renderFullscreen) {
            switch (e->button()) {
            case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
482
                if(_selectedTrackball >= 0)
483
                _trackballEHs[_selectedTrackball]->getTrackball()->mouseReleaseEvent(e);
484
485
486
487
488
489
490
491
                    break;
                
                default:
                    break;
            }
        }
    }

492
493
494
495
496
497
498
499
500
501
502
503
504
    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
505
                _texturesDirty = true;
506
507
            }
        }
508
509
510

        if (_texturesDirty)
            invalidate();
511
512
513
514
515
516
517
518
519
    }

    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);

520
            _texturesDirty = true;
521
522
523
524
525
        }

        invalidate();
    }

526
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor() {
527
528
        return _color;
    }
529

530
    const float& DataContainerInspectorCanvas::getCapturedDepth() {
531
532
533
        return _depth;
    }

534
    void DataContainerInspectorCanvas::updateTextures() {
535

mostajab's avatar
mostajab committed
536
537
        /// Reset the content of the Canvas.
        resetContent();
538

539
        /// Calculate the maximum slices of the textures and fill the textures array
540
        int maxSlices = 1;
541
        unsigned int nMeshGeometry = 0;
542
543
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
544
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
545
                    _textures.push_back(imgGL->getTexture());
546
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
547
548
                }
            }
549
550
551
            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>();
552
                    if (imgGL) {
553
                        imgGL->downloadTexture();
554
                        _textures.push_back(imgGL->getTexture());
555
                    }
556
557
558
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
559
                    if (imgGL) {
560
                        imgGL->downloadTexture();
561
                        _textures.push_back(imgGL->getTexture());
562
                    }
563
564
565

                }
            }
566
            else if(const campvis::GeometryData* gd = dynamic_cast<const campvis::GeometryData*>(it->second.getData())) {
567
                
568
                LGL_ERROR;
569

570
571
572
573
574
575
                GeometryTextureInfo geomTexInfo;
                geomTexInfo._geomData = it->second;
                geomTexInfo._trackballIndx = nMeshGeometry;
                              
                campvis::CameraProperty* cameraProperty = new CameraProperty("camera", "Camera");
                _trackballCameraProperties.push_back(cameraProperty);
576

mostajab's avatar
mostajab committed
577
                /// re-initialize the trackball navigation event listener to reset the object's pose
578
579
580
581
                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
582
                LGL_ERROR;
583
                                
mostajab's avatar
mostajab committed
584
                /// store the trackball in the vector
585
586
                _trackballEHs.push_back(trackballEH);
                
mostajab's avatar
mostajab committed
587
                /// create color buffer and depth buffer.
588
                tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
589

mostajab's avatar
mostajab committed
590
                /// Render the object on the buffers.
591
                glewExperimental = true;
592
                drawGeomteryData(gd, colorBuffer, nMeshGeometry++);
mostajab's avatar
mostajab committed
593

594
595
                geomTexInfo._texture = colorBuffer;

mostajab's avatar
mostajab committed
596
                /// Store the buffers into array.
597
598
                _geomTextureInfos.push_back(geomTexInfo);
                
mostajab's avatar
mostajab committed
599
600

                /// Store the rendered texture in textures.
601
602
                _textures.push_back(colorBuffer);
            }
603
        }
604
605
606
607

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
608
        _meshGeomTexturesDirty = false;
609
        _texturesDirty = false;
610
611
    }

612
    void DataContainerInspectorCanvas::updateMeshGeomRenderedTextures() {
613
        
614
615
616
        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);
617
        }
618

619
        _meshGeomTexturesDirty = false;
620
621
622
623
624
    }

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

625
626
        /// if the Mesh Solid Color property is changed, update the mesh's color
        const std::string propertyName = (prop)->getName();
627
        if(propertyName == "MeshSolidColor") {
628
629
630
            _meshGeomTexturesDirty = true;
            invalidateMeshGeomTextures();
        }        
631
    }
632
}