OpenWalnut  1.5.0dev
WMClusterDisplay.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <memory>
26 #include <queue>
27 #include <string>
28 #include <vector>
29 
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> //NOLINT
37 #include <osgWidget/ViewerEventHandlers> //NOLINT
38 #include <osgWidget/WindowManager> //NOLINT
39 
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"
49 
50 // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
51 W_LOADABLE_MODULE( WMClusterDisplay )
52 
53 
54 bool WMClusterDisplay::MainViewEventHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */ )
55 {
56 // wlog::debug( "WMClusterDisplay::MainViewEventHandler" ) << "handle";
57  if( ea.getEventType() == GUIEvents::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
58  {
59  return ( true == m_signalLeftButtonPush( WVector2f( ea.getX(), ea.getY() ) ) );
60  }
61  return false;
62 }
63 
64 void WMClusterDisplay::MainViewEventHandler::subscribeLeftButtonPush( LeftButtonPushSignalType::slot_type slot )
65 {
66  m_signalLeftButtonPush.connect( slot );
67 }
68 
70  WModule(),
71  m_widgetDirty( false ),
73  m_dendrogramDirty( false ),
74  m_labelMode( 0 )
75 {
76 }
77 
79 {
80  // Cleanup!
81 }
82 
83 std::shared_ptr< WModule > WMClusterDisplay::factory() const
84 {
85  // See "src/modules/template/" for an extensively documented example.
86  return std::shared_ptr< WModule >( new WMClusterDisplay() );
87 }
88 
89 const char** WMClusterDisplay::getXPMIcon() const
90 {
91  return clusterDisplay_xpm; // Please put a real icon here.
92 }
93 const std::string WMClusterDisplay::getName() const
94 {
95  return "Cluster Display";
96 }
97 
98 const std::string WMClusterDisplay::getDescription() const
99 {
100  // Specify your module description here. Be detailed. This text is read by the user.
101  // See "src/modules/template/" for an extensively documented example.
102  return "This module loads a text file containing the hierarchical tree representation of a fiber clustering"
103  " and provides selection appropriate tools";
104 }
105 
107 {
108  using std::shared_ptr;
109  typedef WModuleInputData< const WDataSetFibers > FiberInputData; // just an alias
110 
111  m_fiberInput = shared_ptr< FiberInputData >( new FiberInputData( shared_from_this(), "fiberInput", "A loaded fiber dataset." ) );
112 
114  // call WModules initialization
116 }
117 
118 std::vector< std::string > WMClusterDisplay::readFile( const std::string fileName )
119 {
120  std::ifstream ifs( fileName.c_str(), std::ifstream::in );
121 
122  std::vector< std::string > lines;
123 
124  std::string line;
125 
126  if( ifs.is_open() )
127  {
128  debugLog() << "trying to load " << fileName;
129  debugLog() << "file exists";
130  }
131  else
132  {
133  debugLog() << "trying to load " << fileName;
134  debugLog() << "file doesn\'t exist";
135  ifs.close();
136  return lines;
137  }
138 
139  while( !ifs.eof() )
140  {
141  getline( ifs, line );
142 
143  lines.push_back( std::string( line ) );
144  }
145 
146  ifs.close();
147 
148  return lines;
149 }
150 
151 bool WMClusterDisplay::loadTreeAscii( std::string fileName )
152 {
153  std::vector<std::string> lines;
154 
155  debugLog() << "start parsing tree file...";
156 
157  lines = readFile( fileName );
158 
159  if( lines.size() == 0 )
160  {
161  return false;
162  }
163 
164  for( size_t i = 0; i < lines.size() - 1; ++i )
165  {
166  std::string &ls = lines[i];
167 
168  boost::regex reg1( "\\(" );
169  ls = boost::regex_replace( ls, reg1, "(," );
170 
171  boost::regex reg2( "\\)" );
172  ls = boost::regex_replace( ls, reg2, ",)" );
173 
174  boost::regex reg3( "\\ " );
175  ls = boost::regex_replace( ls, reg3, "" );
176  }
177 
178  std::vector<std::string>svec;
179 
180  for( size_t i = 0; i < lines.size()-1; ++i )
181  {
182  svec.clear();
183  boost::regex reg( "," );
184  boost::sregex_token_iterator it( lines[i].begin(), lines[i].end(), reg, -1 );
185  boost::sregex_token_iterator end;
186  while( it != end )
187  {
188  svec.push_back( *it++ );
189  }
190 
191  size_t level = string_utils::fromString< size_t >( svec[1] );
192  if( level == 0 )
193  {
194  m_tree.addLeaf();
195  }
196  else
197  {
198  // start after ( level (
199  size_t k = 3;
200  std::vector<size_t>leafes;
201  while( svec[k] != ")" )
202  {
203  leafes.push_back( string_utils::fromString< size_t >( svec[k] ) );
204  ++k;
205  }
206  //skip ) (
207  k += 2;
208 
209  size_t cluster1 = string_utils::fromString< size_t >( svec[k++] );
210  size_t cluster2 = string_utils::fromString< size_t >( svec[k++] );
211  ++k;
212  float data = string_utils::fromString< float >( svec[k++] );
213 
214  m_tree.addCluster( cluster1, cluster2, level, leafes, data );
215  //m_tree.addCluster( cluster1, cluster2, data );
216 
217  if( svec[k] != ")" )
218  {
219  std::cout << "parse error" << std::endl;
220  return false;
221  }
222  }
223  }
224  debugLog() << m_tree.getClusterCount() << " clusters created.";
225 
226  debugLog() << "finished parsing tree file...";
227 
228  if( m_tree.getLeafCount() == m_fiberInput->getData()->size() )
229  {
230  return true;
231  }
232  debugLog() << "something is wrong with the tree file";
233  return false;
234 }
235 
237 {
238  osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
239 
240  int height = viewer->getCamera()->getViewport()->height();
241  int width = viewer->getCamera()->getViewport()->width();
242 
243  m_oldViewHeight = height;
244  m_oldViewWidth = width;
245 
246  m_rootNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
247 
248  m_wm = new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
249 
250  float xorig = 100.f;
251  float yorig = 300.f;
252 
253  WOSGButton* current = new WOSGButton( std::string( "current" ), osgWidget::Box::VERTICAL, true, false );
254  WOSGButton* up1 = new WOSGButton( std::string( "+1" ), 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 );
257 
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 );
261 
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 ) );
266 
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 ) );
270 
271  up1->managed( m_wm );
272  current->managed( m_wm );
273  down11->managed( m_wm );
274  down12->managed( m_wm );
275 
276  showN->managed( m_wm );
277  showS->managed( m_wm );
278  showE->managed( m_wm );
279 
280  m_wm->addChild( current );
281  m_wm->addChild( up1 );
282  m_wm->addChild( down11 );
283  m_wm->addChild( down12 );
284 
285  m_wm->addChild( showN );
286  m_wm->addChild( showS );
287  m_wm->addChild( showE );
288 
289  m_treeButtonList.push_back( current );
290  m_treeButtonList.push_back( up1 );
291  m_treeButtonList.push_back( down11 );
292  m_treeButtonList.push_back( down12 );
293 
294  m_treeButtonList.push_back( showN );
295  m_treeButtonList.push_back( showS );
296  m_treeButtonList.push_back( showE );
297 
298  m_camera = new WGECamera();
299  m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
300 
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 );
306 
307  m_rootNode->addChild( m_camera );
308  m_camera->addChild( m_wm );
309 
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() ) );
317 
318  m_wm->resizeAllWindows();
319 
320  m_rootNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMClusterDisplay::updateWidgets, this ) ) );
321  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );
322 }
323 
324 
326 {
327  // Initialize the properties
328  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
329 
330  m_propSelectedCluster = m_properties->addProperty( "Selected Cluster", "", 0, m_propCondition );
331  m_propSelectedCluster->setMin( 0 );
332  m_propSelectedCluster->setMax( 0 );
333 
334  m_propSelectedClusterOffset = m_properties->addProperty( "Offset", "", 0, m_propCondition );
335  m_propSelectedClusterOffset->setMin( -10 );
336  m_propSelectedClusterOffset->setMax( 10 );
337 
338 
339  m_propSubClusters = m_properties->addProperty( "Subclusters", "How many sub clusters should be selected", 10, m_propCondition );
340  m_propSubClusters->setMin( 1 );
341  m_propSubClusters->setMax( 50 );
342 
343  m_propSubLevelsToColor = m_properties->addProperty( "Sublevels to Color", "Number of subclusters to color differently", 0, m_propCondition );
344  m_propSubLevelsToColor->setMin( 0 );
345  m_propSubLevelsToColor->setMax( 0 );
346 
347  m_propMinSizeToColor = m_properties->addProperty( "Min size to show", "Specifies a minimum size for a cluster to be drawn", 1, m_propCondition ); // NOLINT
348  m_propMinSizeToColor->setMin( 1 );
349  m_propMinSizeToColor->setMax( 200 );
350 
351  m_propMaxSubClusters = m_properties->addProperty( "Max clusters in box ", "", 1, m_propCondition );
352  m_propMaxSubClusters->setMin( 1 );
353  m_propMaxSubClusters->setMax( 100 );
354 
355  m_propBoxClusterRatio = m_properties->addProperty( "Box-Cluster Ratio", "", 0.9, m_propCondition );
356  m_propBoxClusterRatio->setMin( 0.0 );
357  m_propBoxClusterRatio->setMax( 1.0 );
358 
359  m_propShowTree = m_properties->addProperty( "Show widget", "", false, m_propCondition );
360 
361  m_groupDendrogram = m_properties->addPropertyGroup( "Dendrogram", "Properties only related to the dendrogram." );
362 
363  m_propShowDendrogram = m_groupDendrogram->addProperty( "Show dendrogram", "", true, m_propCondition );
364 
365  m_propResizeWithWindow = m_groupDendrogram->addProperty( "Resize with window", "", true, m_propCondition );
366 
367  m_propDendrogramSizeX = m_groupDendrogram->addProperty( "Width", "", 100, m_propCondition );
368  m_propDendrogramSizeX->setMin( 0 );
369  m_propDendrogramSizeX->setMax( 10000 );
370  m_propDendrogramSizeY = m_groupDendrogram->addProperty( "Height", "", 100, m_propCondition );
371  m_propDendrogramSizeY->setMin( 0 );
372  m_propDendrogramSizeY->setMax( 10000 );
373  m_propDendrogramOffsetX = m_groupDendrogram->addProperty( "Horizontal position", "", 100, m_propCondition );
374  m_propDendrogramOffsetX->setMin( -9000 );
375  m_propDendrogramOffsetX->setMax( 1000 );
376  m_propDendrogramOffsetY = m_groupDendrogram->addProperty( "Verctical position", "", 100, m_propCondition );
377  m_propDendrogramOffsetY->setMin( -9000 );
378  m_propDendrogramOffsetY->setMax( 1000 );
379 
380  m_propTreeFile = m_properties->addProperty( "Tree file", "", WPathHelper::getAppPath() );
381  m_readTriggerProp = m_properties->addProperty( "Do read", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
383 
385 }
386 
388 {
389  osg::ref_ptr< MainViewEventHandler > eh( new MainViewEventHandler );
390  eh->subscribeLeftButtonPush( boost::bind( &WMClusterDisplay::dendrogramClick, this, boost::placeholders::_1 ) );
391 
392  WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView()->addEventHandler( eh );
393 
394  m_moduleState.setResetable( true, true );
396  m_moduleState.add( m_active->getUpdateCondition() );
397  m_moduleState.add( m_fiberInput->getDataChangedCondition() );
398 
399  ready();
400 
401  bool treeLoaded = false;
402 
403  // no text file was found, wait for the user to manually load on
404  while( !m_shutdownFlag() )
405  {
406  if( m_shutdownFlag() )
407  {
408  break;
409  }
410 
412 
413  if( m_dataSet != m_fiberInput->getData() )
414  {
415  m_dataSet = m_fiberInput->getData();
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 );
420  treeLoaded = loadTreeAscii( fn );
421  if( treeLoaded )
422  {
423  break;
424  }
425  }
426 
427 
429  {
430  std::string fileName = m_propTreeFile->get().string().c_str();
431  treeLoaded = loadTreeAscii( fileName );
433  if( treeLoaded )
434  {
435  break;
436  }
437  }
438  }
439 
440  m_fiberSelector = std::shared_ptr<WFiberSelector>( new WFiberSelector( m_dataSet ) );
441  m_tree.setRoiBitField( m_fiberSelector->getBitfield() );
442 
443  m_propTreeFile->setHidden( true );
444  m_readTriggerProp->setHidden( true );
445 
450  m_propMinSizeToColor->setMax( 100 );
452 
455 
456  initWidgets();
458 
459  m_widgetDirty = true;
460  updateWidgets();
461 
462  WKernel::getRunningKernel()->getRoiManager()->getProperties()->getProperty( "dirty" )->getUpdateCondition()->subscribeSignal(
463  boost::bind( &WMClusterDisplay::handleRoiChanged, this ) );
464 
466  m_camera->addChild( m_dendrogramGeode );
467 
468  m_propSelectedCluster->get( true );
469  m_propSubClusters->get( true );
470  m_propSubLevelsToColor->get( true );
471  m_propMinSizeToColor->get( true );
472 
473  // main loop
474  while( !m_shutdownFlag() )
475  {
477 
478  if( m_shutdownFlag() )
479  {
480  break;
481  }
482 
483  if( m_propSelectedCluster->changed() )
484  {
486  }
487 
488  if( m_propSelectedClusterOffset->changed() )
489  {
491  }
492 
493  if( m_propSubClusters->changed() )
494  {
496  }
497 
498  if( m_propSubLevelsToColor->changed() )
499  {
501  }
502 
503  if( m_propMinSizeToColor->changed() )
504  {
506  }
507 
508  if( m_propBoxClusterRatio->changed() || m_propMaxSubClusters->changed() )
509  {
511  }
512 
513  if( m_propShowTree->changed() )
514  {
515  m_widgetDirty = true;
516  }
517 
518  if( m_propShowDendrogram->changed() || m_propResizeWithWindow->changed() || m_propDendrogramSizeX->changed() ||
519  m_propDendrogramSizeY->changed() || m_propDendrogramOffsetX->changed() || m_propDendrogramOffsetY->changed() )
520  {
521  m_dendrogramDirty = true;
522  }
523 
524  if( m_active->changed() )
525  {
526  //WKernel::getRunningKernel()->getRoiManager()->setUseExternalBitfield( m_active->get( true ) );
527  }
528  }
529 
530  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
531 }
532 
534 {
535  m_rootCluster = m_propSelectedCluster->get( true );
538  m_propSelectedClusterOffset->set( 0 );
539  m_propSelectedClusterOffset->get( true );
540  m_propMinSizeToColor->setMax( m_tree.size( m_biggestClusters.back() ) );
541 
543 
545  colorClusters( m_propSelectedCluster->get( true ) );
546 
547  m_dendrogramDirty = true;
548 }
549 
551 {
552  if( m_propSelectedClusterOffset->get( true ) == 0 )
553  {
554  m_rootCluster = m_propSelectedCluster->get( true );
555  }
556  else if( m_propSelectedClusterOffset->get( true ) > 0 )
557  {
558  int plus = m_propSelectedClusterOffset->get( true );
559  m_rootCluster = m_propSelectedCluster->get( true );
560  while( plus > 0 )
561  {
563  --plus;
564  }
565  }
566  else
567  {
568  int minusOff = m_propSelectedClusterOffset->get( true );
569  m_rootCluster = m_propSelectedCluster->get( true );
570 
571  while( minusOff < 0 )
572  {
573  if( m_tree.getLevel( m_rootCluster ) > 0 )
574  {
575  size_t left = m_tree.getChildren( m_rootCluster ).first;
576  size_t right = m_tree.getChildren( m_rootCluster ).second;
577 
578  size_t leftSize = m_tree.size( left );
579  size_t rightSize = m_tree.size( right );
580 
581  if( leftSize >= rightSize )
582  {
583  m_rootCluster = left;
584  }
585  else
586  {
587  m_rootCluster = right;
588  }
589  }
590  ++minusOff;
591  }
592  }
594 
595  m_dendrogramDirty = true;
596 }
597 
599 {
601 
602  m_propMinSizeToColor->setMax( m_tree.size( m_biggestClusters.back() ) );
603 
604  m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
605  setColor( m_tree.getLeafesForCluster( m_rootCluster ), WColor( 0.3, 0.3, 0.3, 1.0 ) );
606 
607  for( size_t k = 0; k < m_biggestClusters.size(); ++k )
608  {
609  size_t current = m_biggestClusters[k];
611  m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
612  }
613 
614  m_dendrogramDirty = true;
615  m_widgetDirty = true;
617 
619 }
620 
622 {
623  m_propSubLevelsToColor->get( true );
624  m_propMinSizeToColor->get( true );
625  colorClusters( m_propSelectedCluster->get( true ) );
626  m_dendrogramDirty = true;
627 }
628 
630 {
631  m_dendrogramDirty = true;
632 }
633 
635 {
637 
638  if( m_active->get() )
639  {
641 
642  m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
643  setColor( m_tree.getLeafesForCluster( m_rootCluster ), WColor( 0.3, 0.3, 0.3, 1.0 ) );
644 
645  for( size_t k = 0; k < m_biggestClusters.size(); ++k )
646  {
647  size_t current = m_biggestClusters[k];
649  m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
650  }
651 
652  m_widgetDirty = true;
654  m_dendrogramDirty = true;
655  }
656 
658 }
659 
661 {
662  osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
663 
664  int height = viewer->getCamera()->getViewport()->height();
665  int width = viewer->getCamera()->getViewport()->width();
666 
667  if( ( height != m_oldViewHeight ) || width != m_oldViewWidth )
668  {
669  m_oldViewHeight = height;
670  m_oldViewWidth = width;
671 
672  m_dendrogramDirty = true;
673  }
674 
675 
677  {
678  return;
679  }
680  // store current cluster id for ease of access and better readability
681  size_t current = m_propSelectedCluster->get();
682  size_t up1, down11, down12; // up2, down21, down22, down23, down24;
683 
684  m_treeButtonList[0]->setId( current );
685  m_treeButtonList[0]->setLabel( createLabel( current ) );
686 
687  for( size_t i = 0; i < m_treeButtonList.size(); ++i )
688  {
689  m_treeButtonList[i]->hide();
690  }
691 
692  if( m_propShowTree->get( true ) )
693  {
694  m_treeButtonList[0]->show();
695 
696  // are we on top?
697  if( m_tree.getLevel( current ) < m_tree.getMaxLevel() )
698  {
699  // not yet
700  up1 = m_tree.getParent( current );
701  m_treeButtonList[1]->setId( up1 );
702  m_treeButtonList[1]->setLabel( createLabel( up1 ) );
703  m_treeButtonList[1]->show();
704  }
705  // are we all the way down
706  if( m_tree.getLevel( current ) > 0 )
707  {
708  down11 = m_tree.getChildren( current ).first;
709  down12 = m_tree.getChildren( current ).second;
710 
711  m_treeButtonList[2]->setId( down11 );
712  m_treeButtonList[2]->setLabel( createLabel( down11 ) );
713  m_treeButtonList[2]->show();
714 
715  m_treeButtonList[3]->setId( down12 );
716  m_treeButtonList[3]->setLabel( createLabel( down12 ) );
717  m_treeButtonList[3]->show();
718  }
719 
720  m_treeButtonList[4]->show();
721  m_treeButtonList[5]->show();
722  m_treeButtonList[6]->show();
723  }
724 
726  {
727  for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
728  {
729  m_wm->removeChild( m_biggestClustersButtonList[i] );
730  }
731 
733  for( size_t i = 0; i < m_biggestClusters.size(); ++i )
734  {
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 ) );
738  newButton1->setId( 10000000 + m_biggestClusters[i] );
739  newButton1->setLabel( std::string( " S " ) );
740  newButton1->managed( m_wm );
741  m_wm->addChild( newButton1 );
742  m_biggestClustersButtonList.push_back( newButton1 );
743  newButton1->setBackgroundColor( wge::getNthHSVColor( i ) );
744 
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 ) );
748  newButton->setId( m_biggestClusters[i] );
749  newButton->setLabel( createLabel( m_biggestClusters[i] ) );
750  newButton->managed( m_wm );
751  m_wm->addChild( newButton );
752  m_biggestClustersButtonList.push_back( newButton );
753  newButton->setBackgroundColor( wge::getNthHSVColor( i ) );
754  }
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 ) );
758  newButton1->setId( 10000000 + m_propSelectedCluster->get() );
759  newButton1->setLabel( std::string( " S " ) );
760  newButton1->managed( m_wm );
761  m_wm->addChild( newButton1 );
762  m_biggestClustersButtonList.push_back( newButton1 );
763  newButton1->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );
764 
765  osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
766  osgWidget::Box::VERTICAL, true, true ) );
767  newButton->setPosition( osg::Vec3( 35.f, m_biggestClusters.size() * 20.f, 0 ) );
768  newButton->setId( m_propSelectedCluster->get() );
769  newButton->setLabel( createLabel( m_propSelectedCluster->get() ) );
770  newButton->managed( m_wm );
771  m_wm->addChild( newButton );
772 
773  m_biggestClustersButtonList.push_back( newButton );
774  newButton->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );
776  }
777  m_wm->resizeAllWindows();
778 
779  if( m_dendrogramDirty )
780  {
781  //m_camera->removeChild( m_dendrogramGeode );
782  m_camera->removeChild( 1, 1 );
783 
784  int dwidth = m_propDendrogramSizeX->get( true );
785  int dheight = m_propDendrogramSizeY->get( true );
786  int dxOff = m_propDendrogramOffsetX->get( true );
787  int dyOff = m_propDendrogramOffsetY->get( true );
788 
789  if( m_propShowDendrogram->get( true ) )
790  {
791  if( m_propResizeWithWindow->get( true ) )
792  {
794  m_propMinSizeToColor->get(), width - 120, height / 2 , 100 );
795  }
796  else
797  {
799  m_propMinSizeToColor->get(), dwidth, dheight, dxOff, dyOff );
800  }
801  m_camera->addChild( m_dendrogramGeode );
802  }
803  m_dendrogramDirty = false;
804  }
805 }
806 
807 std::string WMClusterDisplay::createLabel( size_t id )
808 {
809  switch( m_labelMode )
810  {
811  case 1:
812  return string_utils::toString( m_tree.size( id ) );
813  break;
814  case 2:
816  break;
817  default:
818  return string_utils::toString( id );
819  }
820 }
821 
823 {
824  bool clicked = false;
825 
826  if( m_treeButtonList[0]->clicked() )
827  {
828  clicked = true;
830  m_propSelectedClusterOffset->set( 0 );
833  }
834 
835  for( size_t i = 1; i < m_treeButtonList.size() - 3; ++i )
836  {
837  if( m_treeButtonList[i]->clicked() )
838  {
839  clicked = true;
840  m_propSelectedCluster->set( m_treeButtonList[i]->getId() );
841  }
842  }
843 
844  for( size_t i = 0; i < 3; ++i )
845  {
846  if( m_treeButtonList[4 + i]->clicked() )
847  {
848  clicked = true;
849  m_labelMode = i;
850  }
851  }
852 
853  bool biggestClusterSelectionChanged = false;
854  for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
855  {
856  if( m_biggestClustersButtonList[i]->clicked() )
857  {
858  if( m_biggestClustersButtonList[i]->getId() < 10000000 )
859  {
860  biggestClusterSelectionChanged = true;
861  clicked = true;
862  }
863  else
864  {
865  clicked = true;
866  m_propSelectedCluster->set( m_biggestClustersButtonList[i]->getId() - 10000000 );
867  }
868  }
869  }
870 
871  if( biggestClusterSelectionChanged )
872  {
873  std::vector<size_t>activeClusters;
874  for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
875  {
876  if( m_biggestClustersButtonList[i]->pushed() )
877  {
878  activeClusters.push_back( m_biggestClustersButtonList[i]->getId() );
879  }
880  }
881 
882  m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( activeClusters ) );
883  //WKernel::getRunningKernel()->getRoiManager()->setExternalBitfield( m_tree.getOutputBitfield( activeClusters ) );
884  }
885  return clicked;
886 }
887 
888 void WMClusterDisplay::colorClusters( size_t current )
889 {
890  size_t num = m_propSubLevelsToColor->get();
891  size_t size = m_propMinSizeToColor->get();
892 
893  m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
894 
895  std::vector<size_t>finalList;
896  std::queue<size_t>currentLevelList;
897 
898  currentLevelList.push( current );
899 
900  std::queue<size_t>nextLevelList;
901  while( num > 0 )
902  {
903  while( !currentLevelList.empty() )
904  {
905  size_t cluster = currentLevelList.front();
906  currentLevelList.pop();
907 
908  if( m_tree.getLevel( cluster ) > 0 )
909  {
910  size_t left = m_tree.getChildren( cluster ).first;
911  size_t right = m_tree.getChildren( cluster ).second;
912 
913  if( m_tree.size( left ) >= size )
914  {
915  nextLevelList.push( left );
916  }
917  else
918  {
919  //finalList.push( left );
920  }
921  if( m_tree.size( right ) >= size )
922  {
923  nextLevelList.push( right );
924  }
925  else
926  {
927  //finalList.push( right );
928  }
929  }
930  else
931  {
932  finalList.push_back( cluster );
933  }
934  }
935 
936  while( !nextLevelList.empty() )
937  {
938  size_t cluster = nextLevelList.front();
939  nextLevelList.pop();
940  currentLevelList.push( cluster );
941  }
942  --num;
943  }
944 
945 
946  while( !currentLevelList.empty() )
947  {
948  size_t cluster = currentLevelList.front();
949  currentLevelList.pop();
950  finalList.push_back( cluster );
951  }
952 
953  int n = 0;
954 
955  for( size_t i = 0; i < finalList.size(); ++i )
956  {
957  size_t cluster = finalList[i];
958  m_tree.colorCluster( cluster, wge::getNthHSVColor( n ) );
960  }
961 
962  m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( finalList ) );
963  //WKernel::getRunningKernel()->getRoiManager()->setExternalBitfield( m_tree.getOutputBitfield( finalList ) );
964 
965  m_biggestClusters.clear();
967 }
968 
969 void WMClusterDisplay::setColor( std::vector<size_t> clusters, WColor color )
970 {
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();
974 
975  for( size_t i = 0; i < clusters.size(); ++i )
976  {
977  size_t current = clusters[i];
978 
979  for( size_t k = (*starts)[current]; k < (*starts)[current] + (*lengths)[current]; ++k)
980  {
981  (*colorField)[k*3] = color[0];
982  (*colorField)[k*3+1] = color[1];
983  (*colorField)[k*3+2] = color[2];
984  }
985  }
986 }
987 
989 {
990  if( m_dendrogramGeode->inDendrogramArea( pos ) )
991  {
992  int x = pos[0];
993  int y = pos[1];
995  return true;
996  }
997  return false;
998 }
999 
1001 {
1002  m_fiberDrawable = osg::ref_ptr< WFiberDrawable >( new WFiberDrawable );
1003  m_fiberDrawable->setBound( m_dataSet->getBoundingBox().toOSGBB() );
1004  m_fiberDrawable->setStartIndexes( m_dataSet->getLineStartIndexes() );
1005  m_fiberDrawable->setPointsPerLine( m_dataSet->getLineLengths() );
1006  m_fiberDrawable->setVerts( m_dataSet->getVertices() );
1007  m_fiberDrawable->setTangents( m_dataSet->getTangents() );
1008  m_fiberDrawable->setColor( m_dataSet->getColorScheme( "Custom Color" )->getColor() );
1009  m_fiberDrawable->setBitfield( m_fiberSelector->getBitfield() );
1010 
1011  m_fiberDrawable->setUseDisplayList( false );
1012  m_fiberDrawable->setDataVariance( osg::Object::DYNAMIC );
1013 
1014  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
1015  geode->addDrawable( m_fiberDrawable );
1016 
1017  m_rootNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
1018  m_rootNode->addChild( geode );
1019 }
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.
Definition: WCondition.h:42
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.
Definition: WGECamera.h:36
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.
Definition: WKernel.cpp:117
std::shared_ptr< WROIManager > getRoiManager()
get for roi manager
Definition: WKernel.cpp:209
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
Definition: WKernel.cpp:122
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.
Definition: WMatrixFixed.h:150
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
std::shared_ptr< WProperties > m_properties
The property object for the module.
Definition: WModule.h:640
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
WPropBool m_active
True whenever the module should be active.
Definition: WModule.h:723
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
Class implements an osgWidget::Box with a label that can be used as a button in the 3D scene.
Definition: WOSGButton.h:42
static boost::filesystem::path getAppPath()
The path where the binary file resides in.
Definition: WPathHelper.cpp:93
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.
Definition: WStringUtils.h:120
WColor getNthHSVColor(int n)
creates the nth color of a partition of the hsv color circle
Definition: WGEUtils.cpp:168