31 #include <osg/BoundingSphere>
32 #include <osg/Drawable>
34 #include <osg/Geometry>
37 #include "WMImageSpaceLIC.h"
38 #include "core/common/WPropertyHelper.h"
39 #include "core/common/math/WMath.h"
40 #include "core/dataHandler/WDataHandler.h"
41 #include "core/dataHandler/WDataTexture3D.h"
42 #include "core/dataHandler/WGridRegular3D.h"
43 #include "core/graphicsEngine/WGEColormapping.h"
44 #include "core/graphicsEngine/WGEGeodeUtils.h"
45 #include "core/graphicsEngine/WGETextureUtils.h"
46 #include "core/graphicsEngine/WGEUtils.h"
47 #include "core/graphicsEngine/callbacks/WGELinearTranslationCallback.h"
48 #include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
49 #include "core/graphicsEngine/offscreen/WGEOffscreenRenderNode.h"
50 #include "core/graphicsEngine/offscreen/WGEOffscreenRenderPass.h"
51 #include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
52 #include "core/graphicsEngine/shaders/WGEShader.h"
53 #include "core/graphicsEngine/shaders/WGEShaderDefineOptions.h"
54 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
55 #include "core/kernel/WKernel.h"
77 return "Image Space LIC";
82 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"
83 "leave it unspecified to use slices.";
90 "Needs to be in the same grid as the mesh." );
93 "Needs to be in the same grid as the mesh." );
132 m_useLight =
m_licGroup->addProperty(
"Use Light",
"Check to enable lightning using the Phong model.",
false );
139 m_useEdgesStep =
m_licGroup->addProperty(
"Edge Step",
"Define the steepness of the blend function between color and edge color.", 1.0 );
147 m_cmapRatio =
m_licGroup->addProperty(
"Ratio Colormap to LIC",
"Blending ratio between LIC and colormap.", 0.5 );
154 m_3dNoise =
m_advancedLicGroup->addProperty(
"Use 3D noise",
"Use 3D noise? This provides better coherence during transformation of "
155 "the geometry but might introduce resolution problems.",
true );
157 "modification of this size.", 1.5 );
162 "automatically according to the screen size. If disabled, the user can zoom into the LIC.",
165 m_numIters =
m_advancedLicGroup->addProperty(
"Number of Iterations",
"How much iterations along a streamline should be done per frame.",
171 "tangential plane of the surface and the vector which is going to be projected. You can adjust how steep a vector can be before it is "
172 "clipped and NOT projected. Note: all vectors with an angle below this threshold are projected but linearly reduced in influence "
173 "depending on the angle.", 90.0 );
191 osg::Geometry* surfaceGeometry =
new osg::Geometry();
192 osg::ref_ptr< osg::Geode > surfaceGeode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
194 surfaceGeometry->setVertexArray( mesh->getVertexArray() );
195 osg::DrawElementsUInt* surfaceElement;
196 surfaceElement =
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
197 std::vector< size_t > tris = mesh->getTriangles();
198 surfaceElement->reserve( tris.size() );
199 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
201 surfaceElement->push_back( tris[vertId] );
203 surfaceGeometry->addPrimitiveSet( surfaceElement );
206 surfaceGeometry->setNormalArray( mesh->getVertexNormalArray() );
207 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
210 surfaceGeometry->setTexCoordArray( 0, mesh->getTextureCoordinateArray() );
213 surfaceGeode->addDrawable( surfaceGeometry );
218 warnLog() <<
"No surface connected to input but surface render mode enabled. Nothing rendered.";
223 osg::ref_ptr< osg::Node > xSlice =
wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsY() * grid->getDirectionY(),
224 grid->getNbCoordsZ() * grid->getDirectionZ() );
226 osg::ref_ptr< osg::Node > ySlice =
wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsX() * grid->getDirectionX(),
227 grid->getNbCoordsZ() * grid->getDirectionZ() );
229 osg::ref_ptr< osg::Node > zSlice =
wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsX() * grid->getDirectionX(),
230 grid->getNbCoordsY() * grid->getDirectionY() );
233 xSlice->setName(
"_X SLice" );
234 ySlice->setName(
"_Y SLice" );
235 zSlice->setName(
"_Z SLice" );
239 osg::StateSet* ss = xSlice->getOrCreateStateSet();
241 ss->addUniform(
new osg::Uniform(
"u_vertexShiftDirection", grid->getDirectionX().as< osg::Vec3f >() ) );
242 ss = ySlice->getOrCreateStateSet();
244 ss->addUniform(
new osg::Uniform(
"u_vertexShiftDirection", grid->getDirectionY().as< osg::Vec3f >() ) );
245 ss = zSlice->getOrCreateStateSet();
247 ss->addUniform(
new osg::Uniform(
"u_vertexShiftDirection", grid->getDirectionZ().as< osg::Vec3f >() ) );
255 xSlice->setCullingActive(
false );
256 ySlice->setCullingActive(
false );
257 zSlice->setCullingActive(
false );
282 const size_t resX = 1024;
289 rand3DTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
290 rand3DTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
291 rand3DTexture->setWrap( osg::Texture::WRAP_R, osg::Texture::REPEAT );
316 osg::ref_ptr< WGEShader > transformationShader =
new WGEShader(
"WMImageSpaceLIC-Transformation",
m_localPath );
318 transformationShader->addPreprocessor( availableDataDefines );
319 transformationShader->addPreprocessor( define3dNoise );
329 osg::ref_ptr< WGEOffscreenRenderPass > transformation = offscreen->addGeometryRenderPass(
331 transformationShader,
334 transformation->bind( rand3DTexture, 1 );
339 osg::ref_ptr< WGEOffscreenRenderPass > edgeDetection = offscreen->addTextureProcessingPass(
343 edgeShader->addPreprocessor( define3dNoise );
347 osg::ref_ptr< WGEOffscreenRenderPass > advection = offscreen->addTextureProcessingPass(
353 osg::ref_ptr< WGEOffscreenRenderPass > clipBlend = offscreen->addFinalOnScreenPass(
364 osg::ref_ptr< osg::Texture2D > transformationOut1 = transformation->attach( WGECamera::COLOR_BUFFER0 );
365 osg::ref_ptr< osg::Texture2D > transformationColormapped = transformation->attach( WGECamera::COLOR_BUFFER1 );
366 osg::ref_ptr< osg::Texture2D > transformationDepth = transformation->attach( WGECamera::DEPTH_BUFFER );
375 osg::ref_ptr< osg::Texture2D > edgeDetectionOut1 = edgeDetection->attach( WGECamera::COLOR_BUFFER0 );
376 edgeDetection->bind( transformationDepth, 0 );
377 edgeDetection->bind( randTexture, 1 );
378 edgeDetection->bind( transformationOut1, 2 );
382 osg::ref_ptr< osg::Texture2D > advectionOutA = advection->attach( WGECamera::COLOR_BUFFER0, GL_LUMINANCE );
383 advection->bind( transformationOut1, 0 );
384 advection->bind( edgeDetectionOut1, 1 );
388 advection->addUniform( numIters );
391 advectionOutA->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
392 edgeDetectionOut1->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
393 transformationColormapped->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
396 clipBlend->bind( advectionOutA, 0 );
397 clipBlend->bind( edgeDetectionOut1, 1 );
398 clipBlend->bind( transformationColormapped, 2 );
411 m_root->insert( offscreen );
414 osg::ref_ptr< osg::Node > cullProxy;
438 std::shared_ptr< WDataSetVector > dataSetVec =
m_vectorsIn->getData();
439 std::shared_ptr< WDataSetScalar > dataSetScal =
m_scalarIn->getData();
440 std::shared_ptr< WTriangleMesh > mesh =
m_meshIn->getData();
442 bool dataValid = ( dataSetVec || dataSetScal );
453 if( dataValid && !dataUpdated && !propertyUpdated )
459 std::shared_ptr< WGridRegular3D > grid;
465 grid = std::dynamic_pointer_cast< WGridRegular3D >( dataSetVec->getGrid() );
466 m_xPos->setMax( grid->getNbCoordsX() - 1 );
467 m_yPos->setMax( grid->getNbCoordsY() - 1 );
468 m_zPos->setMax( grid->getNbCoordsZ() - 1 );
472 availableDataDefines->activateOption( 1 );
473 transformation->bind( dataSetVec->getTexture(), 0 );
475 else if( dataSetScal )
480 grid = std::dynamic_pointer_cast< WGridRegular3D >( dataSetScal->getGrid() );
481 m_xPos->setMax( grid->getNbCoordsX() - 1 );
482 m_yPos->setMax( grid->getNbCoordsY() - 1 );
483 m_zPos->setMax( grid->getNbCoordsZ() - 1 );
487 availableDataDefines->activateOption( 0 );
488 transformation->bind( dataSetScal->getTexture(), 0 );
494 m_root->remove( cullProxy );
496 m_root->insert( cullProxy );
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.
static void apply(osg::ref_ptr< osg::Node > node, WMatrix4d preTransform=WMatrix4d::identity(), osg::ref_ptr< WGEShader > shader=osg::ref_ptr< WGEShader >(), size_t startTexUnit=0)
Apply the colormapping to the specified node.
Class to wrap around the osg Group node and providing a thread safe add/removal mechanism.
This class adds some convenience methods to WGEGroupNode.
This callback is useful to en-/disable nodes using the node mask based on properties.
This type of node basically is a convenience class for managing and creating offscreen renderings.
This GLSL preprocessor is able to set one define from a list of defines depending on the active optio...
std::shared_ptr< WGEShaderDefineOptions > SPtr
Shared pointer for this class.
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.
This module takes an vector dataset and used it to apply an image space based (fast) LIC to an arbitr...
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
WPropBool m_showonY
indicates whether the vector should be shown on slice Y
WPropBool m_useEdges
indicates whether to show the edges
WPropDouble m_cmapRatio
the ratio between colormap and LIC
WPropInt m_yPos
y position of the slice
WPropBool m_showHUD
indicates whether to show the texture HUD
WPropGroup m_geometryGroup
the group contains several input geometry parameters
WPropInt m_numIters
the number of iterations done per frame
WPropBool m_useLight
indicates whether to use Phong
virtual void moduleMain()
Entry point after loading the module.
WPropColor m_useEdgesColor
indicated whether the edges (if enabled) should be black or white or green or red or ....
WPropGroup m_sliceGroup
the group contains several slice properties
WPropBool m_useHighContrast
use the high contrast version?
WPropBool m_useSlices
indicates whether the vector should be shown on slices or input geometry
std::shared_ptr< WModuleInputData< WTriangleMesh > > m_meshIn
The input containing the surface on which the LIC should be applied on.
std::shared_ptr< WModuleInputData< WDataSetVector > > m_vectorsIn
The input connector containing the vector field.
WPropGroup m_advancedLicGroup
The group for more advanced LIC features.
void initOSG(std::shared_ptr< WGridRegular3D > grid, std::shared_ptr< WTriangleMesh > mesh)
Initializes the needed geodes, transformations and vertex arrays.
virtual const std::string getDescription() const
Gives back a description of this module.
WPropBool m_3dNoiseAutoRes
Automatically adapt resolution of 3d texture according to zoom level.
osg::ref_ptr< WGEManagedGroupNode > m_root
Scene root node.
WPropBool m_showonX
indicates whether the vector should be shown on slice X
WPropDouble m_3dNoiseRes
The resolution scaling for the 3d noise.
WPropDouble m_lightIntensity
light intensity
WPropDouble m_useEdgesStep
define the steepness of the step function used to blend in the edge color.
WPropInt m_xPos
x position of the slice
osg::ref_ptr< WGEGroupNode > m_output
The Geode containing all the slices and the mesh.
WPropGroup m_licGroup
the group contains several LIC properties
WPropInt m_zPos
z position of the slice
WPropBool m_3dNoise
If true, a 3d noise texture is used for advection.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_scalarIn
The input connector containing the scalar field whose derived field is used for LIC.
WPropBool m_useDepthCueing
indicates whether to use depth cueing in the shader
virtual void connectors()
Initialize the connectors this module is using.
virtual ~WMImageSpaceLIC()
Destructor.
virtual void properties()
Initialize the properties for this module.
WPropBool m_showonZ
indicates whether the vector should be shown on slice Z
WMImageSpaceLIC()
Default constructor.
virtual const std::string getName() const
Gives back the name of this module.
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...
WPropDouble m_projectionAngleThreshold
the angle threshold between surface and vector before clipping the vector.
Class representing a single module of OpenWalnut.
boost::filesystem::path m_localPath
The path where the module binary resides in.
virtual void properties()
Initialize properties in this function.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
wlog::WStreamedLogger warnLog() const
Logger instance for comfortable warning- logs.
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.
virtual void connectors()
Initialize connectors in this function.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
osg::ref_ptr< osg::Node > generateCullProxy(const WBoundingBox &bbox)
Generate a proxy cube, which ensures OSG does proper near-far plane calculation and culling.
osg::ref_ptr< WGETexture< osg::Texture1D > > genWhiteNoiseTexture(size_t sizeX, size_t channels)
This generates an 1D texture only containing white noise in its channels.
osg::ref_ptr< osg::Geode > genFinitePlane(double xSize, double ySize, const WPlane &p, const WColor &color=WColor(0.0, 0.7, 0.7, 1.0), bool border=false)
Generates a geode out of a Plane with a fixed size in direction of the vectors which span that plane.