datacontainerinspectorcanvas.cpp 22.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(1.f), tgt::vec4(0.f), tgt::vec4(255.f))
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
        , _geomteryRendering_ColorBuffer(0)
        , _geomteryRendering_DepthBuffer(0)
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
85
86
87
88
89
        addProperty(&p_meshSolidColor);
        //addProperty(&_camera);

        _trackballCamera = new tgt::Camera(tgt::vec3(0.0f, 0.0f, 100.0f), tgt::vec3(0, 0, -1));
        _trackballCameraProperty = new campvis::CameraProperty("camera", "Camera", *_trackballCamera);
        _canvasSizeProperty = new campvis::IVec2Property("CanvasSize", "Canvas Size", tgt::ivec2(128, 128), tgt::ivec2(1, 1), tgt::ivec2(4096, 4096));
        _trackballEH = new TrackballNavigationEventListener(_trackballCameraProperty, _canvasSizeProperty);
90
91
92
93
94
95
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

96
    void DataContainerInspectorCanvas::init(DataContainerInspectorWidget* _pWidget) {
schultezub's avatar
schultezub committed
97
98
        initAllProperties();

99
        _widget = _pWidget;
100

101
102
        GLJobProc.registerContext(this);
        _paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
103
		_geomteryRenderingShader = ShdrMgr.loadSeparate("core/glsl/meshgeomteryrenderer.vert", "modules/vis/glsl/meshgeometryrenderer.frag", "", false);
104

105
106
        _paintShader->setAttributeLocation(0, "in_Position");
        _paintShader->setAttributeLocation(1, "in_TexCoords");
107

108
109
        createQuad();

110
        // set this as painter to get notified when window size changes
111
        setPainter(this, false);
112
        getEventHandler()->addEventListenerToFront(this);
113
114
115
    }

    void DataContainerInspectorCanvas::deinit() {
schultezub's avatar
schultezub committed
116
117
        deinitAllProperties();

118
119
120
121
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

122
        _handles.clear();
123
        GLJobProc.deregisterContext(this);
124
        ShdrMgr.dispose(_paintShader);
125
        delete _quad;
126
127
128
129
130
131
132
133
    }

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


    void DataContainerInspectorCanvas::paint() {
134
        LGL_ERROR;
135
        tbb::mutex::scoped_lock lock(_localMutex);
136
137
138
        if (_texturesDirty)
            updateTextures();

139
140
        if (_textures.empty())
            return;
141
142

        glPushAttrib(GL_ALL_ATTRIB_BITS);
143
        glViewport(0, 0, size_.x, size_.y);
144
145
146
147
148
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

        // update layout dimensions
149
150
        _numTiles.x = ceil(sqrt(static_cast<float>(_textures.size())));
        _numTiles.y = ceil(static_cast<float>(_textures.size()) / _numTiles.x);
151
        _quadSize = size_ / _numTiles;
152
153
154
155
156
157

        _paintShader->activate();

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

158
159
        tgt::TextureUnit tfUnit, unit2d, unit3d;
        p_transferFunction.getTF()->bind(_paintShader, tfUnit);
160
161
        _paintShader->setUniform("_texture2d", unit2d.getUnitNumber());
        _paintShader->setUniform("_texture3d", unit3d.getUnitNumber());
162

163
164
165
166
167
168
169
170
171
172
        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);
173
174
175
            }
        }

176
        _paintShader->deactivate();
177
178
179
180
        LGL_ERROR;
        glPopAttrib();
    }

181
    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d) {
182
183

        _paintShader->setIgnoreUniformLocationError(true);
184
185
186
187
        if (texture->getDimensions().z == 1) {
            unit2d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", false);
188
            _paintShader->setUniform("_isDepthTexture", texture->isDepthTexture());
189
190
191
            _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()));
192
193
        }
        else {
194
195
196
            // clamp current slice to texture size, since this can't be done in event handler:
            _currentSlice = tgt::clamp(_currentSlice, -1, texture->getDimensions().z);

197
198
199
            unit3d.activate();
            texture->bind();
            _paintShader->setUniform("_is3d", true);
200
            _paintShader->setUniform("_sliceNumber", p_currentSlice.getValue());
201
202
203
            _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()));
204
        }
205
206
        _paintShader->setIgnoreUniformLocationError(false);

207
        _quad->render(GL_POLYGON);
208
209
210
211
212
213
214
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
        LGL_ERROR;
    }

    void DataContainerInspectorCanvas::drawMeshGeomtery(const campvis::MeshGeometry* mg)
    {
        LGL_ERROR;
        // Here the object will be rendered into a texture and the texture will be shown on the output buffer
		glPushAttrib(GL_ALL_ATTRIB_BITS);
		_geomteryRenderingShader->activate();
		LGL_ERROR;
		_geomteryRenderingShader->setIgnoreUniformLocationError(true);
		LGL_ERROR;
		//decorateRenderProlog(data, _shader);
				
        //_trackballCamera->setPosition(tgt::vec3(0.0f, 0.0f, dist));
        //_trackballCamera->setFocus(tgt::vec3(0, 0, -1));
        //_trackballCamera->setFarDist(1000.0f);

        _trackballEH->setSceneBounds(mg->getWorldBounds());
				
		campvis::IVec4Property* p_color = new campvis::IVec4Property("myColor", "MyRenderingColor", tgt::vec4(1.f), tgt::vec4(0.f), tgt::vec4(1.f));
					
        _geomteryRenderingShader->setUniform("_projectionMatrix", _trackballEH->_trackball->getCamera()->getProjectionMatrix()/*_trackballCameraProperty->getValue().getProjectionMatrix()*/);
										LGL_ERROR;
        tgt::Matrix4f mat = _trackballCamera->getProjectionMatrix();
        _geomteryRenderingShader->setUniform("_viewMatrix", _trackballEH->_trackball->getCamera()->getViewMatrix());
        
		LGL_ERROR;
		LGL_ERROR;

		_geomteryRenderingShader->setUniform("_colormory", p_color->getValue());

		LGL_ERROR;
        _geomteryRenderingShader->setUniform("_cameraPosition", _trackballEH->_trackball->getCamera()->getPosition());
										LGL_ERROR;
		_geomteryRenderingShader->setIgnoreUniformLocationError(false);
						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);

        _geomteryRendering_ColorBuffer->uploadTexture();
		_geomteryRendering_ColorBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);

		_geomteryRendering_DepthBuffer->uploadTexture();
		_geomteryRendering_DepthBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
		LGL_ERROR;
		frameBuffer->attachTexture(_geomteryRendering_ColorBuffer, GL_COLOR_ATTACHMENT0);
		frameBuffer->attachTexture(_geomteryRendering_DepthBuffer, GL_DEPTH_ATTACHMENT);
		frameBuffer->isComplete();
		LGL_ERROR;

		glViewport(0, 0, 400, 100);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);
		glClearDepth(1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		LGL_ERROR;

        //for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
        //    if (const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())) {
                //mg->render(GL_POLYGON);

        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        mg->render(GL_POLYGON);
       //     }
      //  }
		
		
        
        LGL_ERROR;

		_geomteryRendering_ColorBuffer->downloadTexture();
		frameBuffer->deactivate();
		LGL_ERROR;

		_geomteryRenderingShader->deactivate();

        glPopAttrib();

        //delete frameBuffer;
297
298
299
    }

    void DataContainerInspectorCanvas::invalidate() {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
300
301
302
        // only if inited
        if (_quad != 0 && _paintShader != 0)
            GLJobProc.enqueueJob(this, makeJobOnHeap(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
303
304
    }

305
    void DataContainerInspectorCanvas::createQuad() {
306
307
308
        std::vector<tgt::vec3> vertices, texCorods;

        vertices.push_back(tgt::vec3( 0.f,  0.f, 0.f));
309
310
311
        vertices.push_back(tgt::vec3(1.f, 0.f, 0.f));
        vertices.push_back(tgt::vec3(1.f, 1.f, 0.f));
        vertices.push_back(tgt::vec3( 0.f,  1.f, 0.f));
312
313
314
315
316
317
318
319
320
321
        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();
    }

322
323
324
325
    void DataContainerInspectorCanvas::repaint() {
        invalidate();
    }

326
327
328
329
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2&) {
        invalidate();
    }

330
331
332
333
334
335
336
337
338
    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;
        }
339
        e->ignore();
340
341
342
        invalidate();
    }

343
344
    void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
    {
345
        LGL_ERROR;
346
347
348
349
350
351
352
353
354
355
        /*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();*/
356
        if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT)
357
        {
358
359
360
361
362
363
364
365
366
367
368
            tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);

            tgt::MouseEvent adjustedMe(
                me->x(),
                me->y(),
                me->action(),
                me->modifiers(),
                me->button(),
                me->viewport() 
                );
            _trackballEH->onEvent(&adjustedMe);
369

370
371
372
373
374
            _texturesDirty = true;
            invalidate();
        }
        else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT)
        {
375
376
377
378
379
380
381
382
383
384
            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);
385
386
387
388
389
390
391
392
393
394
395
396

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

400
401
402
403
404
405
406
407
408
409
410
411
    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;
412
413
                default:
                    break;
414
415
416
417
418
            }
            invalidate();
        }
    }

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
        LGL_ERROR;
        //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
                _trackballEH->_trackball->startMouseDrag(e);
                   // 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
                _trackballEH->_trackball->endMouseDrag(e);
                   // e->ignore();
                    break;
                
                default:
                    break;
            }
            invalidate();
        }
    }

451
452
453
454
455
456
457
458
459
460
461
462
463
    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
464
                _texturesDirty = true;
465
466
            }
        }
467
468
469

        if (_texturesDirty)
            invalidate();
470
471
472
473
474
475
476
477
478
    }

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

479
            _texturesDirty = true;
480
481
482
483
484
        }

        invalidate();
    }

485
486
487
488
    const tgt::Color& DataContainerInspectorCanvas::getCapturedColor()
    {
        return _color;
    }
489

490
491
492
493
494
	const float& DataContainerInspectorCanvas::getCapturedDepth()
    {
        return _depth;
    }

495
    void DataContainerInspectorCanvas::updateTextures() {
496
        /// Clear the textures Array
497
        _textures.clear();
498

499
        /// Calculate the maximum slices of the textures and fill the textures array
500
        int maxSlices = 1;
501
502
        for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
503
                if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
504
                    _textures.push_back(imgGL->getTexture());
505
                    maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
506
507
                }
            }
508
509
510
511
            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)
512
513
                    {
                        imgGL->downloadTexture();
514
                        _textures.push_back(imgGL->getTexture());
515
                    }
516
517
518
519
                }
                if (rd->hasDepthTexture()) {
                    const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
                    if (imgGL)
520
521
                    {
                        imgGL->downloadTexture();
522
                        _textures.push_back(imgGL->getTexture());
523
                    }
524
525
526

                }
            }
527
            else if(const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())){
528
				
529
530
531
532
533
534
535
536
537
538
539
                LGL_ERROR;
                
                static bool flag = false;

                if(!flag)
                {
                    float dist = 3 * fabs(mg->getWorldBounds().getLLF().z - mg->getWorldBounds().getURB().z);
                    _trackballEH->reinitializeCamera(mg->getWorldBounds());
                    _trackballEH->_trackball->moveCameraBackward(dist);
                    flag = true;
                }
540

541
542
                if(_geomteryRendering_ColorBuffer)
                    delete _geomteryRendering_ColorBuffer;
543

544
545
                if(_geomteryRendering_DepthBuffer)
                    delete _geomteryRendering_DepthBuffer;
546

547
548
                _geomteryRendering_ColorBuffer = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
                _geomteryRendering_DepthBuffer  = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
549

550
551
552
553
                _meshGeomteryPtr = mg;
                drawMeshGeomtery(mg);
                
				_textures.push_back(_geomteryRendering_ColorBuffer);				
554
555
556
557
558

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


			}
559
        }
560
561
562
563

        if (maxSlices == 1)
            maxSlices = -1;
        p_currentSlice.setMaxValue(maxSlices);
564
        _texturesDirty = false;
565
566
567
568
569
570
571
    }

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

572
}