30 #include <osg/Geometry>
31 #include <osg/LightModel>
32 #include <osg/PolygonMode>
33 #include <osg/StateAttribute>
34 #include <osg/StateSet>
36 #include "WMSuperquadricGlyphs.h"
37 #include "WMSuperquadricGlyphs.xpm"
38 #include "core/graphicsEngine/WGEUtils.h"
39 #include "core/graphicsEngine/postprocessing/WGEPostprocessingNode.h"
40 #include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
41 #include "core/kernel/WKernel.h"
66 return superquadricglyphs_xpm;
71 return "Superquadric Glyphs";
76 return "GPU based ray-tracing of second order, superquadric tensor glyphs.";
83 "tensor input",
"An input set of 2nd-order tensors on a regular 3D-grid." )
115 "Clip Glyphs whose smallest eigenvalue is below the given threshold.", 0.01 );
119 "Clip Glyphs whose fractional anisotropy is below the given threshold.", 0.01 );
123 m_gamma =
m_properties->addProperty(
"Gamma",
"Sharpness Parameter of the SuperQuadrics.", 10.0 );
137 vertices->push_back( position );
138 orientation->push_back( osg::Vec3( -1.0, -1.0, -1.0 ) );
139 vertices->push_back( position );
140 orientation->push_back( osg::Vec3( 1.0, -1.0, -1.0 ) );
141 vertices->push_back( position );
142 orientation->push_back( osg::Vec3( 1.0, 1.0, -1.0 ) );
143 vertices->push_back( position );
144 orientation->push_back( osg::Vec3( -1.0, 1.0, -1.0 ) );
147 vertices->push_back( position );
148 orientation->push_back( osg::Vec3( -1.0, -1.0, 1.0 ) );
149 vertices->push_back( position );
150 orientation->push_back( osg::Vec3( 1.0, -1.0, 1.0 ) );
151 vertices->push_back( position );
152 orientation->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
153 vertices->push_back( position );
154 orientation->push_back( osg::Vec3( -1.0, 1.0, 1.0 ) );
157 vertices->push_back( position );
158 orientation->push_back( osg::Vec3( -1.0, 1.0, -1.0 ) );
159 vertices->push_back( position );
160 orientation->push_back( osg::Vec3( 1.0, 1.0, -1.0 ) );
161 vertices->push_back( position );
162 orientation->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
163 vertices->push_back( position );
164 orientation->push_back( osg::Vec3( -1.0, 1.0, 1.0 ) );
167 vertices->push_back( position );
168 orientation->push_back( osg::Vec3( -1.0, -1.0, -1.0 ) );
169 vertices->push_back( position );
170 orientation->push_back( osg::Vec3( 1.0, -1.0, -1.0 ) );
171 vertices->push_back( position );
172 orientation->push_back( osg::Vec3( 1.0, -1.0, 1.0 ) );
173 vertices->push_back( position );
174 orientation->push_back( osg::Vec3( -1.0, -1.0, 1.0 ) );
177 vertices->push_back( position );
178 orientation->push_back( osg::Vec3( -1.0, -1.0, -1.0 ) );
179 vertices->push_back( position );
180 orientation->push_back( osg::Vec3( -1.0, 1.0, -1.0 ) );
181 vertices->push_back( position );
182 orientation->push_back( osg::Vec3( -1.0, 1.0, 1.0 ) );
183 vertices->push_back( position );
184 orientation->push_back( osg::Vec3( -1.0, -1.0, 1.0 ) );
187 vertices->push_back( position );
188 orientation->push_back( osg::Vec3( 1.0, -1.0, -1.0 ) );
189 vertices->push_back( position );
190 orientation->push_back( osg::Vec3( 1.0, 1.0, -1.0 ) );
191 vertices->push_back( position );
192 orientation->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
193 vertices->push_back( position );
194 orientation->push_back( osg::Vec3( 1.0, -1.0, 1.0 ) );
207 for(
size_t c = 0; c < 6 * 4; ++c )
209 diag->push_back( d );
210 offdiag->push_back( o );
229 m_xSlice->setMatrix( osg::Matrixd::identity() );
231 m_ySlice->setMatrix( osg::Matrixd::identity() );
233 m_zSlice->setMatrix( osg::Matrixd::identity() );
236 osg::ref_ptr< osg::Geode > geode;
237 osg::ref_ptr< osg::Geometry > geometry;
238 osg::ref_ptr< osg::DrawArrays > da;
242 osg::ref_ptr< osg::Vec3Array > vertices;
243 osg::ref_ptr< osg::Vec3Array > texcoords0;
249 vertices =
new osg::Vec3Array;
251 texcoords0 =
new osg::Vec3Array;
253 geometry =
new osg::Geometry();
254 geometry->setDataVariance( osg::Object::DYNAMIC );
255 geometry->setVertexArray( vertices );
256 geometry->setUseVertexBufferObjects(
true );
257 geometry->setTexCoordArray( 0, texcoords0 );
258 da =
new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0,
m_nbGlyphsX * 6 * 4 );
259 geometry->addPrimitiveSet( da );
262 geode =
new osg::Geode();
263 geode->addDrawable( geometry );
266 for(
size_t z = 0; z <
m_maxZ; ++z )
268 for(
size_t y = 0; y <
m_maxY; ++y )
270 addGlyph( osg::Vec3d( 0.0, y, z ), vertices, texcoords0 );
284 vertices =
new osg::Vec3Array;
286 texcoords0 =
new osg::Vec3Array;
288 geometry =
new osg::Geometry();
289 geometry->setDataVariance( osg::Object::DYNAMIC );
290 geometry->setVertexArray( vertices );
291 geometry->setUseVertexBufferObjects(
true );
292 geometry->setTexCoordArray( 0, texcoords0 );
293 da =
new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0,
m_nbGlyphsY * 6 * 4 );
294 geometry->addPrimitiveSet( da );
297 geode =
new osg::Geode();
298 geode->addDrawable( geometry );
300 for(
size_t z = 0; z <
m_maxZ; ++z )
302 for(
size_t x = 0; x <
m_maxX; ++x )
304 addGlyph( osg::Vec3d( x, 0.0, z ), vertices, texcoords0 );
318 vertices =
new osg::Vec3Array;
320 texcoords0 =
new osg::Vec3Array;
322 geometry =
new osg::Geometry();
323 geometry->setDataVariance( osg::Object::DYNAMIC );
324 geometry->setVertexArray( vertices );
325 geometry->setUseVertexBufferObjects(
true );
326 geometry->setTexCoordArray( 0, texcoords0 );
327 da =
new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0,
m_nbGlyphsZ * 6 * 4 );
328 geometry->addPrimitiveSet( da );
331 geode =
new osg::Geode();
332 geode->addDrawable( geometry );
334 for(
size_t y = 0; y <
m_maxY; ++y )
336 for(
size_t x = 0; x <
m_maxX; ++x )
338 addGlyph( osg::Vec3d( x, y, 0.0 ), vertices, texcoords0 );
369 m_tensorOffDiag = offdiag;
396 osg::ref_ptr< osg::StateSet > sset =
m_output->getOrCreateStateSet();
397 sset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
411 sset->addUniform( evThreshold );
412 sset->addUniform( faThreshold );
413 sset->addUniform( scaling );
414 sset->addUniform( gamma );
420 bool initialTensorUpload =
true;
440 std::shared_ptr< WDataSetDTI > newDataSet =
m_input->getData();
441 bool dataChanged = (
m_dataSet != newDataSet );
442 bool dataValid = ( newDataSet != NULL );
456 if( dataChanged && dataValid )
460 initialTensorUpload =
true;
463 std::shared_ptr< WProgress > progress1(
new WProgress(
"Building Glyph Geometry" ) );
469 WAssert(
m_dataSetGrid,
"Dataset does not have a regular 3D grid." );
493 if( dataValid && (
m_xPos->changed() || initialTensorUpload ) )
496 std::shared_ptr< WProgress > progress1(
new WProgress(
"Building Glyph Geometry" ) );
500 osg::ref_ptr< osg::Vec3Array > diag =
new osg::Vec3Array;
502 osg::ref_ptr< osg::Vec3Array > offdiag =
new osg::Vec3Array;
507 size_t fixedX =
m_xPos->get(
true );
508 for(
size_t z = 0; z <
m_maxZ; ++z )
513 for(
size_t y = 0; y <
m_maxY; ++y )
524 if( dataValid && (
m_yPos->changed() || initialTensorUpload ) )
527 std::shared_ptr< WProgress > progress1(
new WProgress(
"Building Glyph Geometry" ) );
531 osg::ref_ptr< osg::Vec3Array > diag =
new osg::Vec3Array;
533 osg::ref_ptr< osg::Vec3Array > offdiag =
new osg::Vec3Array;
537 size_t fixedY =
m_yPos->get(
true );
538 size_t fixedYOffset = fixedY *
m_maxX;
539 for(
size_t z = 0; z <
m_maxZ; ++z )
544 for(
size_t x = 0; x <
m_maxX; ++x )
555 if( dataValid && (
m_zPos->changed() || initialTensorUpload ) )
558 std::shared_ptr< WProgress > progress1(
new WProgress(
"Building Glyph Geometry" ) );
562 osg::ref_ptr< osg::Vec3Array > diag =
new osg::Vec3Array;
564 osg::ref_ptr< osg::Vec3Array > offdiag =
new osg::Vec3Array;
568 size_t fixedZ =
static_cast< size_t >(
m_zPos->get(
true ) );
570 for(
size_t y = 0; y <
m_maxY; ++y )
573 size_t yPre = fixedZOffset + ( y *
m_maxX );
575 for(
size_t x = 0; x <
m_maxX; ++x )
586 initialTensorUpload =
false;
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
This class is an OSG Callback which allows simple linear translation of a matrix transform node along...
This class adds some convenience methods to WGEGroupNode.
This callback is useful to en-/disable nodes using the node mask based on properties.
This class enables you to add arbitrary nodes that get post-processed in screen space.
std::shared_ptr< WGEShaderPreprocessor > SPtr
Shared pointer for this class.
This is a WGEShaderDefineOptions class which additionally uses a property to automatically control th...
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
Node callback to handle updates in the glyph tensor data.
virtual void update(osg::NodeVisitor *nv, osg::Drawable *d)
This operator gets called by OSG every update cycle.
osg::Geometry * m_geometry
The geometry node to handle here.
osg::ref_ptr< osg::Vec3Array > m_tensorOffDiag
Off-diagonal tensor elements in texture coordinate array.
osg::ref_ptr< osg::Vec3Array > m_tensorDiag
Diagonal tensor elements in texture coordinate array.
void setNewTensorData(osg::ref_ptr< osg::Vec3Array > diag, osg::ref_ptr< osg::Vec3Array > offdiag)
Updates the tensor data in the glyph slice.
Rendering of GPU bases Superquadric Glyphs.
virtual void properties()
Initialize the properties for this module.
size_t m_nbGlyphsZ
Number of glyphs on Z Plane.
osg::ref_ptr< WGEManagedGroupNode > m_output
The Geode containing all the glyphs.
WMSuperquadricGlyphs()
Constructor.
size_t m_maxY
Number of cells in Y direction.
osg::ref_ptr< WGEManagedGroupNode > m_xSlice
The transformation node moving the X slice through the dataset space if the sliders are used.
osg::ref_ptr< GlyphGeometryNodeCallback > m_zSliceGlyphCallback
The update callback of m_zSlice glphs.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
WPropInt m_zPos
z position of the slice
std::shared_ptr< WModuleInputData< WDataSetDTI > > m_input
The input dataset.
size_t m_maxX
Number of cells in X direction.
WPropDouble m_evThreshold
The eigenvalue threshold to filter glyphs.
WPropDouble m_faThreshold
The FA threshold to filter glyphs.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
osg::ref_ptr< GlyphGeometryNodeCallback > m_ySliceGlyphCallback
The update callback of m_ySlice glphs.
WPropDouble m_gamma
Sharpness of the glyphs.
virtual ~WMSuperquadricGlyphs()
Destructor.
WPropInt m_yPos
y position of the slice
WPropDouble m_scaling
Scaling of the glyphs.
void addTensor(size_t idx, osg::Vec3Array *diag, osg::Vec3Array *offdiag)
Adds a tensor to two arrays.
osg::ref_ptr< GlyphGeometryNodeCallback > m_xSliceGlyphCallback
The update callback of m_xSlice glphs.
WPropInt m_xPos
x position of the slice
virtual const std::string getDescription() const
Gives back a description of this module.
WPropBool m_showonY
indicates whether the vector should be shown on slice Y
WPropBool m_showonZ
indicates whether the vector should be shown on slice Z
size_t m_nbGlyphsX
Number of glyphs on X Plane.
std::shared_ptr< WGridRegular3D > m_dataSetGrid
The current tensor dataset's grid.
void initOSG()
Initializes the needed geodes, transformations and vertex arrays.
std::shared_ptr< WValueSetBase > m_dataSetValueSet
The current tensor dataset's valueset.
osg::ref_ptr< WGEShader > m_shader
the shader actually doing the glyph raytracing
WPropBool m_showonX
indicates whether the vector should be shown on slice X
osg::ref_ptr< WGEManagedGroupNode > m_zSlice
The transformation node moving the Z slice through the dataset space if the sliders are used.
osg::ref_ptr< WGEManagedGroupNode > m_ySlice
The transformation node moving the Y slice through the dataset space if the sliders are used.
std::shared_ptr< const WDataSetDTI > m_dataSet
The current tensor dataset.
virtual void connectors()
Initialize the connectors this module is using.
size_t m_maxZ
Number of cells in Z direction.
virtual const std::string getName() const
Gives back the name of this module.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual void moduleMain()
Entry point after loading the module.
size_t m_nbGlyphsY
Number of glyphs on Y Plane.
WPropBool m_directionalColoring
Color glyphs by direction?
void addGlyph(osg::Vec3 position, osg::ref_ptr< osg::Vec3Array > vertices, osg::ref_ptr< osg::Vec3Array > orientation)
Adds a cube to the vertex array.
Class representing a single module of OpenWalnut.
boost::filesystem::path m_localPath
The path where the module binary resides in.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
void removeConnectors()
Removes all connectors properly.
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
std::shared_ptr< WProperties > m_properties
The property object for the module.
void ready()
Call this whenever your module is ready and can react on property changes.
WConditionSet m_moduleState
The internal state of the module.
WPropBool m_active
True whenever the module should be active.
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
virtual void connectors()
Initialize connectors in this function.
Class managing progress inside of modules.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.