59 #include <boost/regex.hpp>
60 #include <osg/LightModel>
61 #include <osgGA/GUIEventAdapter>
62 #include <osgGA/GUIEventHandler>
63 #include <osgGA/StateSetManipulator>
64 #include <osgGA/TrackballManipulator>
65 #include <osgViewer/ViewerEventHandlers>
66 #include <osgWidget/Util>
67 #include <osgWidget/ViewerEventHandlers>
68 #include <osgWidget/WindowManager>
70 #include "WMHierchClustDisplay.h"
71 #include "core/common/WPathHelper.h"
72 #include "core/common/WPropertyHelper.h"
73 #include "core/common/WStringUtils.h"
74 #include "core/common/algorithms/WMarchingLegoAlgorithm.h"
75 #include "core/graphicsEngine/WGEColormapping.h"
76 #include "core/graphicsEngine/WGEUtils.h"
77 #include "core/kernel/WKernel.h"
78 #include "core/kernel/WROIManager.h"
79 #include "core/kernel/WSelectionManager.h"
84 if( ea.getEventType() == osgGA::GUIEventAdapter::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
88 if( ea.getEventType() == osgGA::GUIEventAdapter::PUSH && ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
97 m_signalLeftButtonPush.connect( slot );
102 m_signalRightButtonPush.connect( slot );
128 return "Hierarchical Clustering Display";
135 return "Visualizes hierarchical clustering in dendrogram tree, texture and 3D seed voxels view";
141 m_input = std::shared_ptr< WModuleInputData < WDataSetSingle > >(
145 m_output = std::shared_ptr< WModuleOutputData < WDataSetVector > >(
149 m_output2 = std::shared_ptr< WModuleOutputData < WDataSetScalar > >(
217 "Selects an intermediate node as partition root.",
224 m_propPartitionSelectionList->addItem(
"Search: min Cluster size diff",
"Search for the partition with minimal cluster size difference" );
267 "Base nodes only containing single leaves will not be subdivided",
277 "Selected cluster colors",
278 WColor( 1.0, 1.0, 1.0, 1.0 ),
281 m_propColorSchemeList->addItem(
"Custom",
"Use custom color values, default is hierarchical tree coloring, can be modified" );
282 m_propColorSchemeList->addItem(
"Partition",
"Disregard custom value and assign color values to selected partition" );
303 "Shows the an info label per selected cluster",
314 "( mesh triangulation is re-done )",
318 "Shows the seed voxel cube triangulation",
329 "Clusters smaller than SafeSize that join clusters bigger than SizeRatio times its size will be pruned" );
331 "Clusters smaller than SafeSize that join clusters bigger than JoinSize will be pruned" );
333 "Clusters smaller than SafeSize that join at a distance level higher than DistanceGap will be pruned" );
335 m_propProcessSelectionsList->addItem(
"Collapse nodes, linear",
"Nodes with branches shorter than DistanceGap * nodeLevel will be collapsed" );
336 m_propProcessSelectionsList->addItem(
"Flatten selection",
"All inner nodes within the currently selected clusters will be collapsed" );
337 m_propProcessSelectionsList->addItem(
"Prune selection",
"currently selected clusters will be eliminated (including contained leaves)" );
401 int height = viewer->getCamera()->getViewport()->height();
402 int width = viewer->getCamera()->getViewport()->width();
417 m_wm =
new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
420 m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
422 m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
423 m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
424 m_camera->setViewMatrix( osg::Matrix::identity() );
425 m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
426 m_camera->setRenderOrder( osg::Camera::POST_RENDER );
431 viewer->addEventHandler(
new osgWidget::MouseHandler(
m_wm ) );
432 viewer->addEventHandler(
new osgWidget::KeyboardHandler(
m_wm ) );
433 viewer->addEventHandler(
new osgWidget::ResizeHandler(
m_wm,
m_camera ) );
434 viewer->addEventHandler(
new osgWidget::CameraSwitchHandler(
m_wm,
m_camera ) );
435 viewer->addEventHandler(
new osgViewer::StatsHandler() );
436 viewer->addEventHandler(
new osgViewer::WindowSizeHandler() );
437 viewer->addEventHandler(
new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
439 m_wm->resizeAllWindows();
449 infoLog() <<
"Init properties...";
598 infoLog() <<
"End Init properties...";
605 infoLog() <<
"Init tree data...";
607 std::shared_ptr< WProgress > progressInitTreeData = std::shared_ptr< WProgress >(
new WProgress(
"Initializing tree data..." ) );
608 m_progress->addSubProgress( progressInitTreeData );
613 infoLog() <<
"Tree was converted to nifti coordinates";
628 for(
size_t j = 0; j < clusterCoords.size(); ++j )
630 size_t voxelID(
m_grid->getVoxelNum( clusterCoords[j].m_x, clusterCoords[j].m_y, clusterCoords[j].m_z ) );
636 for( std::list<WHcoord>::iterator listIter( discarded.begin() ); listIter != discarded.end(); ++listIter )
644 std::vector< size_t > seedVoxelMask;
645 seedVoxelMask.resize(
m_grid->size(), 0 );
648 seedVoxelMask[*iter] = 1;
654 m_grid->getTransformationMatrix(),
659 std::vector< size_t > discardedMask;
660 discardedMask.resize(
m_grid->size(), 0 );
663 discardedMask[*iter] = 1;
669 m_grid->getTransformationMatrix(),
673 progressInitTreeData->finish();
685 size_t currentID( thisID );
686 while( currentID != 0 )
695 if( kids.back().second == currentID )
698 currentID = parentID;
715 if( !kids.back().first )
717 currentID = kids.back().second;
728 size_t colorIndex( 0 );
731 std::list<size_t> worklist;
734 worklist.push_front( i );
736 while( !worklist.empty() )
738 size_t currentID( worklist.front() );
739 worklist.pop_front();
749 if( !kids.back().first )
751 currentID = kids.back().second;
753 worklist.remove( currentID );
766 size_t colorIndex( 0 );
767 std::list<size_t> worklist;
771 std::vector<size_t> initOrder;
775 initOrder.push_back( i );
778 for(
size_t i = 0; i < initOrder.size(); ++i )
780 worklist.push_front( initOrder[i] );
784 while( !worklist.empty() )
786 size_t currentID( worklist.front() );
787 worklist.pop_front();
797 if( !kids.back().first )
799 currentID = kids.back().second;
801 worklist.remove( currentID );
813 std::shared_ptr< WProgress > progressInitTexture = std::shared_ptr< WProgress >(
new WProgress(
"Initializing output texture..." ) );
814 m_progress->addSubProgress( progressInitTexture );
816 osg::ref_ptr< osg::Image > ima =
new osg::Image;
817 ima->allocateImage(
m_grid->getNbCoordsX(),
m_grid->getNbCoordsY(),
m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
818 unsigned char* data = ima->data();
822 for(
unsigned int i = 0; i <
m_grid->size() * 3; ++i )
827 m_texture = osg::ref_ptr<osg::Texture3D>(
new osg::Texture3D );
828 m_texture->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
829 m_texture->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
830 m_texture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER );
831 m_texture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER );
832 m_texture->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER );
834 m_texture->setResizeNonPowerOfTwoHint(
false );
842 progressInitTexture->finish();
844 infoLog() <<
"End Init texture";
878 std::shared_ptr< WDataSetSingle > newDataSet =
m_input->getData();
879 bool dataChanged = (
m_anatomy != newDataSet );
880 bool dataValid = ( newDataSet != NULL );
886 m_grid = std::dynamic_pointer_cast< WGridRegular3D >(
m_anatomy->getGrid() );
902 infoLog() <<
"Loading tree file";
913 infoLog() <<
"Invalid tree file";
947 infoLog() <<
"Loading tree file";
949 std::shared_ptr< WProgress > progressLoadTree = std::shared_ptr< WProgress >(
new WProgress(
"Loading tree from file..." ) );
950 m_progress->addSubProgress( progressLoadTree );
956 infoLog() <<
"Invalid tree file";
957 progressLoadTree->finish();
961 progressLoadTree->finish();
963 std::string message(
"Tree \""+
m_tree.
getName()+
"\" loaded. " +
1051 std::string message(
"Single cluster at distance: " +
1079 std::string message(
"Single cluster at distance: " +
1355 std::shared_ptr< WProgress > progressProcessing = std::shared_ptr< WProgress >(
new WProgress(
"Processing tree..." ) );
1356 m_progress->addSubProgress( progressProcessing );
1358 std::pair<size_t, size_t> prunedElements( 0, 0 );
1360 std::string message;
1366 message =
"Pruning by ratio: ";
1370 message =
"Pruning by join size: ";
1374 message =
"Pruning by join level: ";
1378 message =
"Random Pruning: ";
1382 message =
"Node Collapsing, linear: ";
1386 message =
"Selection Flattened: ";
1390 message =
"Selection Pruned: ";
1396 progressProcessing->finish();
1428 infoLog() <<
"Clearing partitions";
1444 infoLog() <<
"Writing tree file";
1453 infoLog() <<
"Writing partition files";
1477 std::shared_ptr< WProgress > progressRenderCubes = std::shared_ptr< WProgress >(
new WProgress(
"Rendering seed voxels..." ) );
1478 m_progress->addSubProgress( progressRenderCubes );
1481 osg::Geometry* surfaceGeometry =
new osg::Geometry();
1482 osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
1484 outputGeode->setName( std::string(
"seed voxels" ) );
1485 surfaceGeometry->setVertexArray(
m_cubeMesh->getVertexArray() );
1490 surfaceGeometry->setNormalArray(
m_cubeMesh->getVertexNormalArray(
true ) );
1491 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
1497 std::vector<WHcoord> searchCoords;
1499 searchCoords.reserve( 8 );
1500 for(
int cz = 0; cz < 2; ++cz )
1502 for(
int cy = 0; cy < 2; ++cy )
1504 for(
int cx = 0; cx < 2; ++cx )
1506 searchCoords.push_back(
WHcoord( cx, cy, cz ) );
1512 std::vector<std::map<size_t, WColor>::const_reverse_iterator> colorTable;
1514 for( std::map< size_t, WColor >::const_reverse_iterator colorIter(
m_selectionColors.rbegin() );
1518 colorTable.push_back( colorIter );
1521 osg::Vec4Array* cubeMeshColors =
new osg::Vec4Array;
1523 for(
size_t i = 0; i <
m_cubeMesh->getVertexArray()->getNumElements(); ++i )
1526 unsigned int vX(
m_cubeMesh->getVertex( i ).x() );
1527 if( vX >=
m_grid->getNbCoordsX() )
1529 vX =
m_grid->getNbCoordsX()-1;
1531 unsigned int vY(
m_cubeMesh->getVertex( i ).y() );
1532 if( vY >=
m_grid->getNbCoordsY() )
1534 vY =
m_grid->getNbCoordsY()-1;
1536 unsigned int vZ(
m_cubeMesh->getVertex( i ).z() );
1537 if( vZ >=
m_grid->getNbCoordsZ() )
1539 vZ =
m_grid->getNbCoordsZ()-1;
1542 size_t colorLabel( 0 );
1543 for(
size_t j = 0; j < searchCoords.size(); ++j )
1545 if( ( (
static_cast<int>( vX ) )-searchCoords[j].m_x ) < 0 ||
1546 ( (
static_cast<int>( vY ) )-searchCoords[j].m_y ) < 0 ||
1547 ( (
static_cast<int>( vZ ) )-searchCoords[j].m_z ) < 0 )
1552 colorLabel =
m_textureLabels[
m_grid->getVoxelNum( vX-searchCoords[j].m_x, vY-searchCoords[j].m_y, vZ-searchCoords[j].m_z )];
1570 cubeMeshColors->push_back( colorTable[colorLabel-1]->second );
1574 surfaceGeometry->setColorArray( cubeMeshColors );
1575 surfaceGeometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
1578 osg::DrawElementsUInt* surfaceElement =
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
1580 std::vector< size_t >tris =
m_cubeMesh->getTriangles();
1581 surfaceElement->reserve( tris.size() );
1583 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
1585 surfaceElement->push_back( tris[vertId] );
1587 surfaceGeometry->addPrimitiveSet( surfaceElement );
1588 outputGeode->addDrawable( surfaceGeometry );
1590 osg::StateSet* state = outputGeode->getOrCreateStateSet();
1591 osg::ref_ptr<osg::LightModel> lightModel =
new osg::LightModel();
1592 lightModel->setTwoSided(
true );
1593 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
1594 state->setMode( GL_BLEND, osg::StateAttribute::ON );
1602 osg::Geometry* surfaceGeometry =
new osg::Geometry();
1603 osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >(
new osg::Geode );
1605 outputGeode->setName( ( std::string(
"non active" ) ).c_str() );
1612 surfaceGeometry->setNormalArray(
m_discardedMesh->getVertexNormalArray(
true ) );
1613 surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
1617 osg::Vec4Array* discardedColor =
new osg::Vec4Array;
1619 surfaceGeometry->setColorArray( discardedColor );
1620 surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
1622 osg::DrawElementsUInt* surfaceElement =
new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
1625 surfaceElement->reserve( tris.size() );
1627 for(
unsigned int vertId = 0; vertId < tris.size(); ++vertId )
1629 surfaceElement->push_back( tris[vertId] );
1631 surfaceGeometry->addPrimitiveSet( surfaceElement );
1632 outputGeode->addDrawable( surfaceGeometry );
1634 osg::StateSet* state = outputGeode->getOrCreateStateSet();
1635 osg::ref_ptr<osg::LightModel> lightModel =
new osg::LightModel();
1636 lightModel->setTwoSided(
true );
1637 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
1638 state->setMode( GL_BLEND, osg::StateAttribute::ON );
1642 progressRenderCubes->finish();
1651 int totalHeight = viewer->getCamera()->getViewport()->height();
1652 int totalWidth = viewer->getCamera()->getViewport()->width();
1654 const unsigned int labelHeight = 20;
1655 const unsigned int labelWidth = 100;
1656 int labelRows = ( totalHeight - 20 ) / labelHeight;
1666 bool buttonClicked(
false );
1683 buttonClicked =
true;
1693 std::shared_ptr< WProgress > progressUpdateWidgets = std::shared_ptr< WProgress >(
new WProgress(
"Updating widgets..." ) );
1694 m_progress->addSubProgress( progressUpdateWidgets );
1696 int usedXoffset( 0 );
1697 int usedWidth( totalWidth );
1698 int usedHeight( totalHeight/2 );
1699 int usedYoffset( 0 );
1708 usedWidth = ( usedWidth-30 )/2;
1712 usedXoffset += ( usedWidth/2 ) + 5;
1713 usedWidth = ( usedWidth-30 )/2;
1737 std::vector<std::pair<float, size_t> > labelPairs;
1746 value = thisCluster.
getID();
1749 value = thisCluster.
getSize();
1760 labelPairs.push_back( std::make_pair( value, thisCluster.
getID() ) );
1763 std::sort( labelPairs.begin(), labelPairs.end() );
1764 for(
size_t i = 0; i < labelPairs.size(); ++i )
1766 std::string labelString;
1767 if( labelPairs[i].first<1 && labelPairs[i].first>0 )
1769 labelString = ( str( boost::format(
"%.05f" ) % labelPairs[i].first ) );
1773 labelString = ( str( boost::format(
"%-6d" ) % labelPairs[i].first ) );
1776 osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>(
new WOSGButton( labelString, osgWidget::Box::VERTICAL,
true,
true ) );
1777 newButton->setPosition( osg::Vec3( ( i / labelRows ) * labelWidth + usedXoffset, ( i % labelRows ) * 20.f, 0 ) );
1778 newButton->setId( labelPairs[i].second );
1780 newButton->managed(
m_wm );
1781 m_wm->addChild( newButton );
1796 m_wm->resizeAllWindows();
1809 progressUpdateWidgets->finish();
1891 std::vector<nodeID_t> kids( current.
getChildren() );
1892 for(
unsigned int i = 0; i < kids.size(); ++i )
1912 std::vector<nodeID_t> kids( current.
getChildren() );
1913 for(
unsigned int i = 0; i < kids.size(); ++i )
1927 std::shared_ptr< WProgress > progressUpdateSelection = std::shared_ptr< WProgress >(
new WProgress(
"Updating selection..." ) );
1928 m_progress->addSubProgress( progressUpdateSelection );
1947 infoLog() <<
"Error at color assignment";
1966 infoLog() <<
"Error at color assignment";
1973 infoLog() <<
"Preloaded colors";
1987 progressUpdateSelection->finish();
2002 std::shared_ptr< WProgress > progressUpdateColors = std::shared_ptr< WProgress >(
new WProgress(
"Updating colors..." ) );
2003 m_progress->addSubProgress( progressUpdateColors );
2028 std::vector<std::map<size_t, WColor>::const_reverse_iterator> colorTable;
2031 size_t thisLabel = 1;
2032 for( std::map< size_t, WColor >::const_reverse_iterator revIter(
m_selectionColors.rbegin() );
2041 colorTable.push_back( revIter );
2058 for(
size_t i = 0; i <
m_grid->size(); ++i )
2066 std::vector<size_t> nbors(
m_grid->getNeighbours27( i ) );
2069 for(
size_t j = 0; j < nbors.size(); ++j )
2071 size_t nbID( nbors[j] );
2073 if( nbLabel == discardedLabel || nbLabel == 0 || nbLabel == filteredLabel || nbLabel== thisLabel )
2099 unsigned char* data =
m_texture->getImage()->data();
2100 for(
size_t i = 0; i <
m_grid->size(); ++i )
2102 WColor color( 0, 0, 0, 1 );
2117 data[i * 3 ] = color[0] * 255;
2118 data[i * 3 + 1] = color[1] * 255;
2119 data[i * 3 + 2] = color[2] * 255;
2126 WAssert(
m_anatomy->getValueSet(),
"" );
2129 std::shared_ptr< std::vector< unsigned char > >ptr(
new std::vector< unsigned char >(
m_textureLabels.size() * 3 ) );
2133 ptr->at( i ) = data[i];
2136 std::shared_ptr< WValueSet< unsigned char > > vs =
2139 std::shared_ptr< WGridRegular3D> grid =
2147 progressUpdateColors->finish();
2158 std::shared_ptr< WProgress > progressUpdateOutput2 = std::shared_ptr< WProgress >(
new WProgress(
"Updating Output 2 ( coordinates )..." ) );
2159 m_progress->addSubProgress( progressUpdateOutput2 );
2161 std::shared_ptr< std::vector< int > >coordPtr(
new std::vector< int >() );
2163 for( std::vector<WHcoord>::iterator coordIter( coordinates.begin() ); coordIter != coordinates.end(); ++coordIter )
2165 coordPtr->push_back( coordIter->m_x );
2166 coordPtr->push_back( coordIter->m_y );
2167 coordPtr->push_back( coordIter->m_z );
2172 for( std::list<WHcoord>::iterator discardedIter( discarded.begin() ); discardedIter != discarded.end(); ++discardedIter )
2174 coordPtr->push_back( discardedIter->m_x );
2175 coordPtr->push_back( discardedIter->m_y );
2176 coordPtr->push_back( discardedIter->m_z );
2179 std::shared_ptr< WValueSet< int > > vs = std::shared_ptr< WValueSet< int > >(
new WValueSet< int >( 0, 1, coordPtr, W_DT_INT16 ) );
2180 std::shared_ptr< WGridRegular3D> grid = std::shared_ptr< WGridRegular3D>(
2186 progressUpdateOutput2->finish();
2196 infoLog() <<
"Partition empty, partition file not written";
2201 std::ofstream streamFile( partitionFilename.string() );
2204 errorLog() <<
"ERROR: unable to open partition file: \"" << partitionFilename <<
"\"";
2211 size_t thisID( thisNode.
getID() );
2213 for(
size_t j = 0; j < thisCoords.size(); ++j )
2215 streamFile << thisCoords[j] <<
" " << thisID << std::endl;
2223 std::shared_ptr< WProgress > progressPartition = std::shared_ptr< WProgress >(
new WProgress(
"Finding partition..." ) );
2224 m_progress->addSubProgress( progressPartition );
2226 std::vector<nodeID_t> partition;
2227 std::vector< size_t > selectedPartition;
2228 std::vector< WHcoord > selectedColors;
2229 std::vector< WColor > partitionColors;
2231 float returnedCutValue( 0 );
2232 float conditionValue( 0 );
2233 float relativeCoefficient( 0 );
2234 HT_CONDITION conditionMode( HTC_CNUM );
2235 HT_PARTMODE partitionMode1( HTP_HOZ );
2236 HT_PARTMODE2 partitionMode2( HTP2_CSD );
2243 partitionMode1 = HTP_HOZ;
2245 relativeCoefficient = 0.01;
2248 partitionMode1 = HTP_HLEVEL;
2253 partitionMode2 = HTP2_CSD;
2258 partitionMode2 = HTP2_OPT;
2273 conditionMode = HTC_CNUM;
2276 conditionMode = HTC_VALUE;
2280 conditionMode = HTC_VALUE;
2316 infoLog() <<
"tree has no partitions";
2324 infoLog() <<
" Partition index is negative";
2333 partition.reserve( selectedPartition.size() );
2335 for(
size_t i = 0; i < selectedPartition.size(); ++i )
2337 partition.push_back( std::make_pair(
true, selectedPartition[i] ) );
2349 size_t totalLeafClusterNum( 0 ), totalNodeClusterNum( 0 );
2352 std::vector<size_t> empty1, empty2, empty3;
2356 partitionColors.clear();
2357 size_t addIndex( partition.size() );
2359 for(
size_t i = 0; i < partition.size(); ++i )
2361 if( partition[i].first )
2364 ++totalNodeClusterNum;
2366 if( partition.size() == selectedColors.size() )
2368 float Rcolor( selectedColors[i].m_x/ 255.0 );
2369 float Gcolor( selectedColors[i].m_y/ 255.0 );
2370 float Bcolor( selectedColors[i].m_z/ 255.0 );
2371 WColor thisColor( Rcolor, Gcolor, Bcolor, 1.0 );
2374 if( thisColor == WColor( 0, 0, 0, 1 ) )
2380 partitionColors.push_back( thisColor );
2387 ++totalLeafClusterNum;
2404 progressPartition->finish();
2413 std::random_device rd;
2414 std::mt19937 g( rd() );
2417 bool doUpdateSelection(
true );
2424 std::vector<WColor> shuffledColors;
2430 shuffledColors.push_back( cIter->second );
2432 std::shuffle( shuffledColors.begin(), shuffledColors.end(), g );
2436 cIter->second = shuffledColors[i++];
2440 doUpdateSelection =
false;
2457 doUpdateSelection =
false;
2468 doUpdateSelection =
false;
2486 if( doUpdateSelection )
2503 infoLog() <<
"Selection is empty. Partition was not added";
2507 infoLog() <<
"Selection is trivial. Partition was not added";
2511 infoLog() <<
"Adding current partition to tree file";
2519 std::vector< WHcoord > addedPartColor;
2524 WHcoord thisColorCoord( thisColor.r()*255, thisColor.g()*255, thisColor.b()*255 );
2525 addedPartColor.push_back( thisColorCoord );
2527 partColors.push_back( addedPartColor );
2536 std::cout <<
"Tree now has " << partValues.size() <<
" partitions saved of sizes: " << std::flush;
2537 for(
size_t i = 0; i < partSet.size(); ++i )
2539 std::cout << partSet[i].size() <<
"," << std::flush;
2541 std::cout << std::endl;
2550 infoLog() <<
"WARNING: Selection is empty. Nothing was done";
2556 infoLog() <<
"WARNING: Partitions already had assigned colors... they will be replaced";
2561 std::vector< std::vector< WHcoord > > partColors;
2562 partColors.reserve( partValues.size() );
2564 for(
size_t i = 0; i < partSet.size(); ++i )
2566 std::vector< WHcoord > addedPartColor;
2567 addedPartColor.reserve( partSet[i].size() );
2568 for(
size_t j = 0; j < partSet[i].size(); ++j )
2571 WHcoord thisColorCoord( thisColor.r()*255, thisColor.g()*255, thisColor.b()*255 );
2572 addedPartColor.push_back( thisColorCoord );
2574 partColors.push_back( addedPartColor );
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.
This data set type contains vectors as values.
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.
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
A grid that has parallelepiped cells which all have the same proportion.
this class to contain a seed voxel coordinate.
this class implements a hierarchical tree node with several relevant attributes
size_t getSize() const
returns number of elements contained by the node
size_t getHLevel() const
returns maximum number of nodes between the node and a leaf element
bool isRoot() const
returns true if object is the root of the tree
size_t getID() const
returns node/leaf ID
std::string printAllData() const
prints out a string with the node data, in order to implement the operator <<
dist_t getDistLevel() const
returns distance level at which the element was formed
nodeID_t getParent() const
returns parent ID
std::vector< nodeID_t > getChildren() const
returns a vector with the ids of the children of that node
this class operates over the class WHtree to extract partitions and analyze partition quality it may ...
float partitionClassic(float compValue, std::vector< nodeID_t > *const partition, const HT_PARTMODE mode, const HT_CONDITION condition, const bool excludeLeaves, const size_t root) const
Gets a classic partition for the tree (those where clusters are further subdivided until a condition ...
float partitionSharp(const float compValue, std::vector< nodeID_t > *const partition, const bool excludeLeaves, const size_t root, const bool normalized) const
Finds clusters with sharp boundaries (long branches) the tree.
float partitionOptimized(float compValue, std::vector< nodeID_t > *const partition, const HT_PARTMODE2 mode, const HT_CONDITION condition, const bool excludeLeaves, const size_t root, const size_t levelDepth) const
Gets an optimized partition for the tree (those where a partition characteristic must be cosnidered f...
this class implements methods for dendrogram processing, such as pruning, node collapsing and decimat...
std::pair< size_t, size_t > pruneRandom(const size_t numberPruned, unsigned int seed=0)
Prunes the tree from randomly chosen leaves.
size_t collapseTreeLinear(const dist_t coefficient, const bool keepBaseNodes)
Collapses the nodes of the tree that have branch lenghts smoller than the distance level multiplied b...
size_t flattenSelection(const std::list< size_t > selection, const bool keepBaseNodes)
Collapses all the nodes of the subtrees indicated (using only non-leaf node ID)
std::pair< size_t, size_t > pruneSelection(const std::vector< size_t > &selection)
Prunes all of the subtrees indicated (using only non-leaf node ID)
std::pair< size_t, size_t > pruneTree(float condition, size_t safeSize, const HTPROC_MODE pruneType)
Prunes the tree according to the options specified.
size_t getNumDiscarded() const
Returns the number of leaves of the tree.
std::vector< size_t > getRootBaseNodes() const
returns a vector with all the nodes that have direct link to leaves from the main root
const WHnode & getRoot() const
returns a const reference to the root node
size_t getNumNodes() const
Returns the number of nodes of the tree.
std::vector< WHcoord > getCoordinates4node(const size_t nodeID) const
Returns a vector with all the seed voxel coordinates contained in that cluster.
void insertPartitions(const std::vector< std::vector< size_t > > &selectedPartitions, const std::vector< float > &selectedValues, const std::vector< std::vector< WHcoord > > &selectedColors=std::vector< std::vector< WHcoord > >())
insert a set of partitions into the tree data
const WHnode & getNode(const nodeID_t &thisNode) const
returns a const pointer to the node indicated by the ID
std::vector< std::vector< size_t > > getSelectedPartitions() const
Returns the set of the selected partitions.
std::list< WHcoord > getDiscarded() const
Returns the discarded list.
void clearPartitions()
delete all data related to saved partitions
void sortBySize(std::vector< size_t > *const nodeVector) const
Reorders the nodes in the vector according to their size.
bool isLoaded() const
Returns the loading status of the tree.
std::vector< float > getSelectedValues() const
Returns the cutting values for the selected partitions.
std::string getName() const
Returns the tree name.
bool writeTree(const std::string &filename, const bool isNifti=true) const
writes the current tree data
bool convert2grid(const HC_GRID newGrid)
converts all the coordinates to the grid format indicated
float getCpcc() const
Returns the cpcc value of the tree.
bool readTree(const std::string &filename)
Reads the the tree data from a file and creates the structure, containing it in the leaves,...
std::vector< std::vector< WHcoord > > getSelectedColors() const
Returns the set of the selected partition colors.
size_t getNumLeaves() const
Returns the number of leaves of the tree.
std::vector< WHcoord > getRoi() const
Returns the roi coordinate vector.
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.
Small event handler class to catch left mouse buttons clicks in the main view.
void subscribeLeftButtonPush(mouseClickSignalType::slot_type slot)
Registers a function slot to LEFT BUTTON PUSH events.
bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &)
The OSG calls this function whenever a new event has occured.
mouseClickSignalType m_signalLeftButtonPush
Signal used for notification of the LEFT BUTTON PUSH event.
mouseClickSignalType m_signalRightButtonPush
Signal used for notification of the RIGHT BUTTON PUSH event.
void subscribeRightButtonPush(mouseClickSignalType::slot_type slot)
Registers a function slot to RIGHT BUTTON PUSH events.
WPropInt m_infoCountLeaves
Info property: number of leaves.
WPropTrigger m_propPartitionsTrigger
This property triggers the actual writing of the partition file.
osg::ref_ptr< WGEGroupNode > m_dendrogramNode
Pointer to the dendrogram group node.
void initializeColorsSize()
Assigns a default color to each node travelling the tree top-down based on dividing first the biggest...
WPropGroup m_groupSavedPartition
grouping the partition options
WPropGroup m_groupTreeProcess
grouping the different tree processing methods
std::vector< std::vector< size_t > > m_clusterVoxels
stores the contained seed voxel IDs for each cluster, increases speed for texture drawing
std::shared_ptr< WItemSelection > m_propProcessSelectionsList
A list of cluster selection methods.
WPropDouble m_propFlatLimit
distance gap for prunin process
virtual std::shared_ptr< WModule > factory() const
new instance of this module Due to the prototype design pattern used to build modules,...
WPropInt m_propPrunedSeed
rng seed for random pruning
void colorBranchCustom(const size_t &root, const WColor &color)
recursive function that fills the display colors for a whole branch with a custom color from a scheme...
int m_oldViewWidth
stores the old viewport resolution width to check whether a resize happened
WPropBool m_propBoundaries
visualize only parcel boundaries
WPropGroup m_groupInfoPartition
grouping the partition info
void renderCubeMesh()
renders the triangulated seed voxels
std::shared_ptr< WModuleInputData< WDataSetSingle > > m_input
An input connector that accepts order 1 datasets.
std::shared_ptr< WModuleOutputData< WDataSetScalar > > m_output2
An output connector for the output coordinate vector.
WPropInt m_infoMaxLevel
Info property: maximum hierarchical level.
WNonBinDendroGeode * m_dendrogramGeode
stores the dendrogram geode
WPropInt m_propDendroOffsetY
controls the vertical origin of the dendrogram
WPropGroup m_groupWrite
grouping the tree writing
void updateSelection(const std::vector< WColor > &preloadedColors=std::vector< WColor >())
after the active cluster list has changed this function updates the texture, cubeMesh,...
void clusterSelection()
manages cluster selection action response
WPropGroup m_groupDendroManual
grouping the dendrogram manual resizing properties
WPropDouble m_propPartDistanceValue
distance cut value for the desired partition
osg::Camera * m_camera
stores the camera object
WPropColor m_propInactiveColor
color for inactive mesh voxels
std::shared_ptr< WDataSetVector > m_outData
This is a pointer to the current output1.
osgWidget::WindowManager * m_wm
stores a pointer to the window manager used for osg wdgets and overlay stuff
float m_horizontalLine
to draw a horizontal line when theres distance partition cutting
void updateColors()
updates the selection colors
std::vector< size_t > m_textureLabels
label vector for texture creation
WPropTrigger m_propRecolorPartTrigger
This property triggers the recoloring partition of the current partitions.
WPropSelection m_propColorActionSelector
selection of color schemes
WPropInt m_propDendroOffsetX
controls the horizontal origin of the dendrogram
WPropDouble m_infoCpcc
Info property: cpcc value.
std::map< size_t, WColor > m_selectionColorsBackup
stores a backup of m_selectionColors
WPropSelection m_propPartitionSelector
Selection property for clusters.
WPropGroup m_groupRead
grouping the tree loading
WPropBool m_propShowDiscarded
visualize also discarded voxels
bool dendrogramClickRight(const WVector2f &pos)
handles right clicks into the dendrogram
WPropGroup m_groupInfoMessage
grouping the message info
std::shared_ptr< WGridRegular3D > m_grid
stores a pointer to the grid we use;
WPropDouble m_propPruneSizeRatio
size ratio for pruning process
std::shared_ptr< WItemSelection > m_propColorActionList
List of color schemes.
WPropTrigger m_propClearPartsTrigger
This property triggers the clearing of current partitions in the tree.
bool dendrogramClick(const WVector2f &pos)
handles clicks into the dendrogram
int m_oldViewHeight
stores the old viewport resolution height to check whether a resize happened
WPropDouble m_propDistanceGap
distance gap for prunin process
WPropInt m_infoCountDiscarded
Info property: number of discarded voxels.
virtual void connectors()
Initialize the connectors this module is using.
virtual void moduleMain()
Entry point after loading the module. Runs in separate thread.
WPropTrigger m_propPartRoot
triggers the selection of root cluster
std::shared_ptr< WCondition > m_propTriggerChange
A condition used to notify about changes in several properties.
WPropTrigger m_propWriteTreeTrigger
This property triggers the actual writing of the tree file.
void addPartitions()
Adds partitions form current selections into the tree object.
void updateWidgets()
updates the graphical widgets in the 3d scene
std::shared_ptr< WItemSelection > m_propColorSchemeList
List of color schemes.
WPropBool m_propShowDendrogram
controls the display of the dendrogram overlay
void initWidgets()
inits the graphical widgets in the 3d scene
virtual const std::string getName() const
Gives back the name of this module.
WPropBool m_propShowLabels
show info labels for selected clusters
osg::ref_ptr< WGEShader > m_shader
The shader.
std::shared_ptr< WItemSelection > m_propPartitionSelectionList
A list of cluster selection methods.
std::shared_ptr< WModuleOutputData< WDataSetVector > > m_output
An output connector for the output scalar dsataset.
void assignColorHierch(const size_t thisID, const WColor thisColor)
Uses the provided node Id and color to update the current tree default coloring using hierarchical in...
size_t m_treeZoomRoot
control variable for tree zoom mode
std::vector< size_t > m_discardedVoxels
stores the contained seed voxel IDs for discarded elements
WPropGroup m_groupVisualization
grouping the different visualization options
std::shared_ptr< WDataSetSingle > m_anatomy
This is a pointer to the anatomy dataset the module is currently working on.
std::shared_ptr< WTriangleMesh > m_cubeMesh
Cube-like triangulation of the seed voxels.
WPropSelection m_propConditionSelector
Selection condition for clusters.
WPropInt m_propPrunedNumber
number of leaves to be pruned by random pruning
WPropFilename m_propWriteTreeFilename
The tree file will be written to this location.
bool m_treeDirty
true if the dendrogram needs redrawing
virtual void properties()
Initialize the properties for this module.
WPropDouble m_infoCutValue
Info property: cut value for current partition.
WPropColor m_propSubselectedcolor
color for subselected cluster
WPropFilename m_propPartitionFile
The partition file will be written to this location.
WPropSelection m_propColorSchemeSelector
selection of color schemes
WPropInt m_propSafeSize
maximum size to be pruned
void writePartition()
writes partition selection(s) in an ascii file
WMHierchClustDisplay()
Constructor.
WPropInt m_propSourceCluster
the current subtree root cluster
void colorAction()
manages action after the trigger of the color section has been pressed
bool m_labelsDirty
true if the labels need redrawing
WPropTrigger m_propDendroZoomOut
zooms out, m_treeZoom = false, dendrogram shows the whole tree
void initProperties()
updates property min/max values after loading a clustering file
WPropInt m_infoSelectedID
Info property: clusters in current partition.
WPropTrigger m_propDoProcessing
triggers the tree processing
WPropGroup m_groupInfoSelected
grouping the selected info
std::shared_ptr< WItemSelection > m_propDendroSideList
A list of dendrogram positions.
WPropInt m_propPartSearchDepthValue
depth of search for optimized partitioning
std::shared_ptr< WTriangleMesh > m_discardedMesh
Cube-like triangulation of the discarded voxels.
WPropSelection m_propDendroSideSelector
Selection property for dendrogram positions.
WPropInt m_propPartNumClusters
number of clusters of the desired partition
WPropInt m_infoPartNumber
Info property: clusters in current partition.
void initializeColorsHdist()
Assigns a default color to each node travelling the tree top-down based on hierarchy where the bigges...
WPropBool m_propShowCubeMesh
visualize voxel cube triangulation
void initTexture()
creates a texture, assigning the colouring of the current partition to the respective seed voxels in ...
WPropGroup m_groupInfoTree
grouping the tree info
WPropTrigger m_propColorActionTrigger
shuffle current colors
WHtree m_tree
stores the tree object as loaded from file;
WPropTrigger m_propAddPartTrigger
This property triggers the inclusion in the tree of the current partition.
WPropString m_infoPartMessage
Info property: partition output message.
std::vector< WColor > m_treeDisplayColors
stores a the current colors each tree node should be displayed, given the current selection
WPropTrigger m_propReadTreeTrigger
This property triggers the actual reading of the tree file.
WPropInt m_propPruneJoinSize
join size for pruning process
WPropInt m_infoSelectedDistance
Info property: clusters in current partition.
WPropBool m_propTriangleLeaves
specifies a minimum size for a cluster so that too small cluster won't get an own color
std::vector< osg::ref_ptr< WOSGButton > > m_selectionLabels
list of buttons for the active cluster selection
WPropInt m_propDendroSizeY
controls the height of the dendrogram
WPropBool m_propDendroPlotByLevel
controls plotting the height of a join (1 plots the tree by hierarchical level, 0 by cluster distance...
WPropInt m_propPartHlevelValue
hierarchical level cut value for the desired partition
WPropDouble m_propPartRelativeValue
Relative size cut value for the desired partition.
std::shared_ptr< WItemSelection > m_propConditionSelectionsList
A list of condition selection methods.
osg::ref_ptr< WGEGroupNode > m_meshNode
Pointer to the cube mesh group node.
WPropGroup m_groupDendrogram
grouping the dendrogram manipulation properties
WPropTrigger m_propDendroZoomIn
zoom into tree, sets m_treeZoom true and m_zoomRoot to the currently selected cluster
WPropInt m_propPartSizeValue
size cut value for the desired partition
void recolorPartitions()
recolors added partitions from the tree object with current selection set of colors
WPropString m_infoTreeName
Info property: current tree name.
WPropColor m_propBoundaryColor
color for cluster boundaries
osg::ref_ptr< WGEGroupNode > m_moduleNode
Pointer to the modules group node.
std::shared_ptr< WItemSelection > m_propLabelList
List of label contents.
WPropInt m_infoPartActive
Info property: active clusters in current partition.
WPropColor m_propDiscardedColor
color for discarded voxels
std::shared_ptr< WDataSetScalar > m_outData2
This is a pointer to the current output2.
WPropTrigger m_propDoPartition
triggers the cluster selection update
WPropInt m_propSubselectedCluster
the currently selected cluster
osg::ref_ptr< osg::Texture3D > m_texture
stores a pointer to the texture we paint in (to overlay to anatomy)
std::map< size_t, WColor > m_selectionColors
stores a the current colors each cluster should be displayed, given the current selection
void updateOutput2()
updates the voxels coordinate output
WPropInt m_infoSelectedSize
Info property: clusters in current partition.
void initTreeData()
initializes properties depending on the specific tree structure loaded
virtual ~WMHierchClustDisplay()
Destructor.
void colorBranch(const size_t &root, const WColor &color)
recursive function that fills the display colors for a whole branch with a selected color
WPropSelection m_propProcessSelector
Selection property for processing.
WPropInt m_propPreloadPartitionNr
predefined partition to load
std::vector< size_t > m_selectionClusters
stores the currently activated clusters
virtual const std::string getDescription() const
Gives back a description of this module.
WPropGroup m_groupPartition
grouping the different selection methods
WPropBool m_propKeepBases
dont debinarize basenodes
std::vector< size_t > m_selectionLeaves
stores the leaves output by the selection
WPropFilename m_propReadFilename
The tree file will be loaded form this directory.
WPropBool m_propPartExcludeLeaves
defines if base nodes will be subdivided or not
std::vector< WColor > m_nodeColorsCustom
stores preset color for every tree node, so clusters keep same color through different selection
WPropSelection m_propLabelInfoSelector
selection of info on button labels
WPropInt m_propDendroSizeX
controls the width of the dendrogram
WPropInt m_infoPartLeaves
Info property: leaf clusters in current partition.
WPropInt m_infoCountNodes
Info property: number of nodes.
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).
A fixed size matrix class.
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.
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.
wlog::WStreamedLogger errorLog() const
Logger instance for comfortable error logging.
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.
wlog::WStreamedLogger infoLog() const
Logger instance for comfortable info logging.
virtual void connectors()
Initialize connectors in this function.
Class creates a dendrogram from a hierarchical clustering, and allows to click and select specific no...
bool inDendrogramArea(int xClick, int yClick) const
calculates if the given position is within the view area of the dendrogram
size_t getClickedCluster(int xClick, int yClick)
calculate which cluster was clicked from given pixel coordinates
Class managing progress inside of modules.
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