33 #include <osg/Geometry>
34 #include <osg/LightModel>
35 #include <osg/Material>
36 #include <osg/PolygonMode>
37 #include <osg/StateAttribute>
38 #include <osg/StateSet>
39 #include <osgDB/WriteFile>
41 #include "WMIsosurface.h"
42 #include "WMIsosurface.xpm"
43 #include "core/common/WAssert.h"
44 #include "core/common/WLimits.h"
45 #include "core/common/WPathHelper.h"
46 #include "core/common/WProgress.h"
47 #include "core/common/algorithms/WMarchingCubesAlgorithm.h"
48 #include "core/common/algorithms/WMarchingLegoAlgorithm.h"
49 #include "core/common/math/WLinearAlgebraFunctions.h"
50 #include "core/common/math/WMath.h"
51 #include "core/dataHandler/WDataHandler.h"
52 #include "core/dataHandler/WSubject.h"
53 #include "core/graphicsEngine/WGEColormapping.h"
54 #include "core/graphicsEngine/WGEUtils.h"
55 #include "core/graphicsEngine/callbacks/WGEFunctorCallback.h"
56 #include "core/graphicsEngine/postprocessing/WGEPostprocessingNode.h"
57 #include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
58 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefine.h"
59 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
60 #include "core/kernel/WKernel.h"
61 #include "core/kernel/WSelectionManager.h"
70 m_moduleNodeInserted( false ),
90 return iso_surface_xpm;
100 return "This module implements the marching cubes"
101 " algorithm with a consistent triangulation. It allows one to compute isosurfaces"
102 " for a given isovalue on data given on a grid only consisting of cubes. It yields"
103 " the surface as triangle soup.";
151 bool dataChanged =
m_input->handledUpdate();
152 std::shared_ptr< WDataSetScalar > incomingDataSet =
m_input->getData();
154 if( !incomingDataSet )
157 debugLog() <<
"Waiting for data ...";
178 if( !propChanged && !dataChanged )
184 debugLog() <<
"Computing surface ...";
186 std::shared_ptr< WProgress > progress(
new WProgress(
"Marching Cubes", 2 ) );
192 debugLog() <<
"Rendering surface ...";
207 m_input = std::shared_ptr< WModuleInputData < WDataSetScalar > >(
209 "values",
"Dataset to compute isosurface for." )
215 m_output = std::shared_ptr< WModuleOutputData< WTriangleMesh > >(
230 m_nbVertices->setMax( std::numeric_limits< int >::max() );
260 virtual std::shared_ptr< WTriangleMesh > execute(
size_t x,
size_t y,
size_t z,
262 std::shared_ptr<WValueSetBase> valueSet,
264 std::shared_ptr<WProgressCombiner> ) = 0;
271 template<
class AlgoBase>
272 struct MCAlgoMapperBase :
public AlgoBase,
public MCBase
274 virtual ~MCAlgoMapperBase()
289 template<
class AlgoBase,
typename T>
290 struct MCAlgoMapper :
public MCAlgoMapperBase<AlgoBase>
292 virtual ~MCAlgoMapper()
296 virtual std::shared_ptr< WTriangleMesh > execute(
size_t x,
size_t y,
size_t z,
298 std::shared_ptr<WValueSetBase> valueSet,
300 std::shared_ptr<WProgressCombiner> progress )
302 std::shared_ptr< WValueSet< T > > vals(
304 WAssert( vals,
"Data type and data type indicator must fit." );
305 return AlgoBase::generateSurface( x, y, z, matrix, vals->rawDataVectorPointer(), isoValue, progress );
320 template<
typename AlgoBase>
321 std::shared_ptr<MCAlgoMapperBase<AlgoBase> > createAlgo(
int enum_type )
323 #define CASE( enum_type ) \
325 return std::shared_ptr<MCAlgoMapperBase<AlgoBase> >( new MCAlgoMapper<AlgoBase, DataTypeRT< enum_type >::type >() )
330 CASE( W_DT_UNSIGNED_CHAR );
332 CASE( W_DT_SIGNED_SHORT );
333 CASE( W_DT_SIGNED_INT );
340 CASE( W_DT_FLOAT128 );
343 WAssert(
false,
"Data type not implemented because it is not a scalar or just not implemented, yet" );
345 return std::shared_ptr<MCAlgoMapperBase<AlgoBase> >();
352 debugLog() <<
"Isovalue: " << isoValue;
353 WAssert( ( *m_dataSet ).getValueSet()->order() == 0,
"This module only works on scalars." );
357 std::shared_ptr< WGridRegular3D > gridRegular3D = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_dataSet ).getGrid() );
358 WAssert( gridRegular3D,
"Grid is not of type WGridRegular3D." );
361 std::shared_ptr< WValueSetBase > valueSet(
m_dataSet->getValueSet() );
363 std::shared_ptr<MCBase> algo;
366 algo = createAlgo<WMarchingLegoAlgorithm>( valueSet->getDataType() );
370 algo = createAlgo<WMarchingCubesAlgorithm>( valueSet->getDataType() );
376 m_grid->getTransformationMatrix(),
390 std::unique_lock< std::shared_mutex > lock;
391 lock = std::unique_lock< std::shared_mutex >(
m_updateLock );
398 osg::ref_ptr< osg::Geometry > surfaceGeometry(
new osg::Geometry() );
403 surfaceGeometry->setVertexArray(
m_triMesh->getVertexArray() );
404 osg::ref_ptr< osg::DrawElementsUInt > surfaceElement(
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 ) );
406 std::vector< size_t > tris =
m_triMesh->getTriangles();
407 surfaceElement->reserve( tris.size() );
409 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
411 surfaceElement->push_back( tris[vertId] );
413 surfaceGeometry->addPrimitiveSet( surfaceElement );
417 surfaceGeometry->setNormalArray(
m_triMesh->getVertexNormalArray() );
418 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
421 osg::ref_ptr< osg::StateSet > state =
m_surfaceGeode->getOrCreateStateSet();
425 osg::ref_ptr< osg::Vec4Array > colors(
new osg::Vec4Array );
428 surfaceGeometry->setColorArray( colors );
429 surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
431 osg::ref_ptr<osg::LightModel> lightModel(
new osg::LightModel() );
432 lightModel->setTwoSided(
true );
433 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
435 osg::ref_ptr< osg::Material > material(
new osg::Material() );
436 material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
437 material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
438 material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
439 material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
440 material->setShininess( osg::Material::FRONT, 25.0 );
441 state->setAttribute( material );
444 surfaceGeometry->setUseDisplayList(
false );
445 surfaceGeometry->setUseVertexBufferObjects(
true );
461 std::unique_lock< std::shared_mutex > lock;
462 lock = std::unique_lock< std::shared_mutex >(
m_updateLock );
466 osg::ref_ptr< osg::Vec4Array > colors(
new osg::Vec4Array );
469 m_surfaceGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
470 m_surfaceGeode->getDrawable( 0 )->asGeometry()->setColorBinding( osg::Geometry::BIND_OVERALL );
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.
This callback allows you a simple usage of callbacks in your module.
This class adds some convenience methods to WGEGroupNode.
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.
Module implementing the marching cubes algorithm with consistent triangulation for data given on regu...
void updateGraphicsCallback()
updates textures and shader parameters when called (usually from the callback)
WPropInt m_nbVertices
Info-property showing the number of vertices in the mesh.
virtual void moduleMain()
Entry point after loading the module.
osg::ref_ptr< osg::Geode > m_surfaceGeode
Pointer to geode containing the surface.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_input
Input connector required by this module.
virtual const std::string getName() const
Gives back the name of this module.
std::shared_mutex m_updateLock
Lock to prevent concurrent threads trying to update the osg node.
osg::ref_ptr< WGEManagedGroupNode > m_moduleNode
Pointer to the module's group node. We need it to be able to update it for callback.
void renderMesh()
Prepares and commits everything for rendering with the OSG.
std::shared_ptr< WCondition > m_recompute
This condition denotes whether we need to recompute the surface.
WPropBool m_useMarchingLego
Property indicating whether to use interpolated or non interpolated triangulation.
std::shared_ptr< const WDataSetScalar > m_dataSet
pointer to dataSet to be able to access it throughout the whole module.
virtual void properties()
Initialize the properties for this module.
WMIsosurface()
Standard constructor.
virtual const std::string getDescription() const
Gives back a description of this module.
virtual void connectors()
Initialize the connectors this module is using.
std::shared_ptr< WTriangleMesh > m_triMesh
This triangle mesh is provided as output through the connector.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
std::shared_ptr< WModuleOutputData< WTriangleMesh > > m_output
Input connector required by this module.
std::shared_ptr< WGridRegular3D > m_grid
pointer to grid, because we need to access the grid for the dimensions of the texture.
osg::ref_ptr< WGEShader > m_shader
The shader.
WPropInt m_nbTriangles
Info-property showing the number of triangles in the mesh.
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...
void generateSurfacePre(double isoValue)
Kind of a convenience function for generate surface.
WPropColor m_surfaceColor
Property determining the color for the surface if no textures are displayed.
WPropBool m_useTextureProp
Property indicating whether to use texturing with scalar data sets.
~WMIsosurface()
Destructor.
WPropInt m_opacityProp
Property holding the opacity valueassigned to the surface.
WPropDouble m_isoValueProp
Property holding the iso value.
This class does the actual computation of marching cubes.
Creates a non interpolated triangulation of an isosurface.
Class offering an instantiate-able data connection between modules.
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.
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.
std::shared_ptr< WProperties > m_infoProperties
The property object for the module containing only module whose purpose is "PV_PURPOSE_INFORMNATION".
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.
Base Class for all value set types.
void enableTransparency(osg::ref_ptr< osg::Node > node)
Enable transparency for the given node.
const double MAX_DOUBLE
Maximum double value.
const double MIN_DOUBLE
Positive minimum double value.