~noskcaj/ubuntu/saucy/openwalnut/liberation

« back to all changes in this revision

Viewing changes to .pc/boost153/src/modules/imageSpaceLIC/WMImageSpaceLIC.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-05-24 03:12:03 UTC
  • Revision ID: package-import@ubuntu.com-20130524031203-l5g1lzm1vd83fupi
Tags: 1.3.1+hg5849-1ubuntu1
Cherrypick boost1.53 pointer cast fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//---------------------------------------------------------------------------
 
2
//
 
3
// Project: OpenWalnut ( http://www.openwalnut.org )
 
4
//
 
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
 
6
// For more information see http://www.openwalnut.org/copying
 
7
//
 
8
// This file is part of OpenWalnut.
 
9
//
 
10
// OpenWalnut is free software: you can redistribute it and/or modify
 
11
// it under the terms of the GNU Lesser General Public License as published by
 
12
// the Free Software Foundation, either version 3 of the License, or
 
13
// (at your option) any later version.
 
14
//
 
15
// OpenWalnut is distributed in the hope that it will be useful,
 
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
// GNU Lesser General Public License for more details.
 
19
//
 
20
// You should have received a copy of the GNU Lesser General Public License
 
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
 
22
//
 
23
//---------------------------------------------------------------------------
 
24
 
 
25
#include <cmath>
 
26
#include <cstdlib>
 
27
#include <vector>
 
28
#include <string>
 
29
 
 
30
#include <osg/BoundingSphere>
 
31
#include <osg/Vec3>
 
32
#include <osg/Geode>
 
33
#include <osg/Geometry>
 
34
#include <osg/Drawable>
 
35
 
 
36
#include "core/common/WPropertyHelper.h"
 
37
#include "core/common/math/WMath.h"
 
38
#include "core/dataHandler/WDataHandler.h"
 
39
#include "core/dataHandler/WDataTexture3D.h"
 
40
#include "core/dataHandler/WGridRegular3D.h"
 
41
#include "core/graphicsEngine/WGEColormapping.h"
 
42
#include "core/graphicsEngine/WGEGeodeUtils.h"
 
43
#include "core/graphicsEngine/WGETextureUtils.h"
 
44
#include "core/graphicsEngine/callbacks/WGELinearTranslationCallback.h"
 
45
#include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
 
46
#include "core/graphicsEngine/offscreen/WGEOffscreenRenderNode.h"
 
47
#include "core/graphicsEngine/offscreen/WGEOffscreenRenderPass.h"
 
48
#include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
 
49
#include "core/graphicsEngine/shaders/WGEShader.h"
 
50
#include "core/graphicsEngine/shaders/WGEShaderDefineOptions.h"
 
51
#include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
 
52
#include "core/kernel/WKernel.h"
 
53
 
 
54
#include "WMImageSpaceLIC.h"
 
55
#include "WMImageSpaceLIC.xpm"
 
56
 
 
57
// This line is needed by the module loader to actually find your module. You need to add this to your module too. Do NOT add a ";" here.
 
58
W_LOADABLE_MODULE( WMImageSpaceLIC )
 
59
 
 
60
WMImageSpaceLIC::WMImageSpaceLIC():
 
61
    WModule()
 
62
{
 
63
}
 
64
 
 
65
WMImageSpaceLIC::~WMImageSpaceLIC()
 
66
{
 
67
    // Cleanup!
 
68
}
 
69
 
 
70
boost::shared_ptr< WModule > WMImageSpaceLIC::factory() const
 
71
{
 
72
    return boost::shared_ptr< WModule >( new WMImageSpaceLIC() );
 
73
}
 
74
 
 
75
const char** WMImageSpaceLIC::getXPMIcon() const
 
76
{
 
77
    return WMImageSpaceLIC_xpm;
 
78
}
 
79
 
 
80
const std::string WMImageSpaceLIC::getName() const
 
81
{
 
82
    return "Image Space LIC";
 
83
}
 
84
 
 
85
const std::string WMImageSpaceLIC::getDescription() const
 
86
{
 
87
    return "This module takes an vector dataset and creates an LIC-like texture on an arbitrary surface. You can specify the surface as input or"
 
88
           "leave it unspecified to use slices.";
 
89
}
 
90
 
 
91
void WMImageSpaceLIC::connectors()
 
92
{
 
93
    // vector input
 
94
    m_vectorsIn = WModuleInputData< WDataSetVector >::createAndAdd( shared_from_this(), "vectors", "The vector dataset."
 
95
                                                                                                    "Needs to be in the same grid as the mesh." );
 
96
    // scalar input
 
97
    m_scalarIn = WModuleInputData< WDataSetScalar >::createAndAdd( shared_from_this(), "scalars", "The scalar dataset."
 
98
                                                                                                    "Needs to be in the same grid as the mesh." );
 
99
 
 
100
    // mesh input
 
101
    m_meshIn = WModuleInputData< WTriangleMesh >::createAndAdd( shared_from_this(), "surface", "The optional surface to use." );
 
102
 
 
103
    // call WModule's initialization
 
104
    WModule::connectors();
 
105
}
 
106
 
 
107
void WMImageSpaceLIC::properties()
 
108
{
 
109
    m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
 
110
 
 
111
    m_geometryGroup   = m_properties->addPropertyGroup( "Geometry",  "Selection of used geometry to apply LIC to." );
 
112
 
 
113
    m_useSlices       = m_geometryGroup->addProperty( "Use Slices", "Show vectors on slices.", true, m_propCondition );
 
114
 
 
115
    m_sliceGroup      = m_geometryGroup->addPropertyGroup( "Slices",  "Slice based LIC." );
 
116
 
 
117
    // enable slices
 
118
    // Flags denoting whether the glyphs should be shown on the specific slice
 
119
    m_showonX        = m_sliceGroup->addProperty( "Show Sagittal", "Show vectors on sagittal slice.", true );
 
120
    m_showonY        = m_sliceGroup->addProperty( "Show Coronal", "Show vectors on coronal slice.", true );
 
121
    m_showonZ        = m_sliceGroup->addProperty( "Show Axial", "Show vectors on axial slice.", true );
 
122
 
 
123
    // The slice positions. These get update externally.
 
124
    // TODO(all): this should somehow be connected to the nav slices.
 
125
    m_xPos           = m_sliceGroup->addProperty( "Sagittal Position", "Slice X position.", 80 );
 
126
    m_yPos           = m_sliceGroup->addProperty( "Coronal Position", "Slice Y position.", 100 );
 
127
    m_zPos           = m_sliceGroup->addProperty( "Axial Position", "Slice Z position.", 80 );
 
128
    m_xPos->setMin( 0 );
 
129
    m_xPos->setMax( 159 );
 
130
    m_yPos->setMin( 0 );
 
131
    m_yPos->setMax( 199 );
 
132
    m_zPos->setMin( 0 );
 
133
    m_zPos->setMax( 159 );
 
134
 
 
135
    m_licGroup      = m_properties->addPropertyGroup( "LIC",  "LIC properties." );
 
136
 
 
137
    m_useLight       = m_licGroup->addProperty( "Use Light", "Check to enable lightning using the Phong model.", false );
 
138
 
 
139
    m_useEdges       = m_licGroup->addProperty( "Edges", "Check to enable blending in edges.", true );
 
140
    m_useHighContrast = m_licGroup->addProperty( "High Contrast", "Use an extremely increased contrast.", false );
 
141
 
 
142
    m_cmapRatio    = m_licGroup->addProperty( "Ratio Colormap to LIC", "Blending ratio between LIC and colormap.", 0.5 );
 
143
    m_cmapRatio->setMin( 0.0 );
 
144
    m_cmapRatio->setMax( 1.0 );
 
145
 
 
146
    m_advancedLicGroup      = m_properties->addPropertyGroup( "Advanced",  "More advanced LIC properties." );
 
147
    // show hud?
 
148
    m_showHUD        = m_advancedLicGroup->addProperty( "Show HUD", "Check to enable the debugging texture HUD.", false );
 
149
    m_useDepthCueing = m_advancedLicGroup->addProperty( "Depth Cueing", "Use depth as additional cue? Mostly useful for isosurfaces.",
 
150
                                                false );
 
151
    m_3dNoise        = m_advancedLicGroup->addProperty( "Use 3D noise", "Use 3D noise? This provides better coherence during transformation of "
 
152
                                                        "the geometry but might introduce resolution problems.", false );
 
153
    m_3dNoiseRes     = m_advancedLicGroup->addProperty( "3D Noise Resolution", "The 3D noise is of 128^3 pixels size. This scaler allows "
 
154
                                                        "modification of this size.", 3.0 );
 
155
    m_3dNoiseRes->setMin( 1 );
 
156
    m_3dNoiseRes->setMax( 10 );
 
157
 
 
158
    m_3dNoiseAutoRes = m_advancedLicGroup->addProperty( "3D Noise Auto-Resolution", "If checked, the resolution of the 3D noise gets calculated "
 
159
                                                       "automatically according to the screen size. If disabled, the user can zoom into the LIC.",
 
160
                                                       true );
 
161
 
 
162
    m_numIters     = m_advancedLicGroup->addProperty( "Number of Iterations", "How much iterations along a streamline should be done per frame.",
 
163
                                                      30 );
 
164
    m_numIters->setMin( 1 );
 
165
    m_numIters->setMax( 100 );
 
166
 
 
167
    // call WModule's initialization
 
168
    WModule::properties();
 
169
}
 
170
 
 
171
void WMImageSpaceLIC::initOSG( boost::shared_ptr< WGridRegular3D > grid, boost::shared_ptr< WTriangleMesh > mesh )
 
172
{
 
173
    // remove the old slices
 
174
    m_output->clear();
 
175
 
 
176
    if( mesh && !m_useSlices->get( true ) )
 
177
    {
 
178
        // we have a mesh and want to use it
 
179
        // create geometry and geode
 
180
        osg::Geometry* surfaceGeometry = new osg::Geometry();
 
181
        osg::ref_ptr< osg::Geode > surfaceGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
 
182
 
 
183
        surfaceGeometry->setVertexArray( mesh->getVertexArray() );
 
184
        osg::DrawElementsUInt* surfaceElement;
 
185
        surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
 
186
        std::vector< size_t > tris = mesh->getTriangles();
 
187
        surfaceElement->reserve( tris.size() );
 
188
        for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
 
189
        {
 
190
            surfaceElement->push_back( tris[vertId] );
 
191
        }
 
192
        surfaceGeometry->addPrimitiveSet( surfaceElement );
 
193
 
 
194
        // normals
 
195
        surfaceGeometry->setNormalArray( mesh->getVertexNormalArray() );
 
196
        surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
 
197
 
 
198
        // texture coordinates
 
199
        surfaceGeometry->setTexCoordArray( 0, mesh->getTextureCoordinateArray() );
 
200
 
 
201
        // render
 
202
        surfaceGeode->addDrawable( surfaceGeometry );
 
203
        m_output->insert( surfaceGeode );
 
204
    }
 
205
    else if( !mesh && !m_useSlices->get( true ) )
 
206
    {
 
207
        warnLog() << "No surface connected to input but surface render mode enabled. Nothing rendered.";
 
208
    }
 
209
    else
 
210
    {
 
211
        // create a new geode containing the slices
 
212
        osg::ref_ptr< osg::Node > xSlice = wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsY() * grid->getDirectionY(),
 
213
                                                                                   grid->getNbCoordsZ() * grid->getDirectionZ() );
 
214
 
 
215
        osg::ref_ptr< osg::Node > ySlice = wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsX() * grid->getDirectionX(),
 
216
                                                                                   grid->getNbCoordsZ() * grid->getDirectionZ() );
 
217
 
 
218
        osg::ref_ptr< osg::Node > zSlice =  wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsX() * grid->getDirectionX(),
 
219
                                                                                    grid->getNbCoordsY() * grid->getDirectionY() );
 
220
 
 
221
        // The movement of the slice is done in the shader. An alternative would be WGELinearTranslationCallback but there, the needed matrix is
 
222
        // not available in the shader
 
223
        osg::StateSet* ss = xSlice->getOrCreateStateSet();
 
224
        ss->addUniform( new WGEPropertyUniform< WPropInt >( "u_vertexShift", m_xPos ) );
 
225
        ss->addUniform( new osg::Uniform( "u_vertexShiftDirection", grid->getDirectionX().as< osg::Vec3f >() ) );  // the axis to move along
 
226
        ss = ySlice->getOrCreateStateSet();
 
227
        ss->addUniform( new WGEPropertyUniform< WPropInt >( "u_vertexShift", m_yPos ) );
 
228
        ss->addUniform( new osg::Uniform( "u_vertexShiftDirection", grid->getDirectionY().as< osg::Vec3f >() ) );  // the axis to move along
 
229
        ss = zSlice->getOrCreateStateSet();
 
230
        ss->addUniform( new WGEPropertyUniform< WPropInt >( "u_vertexShift", m_zPos ) );
 
231
        ss->addUniform( new osg::Uniform( "u_vertexShiftDirection", grid->getDirectionZ().as< osg::Vec3f >() ) );  // the axis to move along
 
232
 
 
233
        // set callbacks for en-/disabling the nodes
 
234
        xSlice->addUpdateCallback( new WGENodeMaskCallback( m_showonX ) );
 
235
        ySlice->addUpdateCallback( new WGENodeMaskCallback( m_showonY ) );
 
236
        zSlice->addUpdateCallback( new WGENodeMaskCallback( m_showonZ ) );
 
237
 
 
238
        // disable culling.
 
239
        xSlice->setCullingActive( false );
 
240
        ySlice->setCullingActive( false );
 
241
        zSlice->setCullingActive( false );
 
242
 
 
243
        // add the transformation nodes to the output group
 
244
        m_output->insert( xSlice );
 
245
        m_output->insert( ySlice );
 
246
        m_output->insert( zSlice );
 
247
        m_output->dirtyBound();
 
248
    }
 
249
}
 
250
 
 
251
void WMImageSpaceLIC::moduleMain()
 
252
{
 
253
    // get notified about data changes
 
254
    m_moduleState.setResetable( true, true );
 
255
    m_moduleState.add( m_vectorsIn->getDataChangedCondition() );
 
256
    m_moduleState.add( m_scalarIn->getDataChangedCondition() );
 
257
    m_moduleState.add( m_meshIn->getDataChangedCondition() );
 
258
    // Remember the condition provided to some properties in properties()? The condition can now be used with this condition set.
 
259
    m_moduleState.add( m_propCondition );
 
260
 
 
261
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
262
    // Preparation 1: create noise texture
 
263
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
264
 
 
265
    // we need a noise texture with a sufficient resolution. Create it.
 
266
    const size_t resX = 1024;
 
267
 
 
268
    // finally, create a texture from the image
 
269
    osg::ref_ptr< osg::Texture2D > randTexture = wge::genWhiteNoiseTexture( resX, resX, 1 );
 
270
 
 
271
    // create a 3D texture too. This allows transformation-invariant noise but is prone to flickering artifacts due to down/upscaling
 
272
    osg::ref_ptr< osg::Texture3D > rand3DTexture = wge::genWhiteNoiseTexture( 128, 128, 128, 1 );
 
273
    rand3DTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
 
274
    rand3DTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
 
275
    rand3DTexture->setWrap( osg::Texture::WRAP_R, osg::Texture::REPEAT );
 
276
    WGEShaderPreprocessor::SPtr define3dNoise( new WGEShaderPropertyDefineOptions< WPropBool >( m_3dNoise, "NOISE3D_DISABLED", "NOISE3D_ENABLED" ) );
 
277
 
 
278
    // done.
 
279
    ready();
 
280
 
 
281
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
282
    // Preparation 2: initialize offscreen renderer and hardwire it
 
283
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
284
 
 
285
    // create the root node for all the geometry
 
286
    m_output = osg::ref_ptr< WGEManagedGroupNode > ( new WGEManagedGroupNode( m_active ) );
 
287
 
 
288
    // the WGEOffscreenRenderNode manages each of the render-passes for us
 
289
    osg::ref_ptr< WGEOffscreenRenderNode > offscreen = new WGEOffscreenRenderNode(
 
290
        WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getCamera()
 
291
    );
 
292
 
 
293
    // allow en-/disabling the HUD:
 
294
    offscreen->getTextureHUD()->addUpdateCallback( new WGENodeMaskCallback( m_showHUD ) );
 
295
 
 
296
    // setup all the passes needed for image space advection
 
297
    osg::ref_ptr< WGEShader > transformationShader = new WGEShader( "WMImageSpaceLIC-Transformation", m_localPath );
 
298
    WGEShaderDefineOptions::SPtr availableDataDefines = WGEShaderDefineOptions::SPtr( new WGEShaderDefineOptions( "SCALARDATA", "VECTORDATA" ) );
 
299
    transformationShader->addPreprocessor( availableDataDefines );
 
300
    transformationShader->addPreprocessor( define3dNoise );
 
301
    transformationShader->addPreprocessor( WGEShaderPreprocessor::SPtr(
 
302
        new WGEShaderPropertyDefineOptions< WPropBool >( m_3dNoiseAutoRes, "NOISE3DAUTORES_DISABLED", "NOISE3DAUTORES_ENABLED" )
 
303
    ) );
 
304
 
 
305
    osg::ref_ptr< WGEOffscreenRenderPass > transformation = offscreen->addGeometryRenderPass(
 
306
        m_output,
 
307
        transformationShader,
 
308
        "Transformation"
 
309
    );
 
310
    transformation->bind( rand3DTexture, 1 );
 
311
    // apply colormapping to transformation
 
312
    WGEColormapping::apply( transformation, transformationShader, 2 );
 
313
 
 
314
    osg::ref_ptr< WGEShader > edgeShader = new WGEShader( "WMImageSpaceLIC-Edge", m_localPath );
 
315
    osg::ref_ptr< WGEOffscreenRenderPass > edgeDetection =  offscreen->addTextureProcessingPass(
 
316
        edgeShader,
 
317
        "Edge Detection"
 
318
    );
 
319
    edgeShader->addPreprocessor( define3dNoise );
 
320
 
 
321
    // we use two advection passes per frame as the input A of the first produces the output B whereas the second pass uses B as input and
 
322
    // produces A as output. This way we can use A as input for the next step (clipping and blending).
 
323
    osg::ref_ptr< WGEOffscreenRenderPass > advection =  offscreen->addTextureProcessingPass(
 
324
        new WGEShader( "WMImageSpaceLIC-Advection", m_localPath ),
 
325
        "Advection"
 
326
    );
 
327
 
 
328
    // finally, put it back on screen, clip it, color it and apply depth buffer to on-screen buffer
 
329
    osg::ref_ptr< WGEOffscreenRenderPass > clipBlend =  offscreen->addFinalOnScreenPass(
 
330
        new WGEShader( "WMImageSpaceLIC-ClipBlend", m_localPath ),
 
331
        "Clip & Blend"
 
332
    );
 
333
 
 
334
    // hardwire the textures to use for each pass:
 
335
 
 
336
    // Transformation Pass, needs Geometry
 
337
    //  * Creates 2D projected Vectors in RG
 
338
    //  * Lighting in B
 
339
    //  * Depth
 
340
    osg::ref_ptr< osg::Texture2D > transformationOut1  = transformation->attach( osg::Camera::COLOR_BUFFER0 );
 
341
    osg::ref_ptr< osg::Texture2D > transformationColormapped  = transformation->attach( osg::Camera::COLOR_BUFFER1 );
 
342
    osg::ref_ptr< osg::Texture2D > transformationDepth = transformation->attach( osg::Camera::DEPTH_BUFFER );
 
343
    // and some uniforms
 
344
    transformation->addUniform( new WGEPropertyUniform< WPropDouble >( "u_noise3DResoultuion", m_3dNoiseRes ) );
 
345
 
 
346
    // Edge Detection Pass, needs Depth as input
 
347
    //  * Edges in R
 
348
    //  * Depth in G
 
349
    //  * Un-advected Noise in B
 
350
    osg::ref_ptr< osg::Texture2D > edgeDetectionOut1 = edgeDetection->attach( osg::Camera::COLOR_BUFFER0 );
 
351
    edgeDetection->bind( transformationDepth, 0 );
 
352
    edgeDetection->bind( randTexture,         1 );
 
353
    edgeDetection->bind( transformationOut1,  2 );
 
354
 
 
355
    // Advection Pass, needs edges and projected vectors as well as noise texture
 
356
    //  * Advected noise in luminance channel
 
357
    osg::ref_ptr< osg::Texture2D > advectionOutA  = advection->attach( osg::Camera::COLOR_BUFFER0, GL_LUMINANCE );
 
358
    advection->bind( transformationOut1, 0 );
 
359
    advection->bind( edgeDetectionOut1,  1 );
 
360
 
 
361
    // advection needs some uniforms controlled by properties
 
362
    osg::ref_ptr< osg::Uniform > numIters = new WGEPropertyUniform< WPropInt >( "u_numIter", m_numIters );
 
363
    advection->addUniform( numIters );
 
364
 
 
365
    // Final clipping and blending phase, needs Advected Noise, Edges, Depth and Light
 
366
    clipBlend->bind( advectionOutA, 0 );
 
367
    clipBlend->bind( edgeDetectionOut1, 1 );
 
368
    clipBlend->bind( transformationColormapped, 2 );
 
369
    // final pass needs some uniforms controlled by properties
 
370
    clipBlend->addUniform( new WGEPropertyUniform< WPropBool >( "u_useEdges", m_useEdges ) );
 
371
    clipBlend->addUniform( new WGEPropertyUniform< WPropBool >( "u_useLight", m_useLight ) );
 
372
    clipBlend->addUniform( new WGEPropertyUniform< WPropBool >( "u_useDepthCueing", m_useDepthCueing ) );
 
373
    clipBlend->addUniform( new WGEPropertyUniform< WPropBool >( "u_useHighContrast", m_useHighContrast ) );
 
374
    clipBlend->addUniform( new WGEPropertyUniform< WPropDouble >( "u_cmapRatio", m_cmapRatio ) );
 
375
 
 
376
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
377
    // Main loop
 
378
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
379
 
 
380
    // main loop
 
381
    while( !m_shutdownFlag() )
 
382
    {
 
383
        debugLog() << "Waiting ...";
 
384
        m_moduleState.wait();
 
385
 
 
386
        // woke up since the module is requested to finish?
 
387
        if( m_shutdownFlag() )
 
388
        {
 
389
            break;
 
390
        }
 
391
 
 
392
        // To query whether an input was updated, simply ask the input:
 
393
        bool dataUpdated = m_vectorsIn->handledUpdate() || m_scalarIn->handledUpdate() || m_meshIn->handledUpdate();
 
394
        bool propertyUpdated = m_useSlices->changed();
 
395
        boost::shared_ptr< WDataSetVector > dataSetVec = m_vectorsIn->getData();
 
396
        boost::shared_ptr< WDataSetScalar > dataSetScal = m_scalarIn->getData();
 
397
        boost::shared_ptr< WTriangleMesh > mesh = m_meshIn->getData();
 
398
 
 
399
        bool dataValid = ( dataSetVec || dataSetScal );
 
400
 
 
401
        // is data valid? If not, remove graphics
 
402
        if( !dataValid )
 
403
        {
 
404
            debugLog() << "Resetting.";
 
405
            WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( offscreen );
 
406
            continue;
 
407
        }
 
408
 
 
409
        // something interesting for us?
 
410
        if( dataValid && !dataUpdated && !propertyUpdated )
 
411
        {
 
412
            continue;
 
413
        }
 
414
 
 
415
        // ensure it gets added
 
416
        WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( offscreen );
 
417
        WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( offscreen );
 
418
 
 
419
        // prefer vector dataset if existing
 
420
        if( dataSetVec )
 
421
        {
 
422
            debugLog() << "Using vector data";
 
423
 
 
424
            // get grid and prepare OSG
 
425
            boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( dataSetVec->getGrid() );
 
426
            m_xPos->setMax( grid->getNbCoordsX() - 1 );
 
427
            m_yPos->setMax( grid->getNbCoordsY() - 1 );
 
428
            m_zPos->setMax( grid->getNbCoordsZ() - 1 );
 
429
            initOSG( grid, mesh );
 
430
 
 
431
            // prepare offscreen render chain
 
432
            availableDataDefines->activateOption( 1 );  // vector input
 
433
            transformation->bind( dataSetVec->getTexture(), 0 );
 
434
        }
 
435
        else if( dataSetScal )
 
436
        {
 
437
            debugLog() << "Using scalar data";
 
438
 
 
439
            // get grid and prepare OSG
 
440
            boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( dataSetScal->getGrid() );
 
441
            m_xPos->setMax( grid->getNbCoordsX() - 1 );
 
442
            m_yPos->setMax( grid->getNbCoordsY() - 1 );
 
443
            m_zPos->setMax( grid->getNbCoordsZ() - 1 );
 
444
            initOSG( grid, mesh );
 
445
 
 
446
            // prepare offscreen render chain
 
447
            availableDataDefines->activateOption( 0 );  // scalar input
 
448
            transformation->bind( dataSetScal->getTexture(), 0 );
 
449
        }
 
450
 
 
451
        debugLog() << "Done";
 
452
    }
 
453
 
 
454
    // clean up
 
455
    offscreen->clear();
 
456
    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( offscreen );
 
457
}
 
458