datacontainerinspectorcanvas.cpp 31.2 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
67
		, _meshGeomTexturesDirty(false)
		, _renderingWndSize(tgt::ivec2(400, 100))
68
    {
69
		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)));
70
71
72
73
74
75
76
77
78
79

        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);
        }
80
        
81
82
        addProperty(&p_currentSlice);
        addProperty(&p_transferFunction);
83
84
        addProperty(&p_meshSolidColor);
        //addProperty(&_camera);
85
86
87
88
89
90
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

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

94
        _widget = _pWidget;
95

96
97
        GLJobProc.registerContext(this);
        _paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
mostajab's avatar
mostajab committed
98
		_geometryRenderingShader = ShdrMgr.loadSeparate("core/glsl/meshgeometryrenderer.vert", "modules/vis/glsl/meshgeometryrenderer.frag", "", false);
99

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

103
104
        createQuad();

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

    void DataContainerInspectorCanvas::deinit() {
schultezub's avatar
schultezub committed
111
112
        deinitAllProperties();

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

117
        _handles.clear();
118
        GLJobProc.deregisterContext(this);
119
        ShdrMgr.dispose(_paintShader);
120
        delete _quad;
mostajab's avatar
mostajab committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

        resetContent();
    }

    void DataContainerInspectorCanvas::resetContent()
    {
        /// Clear the textures Array and geometry textures indicies array
        _textures.clear();
		_geomTextureIndices.clear();

		/// Clear the trackball navigation event listener array
        /// - First delete the data that it contains
		std::vector<TrackballNavigationEventListener*>::iterator trackballNavEHIterator = _trackballEHs.begin();
		for(; trackballNavEHIterator != _trackballEHs.end(); trackballNavEHIterator++)
		{
			delete (*trackballNavEHIterator);
		}
		_trackballEHs.clear();

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

        /// Clear the Color Buffers that the geometry has been rendered to.
        /// - First delete the data that it contains
        std::vector<tgt::Texture*>::iterator colorBufferIterator = _geometryRendering_ColorBuffers.begin();
        for(; colorBufferIterator != _geometryRendering_ColorBuffers.end(); colorBufferIterator++)
		{
            //delete (*colorBufferIterator);
		}
        _geometryRendering_ColorBuffers.clear();

        /// Clear the Depth Buffers that the geometry has been rendered to.
        /// - First delete the data that it contains
        std::vector<tgt::Texture*>::iterator depthBufferIterator = _geometryRendering_DepthBuffers.begin();
        for(; depthBufferIterator != _geometryRendering_DepthBuffers.end(); depthBufferIterator++)
		{
            //delete (*depthBufferIterator);
		}
        _geometryRendering_DepthBuffers.clear();
166
167
168
169
170
171
172
173
    }

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


    void DataContainerInspectorCanvas::paint() {
174
        LGL_ERROR;
175
        tbb::mutex::scoped_lock lock(_localMutex);
176
177
178
        if (_texturesDirty)
            updateTextures();

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

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

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

        _paintShader->activate();

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

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

203
204
205
206
207
208
209
210
211
212
        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);
213
214
215
            }
        }

216
        _paintShader->deactivate();
217
218
219
220
        LGL_ERROR;
        glPopAttrib();
    }

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

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

269
    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d) {
270
271

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

285
286
287
            unit3d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", true);
288
            _paintShader->setUniform("_sliceNumber", p_currentSlice.getValue());
289
290
291
            _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()));
292
        }
293
294
        _paintShader->setIgnoreUniformLocationError(false);

295
        _quad->render(GL_POLYGON);
296
297
298
        LGL_ERROR;
    }

mostajab's avatar
mostajab committed
299
	void DataContainerInspectorCanvas::drawMeshgeometry(const campvis::MeshGeometry* mg, tgt::Texture* colorBuffer, tgt::Texture* depthBuffer, const unsigned int& meshIndex)
300
301
    {
        LGL_ERROR;
mostajab's avatar
mostajab committed
302
        
303
		glPushAttrib(GL_ALL_ATTRIB_BITS);
mostajab's avatar
mostajab committed
304
305
306
		
        /// Activate the shader for geometry Rendering.
        _geometryRenderingShader->activate();
307
		LGL_ERROR;
mostajab's avatar
mostajab committed
308
		_geometryRenderingShader->setIgnoreUniformLocationError(true);
309
		LGL_ERROR;
mostajab's avatar
mostajab committed
310
		
311
        _trackballEHs[meshIndex]->setSceneBounds(mg->getWorldBounds());
312
				
mostajab's avatar
mostajab committed
313
314
		// setting the uniform data for rendering the geometry
        campvis::IVec4Property* p_color = new campvis::IVec4Property("myColor", "MyRenderingColor", tgt::vec4(1.f), tgt::vec4(0.f), tgt::vec4(1.f));
315
		
mostajab's avatar
mostajab committed
316
        _geometryRenderingShader->setUniform("_projectionMatrix", _trackballEHs[meshIndex]->_trackball->getCamera()->getProjectionMatrix()/*_trackballCameraProperty->getValue().getProjectionMatrix()*/);
317
        LGL_ERROR;
mostajab's avatar
mostajab committed
318
        _geometryRenderingShader->setUniform("_viewMatrix", _trackballEHs[meshIndex]->_trackball->getCamera()->getViewMatrix());
319
320
        LGL_ERROR;

mostajab's avatar
mostajab committed
321
        // The color that will be used for rendering the object
322
323
324
325
326
        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
327
        _geometryRenderingShader->setUniform("_Color", meshColor);
328
329
        
        LGL_ERROR;
mostajab's avatar
mostajab committed
330
331
        _geometryRenderingShader->setUniform("_cameraPosition", _trackballEHs[meshIndex]->_trackball->getCamera()->getPosition());
		_geometryRenderingShader->setIgnoreUniformLocationError(false);
332
333
334
335
336
337
338
339
340
341
342
343
344
						LGL_ERROR;
		tgt::FramebufferObject* frameBuffer = new tgt::FramebufferObject();
						LGL_ERROR;
		frameBuffer->activate();
		LGL_ERROR;

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

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

345
346
        colorBuffer->uploadTexture();
		colorBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
347

348
349
		depthBuffer->uploadTexture();
		depthBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
350
		LGL_ERROR;
351
352
		frameBuffer->attachTexture(colorBuffer, GL_COLOR_ATTACHMENT0);
		frameBuffer->attachTexture(depthBuffer, GL_DEPTH_ATTACHMENT);
353
354
355
		frameBuffer->isComplete();
		LGL_ERROR;

356
		glViewport(0, 0, _renderingWndSize.x, _renderingWndSize.y);
357
358
359
360
361
362
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);
		glClearDepth(1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		LGL_ERROR;

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

368

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

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

378
379
380
		colorBuffer->downloadTexture();
		depthBuffer->downloadTexture();

381
382
383
		frameBuffer->deactivate();
		LGL_ERROR;

mostajab's avatar
mostajab committed
384
		_geometryRenderingShader->deactivate();
385
386
387

        glPopAttrib();

mostajab's avatar
mostajab committed
388
        delete frameBuffer;
389
390
391
    }

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

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

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

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

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

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

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

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

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

467
468
469
470
471
472
473
474
475
			
			if(_selectedTrackball >= 0)
			{
				_trackballEHs[_selectedTrackball]->onEvent(&adjustedMe);

				_meshGeomTexturesDirty = true;
				invalidateMeshGeomTextures();
			}
            
476
477
478
        }
        else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT)
        {
479
480
481
482
483
484
485
486
487
488
            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);
489
490
491
492
493
494
495
496
497
498
499
500

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

504
505
506
507
508
509
510
511
512
513
514
515
    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;
516
517
                default:
                    break;
518
519
520
521
522
            }
            invalidate();
        }
    }

523
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
524
        //LGL_ERROR;
525
        //if (_renderFullscreen) {
526
527
528
529
530

			tgt::ivec2 selectedIndex(e->x() / _quadSize.x, e->y() / _quadSize.y);
			_selectedTrackball = -1;
			int geomTextureIndex = 0;

531
532
533
            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
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549

				_selectedTexture = (selectedIndex.y * _numTiles.x) + selectedIndex.x;

				while(geomTextureIndex < _geomTextureIndices.size() && _geomTextureIndices[geomTextureIndex] <= _selectedTexture)
				{
					if(_geomTextureIndices[geomTextureIndex] == _selectedTexture)
					{
						_selectedTrackball = geomTextureIndex;
						break;
					}

					geomTextureIndex++;
				}

				if(_selectedTrackball >= 0)
					_trackballEHs[_selectedTrackball]->_trackball->startMouseDrag(e);
550
551
552
553
554
555
556
557
558
559
560
561
562
563
                   // 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
564
565
				if(_selectedTrackball >= 0)
                _trackballEHs[_selectedTrackball]->_trackball->endMouseDrag(e);
566
567
568
569
570
571
                   // e->ignore();
                    break;
                
                default:
                    break;
            }
572
            //invalidate();
573
574
575
        }
    }

576
577
578
579
580
581
582
583
584
585
586
587
588
    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
589
                _texturesDirty = true;
590
591
            }
        }
592
593
594

        if (_texturesDirty)
            invalidate();
595
596
597
598
599
600
601
602
603
    }

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

604
            _texturesDirty = true;
605
606
607
608
609
        }

        invalidate();
    }

610
611
612
613
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor()
    {
        return _color;
    }
614

615
616
617
618
619
	const float& DataContainerInspectorCanvas::getCapturedDepth()
    {
        return _depth;
    }

620
    void DataContainerInspectorCanvas::updateTextures() {
621

mostajab's avatar
mostajab committed
622
623
        /// Reset the content of the Canvas.
        resetContent();
624

625
        /// Calculate the maximum slices of the textures and fill the textures array
626
        int maxSlices = 1;
627
		unsigned int nMeshGeometry = 0;
628
629
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
630
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
631
                    _textures.push_back(imgGL->getTexture());
632
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
633
634
                }
            }
635
636
637
638
            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)
639
640
                    {
                        imgGL->downloadTexture();
641
                        _textures.push_back(imgGL->getTexture());
642
                    }
643
644
645
646
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
                    if (imgGL)
647
648
                    {
                        imgGL->downloadTexture();
649
                        _textures.push_back(imgGL->getTexture());
650
                    }
651
652
653

                }
            }
654
            else if(const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())){
655
				
656
657
658
659
                LGL_ERROR;
                
                static bool flag = false;

mostajab's avatar
mostajab committed
660
                /// 
661
662
663
				campvis::CameraProperty* cameraProperty = new CameraProperty("camera", "Camera");
				_trackballCameraProperties.push_back(cameraProperty);

mostajab's avatar
mostajab committed
664
                /// re-initialize the trackball navigation event listener to reset the object's pose
665
                TrackballNavigationEventListener* trackballEH = new TrackballNavigationEventListener(cameraProperty, new IVec2Property("QuadSize", "Size", _renderingWndSize, tgt::ivec2(0), tgt::ivec2(1024)) );
mostajab's avatar
mostajab committed
666
667
668
669
670
671
672
                float dist = 3 * fabs(mg->getWorldBounds().getLLF().z - mg->getWorldBounds().getURB().z);
                trackballEH->reinitializeCamera(mg->getWorldBounds());
                trackballEH->_trackball->moveCameraBackward(dist);
                LGL_ERROR;
                flag = true;
                
                /// store the trackball in the vector
673
674
				_trackballEHs.push_back(trackballEH);
				
mostajab's avatar
mostajab committed
675
                /// create color buffer and depth buffer.
676
677
678
				tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(_renderingWndSize.x, _renderingWndSize.y, 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
				tgt::Texture* depthBuffer  = new tgt::Texture(0, tgt::ivec3(_renderingWndSize.x, _renderingWndSize.y, 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);

mostajab's avatar
mostajab committed
679
                /// Render the object on the buffers.
680
                glewExperimental = true;
mostajab's avatar
mostajab committed
681
                drawMeshgeometry(mg, colorBuffer, depthBuffer, nMeshGeometry++);
682
                LGL_ERROR;
mostajab's avatar
mostajab committed
683
684
685
686
687
688

                /// Store the buffers into array.
                _geometryRendering_ColorBuffers.push_back(colorBuffer);
                _geometryRendering_DepthBuffers.push_back(depthBuffer);

                /// Store the rendered texture in textures.
689
				_textures.push_back(colorBuffer);
mostajab's avatar
mostajab committed
690
691

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

694
            }else if(const campvis::FaceGeometry* fg = dynamic_cast<const campvis::FaceGeometry*>(it->second.getData())){
695
696


697
698
699
700
701
702
703
704
			}
        }

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
        _texturesDirty = false;
    }
705

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
	void DataContainerInspectorCanvas::updateMeshGeomRenderedTextures() {
        
		/// Calculate the maximum slices of the textures and fill the textures array
        int maxSlices = 1;
		unsigned int nMeshGeometry = 0;
		unsigned int nElement = 0;
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
                    nElement++;
                }
            }
            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)
                    {
						nElement++;
                    }
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
                    if (imgGL)
                    {
                        nElement++;
                    }
                }
            }
mostajab's avatar
mostajab committed
734
735
            else if(const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())){     
                /// Createa new color and depth buffer to render the new pose of the mesh object
736
737
				tgt::Texture* colorBuffer = new tgt::Texture(0, tgt::ivec3(_renderingWndSize.x, _renderingWndSize.y, 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
				tgt::Texture* depthBuffer  = new tgt::Texture(0, tgt::ivec3(_renderingWndSize.x, _renderingWndSize.y, 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
738

mostajab's avatar
mostajab committed
739
                /// delete the previous data in the 
740
741
742
				delete *(_textures.begin() + nElement);
				std::vector<const tgt::Texture*>::iterator erased = _textures.erase(_textures.begin() + nElement);

mostajab's avatar
mostajab committed
743
744
745
746
                /// render the mesh object
                drawMeshgeometry(mg, colorBuffer, depthBuffer, nMeshGeometry);
                
                /// insert it into the array of textures (in the 
747
				_textures.insert(_textures.begin() + nElement, colorBuffer);
748

mostajab's avatar
mostajab committed
749
750
                /// increase the number of geomteries and number of elements
                nMeshGeometry++;
751
				nElement++;
752

mostajab's avatar
mostajab committed
753
754
755
                /// delete the stored depth buffer
                delete depthBuffer;

756
757
758
            }else if(const campvis::FaceGeometry* fg = dynamic_cast<const campvis::FaceGeometry*>(it->second.getData())){

				
759
			}
760
        }
761
762
763
764

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
765
        _texturesDirty = false;
766
767
768
769
770
    }

    void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
        HasPropertyCollection::onPropertyChanged(prop);
        invalidate();
771
772
773
774
775
776
777
778

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

781
}