1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
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.
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.
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/>.
23
//---------------------------------------------------------------------------
29
#include <osgGA/TrackballManipulator>
30
#include <osgGA/StateSetManipulator>
31
#include <osgViewer/ViewerEventHandlers>
32
#include <osgWidget/Util> //NOLINT
33
#include <osgWidget/ViewerEventHandlers> //NOLINT
34
#include <osgWidget/WindowManager> //NOLINT
35
#include <osg/LightModel>
37
#include "core/common/WPathHelper.h"
38
#include "core/common/WPropertyHelper.h"
39
#include "core/graphicsEngine/algorithms/WMarchingLegoAlgorithm.h"
40
#include "core/graphicsEngine/WGEColormapping.h"
41
#include "core/graphicsEngine/WGEUtils.h"
42
#include "core/kernel/WKernel.h"
43
#include "core/kernel/WSelectionManager.h"
44
#include "WFileParser.h"
45
#include "WMClusterDisplayVoxels.h"
46
#include "WMClusterDisplayVoxels.xpm"
48
// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
49
W_LOADABLE_MODULE( WMClusterDisplayVoxels )
51
WMClusterDisplayVoxels::WMClusterDisplayVoxels():
53
m_currentDisplayMode( CDV_SINGLE ),
54
m_currentDisplayModeString( "" ),
55
m_moduleNode( new WGEGroupNode() ),
56
m_dendrogramNode( new WGEGroupNode() ),
57
m_meshNode( new WGEGroupNode() ),
58
m_selectionChanged( false ),
59
m_dendrogramDirty( false )
63
WMClusterDisplayVoxels::~WMClusterDisplayVoxels()
68
boost::shared_ptr< WModule > WMClusterDisplayVoxels::factory() const
70
// See "src/modules/template/" for an extensively documented example.
71
return boost::shared_ptr< WModule >( new WMClusterDisplayVoxels() );
74
const char** WMClusterDisplayVoxels::getXPMIcon() const
76
return clusterDisplayVoxels_xpm;
78
const std::string WMClusterDisplayVoxels::getName() const
80
// Specify your module name here. This name must be UNIQUE!
81
return "ClusterDisplayVoxels";
84
const std::string WMClusterDisplayVoxels::getDescription() const
86
// Specify your module description here. Be detailed. This text is read by the user.
87
// See "src/modules/template/" for an extensively documented example.
88
return "Visualizes voxel clusterings in texture and 3D view";
91
void WMClusterDisplayVoxels::connectors()
93
// the input dataset is just used as source for resolurtion and transformation matrix
94
m_input = boost::shared_ptr< WModuleInputData < WDataSetSingle > >(
95
new WModuleInputData< WDataSetSingle >( shared_from_this(), "in", "The input dataset." ) );
96
addConnector( m_input );
98
m_output = boost::shared_ptr< WModuleOutputData < WDataSetScalar > >(
99
new WModuleOutputData< WDataSetScalar >( shared_from_this(), "out", "The extracted image." ) );
100
addConnector( m_output );
102
WModule::connectors();
105
void WMClusterDisplayVoxels::properties()
107
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
109
m_propClusterFile = m_properties->addProperty( "Cluster file", "", boost::filesystem::path( "/SCR/schurade/data/david/whole/avg.txt" ) );
110
m_propReadTrigger = m_properties->addProperty( "Do read", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
114
m_groupSelection = m_properties->addPropertyGroup( "Cluster selections", "Groups the different cluster selection methods" ); //NOLINT
116
m_clusterSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
117
m_clusterSelectionsList->addItem( "Single", "" );
118
m_clusterSelectionsList->addItem( "Biggest", "" );
119
m_clusterSelectionsList->addItem( "X Clusters", "" );
120
m_clusterSelectionsList->addItem( "Similarity", "" );
121
m_clusterSelectionsList->addItem( "Levels from top", "" );
122
m_clusterSelectionsList->addItem( "Minimum branch length", "" );
123
m_clusterSelectionsList->addItem( "Loaded partition", "" );
125
m_clusterSelection = m_groupSelection->addProperty( "Selection method", "selection",
126
m_clusterSelectionsList->getSelectorFirst(), m_propCondition );
127
WPropertyHelper::PC_SELECTONLYONE::addTo( m_clusterSelection );
131
m_propSelectedCluster = m_groupSelection->addProperty( "Selected Cluster", "Selects a single cluster by number.", 0, m_propCondition );
132
m_propSelectedCluster->setMin( 0 );
133
m_propSelectedCluster->setMax( 0 );
135
m_propXBiggestClusters = m_groupSelection->addProperty( "Biggest Clusters", "Selects a number of biggest clusters.", 5, m_propCondition );
136
m_propXBiggestClusters->setMin( 1 );
137
m_propXBiggestClusters->setMax( 1000 );
139
m_propXClusters = m_groupSelection->addProperty( "X Clusters", "Selects a number of clusters by dividing clusters.", 5, m_propCondition );
140
m_propXClusters->setMin( 1 );
141
m_propXClusters->setMax( 1000 );
143
m_propValue = m_groupSelection->addProperty( "Similarity Value", "Selects clusters below a given similarity value", 1.0, m_propCondition );
144
m_propValue->setMin( 0.0 );
145
m_propValue->setMax( 1.0 );
147
m_propLevelsFromTop = m_groupSelection->addProperty( "Levels from top", "", 0, m_propCondition );
148
m_propHideOutliers = m_groupSelection->addProperty( "Hide outliers", "", false, m_propCondition );
150
m_propSelectedLoadedPartion = m_groupSelection->addProperty( "Loaded Partition", "Activates a predetermined partition, loaded from file", 0, m_propCondition ); // NOLINT
151
m_propSelectedLoadedPartion->setMin( 1 );
152
m_propSelectedLoadedPartion->setMax( 1 );
154
m_propMinBranchLength = m_groupSelection->addProperty( "Minimum branch length", "", 0.1, m_propCondition );
155
m_propMinBranchLength->setMin( 0.0 );
156
m_propMinBranchLength->setMax( 1.0 );
158
m_propMinBranchSize = m_groupSelection->addProperty( "Minimum branch size", "", 50, m_propCondition );
159
m_propMinBranchSize->setMin( 1 );
160
m_propMinBranchSize->setMax( 500 );
162
m_buttonExecuteSelection = m_groupSelection->addProperty( "Update", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
164
m_propShowSelectedButtons = m_groupSelection->addProperty( "Show Buttons", "Shows/Hides the buttons for selected cluster on the left side", true, m_propCondition ); //NOLINT
166
m_buttonLabelList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
167
m_buttonLabelList->addItem( "Number", "" );
168
m_buttonLabelList->addItem( "Size", "" );
169
m_buttonLabelList->addItem( "Level", "" );
170
m_buttonLabelList->addItem( "Similarity", "" );
172
m_buttonLabelSelection = m_groupSelection->addProperty( "Button label", "selection",
173
m_buttonLabelList->getSelectorFirst(), m_propCondition );
174
WPropertyHelper::PC_SELECTONLYONE::addTo( m_buttonLabelSelection );
177
// Group Triangulation
178
m_groupTriangulation = m_properties->addPropertyGroup( "Triangulation", "Groups the triangulation properties" ); //NOLINT
179
m_propShowVoxelTriangulation = m_groupTriangulation->addProperty( "Triangulate", "", false, m_propCondition );
180
m_showNotInClusters = m_groupTriangulation->addProperty( "Show non active", "", false, m_propCondition );
183
m_groupDendrogram = m_properties->addPropertyGroup( "Dendrogram", "Properties only related to the dendrogram." );
185
m_propShowDendrogram = m_groupDendrogram->addProperty( "Show dendrogram", "", true, m_propCondition );
186
m_propPlotHeightByLevel = m_groupDendrogram->addProperty( "Height by Level or Value", "", false, m_propCondition );
188
m_propMinSizeToColor = m_groupDendrogram->addProperty( "Min size to show", "Specifies a minimum size for a cluster to be drawn", 1, m_propCondition ); // NOLINT
189
m_propMinSizeToColor->setMin( 1 );
190
m_propMinSizeToColor->setMax( 200 );
192
m_propZoomIn = m_groupDendrogram->addProperty( "Zoom in", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
193
m_propZoomOut = m_groupDendrogram->addProperty( "Zoom out", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
195
m_propResizeWithWindow = m_groupDendrogram->addProperty( "Resize with window", "", true, m_propCondition );
197
m_propDendrogramSizeX = m_groupDendrogram->addProperty( "Width", "", 100, m_propCondition );
198
m_propDendrogramSizeX->setMin( 0 );
199
m_propDendrogramSizeX->setMax( 10000 );
200
m_propDendrogramSizeY = m_groupDendrogram->addProperty( "Height", "", 100, m_propCondition );
201
m_propDendrogramSizeY->setMin( 0 );
202
m_propDendrogramSizeY->setMax( 10000 );
203
m_propDendrogramOffsetX = m_groupDendrogram->addProperty( "Horizontal position", "", 100, m_propCondition );
204
m_propDendrogramOffsetX->setMin( -9000 );
205
m_propDendrogramOffsetX->setMax( 1000 );
206
m_propDendrogramOffsetY = m_groupDendrogram->addProperty( "Verctical position", "", 100, m_propCondition );
207
m_propDendrogramOffsetY->setMin( -9000 );
208
m_propDendrogramOffsetY->setMax( 1000 );
210
m_groupSelection->setHidden( true );
211
m_groupTriangulation->setHidden( true );
212
m_groupDendrogram->setHidden( true );
214
m_buttonUpdateOutput = m_properties->addProperty( "Update output", "Updates the output connector",
215
WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
219
m_infoCountLeafes = m_infoProperties->addProperty( "Count voxels", "", 0 );
220
m_infoCountClusters = m_infoProperties->addProperty( "Count clusters", "", 0 );
221
m_infoMaxLevel = m_infoProperties->addProperty( "Max Level", "", 0 );
223
WModule::properties();
226
void WMClusterDisplayVoxels::setPropertyBoundaries()
228
m_propSelectedCluster->setMin( m_tree.getLeafCount() );
229
m_propSelectedCluster->setMax( m_tree.getClusterCount() - 1 );
231
m_propSelectedCluster->setMin( 0 );
232
m_propSelectedCluster->setMax( m_tree.getClusterCount() - 1 );
233
m_propSelectedCluster->set( m_tree.getClusterCount() - 1 );
235
m_infoCountLeafes->set( m_tree.getLeafCount() );
236
m_infoCountClusters->set( m_tree.getClusterCount() );
237
m_infoMaxLevel->set( m_tree.getMaxLevel() );
239
m_propMinSizeToColor->setMax( 1000 );
240
m_rootCluster = m_propSelectedCluster->get();
242
m_propLevelsFromTop->setMin( 0 );
243
m_propLevelsFromTop->setMax( m_tree.getMaxLevel() );
245
if( m_loadedPartitions.empty() )
247
m_propSelectedLoadedPartion->setHidden( true );
251
m_propSelectedLoadedPartion->setMin( 1 );
252
m_propSelectedLoadedPartion->setMax( m_loadedPartitions.size() );
256
m_zoomRoot = m_propSelectedCluster->get();
259
void WMClusterDisplayVoxels::moduleMain()
261
boost::signals2::connection con = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getPickHandler()->getPickSignal()->
262
connect( boost::bind( &WMClusterDisplayVoxels::dendrogramClick, this, _1 ) );
265
m_moduleState.setResetable( true, true );
266
m_moduleState.add( m_input->getDataChangedCondition() );
267
m_moduleState.add( m_propCondition );
268
m_moduleState.add( m_active->getUpdateCondition() );
272
// wait for a dataset to be connected, most likely an anatomy dataset
273
while( !m_shutdownFlag() )
275
m_moduleState.wait();
277
if( m_shutdownFlag() )
282
boost::shared_ptr< WDataSetSingle > newDataSet = m_input->getData();
283
bool dataChanged = ( m_dataSet != newDataSet );
284
bool dataValid = ( newDataSet );
290
m_dataSet = newDataSet;
291
m_grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
297
// wait for a cluster file to be loaded
298
while( !m_shutdownFlag() )
300
m_moduleState.wait();
302
if( m_shutdownFlag() )
307
if( m_propReadTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
309
boost::filesystem::path fileName = m_propClusterFile->get();
310
m_propReadTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, true );
312
if( loadClustering( fileName ) )
314
m_propReadTrigger->setHidden( true );
315
m_propClusterFile->setHidden( true );
316
m_groupSelection->setHidden( false );
317
m_groupTriangulation->setHidden( false );
318
m_groupDendrogram->setHidden( false );
325
if( !m_shutdownFlag() )
328
setPropertyBoundaries();
331
m_propSelectedCluster->get( true );
332
m_propSelectedLoadedPartion->get( true );
333
m_propMinSizeToColor->get( true );
334
m_propXClusters->get( true );
335
m_propXBiggestClusters->get( true );
336
m_propValue->get( true );
337
m_propMinBranchLength->get( true );
338
m_propMinBranchSize->get( true );
339
m_propLevelsFromTop->get( true );
340
m_propHideOutliers->get( true );
341
m_showNotInClusters->get( true );
346
// main loop, respond to controls
347
while( !m_shutdownFlag() )
349
m_moduleState.wait();
351
if( m_shutdownFlag() )
356
if( m_clusterSelection->changed( true ) )
358
m_propSelectedCluster->setHidden( true );
359
m_propXBiggestClusters->setHidden( true );
360
m_propXClusters->setHidden( true );
361
m_propValue->setHidden( true );
362
m_propLevelsFromTop->setHidden( true );
363
m_propHideOutliers->setHidden( true );
364
m_propMinBranchLength->setHidden( true );
365
m_propMinBranchSize->setHidden( true );
366
m_propSelectedLoadedPartion->setHidden( true );
368
switch ( m_clusterSelection->get( true ).getItemIndexOfSelected( 0 ) )
371
m_propSelectedCluster->setHidden( false );
374
m_propSelectedCluster->setHidden( false );
375
m_propXBiggestClusters->setHidden( false );
378
m_propSelectedCluster->setHidden( false );
379
m_propXClusters->setHidden( false );
382
m_propValue->setHidden( false );
385
m_propLevelsFromTop->setHidden( false );
386
m_propHideOutliers->setHidden( false );
389
m_propMinBranchLength->setHidden( false );
390
m_propMinBranchSize->setHidden( false );
393
m_propSelectedLoadedPartion->setHidden( false );
396
m_propSelectedCluster->setHidden( false );
401
if( m_buttonExecuteSelection->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
403
m_buttonExecuteSelection->set( WPVBaseTypes::PV_TRIGGER_READY, false );
404
switch ( m_clusterSelection->get( true ).getItemIndexOfSelected( 0 ) )
407
m_currentDisplayMode = CDV_SINGLE;
410
m_currentDisplayMode = CDV_BIGGEST;
413
m_currentDisplayMode = CDV_X;
416
m_currentDisplayMode = CDV_SIMILARITY;
419
m_currentDisplayMode = CDV_LEVELSFROMTOP;
422
m_currentDisplayMode = CDV_MINBRANCHLENGTH;
425
m_currentDisplayMode = CDV_LOADED;
428
m_currentDisplayMode = CDV_SINGLE;
434
if( m_propShowVoxelTriangulation->changed( true ) )
440
if( m_showNotInClusters->changed( true ) )
445
if( m_propMinSizeToColor->changed( true ) )
447
handleMinSizeChanged();
450
if( m_buttonLabelSelection->changed() )
455
if( m_propShowDendrogram->changed( true ) || m_propResizeWithWindow->changed( true ) || m_propDendrogramSizeX->changed( true ) ||
456
m_propDendrogramSizeY->changed( true ) || m_propDendrogramOffsetX->changed( true ) || m_propDendrogramOffsetY->changed( true ) ||
457
m_propPlotHeightByLevel->changed( true ) || m_propShowSelectedButtons->changed() )
459
m_dendrogramDirty = true;
462
if( m_buttonUpdateOutput->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
465
m_buttonUpdateOutput->set( WPVBaseTypes::PV_TRIGGER_READY, false );
468
if( m_propZoomIn->changed( true ) )
471
m_zoomRoot = m_propSelectedCluster->get( true );
472
m_dendrogramDirty = true;
473
m_propZoomIn->set( WPVBaseTypes::PV_TRIGGER_READY, true );
474
m_propZoomIn->get( true );
477
if( m_propZoomOut->changed( true ) )
480
m_dendrogramDirty = true;
481
m_propZoomOut->set( WPVBaseTypes::PV_TRIGGER_READY, true );
487
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_moduleNode );
490
void WMClusterDisplayVoxels::updateAll()
492
switch ( m_currentDisplayMode )
495
m_activatedClusters.clear();
496
m_activatedClusters.push_back( m_propSelectedCluster->get( true ) );
497
m_currentDisplayModeString = std::string( "Single selection" );
500
m_activatedClusters = m_tree.findXBiggestClusters( m_propSelectedCluster->get(), m_propXBiggestClusters->get( true ) );
501
m_currentDisplayModeString = std::string( "Biggest clusters" );
504
m_activatedClusters = m_tree.findXClusters( m_propSelectedCluster->get(), m_propXClusters->get( true ) );
505
m_currentDisplayModeString = std::string( "X clusters" );
508
m_activatedClusters = m_tree.findClustersForValue( m_propValue->get( true ) );
509
m_currentDisplayModeString = std::string( "Similarity value selection" );
511
case CDV_LEVELSFROMTOP:
512
m_activatedClusters = m_tree.downXLevelsFromTop( m_propLevelsFromTop->get( true ), m_propHideOutliers->get( true ) );
513
m_currentDisplayModeString = std::string( "Levels from top" );
515
case CDV_MINBRANCHLENGTH:
516
m_activatedClusters = m_tree.findClustersForBranchLength( m_propMinBranchLength->get( true ), m_propMinBranchSize->get( true ) );
517
m_currentDisplayModeString = std::string( "Minimum branch length" );
520
m_activatedClusters = m_loadedPartitions[ m_propSelectedLoadedPartion->get( true ) - 1 ];
521
m_currentDisplayModeString = std::string( "Loaded Partition" );
528
// set colors for cluster in the tree
529
m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
530
for( size_t k = 0; k < m_activatedClusters.size(); ++k )
532
size_t current = m_activatedClusters[k];
533
//m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
534
m_tree.colorCluster( current, m_clusterColors[current] );
537
// redraw the texture
539
m_data.resize( m_grid->size(), 0 );
540
std::vector<size_t> vox = m_tree.getVoxelsForCluster( m_tree.getClusterCount() - 1 );
541
if( m_showNotInClusters->get() )
543
for( size_t k = 0; k < vox.size(); ++k )
545
m_data[vox[k]] = 999999;
548
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
550
std::vector<size_t> voxels = m_tree.getVoxelsForCluster( m_activatedClusters[i] );
552
for( size_t k = 0; k < voxels.size(); ++k )
554
m_data[voxels[k]] = i + 1;
558
unsigned char* data = m_texture->getImage()->data();
559
for( size_t i = 0; i < m_grid->size(); ++i )
561
if( m_data[i] == 999999 )
564
data[i * 3 + 1] = 75;
565
data[i * 3 + 2] = 75;
567
else if( m_data[i] != 0 )
569
WColor color = m_clusterColors[m_activatedClusters[m_data[i]-1]];
570
data[i * 3 ] = color[0] * 255;
571
data[i * 3 + 1] = color[1] * 255;
572
data[i * 3 + 2] = color[2] * 255;
577
data[i * 3 + 1] = 0.0;
578
data[i * 3 + 2] = 0.0;
581
m_texture->dirtyTextureObject();
586
m_selectionChanged = true;
587
m_dendrogramDirty = true;
590
void WMClusterDisplayVoxels::handleMinSizeChanged()
592
m_dendrogramDirty = true;
595
bool WMClusterDisplayVoxels::loadClustering( boost::filesystem::path clusterFile )
597
debugLog() << "start parsing tree file...";
599
WFileParser parser( clusterFile.string() );
600
if( !parser.readFile() )
602
debugLog() << "parser error";
606
std::vector<std::string>lines = parser.getRawLines();
608
if( lines.size() == 0 )
610
debugLog() << "file is empty";
614
std::vector< std::vector< std::string> >coords = parser.getLinesForTagSeparated( "coordinates" );
616
for( size_t i = 0; i < coords.size(); ++i )
618
std::vector< std::string > svec = coords[i];
620
m_tree.addLeaf( m_grid->getVoxelNum( boost::lexical_cast< size_t >( svec[0] ),
621
boost::lexical_cast< size_t >( svec[1] ),
622
boost::lexical_cast< size_t >( svec[2] ) ) );
625
std::vector< std::vector< std::string> >clusters = parser.getLinesForTagSeparated( "clusters" );
627
for( size_t i = 0; i < clusters.size(); ++i )
629
std::vector< std::string > svec = clusters[i];
631
m_tree.addCluster( boost::lexical_cast< size_t >( svec[0] ),
632
boost::lexical_cast< size_t >( svec[1] ),
633
boost::lexical_cast< float >( svec[2] ) );
636
std::vector< std::vector< std::string> >partitions = parser.getLinesForTagSeparated( "partitions" );
638
for( size_t i = 0; i < partitions.size(); ++i )
640
std::vector< std::string > svec = partitions[i];
642
std::vector<size_t>partition;
644
for( size_t k = 0; k < svec.size(); ++k )
646
partition.push_back( boost::lexical_cast< size_t >( svec[k] ) );
648
m_loadedPartitions.push_back( partition );
652
m_clusterColors.resize( m_tree.getClusterCount() );
653
initColors( m_tree.getClusterCount() - 1, 0 );
657
void WMClusterDisplayVoxels::initColors( size_t root, size_t index )
659
if( m_tree.size( root ) == 1 )
661
m_clusterColors[root] = wge::getNthHSVColor( index );
664
m_clusterColors[root] = wge::getNthHSVColor( index );
665
size_t left = m_tree.getChildren( root ).first;
666
size_t right = m_tree.getChildren( root ).second;
667
if( m_tree.size( left ) >= m_tree.size( right ) )
669
initColors( left, index );
670
initColors( right, ++m_colorIndex );
674
initColors( left, ++m_colorIndex );
675
initColors( right, index );
679
void WMClusterDisplayVoxels::createTexture()
681
osg::ref_ptr< osg::Image > ima = new osg::Image;
682
ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
683
unsigned char* data = ima->data();
684
m_data.resize( m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(), 0 );
686
for( unsigned int i = 0; i < m_grid->size() * 3; ++i )
691
m_texture = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
692
m_texture->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
693
m_texture->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
694
m_texture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER );
695
m_texture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER );
696
m_texture->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER );
697
m_texture->setImage( ima );
698
m_texture->setResizeNonPowerOfTwoHint( false );
700
WKernel::getRunningKernel()->getSelectionManager()->setTexture( m_texture, m_grid );
701
WKernel::getRunningKernel()->getSelectionManager()->setShader( 0 );
702
WKernel::getRunningKernel()->getSelectionManager()->setUseTexture( true );
704
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
707
// osg::ref_ptr< osg::Image > ima = new osg::Image;
708
// ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
710
// unsigned char* data = ima->data();
711
// m_data.resize( m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(), 0 );
713
// for( unsigned int i = 0; i < m_grid->size() * 3; ++i )
718
// m_texture = osg::ref_ptr< WGETexture3D >( new WGETexture3D( ima ) );
719
// m_texture->setFilterMinMag( osg::Texture3D::LINEAR );
720
// m_texture->setWrapSTR( osg::Texture::CLAMP_TO_BORDER );
721
// m_texture->colormap()->set( m_texture->colormap()->get().newSelector( WItemSelector::IndexList( 1, 4 ) ) );
722
// m_properties->addProperty( m_texture->alpha() );
724
// WGEColormapping::registerTexture( m_texture, "Cluster Texture" );
727
void WMClusterDisplayVoxels::createMesh()
731
for( size_t k = 1; k <= m_activatedClusters.size(); ++k )
733
WMarchingLegoAlgorithm mlAlgo;
734
m_triMeshes.push_back( mlAlgo.genSurfaceOneValue( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(),
735
m_grid->getTransformationMatrix(),
740
if( m_showNotInClusters->get() )
742
WMarchingLegoAlgorithm mlAlgo;
743
m_nonActiveMesh = mlAlgo.genSurfaceOneValue( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(),
744
m_grid->getTransformationMatrix(),
750
void WMClusterDisplayVoxels::renderMesh()
752
if( !m_outputGeodes.empty() )
754
for( size_t i = 0; i < m_outputGeodes.size(); ++i )
756
m_meshNode->remove( m_outputGeodes[i] );
758
m_outputGeodes.clear();
761
if( m_propShowVoxelTriangulation->get( true ) )
763
for( size_t i = 0; i < m_triMeshes.size(); ++i )
765
osg::Geometry* surfaceGeometry = new osg::Geometry();
766
osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
768
outputGeode->setName( ( std::string( "cluster" ) + boost::lexical_cast<std::string>( m_activatedClusters[i] ) ).c_str() );
770
surfaceGeometry->setVertexArray( m_triMeshes[i]->getVertexArray() );
772
// ------------------------------------------------
774
surfaceGeometry->setNormalArray( m_triMeshes[i]->getTriangleNormalArray() );
775
surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
777
// ------------------------------------------------
779
osg::Vec4Array* colors = new osg::Vec4Array;
780
colors->push_back( m_clusterColors[m_activatedClusters[i]] );
781
surfaceGeometry->setColorArray( colors );
782
surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
784
osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
786
std::vector< size_t >tris = m_triMeshes[i]->getTriangles();
787
surfaceElement->reserve( tris.size() );
789
for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
791
surfaceElement->push_back( tris[vertId] );
793
surfaceGeometry->addPrimitiveSet( surfaceElement );
794
outputGeode->addDrawable( surfaceGeometry );
796
osg::StateSet* state = outputGeode->getOrCreateStateSet();
797
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
798
lightModel->setTwoSided( true );
799
state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
800
state->setMode( GL_BLEND, osg::StateAttribute::ON );
802
m_meshNode->insert( outputGeode );
803
m_outputGeodes.push_back( outputGeode );
806
if( m_propShowVoxelTriangulation->get( true ) && m_showNotInClusters->get() )
808
osg::Geometry* surfaceGeometry = new osg::Geometry();
809
osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
811
outputGeode->setName( ( std::string( "non active" ) ).c_str() );
813
surfaceGeometry->setVertexArray( m_nonActiveMesh->getVertexArray() );
815
// ------------------------------------------------
817
surfaceGeometry->setNormalArray( m_nonActiveMesh->getTriangleNormalArray() );
818
surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
820
// ------------------------------------------------
822
osg::Vec4Array* colors = new osg::Vec4Array;
824
colors->push_back( osg::Vec4( 0.3, 0.3, 0.3, 1.0f ) );
825
surfaceGeometry->setColorArray( colors );
826
surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
828
osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
830
std::vector< size_t >tris = m_nonActiveMesh->getTriangles();
831
surfaceElement->reserve( tris.size() );
833
for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
835
surfaceElement->push_back( tris[vertId] );
837
surfaceGeometry->addPrimitiveSet( surfaceElement );
838
outputGeode->addDrawable( surfaceGeometry );
840
osg::StateSet* state = outputGeode->getOrCreateStateSet();
841
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
842
lightModel->setTwoSided( true );
843
state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
844
state->setMode( GL_BLEND, osg::StateAttribute::ON );
846
m_meshNode->insert( outputGeode );
847
m_outputGeodes.push_back( outputGeode );
851
void WMClusterDisplayVoxels::initWidgets()
853
osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
855
int height = viewer->getCamera()->getViewport()->height();
856
int width = viewer->getCamera()->getViewport()->width();
858
m_oldViewHeight = height;
859
m_oldViewWidth = width;
861
m_moduleNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
862
m_dendrogramNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
863
m_meshNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
864
m_moduleNode->insert( m_dendrogramNode );
865
m_moduleNode->insert( m_meshNode );
867
m_wm = new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
869
m_camera = new osg::Camera();
870
m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
872
m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
873
m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
874
m_camera->setViewMatrix( osg::Matrix::identity() );
875
m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
876
m_camera->setRenderOrder( osg::Camera::POST_RENDER );
878
m_dendrogramNode->addChild( m_camera );
879
m_camera->addChild( m_wm );
881
viewer->addEventHandler( new osgWidget::MouseHandler( m_wm ) );
882
viewer->addEventHandler( new osgWidget::KeyboardHandler( m_wm ) );
883
viewer->addEventHandler( new osgWidget::ResizeHandler( m_wm, m_camera ) );
884
viewer->addEventHandler( new osgWidget::CameraSwitchHandler( m_wm, m_camera ) );
885
viewer->addEventHandler( new osgViewer::StatsHandler() );
886
viewer->addEventHandler( new osgViewer::WindowSizeHandler() );
887
viewer->addEventHandler( new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
889
m_wm->resizeAllWindows();
891
m_moduleNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMClusterDisplayVoxels::updateWidgets, this ) ) );
892
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_moduleNode );
895
void WMClusterDisplayVoxels::updateWidgets()
897
osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
899
int height = viewer->getCamera()->getViewport()->height();
900
int width = viewer->getCamera()->getViewport()->width();
902
int rows = ( height - 20 ) / 20;
903
int buttonWidth = 70;
905
if( ( height != m_oldViewHeight ) || width != m_oldViewWidth )
907
m_oldViewHeight = height;
908
m_oldViewWidth = width;
910
m_dendrogramDirty = true;
913
bool buttonClicked = widgetClicked();
915
if( !buttonClicked && !m_dendrogramDirty )
920
if( m_selectionChanged || m_propShowSelectedButtons->changed() || m_dendrogramDirty )
922
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
924
m_wm->removeChild( m_activeClustersButtonList[i] );
927
m_activeClustersButtonList.clear();
929
if( m_propShowSelectedButtons->get( true ) )
931
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
933
osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
934
osgWidget::Box::VERTICAL, true, true ) );
935
newButton->setPosition( osg::Vec3( 5.f + ( i / rows ) * buttonWidth, ( i % rows ) * 20.f, 0 ) );
936
newButton->setId( m_activatedClusters[i] );
937
newButton->managed( m_wm );
938
m_wm->addChild( newButton );
939
m_activeClustersButtonList.push_back( newButton );
940
newButton->setBackgroundColor( m_clusterColors[m_activatedClusters[i]] );
946
osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
947
osgWidget::Box::VERTICAL, true, true ) );
948
newButton->setPosition( osg::Vec3( 5.f, height - 20.f, 0 ) );
949
newButton->setId( 0 );
950
newButton->setLabel( m_currentDisplayModeString );
951
newButton->managed( m_wm );
952
m_wm->addChild( newButton );
953
m_activeClustersButtonList.push_back( newButton );
954
newButton->setBackgroundColor( wge::getNthHSVColor( m_currentDisplayMode ) );
956
m_selectionChanged = false;
958
m_wm->resizeAllWindows();
960
if( m_propShowSelectedButtons && buttonClicked )
962
m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
963
for( size_t k = 0; k < m_activatedClusters.size(); ++k )
965
if( m_activeClustersButtonList[k]->pushed() )
967
size_t current = m_activatedClusters[k];
968
//m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
969
m_tree.colorCluster( current, m_clusterColors[current] );
972
m_dendrogramDirty = true;
977
if( m_dendrogramDirty )
979
m_camera->removeChild( m_dendrogramGeode );
980
//m_camera->removeChild( 1, 1 );
982
int dwidth = m_propDendrogramSizeX->get( true );
983
int dheight = m_propDendrogramSizeY->get( true );
984
int dxOff = m_propDendrogramOffsetX->get( true );
985
int dyOff = m_propDendrogramOffsetY->get( true );
987
if( m_propShowDendrogram->get( true ) )
989
size_t rootCluster = m_tree.getClusterCount() - 1;
993
rootCluster = m_zoomRoot;
997
if( m_propResizeWithWindow->get( true ) )
999
if( m_propShowSelectedButtons->get() )
1001
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1002
m_propMinSizeToColor->get(), width - ( ( m_activatedClusters.size() / rows ) + 1 ) * buttonWidth, height / 2 ,
1003
( ( m_activatedClusters.size() / rows ) + 1 ) * buttonWidth );
1007
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1008
m_propMinSizeToColor->get(), width - 20, height / 2 , 10 );
1013
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1014
m_propMinSizeToColor->get(), dwidth, dheight, dxOff, dyOff );
1016
m_camera->addChild( m_dendrogramGeode );
1018
m_dendrogramDirty = false;
1022
bool WMClusterDisplayVoxels::widgetClicked()
1024
bool clicked = false;
1025
bool selectionChanged = false;
1027
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
1029
if( m_activeClustersButtonList[i]->clicked() )
1031
if( m_activeClustersButtonList[i]->getId() < 10000000 )
1033
selectionChanged = true;
1039
if( selectionChanged )
1041
std::vector<size_t>activeClusters;
1042
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
1044
if( m_activeClustersButtonList[i]->pushed() )
1046
if( m_outputGeodes.size() > i )
1048
m_outputGeodes[i]->setNodeMask( 0xFFFFFFFF );
1053
if( m_outputGeodes.size() > i )
1055
m_outputGeodes[i]->setNodeMask( 0x00000000 );
1063
void WMClusterDisplayVoxels::dendrogramClick( WPickInfo pickInfo )
1065
if( !m_propShowDendrogram->get() || !( pickInfo.getName() == "nothing" ) )
1069
int x = pickInfo.getPickPixel().x();
1070
int y = pickInfo.getPickPixel().y();
1072
size_t cluster = m_dendrogramGeode->getClickedCluster( x, y );
1073
//std::cout << cluster << std::endl;
1074
m_propSelectedCluster->set( cluster );
1075
m_buttonExecuteSelection->set( WPVBaseTypes::PV_TRIGGER_TRIGGERED );
1078
void WMClusterDisplayVoxels::updateOutDataset()
1080
WAssert( m_dataSet, "" );
1081
WAssert( m_dataSet->getValueSet(), "" );
1082
WAssert( m_dataSet->getGrid(), "" );
1084
boost::shared_ptr< std::vector< float > >ptr( new std::vector< float >( m_data.size() ) );
1086
for( size_t i = 0; i < m_data.size(); ++i )
1088
ptr->at( i ) = static_cast<float>( m_data[i] );
1091
boost::shared_ptr< WValueSet< float > > vs =
1092
boost::shared_ptr< WValueSet< float > >( new WValueSet< float >( 0, 1, ptr, W_DT_FLOAT ) );
1094
m_outData = boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( vs, m_grid ) );
1095
m_output->updateData( m_outData );
1098
void WMClusterDisplayVoxels::setButtonLabels()
1100
if( m_propShowSelectedButtons->get() )
1103
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
1105
if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 0 )
1107
ns = boost::lexical_cast<std::string>( m_activatedClusters[i] );
1109
else if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 1 )
1111
ns = boost::lexical_cast<std::string>( m_tree.size( m_activatedClusters[i] ) );
1113
else if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 2 )
1115
ns = boost::lexical_cast<std::string>( m_tree.getLevel( m_activatedClusters[i] ) );
1119
ns = boost::lexical_cast<std::string>( m_tree.getCustomData( m_activatedClusters[i] ) );
1122
ns = ns.substr( 0, 8 );
1127
for( size_t k = 8 - ns.size(); k > 0; --k )
1131
ns = std::string( " " ) + ns;
1135
ns = ns + std::string( " " );
1138
if( m_activeClustersButtonList.size() > i )
1140
m_activeClustersButtonList[i]->setLabel( ns );