datacontainerinspectorcanvas.cpp 29.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, 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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

        /// if the window is resized, change the depth buffer size, also!
        if(_depthBuffer)
            if(_depthBuffer->getWidth() != width() || _depthBuffer->getHeight() != height()) {
                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;
            }
            else {
                // Do nothing!
            }
        else {
            _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;
        }

179
        LGL_ERROR;
180
        tbb::mutex::scoped_lock lock(_localMutex);
181
182
183
        if (_texturesDirty)
            updateTextures();

184
185
        if (_textures.empty())
            return;
186
187

        glPushAttrib(GL_ALL_ATTRIB_BITS);
188
        glViewport(0, 0, size_.x, size_.y);
189
190
191
192
193
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
194
195
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
196
        _quadSize = size_ / _numTiles;
197
198
199
200
201
202

        _paintShader->activate();

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

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

208
209
210
211
212
213
214
215
216
217
        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);
218
219
220
            }
        }

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

226
    void DataContainerInspectorCanvas::paintMeshGeomTextures() {
227
228
229
        LGL_ERROR;
        tbb::mutex::scoped_lock lock(_localMutex);
        if (_meshGeomTexturesDirty)
230
            updateMeshGeomRenderedTextures();
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
262
263
264
265
266
267
268
269
270
271
272
273

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

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

        _paintShader->setIgnoreUniformLocationError(true);
277
278
279
280
        if (texture->getDimensions().z == 1) {
            unit2d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", false);
281
            _paintShader->setUniform("_isDepthTexture", texture->isDepthTexture());
282
283
284
            _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()));
285
286
        }
        else {
287
288
289
            // clamp current slice to texture size, since this can't be done in event handler:
            _currentSlice = tgt::clamp(_currentSlice, -1, texture->getDimensions().z);

290
291
292
            unit3d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", true);
293
            _paintShader->setUniform("_sliceNumber", p_currentSlice.getValue());
294
295
296
            _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()));
297
        }
298
299
        _paintShader->setIgnoreUniformLocationError(false);

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

304
    void DataContainerInspectorCanvas::drawGeomteryData(const campvis::GeometryData* mg, tgt::Texture* colorBuffer, const int& trackballndx) {
305
        LGL_ERROR;
mostajab's avatar
mostajab committed
306
        
307
308
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        
mostajab's avatar
mostajab committed
309
310
        /// Activate the shader for geometry Rendering.
        _geometryRenderingShader->activate();
311
        LGL_ERROR;
312
313
314
315
316
317
318
319
        _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());
320
321
        LGL_ERROR;

mostajab's avatar
mostajab committed
322
        // The color that will be used for rendering the object
323
324
325
326
327
        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
328
        _geometryRenderingShader->setUniform("_Color", meshColor);
329
330
        
        LGL_ERROR;
331
332
333
334
335
336
        //_geometryRenderingShader->setUniform("_cameraPosition", _trackballEHs[trackballndx]->_trackball->getCamera()->getPosition());
        _geometryRenderingShader->setIgnoreUniformLocationError(false);
                        LGL_ERROR;
        
        _frameBuffer->activate();
        LGL_ERROR;
337

338
339
340
        // acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
        //tgt::TextureUnit rtUnit;
        //rtUnit.activate();
341

342
343
        // Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
344

345
        colorBuffer->uploadTexture();
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
        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;
363

364
        
mostajab's avatar
mostajab committed
365
        // render the geometry into a polygon mesh.
366
        glPolygonMode(GL_FRONT, GL_POLYGON);
367
        mg->render(GL_POLYGON);
368

369

mostajab's avatar
mostajab committed
370
371
372
373
        // change the color to white for the wireframe.
        _geometryRenderingShader->setUniform("_Color", 1.0f, 1.0f, 1.0f, 1.0f);

        // Render wireframe around the geometry.
374
375
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        mg->render(GL_POLYGON);
mostajab's avatar
mostajab committed
376
             
377
378
        LGL_ERROR;

379
380
        colorBuffer->downloadTexture();
        /*_depthBuffer.downloadTexture();*/
381

382
383
        _frameBuffer->deactivate();
        LGL_ERROR;
384

385
        _geometryRenderingShader->deactivate();
386
387

        glPopAttrib();
388
389
390
    }

    void DataContainerInspectorCanvas::invalidate() {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
391
392
393
        // only if inited
        if (_quad != 0 && _paintShader != 0)
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
394
395
    }

396
    void DataContainerInspectorCanvas::invalidateMeshGeomTextures() {
397
398
        // only if inited
        if (_quad != 0 && _paintShader != 0)
399
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paintMeshGeomTextures), OpenGLJobProcessor::PaintJob);
400
401
    }

402
    void DataContainerInspectorCanvas::createQuad() {
403
404
        std::vector<tgt::vec3> vertices, texCorods;

405
        vertices.push_back(tgt::vec3(0.f,  0.f, 0.f));
406
407
        vertices.push_back(tgt::vec3(1.f, 0.f, 0.f));
        vertices.push_back(tgt::vec3(1.f, 1.f, 0.f));
408
        vertices.push_back(tgt::vec3(0.f,  1.f, 0.f));
409
410
411
412
413
414
415
416
417
418
        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();
    }

419
420
421
422
    void DataContainerInspectorCanvas::repaint() {
        invalidate();
    }

423
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2& size) {
424
425
426
        invalidate();
    }

427
428
429
430
431
432
433
434
435
    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;
        }
436
        e->ignore();
437
438
439
        invalidate();
    }

440
441
    void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
    {
442
        //LGL_ERROR;
443
444
445
446
447
448
449
450
451
452
        /*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();*/
453
        if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT) {
454
455
456
457
458
459
460
461
462
463
            tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);

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

465
466
467
            
            if(_selectedTrackball >= 0) {
                _trackballEHs[_selectedTrackball]->onEvent(&adjustedMe);
468

469
470
471
                _meshGeomTexturesDirty = true;
                invalidateMeshGeomTextures();
            }
472
            
473
        }
474
        else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT) {
475
476
477
478
479
480
481
482
483
484
            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);
485

486
487
488
489
490
491
492
493
494
            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();
            }      
495
        }
496
497
    }

498
499
500
501
502
503
504
505
506
507
508
509
    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;
510
511
                default:
                    break;
512
513
514
515
516
            }
            invalidate();
        }
    }

517
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
518
        //LGL_ERROR;
519
        //if (_renderFullscreen) {
520

521
522
523
            tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
            _selectedTrackball = -1;
            std::vector<GeometryTextureInfo>::iterator geomTexInfoIter = _geomTextureInfos.begin();
524

525
526
527
            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
528

529
530
531
532
533
534
535
536
                _selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;
                
                for(; geomTexInfoIter != _geomTextureInfos.end(); geomTexInfoIter++) {
                    if((*geomTexInfoIter)._trackballIndx == _selectedTexture) {
                        _selectedTrackball = (*geomTexInfoIter)._trackballIndx;
                        break;
                    }
                }
537

538
539
                if(_selectedTrackball >= 0)
                    _trackballEHs[_selectedTrackball]->getTrackball()->startMouseDrag(e);
540
541
542
543
544
545
546
547
548
549
550
551
552
553
                   // 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
554
555
                if(_selectedTrackball >= 0)
                _trackballEHs[_selectedTrackball]->getTrackball()->endMouseDrag(e);
556
557
558
559
560
561
                   // e->ignore();
                    break;
                
                default:
                    break;
            }
562
            //invalidate();
563
564
565
        }
    }

566
567
568
569
570
571
572
573
574
575
576
577
578
    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
579
                _texturesDirty = true;
580
581
            }
        }
582
583
584

        if (_texturesDirty)
            invalidate();
585
586
587
588
589
590
591
592
593
    }

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

594
            _texturesDirty = true;
595
596
597
598
599
        }

        invalidate();
    }

600
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor() {
601
602
        return _color;
    }
603

604
    const float& DataContainerInspectorCanvas::getCapturedDepth() {
605
606
607
        return _depth;
    }

608
    void DataContainerInspectorCanvas::updateTextures() {
609

mostajab's avatar
mostajab committed
610
611
        /// Reset the content of the Canvas.
        resetContent();
612

613
        /// Calculate the maximum slices of the textures and fill the textures array
614
        int maxSlices = 1;
615
        unsigned int nMeshGeometry = 0;
616
617
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
618
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
619
                    _textures.push_back(imgGL->getTexture());
620
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
621
622
                }
            }
623
624
625
626
            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)
627
628
                    {
                        imgGL->downloadTexture();
629
                        _textures.push_back(imgGL->getTexture());
630
                    }
631
632
633
634
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
                    if (imgGL)
635
636
                    {
                        imgGL->downloadTexture();
637
                        _textures.push_back(imgGL->getTexture());
638
                    }
639
640
641

                }
            }
642
            else if(const campvis::GeometryData* gd = dynamic_cast<const campvis::GeometryData*>(it->second.getData())) {
643
                
644
                LGL_ERROR;
645

646
647
648
649
650
651
                GeometryTextureInfo geomTexInfo;
                geomTexInfo._geomData = it->second;
                geomTexInfo._trackballIndx = nMeshGeometry;
                              
                campvis::CameraProperty* cameraProperty = new CameraProperty("camera", "Camera");
                _trackballCameraProperties.push_back(cameraProperty);
652

mostajab's avatar
mostajab committed
653
                /// re-initialize the trackball navigation event listener to reset the object's pose
654
655
656
657
                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
658
                LGL_ERROR;
659
                                
mostajab's avatar
mostajab committed
660
                /// store the trackball in the vector
661
662
                _trackballEHs.push_back(trackballEH);
                
mostajab's avatar
mostajab committed
663
                /// create color buffer and depth buffer.
664
                tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(width(), height(), 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
665

mostajab's avatar
mostajab committed
666
                /// Render the object on the buffers.
667
                glewExperimental = true;
668
                drawGeomteryData(gd, colorBuffer, nMeshGeometry++);
669
                LGL_ERROR;
mostajab's avatar
mostajab committed
670

671
672
                geomTexInfo._texture = colorBuffer;

mostajab's avatar
mostajab committed
673
                /// Store the buffers into array.
674
675
                _geomTextureInfos.push_back(geomTexInfo);
                
mostajab's avatar
mostajab committed
676
677

                /// Store the rendered texture in textures.
678
                _textures.push_back(colorBuffer);
mostajab's avatar
mostajab committed
679
680

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

683
            }
684
685
686
687
688
        }

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
689
        _meshGeomTexturesDirty = false;
690
691
        _texturesDirty = false;
    }
692

693
    void DataContainerInspectorCanvas::updateMeshGeomRenderedTextures() {
694
        
695
696
697
        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);
698
        }
699

700
        _meshGeomTexturesDirty = false;
701
702
703
704
705
    }

    void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
        HasPropertyCollection::onPropertyChanged(prop);
        invalidate();
706
707
708

        /// if the Mesh Solid Color property is changed, update the mesh's color
        const std::string propertyName = (prop)->getName();
709
        if(propertyName == "MeshSolidColor") {
710
711
712
            _meshGeomTexturesDirty = true;
            invalidateMeshGeomTextures();
        }        
713
    }
714
}