30 #include <boost/regex.hpp>
31 #include <osgGA/GUIEventAdapter>
32 #include <osgGA/GUIEventHandler>
33 #include <osgGA/StateSetManipulator>
34 #include <osgGA/TrackballManipulator>
35 #include <osgViewer/ViewerEventHandlers>
36 #include <osgWidget/Util>
37 #include <osgWidget/ViewerEventHandlers>
38 #include <osgWidget/WindowManager>
40 #include "WMClusterDisplay.h"
41 #include "WMClusterDisplay.xpm"
42 #include "core/common/WPathHelper.h"
43 #include "core/common/WPropertyHelper.h"
44 #include "core/common/WStringUtils.h"
45 #include "core/graphicsEngine/WGEUtils.h"
46 #include "core/kernel/WKernel.h"
47 #include "core/kernel/WROIManager.h"
48 #include "core/ui/WUIViewWidget.h"
57 if( ea.getEventType() == GUIEvents::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
59 return (
true == m_signalLeftButtonPush(
WVector2f( ea.getX(), ea.getY() ) ) );
91 return clusterDisplay_xpm;
95 return "Cluster Display";
102 return "This module loads a text file containing the hierarchical tree representation of a fiber clustering"
103 " and provides selection appropriate tools";
108 using std::shared_ptr;
111 m_fiberInput = shared_ptr< FiberInputData >(
new FiberInputData( shared_from_this(),
"fiberInput",
"A loaded fiber dataset." ) );
120 std::ifstream ifs( fileName.c_str(), std::ifstream::in );
122 std::vector< std::string > lines;
128 debugLog() <<
"trying to load " << fileName;
133 debugLog() <<
"trying to load " << fileName;
134 debugLog() <<
"file doesn\'t exist";
141 getline( ifs, line );
143 lines.push_back( std::string( line ) );
153 std::vector<std::string> lines;
155 debugLog() <<
"start parsing tree file...";
159 if( lines.size() == 0 )
164 for(
size_t i = 0; i < lines.size() - 1; ++i )
166 std::string &ls = lines[i];
168 boost::regex reg1(
"\\(" );
169 ls = boost::regex_replace( ls, reg1,
"(," );
171 boost::regex reg2(
"\\)" );
172 ls = boost::regex_replace( ls, reg2,
",)" );
174 boost::regex reg3(
"\\ " );
175 ls = boost::regex_replace( ls, reg3,
"" );
178 std::vector<std::string>svec;
180 for(
size_t i = 0; i < lines.size()-1; ++i )
183 boost::regex reg(
"," );
184 boost::sregex_token_iterator it( lines[i].begin(), lines[i].end(), reg, -1 );
185 boost::sregex_token_iterator end;
188 svec.push_back( *it++ );
191 size_t level = string_utils::fromString< size_t >( svec[1] );
200 std::vector<size_t>leafes;
201 while( svec[k] !=
")" )
203 leafes.push_back( string_utils::fromString< size_t >( svec[k] ) );
209 size_t cluster1 = string_utils::fromString< size_t >( svec[k++] );
210 size_t cluster2 = string_utils::fromString< size_t >( svec[k++] );
212 float data = string_utils::fromString< float >( svec[k++] );
219 std::cout <<
"parse error" << std::endl;
226 debugLog() <<
"finished parsing tree file...";
232 debugLog() <<
"something is wrong with the tree file";
240 int height = viewer->getCamera()->getViewport()->height();
241 int width = viewer->getCamera()->getViewport()->width();
248 m_wm =
new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
253 WOSGButton* current =
new WOSGButton( std::string(
"current" ), osgWidget::Box::VERTICAL,
true,
false );
255 WOSGButton* down11 =
new WOSGButton( std::string(
"-1.1" ), osgWidget::Box::VERTICAL,
true,
false );
256 WOSGButton* down12 =
new WOSGButton( std::string(
"-1.2" ), osgWidget::Box::VERTICAL,
true,
false );
258 WOSGButton* showN =
new WOSGButton( std::string(
" N " ), osgWidget::Box::VERTICAL,
true,
false );
259 WOSGButton* showS =
new WOSGButton( std::string(
" S " ), osgWidget::Box::VERTICAL,
true,
false );
260 WOSGButton* showE =
new WOSGButton( std::string(
" E " ), osgWidget::Box::VERTICAL,
true,
false );
262 up1->setPosition( osg::Vec3( xorig + 85.f, yorig + 300.f, 0 ) );
263 current->setPosition( osg::Vec3( xorig + 85.f, yorig + 200.f, 0 ) );
264 down11->setPosition( osg::Vec3( xorig + 30.f, yorig + 100.f, 0 ) );
265 down12->setPosition( osg::Vec3( xorig + 140.f, yorig + 100.f, 0 ) );
267 showN->setPosition( osg::Vec3( xorig + 85.f, yorig + 220.f, 0 ) );
268 showS->setPosition( osg::Vec3( xorig + 110.f, yorig + 220.f, 0 ) );
269 showE->setPosition( osg::Vec3( xorig + 135.f, yorig + 220.f, 0 ) );
271 up1->managed(
m_wm );
272 current->managed(
m_wm );
273 down11->managed(
m_wm );
274 down12->managed(
m_wm );
276 showN->managed(
m_wm );
277 showS->managed(
m_wm );
278 showE->managed(
m_wm );
280 m_wm->addChild( current );
281 m_wm->addChild( up1 );
282 m_wm->addChild( down11 );
283 m_wm->addChild( down12 );
285 m_wm->addChild( showN );
286 m_wm->addChild( showS );
287 m_wm->addChild( showE );
299 m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
301 m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
302 m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
303 m_camera->setViewMatrix( osg::Matrix::identity() );
304 m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
305 m_camera->setRenderOrder( WGECamera::POST_RENDER );
310 viewer->addEventHandler(
new osgWidget::MouseHandler(
m_wm ) );
311 viewer->addEventHandler(
new osgWidget::KeyboardHandler(
m_wm ) );
312 viewer->addEventHandler(
new osgWidget::ResizeHandler(
m_wm,
m_camera ) );
313 viewer->addEventHandler(
new osgWidget::CameraSwitchHandler(
m_wm,
m_camera ) );
314 viewer->addEventHandler(
new osgViewer::StatsHandler() );
315 viewer->addEventHandler(
new osgViewer::WindowSizeHandler() );
316 viewer->addEventHandler(
new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
318 m_wm->resizeAllWindows();
401 bool treeLoaded =
false;
416 std::string fn =
m_dataSet->getFilename();
417 std::string ext(
".fib" );
418 std::string csvExt(
"_hie.txt" );
419 fn.replace( fn.find( ext ), ext.size(), csvExt );
571 while( minusOff < 0 )
581 if( leftSize >= rightSize )
664 int height = viewer->getCamera()->getViewport()->height();
665 int width = viewer->getCamera()->getViewport()->width();
682 size_t up1, down11, down12;
735 osg::ref_ptr<WOSGButton> newButton1 = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
736 osgWidget::Box::VERTICAL,
true,
false ) );
737 newButton1->setPosition( osg::Vec3( 10.f, i * 20.f, 0 ) );
739 newButton1->setLabel( std::string(
" S " ) );
740 newButton1->managed(
m_wm );
741 m_wm->addChild( newButton1 );
745 osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
746 osgWidget::Box::VERTICAL,
true,
true ) );
747 newButton->setPosition( osg::Vec3( 35.f, i * 20.f, 0 ) );
750 newButton->managed(
m_wm );
751 m_wm->addChild( newButton );
755 osg::ref_ptr<WOSGButton> newButton1 = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
756 osgWidget::Box::VERTICAL,
true,
false ) );
757 newButton1->setPosition( osg::Vec3( 10.f,
m_biggestClusters.size() * 20.f, 0 ) );
759 newButton1->setLabel( std::string(
" S " ) );
760 newButton1->managed(
m_wm );
761 m_wm->addChild( newButton1 );
763 newButton1->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );
765 osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>(
new WOSGButton( std::string(
"" ),
766 osgWidget::Box::VERTICAL,
true,
true ) );
770 newButton->managed(
m_wm );
771 m_wm->addChild( newButton );
774 newButton->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );
777 m_wm->resizeAllWindows();
824 bool clicked =
false;
844 for(
size_t i = 0; i < 3; ++i )
853 bool biggestClusterSelectionChanged =
false;
860 biggestClusterSelectionChanged =
true;
871 if( biggestClusterSelectionChanged )
873 std::vector<size_t>activeClusters;
895 std::vector<size_t>finalList;
896 std::queue<size_t>currentLevelList;
898 currentLevelList.push( current );
900 std::queue<size_t>nextLevelList;
903 while( !currentLevelList.empty() )
905 size_t cluster = currentLevelList.front();
906 currentLevelList.pop();
915 nextLevelList.push( left );
923 nextLevelList.push( right );
932 finalList.push_back( cluster );
936 while( !nextLevelList.empty() )
938 size_t cluster = nextLevelList.front();
940 currentLevelList.push( cluster );
946 while( !currentLevelList.empty() )
948 size_t cluster = currentLevelList.front();
949 currentLevelList.pop();
950 finalList.push_back( cluster );
955 for(
size_t i = 0; i < finalList.size(); ++i )
957 size_t cluster = finalList[i];
971 std::shared_ptr< std::vector< float > >colorField =
m_dataSet->getColorScheme(
"Custom Color" )->getColor();
972 std::shared_ptr< std::vector< size_t > > starts =
m_fiberSelector->getStarts();
973 std::shared_ptr< std::vector< size_t > > lengths =
m_fiberSelector->getLengths();
975 for(
size_t i = 0; i < clusters.size(); ++i )
977 size_t current = clusters[i];
979 for(
size_t k = (*starts)[current]; k < (*starts)[current] + (*lengths)[current]; ++k)
981 (*colorField)[k*3] = color[0];
982 (*colorField)[k*3+1] = color[1];
983 (*colorField)[k*3+2] = color[2];
1014 osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
1017 m_rootNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
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.
Class creates a dendrogram from a hierarchical clustering.
size_t getClickedCluster(int xClick, int yClick)
calculate which cluster was clicked from given pixel coordinates
bool inDendrogramArea(const WVector2f &pos) const
calculates if the given position is within the view area of the dendrogram
Class implements an osg::Drawable that paints fiber representations either using lines or tubes.
Adaptor class between the roi manager and the fiber display.
Class for wrapping around the OSG Camera class.
This callback allows you a simple usage of callbacks in your module.
This class adds some convenience methods to WGEGroupNode.
void addCluster(size_t cluster1, size_t cluster2, size_t level, std::vector< size_t > leafes, float customData)
adds a cluster to the set, it combines 2 already existing clusters
std::shared_ptr< std::vector< bool > > getOutputBitfield(size_t cluster)
generates a bitfield where for every leaf in the selected cluster the value is true,...
std::vector< size_t > getBestClustersFittingRoi(float ratio=0.9, size_t number=1)
finds clusters that match a given ROI up to a certain percentage
void setRoiBitField(std::shared_ptr< std::vector< bool > > bitfield)
setter
void addLeaf()
A leaf is at the very bottom of the tree, it represents a single fiber or voxel, for several purposes...
size_t size(size_t cluster) const
getter
std::pair< size_t, size_t > getChildren(size_t cluster) const
getter
size_t getParent(size_t cluster) const
getter
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 > getLeafesForCluster(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
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
std::shared_ptr< WROIManager > getRoiManager()
get for roi manager
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
Small event handler class to catch left mouse buttons clicks in the main view.
void subscribeLeftButtonPush(LeftButtonPushSignalType::slot_type slot)
Registers a function slot to LEFT BUTTON PUSH events.
LeftButtonPushSignalType m_signalLeftButtonPush
Signal used for notification of the LEFT BUTTON PUSH event.
Module offers several fiber selection and coloring options depending on a hierarchical clustering.
std::shared_ptr< WFiberSelector > m_fiberSelector
Point to a fiber selector, which is an adapater between the roi manager and the this module.
bool dendrogramClick(const WVector2f &pos)
handles clicks into the dendrogram
void colorClusters(size_t current)
colors subclusters depending on slider settings
osgWidget::WindowManager * m_wm
stores a pointer to the window manager used for osg wdgets and overlay stuff
bool m_widgetDirty
true if the widgets need redrawing
WDendrogramGeode * m_dendrogramGeode
stores the dendrogram geode
bool m_biggestClusterButtonsChanged
true if the buttons for the biggest clusters need updating
WMClusterDisplay()
constructor
WPropInt m_propMinSizeToColor
specifies a minimum size for a cluster so that too small cluster won't get an own color
WPropBool m_propShowTree
controls the display of the tree navigation widget
WPropInt m_propDendrogramOffsetX
controls the horizontal origin of the dendrogram
std::vector< std::string > readFile(const std::string fileName)
helper function to read a text file
std::vector< size_t > m_biggestClusters
stores the currently selected biggest clusters
WPropInt m_propSelectedCluster
the currently selected cluster
WPropFilename m_propTreeFile
The tree will be read from this file, i hope we will get a real load button some time.
WPropBool m_propShowDendrogram
controls the display of the dendrogram overlay
void handleMinSizeChanged()
function to handle user input
WPropGroup m_groupDendrogram
grouping the dendrogram manipulation properties
void handleOffsetChanged()
function to handle user input
virtual const std::string getName() const
Gives back the name of this module.
void updateWidgets()
updates all the overlay widgets within the osg thread
int m_oldViewWidth
stores the old viewport resolution to check whether a resize happened
std::shared_ptr< const WDataSetFibers > m_dataSet
pointer to dataSet to be able to access it throughout the whole module.
osg::ref_ptr< WGEManagedGroupNode > m_rootNode
The root node used for this modules graphics.
WPropTrigger m_readTriggerProp
This property triggers the actual reading,.
bool m_dendrogramDirty
true if the dendrogram needs redrawing
void initWidgets()
inits the cluster navigation widgets
WGECamera * m_camera
stores the camera object
virtual const std::string getDescription() const
Gives back a description of this module.
size_t m_labelMode
indicates wheter the cluster number, size of custom data should be shown on labels
void createFiberGeode()
helper function to initialize a fiber display node
WPropDouble m_propBoxClusterRatio
ratio of how many leafes of a cluster must be inside the roi setting to be considered
WPropBool m_propResizeWithWindow
if true position and size sliders will have no effect
WPropInt m_propSubClusters
number of biggest sub cluster to determine and show
void handleColoringChanged()
function to handle user input
bool loadTreeAscii(std::string fileName)
helper function to load and parse a tree file, the tree is stored in the member variable m_tree
virtual ~WMClusterDisplay()
destructor
std::shared_ptr< WModuleInputData< const WDataSetFibers > > m_fiberInput
Input connector for a fiber dataset.
virtual void moduleMain()
Entry point after loading the module.
WPropInt m_propSelectedClusterOffset
offset to the currently selected cluster, this allows tree navigation and return to the current clust...
std::vector< osg::ref_ptr< WOSGButton > > m_treeButtonList
list of buttons for the tree widget
virtual void connectors()
Initialize the connectors this module is using.
size_t m_rootCluster
currently selected cluster + offset
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
WPropInt m_propDendrogramOffsetY
controls the vertical origin of the dendrogram
int m_oldViewHeight
stores the old viewport resolution to check whether a resize happened
void handleSelectedClusterChanged()
function to handle user input
void handleRoiChanged()
function to handle user input
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...
WPropInt m_propSubLevelsToColor
number of subclusters to color differently
std::string createLabel(size_t id)
creates a label depending ont he current labeling setting
osg::ref_ptr< WFiberDrawable > m_fiberDrawable
stores pointer to the fiber drawer
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
void handleBiggestClustersChanged()
function to handle user input
void setColor(std::vector< size_t > clusters, WColor color)
sets a set of cluster to a single color
std::vector< osg::ref_ptr< WOSGButton > > m_biggestClustersButtonList
list of buttons for biggest cluster selection
WPropInt m_propDendrogramSizeY
controls the height of the dendrogram
virtual void properties()
Initialize the properties for this module.
WPropInt m_propDendrogramSizeX
controls the width of the dendrogram
WHierarchicalTreeFibers m_tree
stores the tree object
bool widgetClicked()
function checks all on screen buttons if they have been clicked
WPropInt m_propMaxSubClusters
number of clusters that are selected by the current roi setting and meet the ratio condition
A fixed size matrix class.
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.
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.
static boost::filesystem::path getAppPath()
The path where the binary file resides in.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)
void addTo(WPropFilename prop)
Add the PC_PATHEXISTS 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