WMClusterDisplay.cpp 34.4 KB
Newer Older
1 2 3 4
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#include <queue>
#include <string>
#include <vector>

#include <boost/regex.hpp>

31 32
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIEventHandler>
33
#include <osgGA/StateSetManipulator>
34
#include <osgGA/TrackballManipulator>
35 36 37 38 39
#include <osgViewer/ViewerEventHandlers>
#include <osgWidget/Util> //NOLINT
#include <osgWidget/ViewerEventHandlers> //NOLINT
#include <osgWidget/WindowManager> //NOLINT

40
#include "core/common/WStringUtils.h"
41 42 43 44 45
#include "core/common/WPathHelper.h"
#include "core/common/WPropertyHelper.h"
#include "core/graphicsEngine/WGEUtils.h"
#include "core/kernel/WKernel.h"
#include "core/kernel/WROIManager.h"
46
#include "core/ui/WUIViewWidget.h"
47

48
#include "WMClusterDisplay.h"
49
#include "WMClusterDisplay.xpm"
50 51 52 53

// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
W_LOADABLE_MODULE( WMClusterDisplay )

54 55 56 57 58 59

bool WMClusterDisplay::MainViewEventHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */ )
{
//    wlog::debug( "WMClusterDisplay::MainViewEventHandler" ) << "handle";
    if( ea.getEventType() == GUIEvents::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
    {
60
        return ( true == m_signalLeftButtonPush( WVector2f( ea.getX(), ea.getY() ) ) );
61 62 63 64 65 66 67 68 69
    }
    return false;
}

void WMClusterDisplay::MainViewEventHandler::subscribeLeftButtonPush( LeftButtonPushSignalType::slot_type slot )
{
    m_signalLeftButtonPush.connect( slot );
}

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
WMClusterDisplay::WMClusterDisplay():
    WModule(),
    m_widgetDirty( false ),
    m_biggestClusterButtonsChanged( false ),
    m_dendrogramDirty( false ),
    m_labelMode( 0 )
{
}

WMClusterDisplay::~WMClusterDisplay()
{
    // Cleanup!
}

boost::shared_ptr< WModule > WMClusterDisplay::factory() const
{
    // See "src/modules/template/" for an extensively documented example.
    return boost::shared_ptr< WModule >( new WMClusterDisplay() );
}

const char** WMClusterDisplay::getXPMIcon() const
{
92
    return clusterDisplay_xpm; // Please put a real icon here.
93 94 95
}
const std::string WMClusterDisplay::getName() const
{
96
    return "Cluster Display";
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
}

const std::string WMClusterDisplay::getDescription() const
{
    // Specify your module description here. Be detailed. This text is read by the user.
    // See "src/modules/template/" for an extensively documented example.
    return "This module loads a text file containing the hierarchical tree representation of a fiber clustering"
            " and provides selection appropriate tools";
}

void WMClusterDisplay::connectors()
{
    using boost::shared_ptr;
    typedef WModuleInputData< const WDataSetFibers > FiberInputData;  // just an alias

    m_fiberInput = shared_ptr< FiberInputData >( new FiberInputData( shared_from_this(), "fiberInput", "A loaded fiber dataset." ) );

114
    addConnector( m_fiberInput );
115 116 117 118 119 120 121 122 123 124 125 126
    // call WModules initialization
    WModule::connectors();
}

std::vector< std::string > WMClusterDisplay::readFile( const std::string fileName )
{
    std::ifstream ifs( fileName.c_str(), std::ifstream::in );

    std::vector< std::string > lines;

    std::string line;

127
    if( ifs.is_open() )
128 129 130 131 132 133 134 135 136 137 138 139
    {
        debugLog() << "trying to load " << fileName;
        debugLog() << "file exists";
    }
    else
    {
        debugLog() << "trying to load " << fileName;
        debugLog() << "file doesn\'t exist";
        ifs.close();
        return lines;
    }

140
    while( !ifs.eof() )
141 142 143 144 145 146 147 148 149 150 151
    {
        getline( ifs, line );

        lines.push_back( std::string( line ) );
    }

    ifs.close();

    return lines;
}

152
bool WMClusterDisplay::loadTreeAscii( std::string fileName )
153 154 155 156 157 158 159
{
    std::vector<std::string> lines;

    debugLog() << "start parsing tree file...";

    lines = readFile( fileName );

160
    if( lines.size() == 0 )
161 162 163 164
    {
        return false;
    }

165
    for( size_t i = 0; i < lines.size() - 1; ++i )
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    {
        std::string &ls = lines[i];

        boost::regex reg1( "\\(" );
        ls = boost::regex_replace( ls, reg1, "(," );

        boost::regex reg2( "\\)" );
        ls = boost::regex_replace( ls, reg2, ",)" );

        boost::regex reg3( "\\ " );
        ls = boost::regex_replace( ls, reg3, "" );
    }

    std::vector<std::string>svec;

181
    for( size_t i = 0; i < lines.size()-1; ++i )
182 183 184 185 186
    {
        svec.clear();
        boost::regex reg( "," );
        boost::sregex_token_iterator it( lines[i].begin(), lines[i].end(), reg, -1 );
        boost::sregex_token_iterator end;
187
        while( it != end )
188 189 190 191
        {
            svec.push_back( *it++ );
        }

192
        size_t level = string_utils::fromString< size_t >( svec[1] );
193
        if( level == 0 )
194 195 196 197 198 199 200 201
        {
            m_tree.addLeaf();
        }
        else
        {
            // start after ( level (
            size_t k = 3;
            std::vector<size_t>leafes;
202
            while( svec[k] != ")" )
203
            {
204
                leafes.push_back( string_utils::fromString< size_t >( svec[k] ) );
205 206 207 208 209
                ++k;
            }
            //skip ) (
            k += 2;

210 211
            size_t cluster1 = string_utils::fromString< size_t >( svec[k++] );
            size_t cluster2 = string_utils::fromString< size_t >( svec[k++] );
212
            ++k;
213
            float data = string_utils::fromString< float >( svec[k++] );
214 215

            m_tree.addCluster( cluster1, cluster2, level, leafes, data );
216
            //m_tree.addCluster( cluster1, cluster2, data );
217

218
            if( svec[k] != ")" )
219 220
            {
                std::cout << "parse error" << std::endl;
221
                return false;
222 223 224 225 226 227
            }
        }
    }
    debugLog() << m_tree.getClusterCount() << " clusters created.";

    debugLog() << "finished parsing tree file...";
228

229
    if( m_tree.getLeafCount() == m_fiberInput->getData()->size() )
230 231 232
    {
        return true;
    }
233
    debugLog() << "something is wrong with the tree file";
234
    return false;
235 236 237 238
}

void WMClusterDisplay::initWidgets()
{
239
    osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
240

241 242 243 244 245
    int height = viewer->getCamera()->getViewport()->height();
    int width = viewer->getCamera()->getViewport()->width();

    m_oldViewHeight = height;
    m_oldViewWidth = width;
246 247 248

    m_rootNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );

schurade's avatar
schurade committed
249
    m_wm = new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298

    float xorig = 100.f;
    float yorig = 300.f;

    WOSGButton* current = new WOSGButton( std::string( "current" ), osgWidget::Box::VERTICAL, true, false );
    WOSGButton* up1 =     new WOSGButton( std::string( "+1" ),      osgWidget::Box::VERTICAL, true, false );
    WOSGButton* down11 =  new WOSGButton( std::string( "-1.1" ),    osgWidget::Box::VERTICAL, true, false );
    WOSGButton* down12 =  new WOSGButton( std::string( "-1.2" ),    osgWidget::Box::VERTICAL, true, false );

    WOSGButton* showN =  new WOSGButton( std::string( " N " ),    osgWidget::Box::VERTICAL, true, false );
    WOSGButton* showS =  new WOSGButton( std::string( " S " ),    osgWidget::Box::VERTICAL, true, false );
    WOSGButton* showE =  new WOSGButton( std::string( " E " ),    osgWidget::Box::VERTICAL, true, false );

    up1->setPosition(     osg::Vec3( xorig + 85.f,  yorig + 300.f, 0 ) );
    current->setPosition( osg::Vec3( xorig + 85.f,  yorig + 200.f, 0 ) );
    down11->setPosition(  osg::Vec3( xorig + 30.f,  yorig + 100.f, 0 ) );
    down12->setPosition(  osg::Vec3( xorig + 140.f, yorig + 100.f, 0 ) );

    showN->setPosition( osg::Vec3( xorig + 85.f,  yorig + 220.f, 0 ) );
    showS->setPosition( osg::Vec3( xorig + 110.f,  yorig + 220.f, 0 ) );
    showE->setPosition( osg::Vec3( xorig + 135.f,  yorig + 220.f, 0 ) );

    up1->managed( m_wm );
    current->managed( m_wm );
    down11->managed( m_wm );
    down12->managed( m_wm );

    showN->managed( m_wm );
    showS->managed( m_wm );
    showE->managed( m_wm );

    m_wm->addChild( current );
    m_wm->addChild( up1 );
    m_wm->addChild( down11 );
    m_wm->addChild( down12 );

    m_wm->addChild( showN );
    m_wm->addChild( showS );
    m_wm->addChild( showE );

    m_treeButtonList.push_back( current );
    m_treeButtonList.push_back( up1 );
    m_treeButtonList.push_back( down11 );
    m_treeButtonList.push_back( down12 );

    m_treeButtonList.push_back( showN );
    m_treeButtonList.push_back( showS );
    m_treeButtonList.push_back( showE );

299
    m_camera = new WGECamera();
300 301 302 303 304 305
    m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );

    m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
    m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
    m_camera->setViewMatrix( osg::Matrix::identity() );
    m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
306
    m_camera->setRenderOrder( WGECamera::POST_RENDER );
307 308 309 310 311 312 313 314 315 316 317 318 319 320

    m_rootNode->addChild( m_camera );
    m_camera->addChild( m_wm );

    viewer->addEventHandler( new osgWidget::MouseHandler( m_wm ) );
    viewer->addEventHandler( new osgWidget::KeyboardHandler( m_wm ) );
    viewer->addEventHandler( new osgWidget::ResizeHandler( m_wm, m_camera ) );
    viewer->addEventHandler( new osgWidget::CameraSwitchHandler( m_wm, m_camera ) );
    viewer->addEventHandler( new osgViewer::StatsHandler() );
    viewer->addEventHandler( new osgViewer::WindowSizeHandler() );
    viewer->addEventHandler( new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );

    m_wm->resizeAllWindows();

schurade's avatar
schurade committed
321
    m_rootNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMClusterDisplay::updateWidgets, this ) ) );
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );
}


void WMClusterDisplay::properties()
{
    // Initialize the properties
    m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );

    m_propSelectedCluster = m_properties->addProperty( "Selected Cluster", "", 0, m_propCondition );
    m_propSelectedCluster->setMin( 0 );
    m_propSelectedCluster->setMax( 0 );

    m_propSelectedClusterOffset = m_properties->addProperty( "Offset", "", 0, m_propCondition );
    m_propSelectedClusterOffset->setMin( -10 );
    m_propSelectedClusterOffset->setMax( 10 );


    m_propSubClusters = m_properties->addProperty( "Subclusters", "How many sub clusters should be selected", 10, m_propCondition );
    m_propSubClusters->setMin( 1 );
    m_propSubClusters->setMax( 50 );

344
    m_propSubLevelsToColor = m_properties->addProperty( "Sublevels to Color", "Number of subclusters to color differently", 0, m_propCondition );
345 346 347
    m_propSubLevelsToColor->setMin( 0 );
    m_propSubLevelsToColor->setMax( 0 );

348
    m_propMinSizeToColor = m_properties->addProperty( "Min size to show", "Specifies a minimum size for a cluster to be drawn", 1, m_propCondition ); // NOLINT
349 350 351 352 353 354 355 356 357 358 359
    m_propMinSizeToColor->setMin( 1 );
    m_propMinSizeToColor->setMax( 200 );

    m_propMaxSubClusters = m_properties->addProperty( "Max clusters in box ", "", 1, m_propCondition );
    m_propMaxSubClusters->setMin( 1 );
    m_propMaxSubClusters->setMax( 100 );

    m_propBoxClusterRatio = m_properties->addProperty( "Box-Cluster Ratio", "", 0.9, m_propCondition );
    m_propBoxClusterRatio->setMin( 0.0 );
    m_propBoxClusterRatio->setMax( 1.0 );

360
    m_propShowTree = m_properties->addProperty( "Show widget", "", false, m_propCondition );
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

    m_groupDendrogram = m_properties->addPropertyGroup( "Dendrogram",  "Properties only related to the dendrogram." );

    m_propShowDendrogram = m_groupDendrogram->addProperty( "Show dendrogram", "", true, m_propCondition );

    m_propResizeWithWindow = m_groupDendrogram->addProperty( "Resize with window", "", true, m_propCondition );

    m_propDendrogramSizeX = m_groupDendrogram->addProperty( "Width", "", 100, m_propCondition );
    m_propDendrogramSizeX->setMin( 0 );
    m_propDendrogramSizeX->setMax( 10000 );
    m_propDendrogramSizeY = m_groupDendrogram->addProperty( "Height", "", 100, m_propCondition );
    m_propDendrogramSizeY->setMin( 0 );
    m_propDendrogramSizeY->setMax( 10000 );
    m_propDendrogramOffsetX = m_groupDendrogram->addProperty( "Horizontal position", "", 100, m_propCondition );
    m_propDendrogramOffsetX->setMin( -9000 );
    m_propDendrogramOffsetX->setMax( 1000 );
    m_propDendrogramOffsetY = m_groupDendrogram->addProperty( "Verctical position", "", 100, m_propCondition );
    m_propDendrogramOffsetY->setMin( -9000 );
    m_propDendrogramOffsetY->setMax( 1000 );
380 381 382 383

    m_propTreeFile = m_properties->addProperty( "Tree file", "", WPathHelper::getAppPath() );
    m_readTriggerProp = m_properties->addProperty( "Do read",  "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
    WPropertyHelper::PC_PATHEXISTS::addTo( m_propTreeFile );
384

385
    WModule::properties();
386 387 388 389
}

void WMClusterDisplay::moduleMain()
{
390 391 392 393
    osg::ref_ptr< MainViewEventHandler > eh( new MainViewEventHandler );
    eh->subscribeLeftButtonPush( boost::bind( &WMClusterDisplay::dendrogramClick, this, _1 ) );

    WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView()->addEventHandler( eh );
394

395 396 397
    m_moduleState.setResetable( true, true );
    m_moduleState.add( m_propCondition );
    m_moduleState.add( m_active->getUpdateCondition() );
398 399 400 401 402
    m_moduleState.add( m_fiberInput->getDataChangedCondition() );

    ready();

    bool treeLoaded = false;
403

404
    // no text file was found, wait for the user to manually load on
405
    while( !m_shutdownFlag() )
406
    {
407
        if( m_shutdownFlag() )
408 409 410 411
        {
            break;
        }

412
        m_moduleState.wait();
413

414
        if( m_dataSet != m_fiberInput->getData() )
415 416
        {
            m_dataSet = m_fiberInput->getData();
417
            std::string fn = m_dataSet->getFilename();
418 419 420 421
            std::string ext( ".fib" );
            std::string csvExt( "_hie.txt" );
            fn.replace( fn.find( ext ), ext.size(), csvExt );
            treeLoaded = loadTreeAscii( fn );
422
            if( treeLoaded )
423 424 425 426 427 428
            {
                break;
            }
        }


429
        if( m_readTriggerProp->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
430
        {
431
            std::string fileName = m_propTreeFile->get().string().c_str();
432 433
            treeLoaded = loadTreeAscii( fileName );
            m_readTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, true );
434
            if( treeLoaded )
435 436 437
            {
                break;
            }
438 439 440
        }
    }

441 442 443
    m_fiberSelector = boost::shared_ptr<WFiberSelector>( new WFiberSelector( m_dataSet ) );
    m_tree.setRoiBitField( m_fiberSelector->getBitfield() );

444 445
    m_propTreeFile->setHidden( true );
    m_readTriggerProp->setHidden( true );
446 447 448 449 450 451 452 453 454 455 456 457

    m_propSelectedCluster->setMin( m_tree.getLeafCount() );
    m_propSelectedCluster->setMax( m_tree.getClusterCount() - 1 );
    m_propSelectedCluster->set( m_tree.getClusterCount() - 1 );
    m_propSubLevelsToColor->setMax( m_tree.getLevel( m_propSelectedCluster->get() ) );
    m_propMinSizeToColor->setMax( 100 );
    m_rootCluster = m_propSelectedCluster->get();

    m_propSelectedClusterOffset->setMax( m_tree.getMaxLevel() - m_tree.getLevel( m_propSelectedCluster->get() ) );
    m_propSelectedClusterOffset->setMin( 0 - m_tree.getLevel( m_propSelectedCluster->get() ) );

    initWidgets();
458 459
    createFiberGeode();

460 461 462 463 464 465
    m_widgetDirty = true;
    updateWidgets();

    WKernel::getRunningKernel()->getRoiManager()->getProperties()->getProperty( "dirty" )->getUpdateCondition()->subscribeSignal(
            boost::bind( &WMClusterDisplay::handleRoiChanged, this ) );

466
    m_dendrogramGeode = new WDendrogramGeode( &m_tree, m_rootCluster, 1000, 500 );
467 468 469 470 471 472 473
    m_camera->addChild( m_dendrogramGeode );

    m_propSelectedCluster->get( true );
    m_propSubClusters->get( true );
    m_propSubLevelsToColor->get( true );
    m_propMinSizeToColor->get( true );

474
    // main loop
475
    while( !m_shutdownFlag() )
476 477 478
    {
        m_moduleState.wait();

479
        if( m_shutdownFlag() )
480 481 482 483
        {
           break;
        }

484
        if( m_propSelectedCluster->changed() )
485 486 487 488
        {
            handleSelectedClusterChanged();
        }

489
        if( m_propSelectedClusterOffset->changed() )
490 491 492 493
        {
            handleOffsetChanged();
        }

494 495 496 497 498
        if( m_propSubClusters->changed() )
        {
            handleBiggestClustersChanged();
        }

499
        if( m_propSubLevelsToColor->changed() )
500 501 502 503
        {
            handleColoringChanged();
        }

504
        if( m_propMinSizeToColor->changed() )
505 506 507 508
        {
            handleMinSizeChanged();
        }

509
        if( m_propBoxClusterRatio->changed() || m_propMaxSubClusters->changed() )
510 511 512 513
        {
            handleRoiChanged();
        }

514
        if( m_propShowTree->changed() )
515 516 517 518
        {
            m_widgetDirty = true;
        }

519
        if( m_propShowDendrogram->changed() || m_propResizeWithWindow->changed() || m_propDendrogramSizeX->changed() ||
520
                m_propDendrogramSizeY->changed() || m_propDendrogramOffsetX->changed() || m_propDendrogramOffsetY->changed() )
521 522 523 524
        {
            m_dendrogramDirty = true;
        }

525
        if( m_active->changed() )
526
        {
527
            //WKernel::getRunningKernel()->getRoiManager()->setUseExternalBitfield( m_active->get( true ) );
528 529 530 531 532 533 534
        }
    }

    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
}

void WMClusterDisplay::handleSelectedClusterChanged()
535 536 537 538 539 540
{
    m_rootCluster = m_propSelectedCluster->get( true );
    m_propSelectedClusterOffset->setMax( m_tree.getMaxLevel() - m_tree.getLevel( m_propSelectedCluster->get() ) );
    m_propSelectedClusterOffset->setMin( 0 - m_tree.getLevel( m_propSelectedCluster->get() ) );
    m_propSelectedClusterOffset->set( 0 );
    m_propSelectedClusterOffset->get( true );
541
    m_propMinSizeToColor->setMax( m_tree.size( m_biggestClusters.back() ) );
542

543 544
    m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( m_rootCluster ) );

545
    m_propSubLevelsToColor->setMax( m_tree.getLevel( m_rootCluster ) );
546
    colorClusters( m_propSelectedCluster->get( true ) );
547

548 549 550 551
    m_dendrogramDirty = true;
}

void WMClusterDisplay::handleOffsetChanged()
552
{
553
    if( m_propSelectedClusterOffset->get( true ) == 0 )
554 555 556
    {
        m_rootCluster = m_propSelectedCluster->get( true );
    }
557
    else if( m_propSelectedClusterOffset->get( true ) > 0 )
558 559 560
    {
        int plus = m_propSelectedClusterOffset->get( true );
        m_rootCluster = m_propSelectedCluster->get( true );
561
        while( plus > 0 )
562 563 564 565 566 567 568 569 570 571
        {
            m_rootCluster = m_tree.getParent( m_rootCluster );
            --plus;
        }
    }
    else
    {
        int minusOff = m_propSelectedClusterOffset->get( true );
        m_rootCluster = m_propSelectedCluster->get( true );

572
        while( minusOff < 0 )
573
        {
574
            if( m_tree.getLevel( m_rootCluster ) > 0 )
575 576 577 578 579 580 581
            {
                size_t left =  m_tree.getChildren( m_rootCluster ).first;
                size_t right = m_tree.getChildren( m_rootCluster ).second;

                size_t leftSize =  m_tree.size( left );
                size_t rightSize = m_tree.size( right );

582
                if( leftSize >= rightSize )
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
                {
                    m_rootCluster = left;
                }
                else
                {
                    m_rootCluster = right;
                }
            }
            ++minusOff;
        }
    }
    m_propSubLevelsToColor->setMax( m_tree.getLevel( m_rootCluster ) );

    m_dendrogramDirty = true;
}

void WMClusterDisplay::handleBiggestClustersChanged()
{
    m_biggestClusters = m_tree.findXBiggestClusters( m_propSelectedCluster->get(), m_propSubClusters->get( true ) );

603 604
    m_propMinSizeToColor->setMax( m_tree.size( m_biggestClusters.back() ) );

605
    m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
606
    setColor( m_tree.getLeafesForCluster( m_rootCluster ), WColor( 0.3, 0.3, 0.3, 1.0 ) );
607

608
    for( size_t k = 0; k < m_biggestClusters.size(); ++k )
609 610
    {
        size_t current = m_biggestClusters[k];
611 612
        setColor( m_tree.getLeafesForCluster( current ), wge::getNthHSVColor( k ) );
        m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
613 614 615 616 617
    }

    m_dendrogramDirty = true;
    m_widgetDirty = true;
    m_biggestClusterButtonsChanged = true;
618 619

    m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( m_biggestClusters ) );
620 621 622 623 624 625 626 627 628 629
}

void WMClusterDisplay::handleColoringChanged()
{
    m_propSubLevelsToColor->get( true );
    m_propMinSizeToColor->get( true );
    colorClusters( m_propSelectedCluster->get( true ) );
    m_dendrogramDirty = true;
}

630 631 632 633 634
void WMClusterDisplay::handleMinSizeChanged()
{
    m_dendrogramDirty = true;
}

635 636
void WMClusterDisplay::handleRoiChanged()
{
637 638
    WKernel::getRunningKernel()->getRunningKernel()->getRoiManager()->dirty( true );

639
    if( m_active->get() )
640 641 642
    {
        m_biggestClusters = m_tree.getBestClustersFittingRoi( m_propBoxClusterRatio->get( true ), m_propMaxSubClusters->get( true ) );

643 644
        m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
        setColor( m_tree.getLeafesForCluster( m_rootCluster ), WColor( 0.3, 0.3, 0.3, 1.0 ) );
645

646
        for( size_t k = 0; k < m_biggestClusters.size(); ++k )
647 648
        {
            size_t current = m_biggestClusters[k];
649 650
            setColor( m_tree.getLeafesForCluster( current ), wge::getNthHSVColor( k ) );
            m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
651 652 653 654
        }

        m_widgetDirty = true;
        m_biggestClusterButtonsChanged = true;
655
        m_dendrogramDirty = true;
656
    }
657

658
    m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( m_biggestClusters ) );
659 660 661 662
}

void WMClusterDisplay::updateWidgets()
{
663
    osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
664 665 666 667

    int height = viewer->getCamera()->getViewport()->height();
    int width = viewer->getCamera()->getViewport()->width();

668
    if( ( height != m_oldViewHeight ) || width != m_oldViewWidth )
669 670 671 672 673 674 675 676
    {
        m_oldViewHeight = height;
        m_oldViewWidth = width;

        m_dendrogramDirty = true;
    }


677
    if( !widgetClicked() && !m_widgetDirty && !m_dendrogramDirty )
678 679 680 681 682 683 684 685 686 687
    {
        return;
    }
    // store current cluster id for ease of access and better readability
    size_t current = m_propSelectedCluster->get();
    size_t up1, down11, down12; // up2, down21, down22, down23, down24;

    m_treeButtonList[0]->setId( current );
    m_treeButtonList[0]->setLabel( createLabel( current ) );

688
    for( size_t i = 0; i < m_treeButtonList.size(); ++i )
689 690 691 692
    {
        m_treeButtonList[i]->hide();
    }

693
    if( m_propShowTree->get( true ) )
694 695 696 697
    {
        m_treeButtonList[0]->show();

        // are we on top?
698
        if( m_tree.getLevel( current ) < m_tree.getMaxLevel() )
699 700 701 702 703 704 705 706
        {
            // not yet
            up1 = m_tree.getParent( current );
            m_treeButtonList[1]->setId( up1 );
            m_treeButtonList[1]->setLabel( createLabel( up1 ) );
            m_treeButtonList[1]->show();
        }
        // are we all the way down
707
        if( m_tree.getLevel( current ) > 0 )
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
        {
            down11 = m_tree.getChildren( current ).first;
            down12 = m_tree.getChildren( current ).second;

            m_treeButtonList[2]->setId( down11 );
            m_treeButtonList[2]->setLabel( createLabel( down11 ) );
            m_treeButtonList[2]->show();

            m_treeButtonList[3]->setId( down12 );
            m_treeButtonList[3]->setLabel( createLabel( down12 ) );
            m_treeButtonList[3]->show();
        }

        m_treeButtonList[4]->show();
        m_treeButtonList[5]->show();
        m_treeButtonList[6]->show();
    }

726
    if( m_biggestClusterButtonsChanged )
727
    {
728
        for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
729 730 731 732 733
        {
            m_wm->removeChild( m_biggestClustersButtonList[i] );
        }

        m_biggestClustersButtonList.clear();
734
        for( size_t i = 0; i < m_biggestClusters.size(); ++i )
735 736 737 738 739 740 741 742 743
        {
            osg::ref_ptr<WOSGButton> newButton1 = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
                    osgWidget::Box::VERTICAL, true, false ) );
            newButton1->setPosition( osg::Vec3( 10.f,  i * 20.f, 0 ) );
            newButton1->setId( 10000000 + m_biggestClusters[i] );
            newButton1->setLabel( std::string( " S " ) );
            newButton1->managed( m_wm );
            m_wm->addChild( newButton1 );
            m_biggestClustersButtonList.push_back( newButton1 );
744
            newButton1->setBackgroundColor( wge::getNthHSVColor( i ) );
745 746 747 748 749 750 751 752 753

            osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
                    osgWidget::Box::VERTICAL, true, true ) );
            newButton->setPosition( osg::Vec3( 35.f,  i * 20.f, 0 ) );
            newButton->setId( m_biggestClusters[i] );
            newButton->setLabel( createLabel( m_biggestClusters[i] ) );
            newButton->managed( m_wm );
            m_wm->addChild( newButton );
            m_biggestClustersButtonList.push_back( newButton );
754
            newButton->setBackgroundColor( wge::getNthHSVColor( i ) );
755
        }
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
        osg::ref_ptr<WOSGButton> newButton1 = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
                osgWidget::Box::VERTICAL, true, false ) );
        newButton1->setPosition( osg::Vec3( 10.f,  m_biggestClusters.size() * 20.f, 0 ) );
        newButton1->setId( 10000000 + m_propSelectedCluster->get() );
        newButton1->setLabel( std::string( " S " ) );
        newButton1->managed( m_wm );
        m_wm->addChild( newButton1 );
        m_biggestClustersButtonList.push_back( newButton1 );
        newButton1->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );

        osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
                        osgWidget::Box::VERTICAL, true, true ) );
        newButton->setPosition( osg::Vec3( 35.f,  m_biggestClusters.size() * 20.f, 0 ) );
        newButton->setId( m_propSelectedCluster->get() );
        newButton->setLabel( createLabel( m_propSelectedCluster->get() ) );
        newButton->managed( m_wm );
        m_wm->addChild( newButton );

        m_biggestClustersButtonList.push_back( newButton );
        newButton->setBackgroundColor( WColor( 0.4, 0.4, 0.4, 1.0 ) );
776 777 778 779
        m_biggestClusterButtonsChanged = false;
    }
    m_wm->resizeAllWindows();

780
    if( m_dendrogramDirty )
781 782 783 784
    {
        //m_camera->removeChild( m_dendrogramGeode );
        m_camera->removeChild( 1, 1 );

785 786 787 788 789
        int dwidth = m_propDendrogramSizeX->get( true );
        int dheight = m_propDendrogramSizeY->get( true );
        int dxOff = m_propDendrogramOffsetX->get( true );
        int dyOff = m_propDendrogramOffsetY->get( true );

790
        if( m_propShowDendrogram->get( true ) )
791
        {
792
            if( m_propResizeWithWindow->get( true ) )
793
            {
794
                m_dendrogramGeode = new WDendrogramGeode( &m_tree, m_tree.getClusterCount() - 1, true,
795 796 797 798
                        m_propMinSizeToColor->get(), width - 120, height / 2 , 100 );
            }
            else
            {
799
                m_dendrogramGeode = new WDendrogramGeode( &m_tree, m_tree.getClusterCount() - 1, true,
800 801
                        m_propMinSizeToColor->get(), dwidth, dheight, dxOff, dyOff );
            }
802 803 804 805 806 807 808 809
            m_camera->addChild( m_dendrogramGeode );
        }
        m_dendrogramDirty = false;
    }
}

std::string WMClusterDisplay::createLabel( size_t id )
{
810
    switch( m_labelMode )
811 812
    {
        case 1:
813
            return string_utils::toString( m_tree.size( id ) );
814 815
            break;
        case 2:
816
            return string_utils::toString( m_tree.getCustomData( id ) );
817 818
            break;
        default:
819
            return string_utils::toString( id );
820 821 822 823 824 825 826
    }
}

bool WMClusterDisplay::widgetClicked()
{
    bool clicked = false;

827
    if( m_treeButtonList[0]->clicked() )
828 829 830 831 832 833 834 835
    {
        clicked = true;
        m_propSelectedCluster->set( m_rootCluster );
        m_propSelectedClusterOffset->set( 0 );
        m_propSelectedClusterOffset->setMax( m_tree.getMaxLevel() - m_tree.getLevel( m_propSelectedCluster->get() ) );
        m_propSelectedClusterOffset->setMin( 0 - m_tree.getLevel( m_propSelectedCluster->get() ) );
    }

836
    for( size_t i = 1; i < m_treeButtonList.size() - 3; ++i )
837
    {
838
        if( m_treeButtonList[i]->clicked() )
839 840 841 842 843 844
        {
            clicked = true;
            m_propSelectedCluster->set( m_treeButtonList[i]->getId() );
        }
    }

845
    for( size_t i = 0; i < 3; ++i )
846
    {
847
        if( m_treeButtonList[4 + i]->clicked() )
848 849 850 851 852 853 854
        {
            clicked = true;
            m_labelMode = i;
        }
    }

    bool biggestClusterSelectionChanged = false;
855
    for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
856
    {
857
        if( m_biggestClustersButtonList[i]->clicked() )
858
        {
859
            if( m_biggestClustersButtonList[i]->getId() < 10000000 )
860 861 862 863 864 865 866 867 868 869 870 871
            {
                biggestClusterSelectionChanged = true;
                clicked = true;
            }
            else
            {
                clicked = true;
                m_propSelectedCluster->set( m_biggestClustersButtonList[i]->getId() - 10000000 );
            }
        }
    }

872
    if( biggestClusterSelectionChanged )
873 874
    {
        std::vector<size_t>activeClusters;
875
        for( size_t i = 0; i < m_biggestClustersButtonList.size(); ++i )
876
        {
877
            if( m_biggestClustersButtonList[i]->pushed() )
878 879 880 881 882
            {
                activeClusters.push_back( m_biggestClustersButtonList[i]->getId() );
            }
        }

883 884
        m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( activeClusters ) );
        //WKernel::getRunningKernel()->getRoiManager()->setExternalBitfield( m_tree.getOutputBitfield( activeClusters ) );
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
    }
    return clicked;
}

void WMClusterDisplay::colorClusters( size_t current )
{
    size_t num = m_propSubLevelsToColor->get();
    size_t size = m_propMinSizeToColor->get();

    m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );

    std::vector<size_t>finalList;
    std::queue<size_t>currentLevelList;

    currentLevelList.push( current );

    std::queue<size_t>nextLevelList;
902
    while( num > 0 )
903
    {
904
        while( !currentLevelList.empty() )
905 906 907 908
        {
            size_t cluster = currentLevelList.front();
            currentLevelList.pop();

909
            if( m_tree.getLevel( cluster ) > 0 )
910 911 912 913
            {
                size_t left = m_tree.getChildren( cluster ).first;
                size_t right = m_tree.getChildren( cluster ).second;

914
                if(  m_tree.size( left ) >= size )
915 916 917 918 919 920 921
                {
                    nextLevelList.push( left );
                }
                else
                {
                    //finalList.push( left );
                }
922
                if( m_tree.size( right ) >= size )
923 924 925 926 927 928 929 930 931 932 933 934 935 936
                {
                    nextLevelList.push( right );
                }
                else
                {
                    //finalList.push( right );
                }
            }
            else
            {
                finalList.push_back( cluster );
            }
        }

937
        while( !nextLevelList.empty() )
938 939 940 941 942 943 944 945 946
        {
            size_t cluster = nextLevelList.front();
            nextLevelList.pop();
            currentLevelList.push( cluster );
        }
        --num;
    }


947
    while( !currentLevelList.empty() )
948 949 950 951 952 953 954 955
    {
        size_t cluster = currentLevelList.front();
        currentLevelList.pop();
        finalList.push_back( cluster );
    }

    int n = 0;

956
    for( size_t i = 0; i < finalList.size(); ++i )
957 958
    {
        size_t cluster = finalList[i];
959 960
        m_tree.colorCluster( cluster, wge::getNthHSVColor( n ) );
        setColor( m_tree.getLeafesForCluster( cluster ), wge::getNthHSVColor( n++ ) );
961 962
    }

963 964
    m_fiberDrawable->setBitfield( m_tree.getOutputBitfield( finalList ) );
    //WKernel::getRunningKernel()->getRoiManager()->setExternalBitfield( m_tree.getOutputBitfield( finalList ) );
965 966 967 968 969 970 971

    m_biggestClusters.clear();
    m_biggestClusterButtonsChanged = true;
}

void WMClusterDisplay::setColor( std::vector<size_t> clusters, WColor color )
{
972 973 974
    boost::shared_ptr< std::vector< float > >colorField = m_dataSet->getColorScheme( "Custom Color" )->getColor();
    boost::shared_ptr< std::vector< size_t > > starts   = m_fiberSelector->getStarts();
    boost::shared_ptr< std::vector< size_t > > lengths  = m_fiberSelector->getLengths();
975

976
    for( size_t i = 0; i < clusters.size(); ++i )
977 978 979
    {
        size_t current = clusters[i];

980
        for( size_t k = (*starts)[current]; k < (*starts)[current] + (*lengths)[current]; ++k)
981
        {
982 983 984
            (*colorField)[k*3] =   color[0];
            (*colorField)[k*3+1] = color[1];
            (*colorField)[k*3+2] = color[2];
985 986 987
        }
    }
}
988

989
bool WMClusterDisplay::dendrogramClick( const WVector2f& pos )
990
{
991
    if( m_dendrogramGeode->inDendrogramArea( pos ) )
992
    {
993 994 995 996
        int x = pos[0];
        int y = pos[1];
        m_propSelectedCluster->set( m_dendrogramGeode->getClickedCluster( x, y ) );
        return true;
997
    }
998
    return false;
999
}
1000 1001 1002 1003

void WMClusterDisplay::createFiberGeode()
{
    m_fiberDrawable = osg::ref_ptr< WFiberDrawable >( new WFiberDrawable );
1004
    m_fiberDrawable->setBound( m_dataSet->getBoundingBox().toOSGBB() );
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
    m_fiberDrawable->setStartIndexes( m_dataSet->getLineStartIndexes() );
    m_fiberDrawable->setPointsPerLine( m_dataSet->getLineLengths() );
    m_fiberDrawable->setVerts( m_dataSet->getVertices() );
    m_fiberDrawable->setTangents( m_dataSet->getTangents() );
    m_fiberDrawable->setColor( m_dataSet->getColorScheme( "Custom Color" )->getColor() );
    m_fiberDrawable->setBitfield( m_fiberSelector->getBitfield() );

    m_fiberDrawable->setUseDisplayList( false );
    m_fiberDrawable->setDataVariance( osg::Object::DYNAMIC );

    osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
    geode->addDrawable( m_fiberDrawable );

    m_rootNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
    m_rootNode->addChild( geode );
}