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)
Sebastian Pölsterl's avatar
Sebastian Pölsterl committed
57
        , _meshGeomTexturesDirty(false)
58
59
        , _dataContainer(0)
        , _paintShader(0)
60
        , _quad(0)
Sebastian Pölsterl's avatar
Sebastian Pölsterl committed
61
        , _color(0.0f, 0.0f, 0.0f, 0.0f)
62
63
64
65
        , _numTiles(0, 0)
        , _quadSize(0, 0)
        , _selectedTexture(0)
        , _renderFullscreen(false)
66
        , _currentSlice(-1)
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
        std::vector<TrackballNavigationEventListener*>::iterator trackballNavEHIterator = _trackballEHs.begin();
140
        for(; trackballNavEHIterator != _trackballEHs.end(); ++trackballNavEHIterator) {
141
142
143
            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
        for(; camPropertyIterator != _trackballCameraProperties.end(); ++camPropertyIterator) {
149
150
            delete (*camPropertyIterator);
        }
mostajab's avatar
mostajab committed
151
152
        _trackballCameraProperties.clear();

153
        std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
154
        for(; geomTexInfoIter != _geomTextureInfos.end(); ++geomTexInfoIter) {
155
156
157
            (*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
            if(_textures[texIndx]->isDepthTexture()) {
                _depth = _textures[texIndx]->depthAsFloat(cursorPosX, texHeight - cursorPosY - 1);
                _widget->updateDepth();
            }
            else {
445
446
447
448
449
450
451
452
453
454
                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();
                }
455
            }      
456
        }
457
458
    }

459
460
461
462
463
464
465
466
467
468
469
470
    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;
471
472
                default:
                    break;
473
474
475
476
477
            }
            invalidate();
        }
    }

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

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

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

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

517
518
519
520
521
522
523
524
525
526
527
528
529
    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
530
                _texturesDirty = true;
531
532
            }
        }
533
534
535

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

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

545
            _texturesDirty = true;
546
547
548
549
550
        }

        invalidate();
    }

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

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

559
    void DataContainerInspectorCanvas::updateTextures() {
560

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

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

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

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

mostajab's avatar
mostajab committed
603
                /// re-initialize the trackball navigation event listener to reset the object's pose
604
605
606
607
                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
608
                LGL_ERROR;
609
                                
mostajab's avatar
mostajab committed
610
                /// store the trackball in the vector
611
612
                _trackballEHs.push_back(trackballEH);
                
mostajab's avatar
mostajab committed
613
                /// create color buffer and depth buffer.
614
                tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
615

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

619
620
                geomTexInfo._texture = colorBuffer;

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

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

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

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

644
        _meshGeomTexturesDirty = false;
645
646
647
648
649
    }

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

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