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

#include "datacontainerinspectorcanvas.h"

#include "tgt/assert.h"
#include "tgt/shadermanager.h"
34
35
#include "tgt/textureunit.h"

36
37
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/datahandle.h"
38
#include "core/datastructures/renderdata.h"
39
#include "core/datastructures/imagerepresentationgl.h"
40
#include "core/datastructures/facegeometry.h"
41
#include "core/tools/job.h"
42
43
#include "core/classification/tfgeometry1d.h"
#include "core/classification/geometry1dtransferfunction.h"
44

45
46
#include "datacontainerinspectorwidget.h"

47
48
#include "ext/tgt/navigation/trackball.h"

49

schultezub's avatar
schultezub committed
50
namespace campvis {
51
52
53

    DataContainerInspectorCanvas::DataContainerInspectorCanvas(QWidget* parent /*= 0*/) 
        : tgt::QtThreadedCanvas("DataContainer Inspector", tgt::ivec2(640, 480), tgt::GLCanvas::RGBA_BUFFER, parent, true)
54
        , p_currentSlice("CurrentSlice", "Slice", -1, -1, -1)
55
        , p_meshSolidColor("MeshSolidColor", "Mesh Solid Color", tgt::vec4(50.f, 70.0f, 50.0f, 255.f), tgt::vec4(0.0f), tgt::vec4(255.0f))
56
        , p_transferFunction("TransferFunction", "Transfer Function", new Geometry1DTransferFunction(256, tgt::vec2(0.f, 1.f)))
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
83
        addProperty(&p_meshSolidColor);
        //addProperty(&_camera);
84
85
86
87
88
89
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

90
    void DataContainerInspectorCanvas::init(DataContainerInspectorWidget* _pWidget) {
schultezub's avatar
schultezub committed
91
92
        initAllProperties();

93
        _widget = _pWidget;
94

95
96
        GLJobProc.registerContext(this);
        _paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
97
        _geometryRenderingShader = ShdrMgr.loadSeparate("application/glsl/meshgeometryrenderer.vert", "application/glsl/meshgeometryrenderer.frag", "", false);
98

99
100
        _paintShader->setAttributeLocation(0, "in_Position");
        _paintShader->setAttributeLocation(1, "in_TexCoords");
101

102
103
        createQuad();

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

        _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))
110
111
112
    }

    void DataContainerInspectorCanvas::deinit() {
schultezub's avatar
schultezub committed
113
114
        deinitAllProperties();

115
116
117
118
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

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

        resetContent();
    }

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

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

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

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

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


    void DataContainerInspectorCanvas::paint() {
163
        LGL_ERROR;
164
        tbb::mutex::scoped_lock lock(_localMutex);
165
166
167
        if (_texturesDirty)
            updateTextures();

168
169
        if (_textures.empty())
            return;
170
171

        glPushAttrib(GL_ALL_ATTRIB_BITS);
172
        glViewport(0, 0, size_.x, size_.y);
173
174
175
176
177
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
178
179
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
180
        _quadSize = size_ / _numTiles;
181
182
183
184
185
186

        _paintShader->activate();

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

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

192
193
194
195
196
197
198
199
200
201
        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);
202
203
204
            }
        }

205
        _paintShader->deactivate();
206
207
208
209
        LGL_ERROR;
        glPopAttrib();
    }

210
    void DataContainerInspectorCanvas::paintMeshGeomTextures() {
211
212
213
        LGL_ERROR;
        tbb::mutex::scoped_lock lock(_localMutex);
        if (_meshGeomTexturesDirty)
214
            updateMeshGeomRenderedTextures();
215
216
217
218
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

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

258
    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d) {
259
260

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

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

284
        _quad->render(GL_POLYGON);
285
286
287
        LGL_ERROR;
    }

288
    void DataContainerInspectorCanvas::drawGeomteryData(const campvis::GeometryData* mg, tgt::Texture* colorBuffer, const int& trackballndx) {
289
        LGL_ERROR;
mostajab's avatar
mostajab committed
290
        
291
292
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        
mostajab's avatar
mostajab committed
293
294
        /// Activate the shader for geometry Rendering.
        _geometryRenderingShader->activate();
295
        LGL_ERROR;
296
297
298
299
300
301
302
303
        _geometryRenderingShader->setIgnoreUniformLocationError(true);
        LGL_ERROR;
        
        _trackballEHs[trackballndx]->setSceneBounds(mg->getWorldBounds());
        
        _geometryRenderingShader->setUniform("_projectionMatrix", _trackballEHs[trackballndx]->getTrackball()->getCamera()->getProjectionMatrix()/*_trackballCameraProperty->getValue().getProjectionMatrix()*/);
        LGL_ERROR;
        _geometryRenderingShader->setUniform("_viewMatrix", _trackballEHs[trackballndx]->getTrackball()->getCamera()->getViewMatrix());
304
305
        LGL_ERROR;

mostajab's avatar
mostajab committed
306
        // The color that will be used for rendering the object
307
308
309
310
311
        tgt::Vector4<float> meshColor = static_cast<tgt::Vector4<float>>(p_meshSolidColor.getValue());
        meshColor.r /= 255.0f;
        meshColor.g /= 255.0f;
        meshColor.b /= 255.0f;
        meshColor.a /= 255.0f;
mostajab's avatar
mostajab committed
312
        _geometryRenderingShader->setUniform("_Color", meshColor);
313
314
        
        LGL_ERROR;
315
316
317
318
319
320
        //_geometryRenderingShader->setUniform("_cameraPosition", _trackballEHs[trackballndx]->_trackball->getCamera()->getPosition());
        _geometryRenderingShader->setIgnoreUniformLocationError(false);
                        LGL_ERROR;
        
        _frameBuffer->activate();
        LGL_ERROR;
321

322
323
324
        // acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
        //tgt::TextureUnit rtUnit;
        //rtUnit.activate();
325

326
327
        // 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
344
345
346
        colorBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);

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

        glViewport(0, 0, width(), height());
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glClearDepth(1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        LGL_ERROR;
347

348
        
mostajab's avatar
mostajab committed
349
        // render the geometry into a polygon mesh.
350
        glPolygonMode(GL_FRONT, GL_POLYGON);
351
        mg->render(GL_POLYGON);
352

353

mostajab's avatar
mostajab committed
354
355
356
357
        // change the color to white for the wireframe.
        _geometryRenderingShader->setUniform("_Color", 1.0f, 1.0f, 1.0f, 1.0f);

        // Render wireframe around the geometry.
358
359
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        mg->render(GL_POLYGON);
mostajab's avatar
mostajab committed
360
             
361
362
        LGL_ERROR;

363
364
        colorBuffer->downloadTexture();
        /*_depthBuffer.downloadTexture();*/
365

366
367
        _frameBuffer->deactivate();
        LGL_ERROR;
368

369
        _geometryRenderingShader->deactivate();
370
371

        glPopAttrib();
372
373
374
    }

    void DataContainerInspectorCanvas::invalidate() {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
375
376
377
        // only if inited
        if (_quad != 0 && _paintShader != 0)
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
378
379
    }

380
    void DataContainerInspectorCanvas::invalidateMeshGeomTextures() {
381
382
        // only if inited
        if (_quad != 0 && _paintShader != 0)
383
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paintMeshGeomTextures), OpenGLJobProcessor::PaintJob);
384
385
    }

386
    void DataContainerInspectorCanvas::createQuad() {
387
388
        std::vector<tgt::vec3> vertices, texCorods;

389
        vertices.push_back(tgt::vec3(0.f,  0.f, 0.f));
390
391
        vertices.push_back(tgt::vec3(1.f, 0.f, 0.f));
        vertices.push_back(tgt::vec3(1.f, 1.f, 0.f));
392
        vertices.push_back(tgt::vec3(0.f,  1.f, 0.f));
393
394
395
396
397
398
399
400
401
402
        texCorods.push_back(tgt::vec3(0.f, 1.f, 0.f));
        texCorods.push_back(tgt::vec3(1.f, 1.f, 0.f));
        texCorods.push_back(tgt::vec3(1.f, 0.f, 0.f));
        texCorods.push_back(tgt::vec3(0.f, 0.f, 0.f));

        delete _quad;
        _quad = new FaceGeometry(vertices, texCorods);
        _quad->createGLBuffers();
    }

403
404
405
406
    void DataContainerInspectorCanvas::repaint() {
        invalidate();
    }

407
408
409
410
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2&) {
        invalidate();
    }

411
412
413
414
415
416
417
418
419
    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;
        }
420
        e->ignore();
421
422
423
        invalidate();
    }

424
425
    void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
    {
426
        //LGL_ERROR;
427
428
429
430
431
432
433
434
435
436
        /*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;
        }
        e->ignore();
        invalidate();*/
437
        if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT) {
438
439
440
441
442
443
444
445
446
447
            tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);

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

449
450
451
            
            if(_selectedTrackball >= 0) {
                _trackballEHs[_selectedTrackball]->onEvent(&adjustedMe);
452

453
454
455
                _meshGeomTexturesDirty = true;
                invalidateMeshGeomTextures();
            }
456
            
457
        }
458
        else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT) {
459
460
461
462
463
464
465
466
467
468
            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);
469

470
471
472
473
474
475
476
477
478
            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();
            }      
479
        }
480
481
    }

482
483
484
485
486
487
488
489
490
491
492
493
    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;
494
495
                default:
                    break;
496
497
498
499
500
            }
            invalidate();
        }
    }

501
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
502
        //LGL_ERROR;
503
        //if (_renderFullscreen) {
504

505
506
507
            tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
            _selectedTrackball = -1;
            std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
508

509
510
511
            switch (e->button()) {
            case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
                    //++_currentSlice; // we cant clamp the value here to the number of slices - we do this during rendering
512

513
514
515
516
517
518
519
520
                _selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;
                
                for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
                    if((*geomTexInfoIter)._trackballIndx == _selectedTexture) {
                        _selectedTrackball = (*geomTexInfoIter)._trackballIndx;
                        break;
                    }
                }
521

522
523
                if(_selectedTrackball >= 0)
                    _trackballEHs[_selectedTrackball]->getTrackball()->startMouseDrag(e);
524
525
526
527
528
529
530
531
532
533
534
535
536
537
                   // e->ignore();
                    break;
                
                default:
                    break;
            }
        //}
    }

    void DataContainerInspectorCanvas::mouseReleaseEvent(tgt::MouseEvent* e) {
        if (_renderFullscreen) {
            switch (e->button()) {
            case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
                    //++_currentSlice; // we cant clamp the value here to the number of slices - we do this during rendering
538
539
                if(_selectedTrackball >= 0)
                _trackballEHs[_selectedTrackball]->getTrackball()->endMouseDrag(e);
540
541
542
543
544
545
                   // e->ignore();
                    break;
                
                default:
                    break;
            }
546
            //invalidate();
547
548
549
        }
    }

550
551
552
553
554
555
556
557
558
559
560
561
562
    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
563
                _texturesDirty = true;
564
565
            }
        }
566
567
568

        if (_texturesDirty)
            invalidate();
569
570
571
572
573
574
575
576
577
    }

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

578
            _texturesDirty = true;
579
580
581
582
583
        }

        invalidate();
    }

584
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor() {
585
586
        return _color;
    }
587

588
    const float& DataContainerInspectorCanvas::getCapturedDepth() {
589
590
591
        return _depth;
    }

592
    void DataContainerInspectorCanvas::updateTextures() {
593

mostajab's avatar
mostajab committed
594
595
        /// Reset the content of the Canvas.
        resetContent();
596

597
        /// Calculate the maximum slices of the textures and fill the textures array
598
        int maxSlices = 1;
599
        unsigned int nMeshGeometry = 0;
600
601
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
602
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
603
                    _textures.push_back(imgGL->getTexture());
604
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
605
606
                }
            }
607
608
609
610
            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>();
                    if (imgGL)
611
612
                    {
                        imgGL->downloadTexture();
613
                        _textures.push_back(imgGL->getTexture());
614
                    }
615
616
617
618
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
                    if (imgGL)
619
620
                    {
                        imgGL->downloadTexture();
621
                        _textures.push_back(imgGL->getTexture());
622
                    }
623
624
625

                }
            }
626
            else if(const campvis::GeometryData* gd = dynamic_cast<const campvis::GeometryData*>(it->second.getData())) {
627
                
628
                LGL_ERROR;
629

630
631
632
633
634
635
                GeometryTextureInfo geomTexInfo;
                geomTexInfo._geomData = it->second;
                geomTexInfo._trackballIndx = nMeshGeometry;
                              
                campvis::CameraProperty* cameraProperty = new CameraProperty("camera", "Camera");
                _trackballCameraProperties.push_back(cameraProperty);
636

mostajab's avatar
mostajab committed
637
                /// re-initialize the trackball navigation event listener to reset the object's pose
638
639
640
641
                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
642
                LGL_ERROR;
643
                                
mostajab's avatar
mostajab committed
644
                /// store the trackball in the vector
645
646
                _trackballEHs.push_back(trackballEH);
                
mostajab's avatar
mostajab committed
647
                /// create color buffer and depth buffer.
648
                tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
649

mostajab's avatar
mostajab committed
650
                /// Render the object on the buffers.
651
                glewExperimental = true;
652
                drawGeomteryData(gd, colorBuffer, nMeshGeometry++);
653
                LGL_ERROR;
mostajab's avatar
mostajab committed
654

655
656
                geomTexInfo._texture = colorBuffer;

mostajab's avatar
mostajab committed
657
                /// Store the buffers into array.
658
659
                _geomTextureInfos.push_back(geomTexInfo);
                
mostajab's avatar
mostajab committed
660
661

                /// Store the rendered texture in textures.
662
                _textures.push_back(colorBuffer);
mostajab's avatar
mostajab committed
663
664

                /// Store the object index in the array in the geometry texture indices array.
665
                // _geomTextureIndices.push_back(_textures.size() - 1);
666

667
            }
668
669
670
671
672
        }

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
673
        _meshGeomTexturesDirty = false;
674
675
        _texturesDirty = false;
    }
676

677
    void DataContainerInspectorCanvas::updateMeshGeomRenderedTextures() {
678
        
679
680
681
        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);
682
        }
683

684
        _meshGeomTexturesDirty = false;
685
686
687
688
689
    }

    void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
        HasPropertyCollection::onPropertyChanged(prop);
        invalidate();
690
691
692

        /// if the Mesh Solid Color property is changed, update the mesh's color
        const std::string propertyName = (prop)->getName();
693
        if(propertyName == "MeshSolidColor") {
694
695
696
            _meshGeomTexturesDirty = true;
            invalidateMeshGeomTextures();
        }        
697
    }
698
}