30 #include <osg/LightModel>
31 #include <osgGA/StateSetManipulator>
32 #include <osgViewer/ViewerEventHandlers>
33 #include <osgWidget/Util>
34 #include <osgWidget/ViewerEventHandlers>
35 #include <osgWidget/WindowManager>
37 #include "WFileParser.h"
38 #include "WMClusterDisplayVoxels.h"
39 #include "WMClusterDisplayVoxels.xpm"
40 #include "core/common/WPathHelper.h"
41 #include "core/common/WPropertyHelper.h"
42 #include "core/common/WStringUtils.h"
43 #include "core/common/algorithms/WMarchingLegoAlgorithm.h"
44 #include "core/graphicsEngine/WGEColormapping.h"
45 #include "core/graphicsEngine/WGEUtils.h"
46 #include "core/kernel/WKernel.h"
47 #include "core/kernel/WSelectionManager.h"
52 WMClusterDisplayVoxels::WMClusterDisplayVoxels():
54 m_currentDisplayMode( CDV_SINGLE ),
55 m_currentDisplayModeString(
"" ),
59 m_selectionChanged( false ),
60 m_dendrogramDirty( false )
64 WMClusterDisplayVoxels::~WMClusterDisplayVoxels()
77 return clusterDisplayVoxels_xpm;
82 return "ClusterDisplayVoxels";
89 return "Visualizes voxel clusterings in texture and 3D view";
95 m_input = std::shared_ptr< WModuleInputData < WDataSetSingle > >(
99 m_output = std::shared_ptr< WModuleOutputData < WDataSetScalar > >(
283 std::shared_ptr< WDataSetSingle > newDataSet =
m_input->getData();
284 bool dataChanged = (
m_dataSet != newDataSet );
285 bool dataValid = ( newDataSet != NULL );
292 m_grid = std::dynamic_pointer_cast< WGridRegular3D >(
m_dataSet->getGrid() );
512 case CDV_LEVELSFROMTOP:
516 case CDV_MINBRANCHLENGTH:
544 for(
size_t k = 0; k < vox.size(); ++k )
553 for(
size_t k = 0; k < voxels.size(); ++k )
555 m_data[voxels[k]] = i + 1;
559 unsigned char* data =
m_texture->getImage()->data();
560 for(
size_t i = 0; i <
m_grid->size(); ++i )
565 data[i * 3 + 1] = 75;
566 data[i * 3 + 2] = 75;
571 data[i * 3 ] = color[0] * 255;
572 data[i * 3 + 1] = color[1] * 255;
573 data[i * 3 + 2] = color[2] * 255;
578 data[i * 3 + 1] = 0.0;
579 data[i * 3 + 2] = 0.0;
598 debugLog() <<
"start parsing tree file...";
607 std::vector<std::string>lines = parser.
getRawLines();
609 if( lines.size() == 0 )
617 for(
size_t i = 0; i < coords.size(); ++i )
619 std::vector< std::string > svec = coords[i];
622 string_utils::fromString< size_t >( svec[1] ),
623 string_utils::fromString< size_t >( svec[2] ) ) );
628 for(
size_t i = 0; i < clusters.size(); ++i )
630 std::vector< std::string > svec = clusters[i];
633 string_utils::fromString< size_t >( svec[1] ),
634 string_utils::fromString< float >( svec[2] ) );
639 for(
size_t i = 0; i < partitions.size(); ++i )
641 std::vector< std::string > svec = partitions[i];
643 std::vector<size_t>partition;
645 for(
size_t k = 0; k < svec.size(); ++k )
647 partition.push_back( string_utils::fromString< size_t >( svec[k] ) );
682 osg::ref_ptr< osg::Image > ima =
new osg::Image;
683 ima->allocateImage(
m_grid->getNbCoordsX(),
m_grid->getNbCoordsY(),
m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
684 unsigned char* data = ima->data();
687 for(
unsigned int i = 0; i <
m_grid->size() * 3; ++i )
692 m_texture = osg::ref_ptr<osg::Texture3D>(
new osg::Texture3D );
693 m_texture->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
694 m_texture->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
695 m_texture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER );
696 m_texture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER );
697 m_texture->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER );
699 m_texture->setResizeNonPowerOfTwoHint(
false );
736 m_grid->getTransformationMatrix(),
745 m_grid->getTransformationMatrix(),
766 osg::Geometry* surfaceGeometry =
new osg::Geometry();
767 osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
771 surfaceGeometry->setVertexArray(
m_triMeshes[i]->getVertexArray() );
775 surfaceGeometry->setNormalArray(
m_triMeshes[i]->getVertexNormalArray() );
776 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
780 osg::Vec4Array* colors =
new osg::Vec4Array;
782 surfaceGeometry->setColorArray( colors );
783 surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
785 osg::DrawElementsUInt* surfaceElement =
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
787 std::vector< size_t >tris =
m_triMeshes[i]->getTriangles();
788 surfaceElement->reserve( tris.size() );
790 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
792 surfaceElement->push_back( tris[vertId] );
794 surfaceGeometry->addPrimitiveSet( surfaceElement );
795 outputGeode->addDrawable( surfaceGeometry );
797 osg::StateSet* state = outputGeode->getOrCreateStateSet();
798 osg::ref_ptr<osg::LightModel> lightModel =
new osg::LightModel();
799 lightModel->setTwoSided(
true );
800 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
801 state->setMode( GL_BLEND, osg::StateAttribute::ON );
809 osg::Geometry* surfaceGeometry =
new osg::Geometry();
810 osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
812 outputGeode->setName( ( std::string(
"non active" ) ).c_str() );
818 surfaceGeometry->setNormalArray(
m_nonActiveMesh->getVertexNormalArray() );
819 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
823 osg::Vec4Array* colors =
new osg::Vec4Array;
825 colors->push_back( osg::Vec4( 0.3, 0.3, 0.3, 1.0f ) );
826 surfaceGeometry->setColorArray( colors );
827 surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
829 osg::DrawElementsUInt* surfaceElement =
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
832 surfaceElement->reserve( tris.size() );
834 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
836 surfaceElement->push_back( tris[vertId] );
838 surfaceGeometry->addPrimitiveSet( surfaceElement );
839 outputGeode->addDrawable( surfaceGeometry );
841 osg::StateSet* state = outputGeode->getOrCreateStateSet();
842 osg::ref_ptr<osg::LightModel> lightModel =
new osg::LightModel();
843 lightModel->setTwoSided(
true );
844 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
845 state->setMode( GL_BLEND, osg::StateAttribute::ON );
856 int height = viewer->getCamera()->getViewport()->height();
857 int width = viewer->getCamera()->getViewport()->width();
868 m_wm =
new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
871 m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
873 m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
874 m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
875 m_camera->setViewMatrix( osg::Matrix::identity() );
876 m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
877 m_camera->setRenderOrder( WGECamera::POST_RENDER );
882 viewer->addEventHandler(
new osgWidget::MouseHandler(
m_wm ) );
883 viewer->addEventHandler(
new osgWidget::KeyboardHandler(
m_wm ) );
884 viewer->addEventHandler(
new osgWidget::ResizeHandler(
m_wm,
m_camera ) );
885 viewer->addEventHandler(
new osgWidget::CameraSwitchHandler(
m_wm,
m_camera ) );
886 viewer->addEventHandler(
new osgViewer::StatsHandler() );
887 viewer->addEventHandler(
new osgViewer::WindowSizeHandler() );
888 viewer->addEventHandler(
new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
890 m_wm->resizeAllWindows();
900 int height = viewer->getCamera()->getViewport()->height();
901 int width = viewer->getCamera()->getViewport()->width();
903 int rows = ( height - 20 ) / 20;
904 int buttonWidth = 70;
934 osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
935 osgWidget::Box::VERTICAL,
true,
true ) );
936 newButton->setPosition( osg::Vec3( 5.f + ( i / rows ) * buttonWidth, ( i % rows ) * 20.f, 0 ) );
938 newButton->managed(
m_wm );
939 m_wm->addChild( newButton );
947 osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
948 osgWidget::Box::VERTICAL,
true,
true ) );
949 newButton->setPosition( osg::Vec3( 5.f, height - 20.f, 0 ) );
950 newButton->setId( 0 );
952 newButton->managed(
m_wm );
953 m_wm->addChild( newButton );
959 m_wm->resizeAllWindows();
1025 bool clicked =
false;
1026 bool selectionChanged =
false;
1034 selectionChanged =
true;
1040 if( selectionChanged )
1042 std::vector<size_t>activeClusters;
1082 WAssert(
m_dataSet->getValueSet(),
"" );
1085 std::shared_ptr< std::vector< float > >ptr(
new std::vector< float >(
m_data.size() ) );
1087 for(
size_t i = 0; i <
m_data.size(); ++i )
1089 ptr->at( i ) =
static_cast<float>(
m_data[i] );
1092 std::shared_ptr< WValueSet< float > > vs =
1093 std::shared_ptr< WValueSet< float > >(
new WValueSet< float >( 0, 1, ptr, W_DT_FLOAT ) );
1123 ns = ns.substr( 0, 8 );
1128 for(
size_t k = 8 - ns.size(); k > 0; --k )
1132 ns = std::string(
" " ) + ns;
1136 ns = ns + std::string(
" " );
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 std::shared_ptr< WSubject > getDefaultSubject()
Gets the subject with the ID SUBJECT_UNKNOWN.
This data set type contains scalars as values.
Class creates a dendrogram from a hierarchical clustering.
size_t getClickedCluster(int xClick, int yClick)
calculate which cluster was clicked from given pixel coordinates
class implements text file loading and several convinience methods to access
std::vector< std::vector< std::string > > getLinesForTagSeparated(std::string tag)
getter
std::vector< std::string > getRawLines()
getter
bool readFile()
helper function to read a text file
Class for wrapping around the OSG Camera class.
This callback allows you a simple usage of callbacks in your module.
Class to wrap around the osg Group node and providing a thread safe add/removal mechanism.
This class adds some convenience methods to WGEGroupNode.
std::vector< size_t > getVoxelsForCluster(size_t cluster)
getter
std::vector< size_t > findXClusters(size_t root, size_t number)
finds a number of clusters, the algorithm travers down the tree and will always split the cluster wit...
std::vector< size_t > findClustersForBranchLength(float value, size_t minSize=100)
finds the clusters for a given similarity value
std::vector< size_t > findClustersForValue(float value)
finds the clusters for a given similarity value
void addLeaf(size_t voxelnum)
A leaf is at the very bottom of the tree, it represents a single fiber or voxel, for several purposes...
void addCluster(size_t cluster1, size_t cluster2, float customData)
adds a cluster to the set, it combines 2 already existing clusters
size_t size(size_t cluster) const
getter
std::pair< size_t, size_t > getChildren(size_t cluster) const
getter
std::vector< size_t > downXLevelsFromTop(size_t level, bool hideOutliers=false) const
returns a number of clusters at a certain level down from top cluster
void colorCluster(size_t cluster, WColor color)
sets the color for a selected cluster and all sub clusters
float getCustomData(size_t cluster) const
getter
size_t getLevel(size_t cluster) const
getter
std::vector< size_t > findXBiggestClusters(size_t cluster, size_t number=10) const
finds the X biggest clusters for a given cluster
size_t getLeafCount() const
getter
size_t getClusterCount() const
getter
size_t getMaxLevel() const
getter
A class containing a list of named items.
std::shared_ptr< WSelectionManager > getSelectionManager()
get for selection manager
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.
Allows one to display and interact with clustered voxel data.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
WPropBool m_propPlotHeightByLevel
controls plotting the height of a join
WPropGroup m_groupTriangulation
grouping the dendrogram manipulation properties
WPropBool m_propShowVoxelTriangulation
if true position and size sliders will have no effect
virtual const std::string getName() const
Gives back the name of this module.
std::string m_currentDisplayModeString
the currently active display mode as string
WPropGroup m_groupSelection
grouping the different selection methods
std::vector< std::shared_ptr< WTriangleMesh > > m_triMeshes
triangulation of the active clusters
WPropInt m_propSelectedLoadedPartion
property to select a loaded partition
std::shared_ptr< WItemSelection > m_buttonLabelList
A list of button labels.
void createMesh()
creates a triangulation from the selected clusters
WDendrogramGeode * m_dendrogramGeode
stores the dendrogram geode
WPropSelection m_buttonLabelSelection
Selection property for button labels.
void updateOutDataset()
update the output connector on demand, for performance reasons this is not done every time a change t...
WPropBool m_propShowSelectedButtons
show or hide outliers
size_t m_rootCluster
currently selected cluster + offset
std::vector< std::vector< size_t > > m_loadedPartitions
set partitions loaded from file
bool m_zoom
control variable for zoom mode
int m_oldViewWidth
stores the old viewport resolution to check whether a resize happened
WPropBool m_showNotInClusters
if true clusters not in the current selection list will be rendered grey in the texture and triangula...
virtual void moduleMain()
Entry point after loading the module.
WPropInt m_propDendrogramSizeY
controls the height of the dendrogram
void dendrogramClick(WPickInfo pickInfo)
listenes to the pickhandler and determines if a click into the dendrogram happened
virtual void properties()
Initialize the properties for this module.
std::shared_ptr< WDataSetScalar > m_outData
This is a pointer to the current output.
WPropTrigger m_propReadTrigger
This property triggers the actual reading,.
WPropBool m_propShowDendrogram
controls the display of the dendrogram overlay
std::shared_ptr< WModuleInputData< WDataSetSingle > > m_input
An input connector that accepts order 1 datasets.
WPropInt m_propSelectedCluster
the currently selected cluster
WPropTrigger m_buttonExecuteSelection
triggers the cluster selection update
std::vector< osg::ref_ptr< WOSGButton > > m_activeClustersButtonList
list of buttons for the active cluster selection
std::shared_ptr< WTriangleMesh > m_nonActiveMesh
triangulation of the voxels not in active clusters
WPropTrigger m_buttonUpdateOutput
updates the output connector on demand, as we don't want to do this every paint command
size_t m_zoomRoot
control variable for zoom mode
bool loadClustering(boost::filesystem::path clusterFile)
loads and parses the clustering text file
WPropInt m_propXClusters
how many levels to go down from top
WGECamera * m_camera
stores the camera object
std::shared_ptr< WItemSelection > m_clusterSelectionsList
A list of cluster selection methods.
WPropInt m_propXBiggestClusters
the currently selected cluster
int m_oldViewHeight
stores the old viewport resolution to check whether a resize happened
std::vector< WColor > m_clusterColors
stores a preset color for every cluster, so clusters can keep the same color through different select...
void updateWidgets()
updates the graphical widgets in the 3d scene
osg::ref_ptr< WGEGroupNode > m_meshNode
Pointer to the mesh group node.
osgWidget::WindowManager * m_wm
stores a pointer to the window manager used for osg wdgets and overlay stuff
void updateAll()
after the active cluster list has changed this function updates the texture, triangulation and dendro...
size_t m_colorIndex
temp variable for the initColors function
WPropInt m_propMinSizeToColor
specifies a minimum size for a cluster so that too small cluster won't get an own color
WPropInt m_propLevelsFromTop
how many levels to go down from top
WPropBool m_propResizeWithWindow
if true position and size sliders will have no effect
std::shared_ptr< WModuleOutputData< WDataSetScalar > > m_output
An output connector for the output scalar dsataset.
void setButtonLabels()
helper function to set the label on the in scene buttons depending on which labeling scheme is select...
void setPropertyBoundaries()
updates property min/max values after loading a clustering file
void initWidgets()
inits the graphical widgets in the 3d scene
WPropInt m_infoCountClusters
info property
WPropInt m_propDendrogramOffsetX
controls the horizontal origin of the dendrogram
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...
WPropTrigger m_propZoomOut
zooms out, m_zoom = false, dendrogram shows the whole tree
virtual const std::string getDescription() const
Gives back a description of this module.
osg::ref_ptr< osg::Texture3D > m_texture
stores a pointer to the texture we paint in
bool m_dendrogramDirty
true if the dendrogram needs redrawing
osg::ref_ptr< WGEGroupNode > m_dendrogramNode
Pointer to the dendrogram group node.
WPropInt m_infoMaxLevel
info property
std::vector< size_t > m_data
stores a pointer to the texture we paint in
CDV_DISPLAYMODE m_currentDisplayMode
the currently active display mode
WPropFilename m_propClusterFile
The png files will be loaded form this directory.
bool m_selectionChanged
true if the selection changed and widgets need redrawing
WPropSelection m_clusterSelection
Selection property for clusters.
WHierarchicalTreeVoxels m_tree
the tree object as loaded from the file
osg::ref_ptr< WGEGroupNode > m_moduleNode
Pointer to the modules group node.
WPropTrigger m_propZoomIn
zoom into tree, sets m_zoom true and m_zoomRoot to the currently selected cluster
std::vector< osg::ref_ptr< osg::Geode > > m_outputGeodes
a vector of dendrogram nodes
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
WPropInt m_infoCountLeafes
info property
std::shared_ptr< WDataSetSingle > m_dataSet
This is a pointer to the dataset the module is currently working on.
virtual void connectors()
Initialize the connectors this module is using.
void handleMinSizeChanged()
function to handle user input
WPropDouble m_propMinBranchLength
minimum branch length
WPropBool m_propHideOutliers
show or hide outliers
std::vector< size_t > m_activatedClusters
stores the currently activated clusters
void createTexture()
creates a new texture
void initColors(size_t root, size_t index)
recursive function that initalizes a color for for every cluster, the biggest of the two children of ...
std::shared_ptr< WGridRegular3D > m_grid
stores a pointer to the grid we use;
WPropInt m_propDendrogramOffsetY
controls the vertical origin of the dendrogram
void renderMesh()
renders the triangulated clusters
bool widgetClicked()
handles mouse clicks into the dendrogram
WPropInt m_propDendrogramSizeX
controls the width of the dendrogram
WPropDouble m_propValue
the similarity value for selecting clusters
WPropInt m_propMinBranchSize
minimum branch size
WPropGroup m_groupDendrogram
grouping the dendrogram manipulation properties
Creates a non interpolated triangulation of an isosurface.
std::shared_ptr< WTriangleMesh > genSurfaceOneValue(size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ, const WMatrix< double > &mat, const std::vector< size_t > *vals, size_t isoValue, std::shared_ptr< WProgressCombiner > progress=std::shared_ptr< WProgressCombiner >())
Generate the triangles for the surface on the given dataSet (inGrid, vals).
ValueT & y()
Access y element of vector.
ValueT & x()
Access x element of vector.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
virtual void properties()
Initialize properties in this function.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
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.
virtual void connectors()
Initialize connectors in this function.
Encapsulates info for pick action.
WVector2d getPickPixel() const
Returns the picked pixel coordinates in screen-space.
std::string getName() const
Get name of picked object.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)
void addTo(WPropSelection prop)
Add the PC_SELECTONLYONE constraint to the property.
std::string toString(const T &value)
Convert a given value to a string.
WColor getNthHSVColor(int n)
creates the nth color of a partition of the hsv color circle