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/WStringUtils.h"
38
#include "core/common/WPathHelper.h"
39
#include "core/common/WPropertyHelper.h"
40
#include "core/graphicsEngine/algorithms/WMarchingLegoAlgorithm.h"
41
#include "core/graphicsEngine/WGEColormapping.h"
42
#include "core/graphicsEngine/WGEUtils.h"
43
#include "core/kernel/WKernel.h"
44
#include "core/kernel/WSelectionManager.h"
46
#include "WFileParser.h"
47
#include "WMClusterDisplayVoxels.h"
48
#include "WMClusterDisplayVoxels.xpm"
50
// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
51
W_LOADABLE_MODULE( WMClusterDisplayVoxels )
53
WMClusterDisplayVoxels::WMClusterDisplayVoxels():
55
m_currentDisplayMode( CDV_SINGLE ),
56
m_currentDisplayModeString( "" ),
57
m_moduleNode( new WGEGroupNode() ),
58
m_dendrogramNode( new WGEGroupNode() ),
59
m_meshNode( new WGEGroupNode() ),
60
m_selectionChanged( false ),
61
m_dendrogramDirty( false )
65
WMClusterDisplayVoxels::~WMClusterDisplayVoxels()
70
boost::shared_ptr< WModule > WMClusterDisplayVoxels::factory() const
72
// See "src/modules/template/" for an extensively documented example.
73
return boost::shared_ptr< WModule >( new WMClusterDisplayVoxels() );
76
const char** WMClusterDisplayVoxels::getXPMIcon() const
78
return clusterDisplayVoxels_xpm;
80
const std::string WMClusterDisplayVoxels::getName() const
82
// Specify your module name here. This name must be UNIQUE!
83
return "ClusterDisplayVoxels";
86
const std::string WMClusterDisplayVoxels::getDescription() const
88
// Specify your module description here. Be detailed. This text is read by the user.
89
// See "src/modules/template/" for an extensively documented example.
90
return "Visualizes voxel clusterings in texture and 3D view";
93
void WMClusterDisplayVoxels::connectors()
95
// the input dataset is just used as source for resolurtion and transformation matrix
96
m_input = boost::shared_ptr< WModuleInputData < WDataSetSingle > >(
97
new WModuleInputData< WDataSetSingle >( shared_from_this(), "in", "The input dataset." ) );
98
addConnector( m_input );
100
m_output = boost::shared_ptr< WModuleOutputData < WDataSetScalar > >(
101
new WModuleOutputData< WDataSetScalar >( shared_from_this(), "out", "The extracted image." ) );
102
addConnector( m_output );
104
WModule::connectors();
107
void WMClusterDisplayVoxels::properties()
109
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
111
m_propClusterFile = m_properties->addProperty( "Cluster file", "", boost::filesystem::path( "/SCR/schurade/data/david/whole/avg.txt" ) );
112
m_propReadTrigger = m_properties->addProperty( "Do read", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
116
m_groupSelection = m_properties->addPropertyGroup( "Cluster selections", "Groups the different cluster selection methods" ); //NOLINT
118
m_clusterSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
119
m_clusterSelectionsList->addItem( "Single", "" );
120
m_clusterSelectionsList->addItem( "Biggest", "" );
121
m_clusterSelectionsList->addItem( "X Clusters", "" );
122
m_clusterSelectionsList->addItem( "Similarity", "" );
123
m_clusterSelectionsList->addItem( "Levels from top", "" );
124
m_clusterSelectionsList->addItem( "Minimum branch length", "" );
125
m_clusterSelectionsList->addItem( "Loaded partition", "" );
127
m_clusterSelection = m_groupSelection->addProperty( "Selection method", "selection",
128
m_clusterSelectionsList->getSelectorFirst(), m_propCondition );
129
WPropertyHelper::PC_SELECTONLYONE::addTo( m_clusterSelection );
133
m_propSelectedCluster = m_groupSelection->addProperty( "Selected Cluster", "Selects a single cluster by number.", 0, m_propCondition );
134
m_propSelectedCluster->setMin( 0 );
135
m_propSelectedCluster->setMax( 0 );
137
m_propXBiggestClusters = m_groupSelection->addProperty( "Biggest Clusters", "Selects a number of biggest clusters.", 5, m_propCondition );
138
m_propXBiggestClusters->setMin( 1 );
139
m_propXBiggestClusters->setMax( 1000 );
141
m_propXClusters = m_groupSelection->addProperty( "X Clusters", "Selects a number of clusters by dividing clusters.", 5, m_propCondition );
142
m_propXClusters->setMin( 1 );
143
m_propXClusters->setMax( 1000 );
145
m_propValue = m_groupSelection->addProperty( "Similarity Value", "Selects clusters below a given similarity value", 1.0, m_propCondition );
146
m_propValue->setMin( 0.0 );
147
m_propValue->setMax( 1.0 );
149
m_propLevelsFromTop = m_groupSelection->addProperty( "Levels from top", "", 0, m_propCondition );
150
m_propHideOutliers = m_groupSelection->addProperty( "Hide outliers", "", false, m_propCondition );
152
m_propSelectedLoadedPartion = m_groupSelection->addProperty( "Loaded Partition", "Activates a predetermined partition, loaded from file", 0, m_propCondition ); // NOLINT
153
m_propSelectedLoadedPartion->setMin( 1 );
154
m_propSelectedLoadedPartion->setMax( 1 );
156
m_propMinBranchLength = m_groupSelection->addProperty( "Minimum branch length", "", 0.1, m_propCondition );
157
m_propMinBranchLength->setMin( 0.0 );
158
m_propMinBranchLength->setMax( 1.0 );
160
m_propMinBranchSize = m_groupSelection->addProperty( "Minimum branch size", "", 50, m_propCondition );
161
m_propMinBranchSize->setMin( 1 );
162
m_propMinBranchSize->setMax( 500 );
164
m_buttonExecuteSelection = m_groupSelection->addProperty( "Update", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
166
m_propShowSelectedButtons = m_groupSelection->addProperty( "Show Buttons", "Shows/Hides the buttons for selected cluster on the left side", true, m_propCondition ); //NOLINT
168
m_buttonLabelList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
169
m_buttonLabelList->addItem( "Number", "" );
170
m_buttonLabelList->addItem( "Size", "" );
171
m_buttonLabelList->addItem( "Level", "" );
172
m_buttonLabelList->addItem( "Similarity", "" );
174
m_buttonLabelSelection = m_groupSelection->addProperty( "Button label", "selection",
175
m_buttonLabelList->getSelectorFirst(), m_propCondition );
176
WPropertyHelper::PC_SELECTONLYONE::addTo( m_buttonLabelSelection );
179
// Group Triangulation
180
m_groupTriangulation = m_properties->addPropertyGroup( "Triangulation", "Groups the triangulation properties" ); //NOLINT
181
m_propShowVoxelTriangulation = m_groupTriangulation->addProperty( "Triangulate", "", false, m_propCondition );
182
m_showNotInClusters = m_groupTriangulation->addProperty( "Show non active", "", false, m_propCondition );
185
m_groupDendrogram = m_properties->addPropertyGroup( "Dendrogram", "Properties only related to the dendrogram." );
187
m_propShowDendrogram = m_groupDendrogram->addProperty( "Show dendrogram", "", true, m_propCondition );
188
m_propPlotHeightByLevel = m_groupDendrogram->addProperty( "Height by Level or Value", "", false, m_propCondition );
190
m_propMinSizeToColor = m_groupDendrogram->addProperty( "Min size to show", "Specifies a minimum size for a cluster to be drawn", 1, m_propCondition ); // NOLINT
191
m_propMinSizeToColor->setMin( 1 );
192
m_propMinSizeToColor->setMax( 200 );
194
m_propZoomIn = m_groupDendrogram->addProperty( "Zoom in", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
195
m_propZoomOut = m_groupDendrogram->addProperty( "Zoom out", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
197
m_propResizeWithWindow = m_groupDendrogram->addProperty( "Resize with window", "", true, m_propCondition );
199
m_propDendrogramSizeX = m_groupDendrogram->addProperty( "Width", "", 100, m_propCondition );
200
m_propDendrogramSizeX->setMin( 0 );
201
m_propDendrogramSizeX->setMax( 10000 );
202
m_propDendrogramSizeY = m_groupDendrogram->addProperty( "Height", "", 100, m_propCondition );
203
m_propDendrogramSizeY->setMin( 0 );
204
m_propDendrogramSizeY->setMax( 10000 );
205
m_propDendrogramOffsetX = m_groupDendrogram->addProperty( "Horizontal position", "", 100, m_propCondition );
206
m_propDendrogramOffsetX->setMin( -9000 );
207
m_propDendrogramOffsetX->setMax( 1000 );
208
m_propDendrogramOffsetY = m_groupDendrogram->addProperty( "Verctical position", "", 100, m_propCondition );
209
m_propDendrogramOffsetY->setMin( -9000 );
210
m_propDendrogramOffsetY->setMax( 1000 );
212
m_groupSelection->setHidden( true );
213
m_groupTriangulation->setHidden( true );
214
m_groupDendrogram->setHidden( true );
216
m_buttonUpdateOutput = m_properties->addProperty( "Update output", "Updates the output connector",
217
WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
221
m_infoCountLeafes = m_infoProperties->addProperty( "Count voxels", "", 0 );
222
m_infoCountClusters = m_infoProperties->addProperty( "Count clusters", "", 0 );
223
m_infoMaxLevel = m_infoProperties->addProperty( "Max Level", "", 0 );
225
WModule::properties();
228
void WMClusterDisplayVoxels::setPropertyBoundaries()
230
m_propSelectedCluster->setMin( m_tree.getLeafCount() );
231
m_propSelectedCluster->setMax( m_tree.getClusterCount() - 1 );
233
m_propSelectedCluster->setMin( 0 );
234
m_propSelectedCluster->setMax( m_tree.getClusterCount() - 1 );
235
m_propSelectedCluster->set( m_tree.getClusterCount() - 1 );
237
m_infoCountLeafes->set( m_tree.getLeafCount() );
238
m_infoCountClusters->set( m_tree.getClusterCount() );
239
m_infoMaxLevel->set( m_tree.getMaxLevel() );
241
m_propMinSizeToColor->setMax( 1000 );
242
m_rootCluster = m_propSelectedCluster->get();
244
m_propLevelsFromTop->setMin( 0 );
245
m_propLevelsFromTop->setMax( m_tree.getMaxLevel() );
247
if( m_loadedPartitions.empty() )
249
m_propSelectedLoadedPartion->setHidden( true );
253
m_propSelectedLoadedPartion->setMin( 1 );
254
m_propSelectedLoadedPartion->setMax( m_loadedPartitions.size() );
258
m_zoomRoot = m_propSelectedCluster->get();
261
void WMClusterDisplayVoxels::moduleMain()
263
boost::signals2::connection con = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getPickHandler()->getPickSignal()->
264
connect( boost::bind( &WMClusterDisplayVoxels::dendrogramClick, this, _1 ) );
267
m_moduleState.setResetable( true, true );
268
m_moduleState.add( m_input->getDataChangedCondition() );
269
m_moduleState.add( m_propCondition );
270
m_moduleState.add( m_active->getUpdateCondition() );
274
// wait for a dataset to be connected, most likely an anatomy dataset
275
while( !m_shutdownFlag() )
277
m_moduleState.wait();
279
if( m_shutdownFlag() )
284
boost::shared_ptr< WDataSetSingle > newDataSet = m_input->getData();
285
bool dataChanged = ( m_dataSet != newDataSet );
286
bool dataValid = ( newDataSet );
292
m_dataSet = newDataSet;
293
m_grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
299
// wait for a cluster file to be loaded
300
while( !m_shutdownFlag() )
302
m_moduleState.wait();
304
if( m_shutdownFlag() )
309
if( m_propReadTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
311
boost::filesystem::path fileName = m_propClusterFile->get();
312
m_propReadTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, true );
314
if( loadClustering( fileName ) )
316
m_propReadTrigger->setHidden( true );
317
m_propClusterFile->setHidden( true );
318
m_groupSelection->setHidden( false );
319
m_groupTriangulation->setHidden( false );
320
m_groupDendrogram->setHidden( false );
327
if( !m_shutdownFlag() )
330
setPropertyBoundaries();
333
m_propSelectedCluster->get( true );
334
m_propSelectedLoadedPartion->get( true );
335
m_propMinSizeToColor->get( true );
336
m_propXClusters->get( true );
337
m_propXBiggestClusters->get( true );
338
m_propValue->get( true );
339
m_propMinBranchLength->get( true );
340
m_propMinBranchSize->get( true );
341
m_propLevelsFromTop->get( true );
342
m_propHideOutliers->get( true );
343
m_showNotInClusters->get( true );
348
// main loop, respond to controls
349
while( !m_shutdownFlag() )
351
m_moduleState.wait();
353
if( m_shutdownFlag() )
358
if( m_clusterSelection->changed( true ) )
360
m_propSelectedCluster->setHidden( true );
361
m_propXBiggestClusters->setHidden( true );
362
m_propXClusters->setHidden( true );
363
m_propValue->setHidden( true );
364
m_propLevelsFromTop->setHidden( true );
365
m_propHideOutliers->setHidden( true );
366
m_propMinBranchLength->setHidden( true );
367
m_propMinBranchSize->setHidden( true );
368
m_propSelectedLoadedPartion->setHidden( true );
370
switch( m_clusterSelection->get( true ).getItemIndexOfSelected( 0 ) )
373
m_propSelectedCluster->setHidden( false );
376
m_propSelectedCluster->setHidden( false );
377
m_propXBiggestClusters->setHidden( false );
380
m_propSelectedCluster->setHidden( false );
381
m_propXClusters->setHidden( false );
384
m_propValue->setHidden( false );
387
m_propLevelsFromTop->setHidden( false );
388
m_propHideOutliers->setHidden( false );
391
m_propMinBranchLength->setHidden( false );
392
m_propMinBranchSize->setHidden( false );
395
m_propSelectedLoadedPartion->setHidden( false );
398
m_propSelectedCluster->setHidden( false );
403
if( m_buttonExecuteSelection->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
405
m_buttonExecuteSelection->set( WPVBaseTypes::PV_TRIGGER_READY, false );
406
switch( m_clusterSelection->get( true ).getItemIndexOfSelected( 0 ) )
409
m_currentDisplayMode = CDV_SINGLE;
412
m_currentDisplayMode = CDV_BIGGEST;
415
m_currentDisplayMode = CDV_X;
418
m_currentDisplayMode = CDV_SIMILARITY;
421
m_currentDisplayMode = CDV_LEVELSFROMTOP;
424
m_currentDisplayMode = CDV_MINBRANCHLENGTH;
427
m_currentDisplayMode = CDV_LOADED;
430
m_currentDisplayMode = CDV_SINGLE;
436
if( m_propShowVoxelTriangulation->changed( true ) )
442
if( m_showNotInClusters->changed( true ) )
447
if( m_propMinSizeToColor->changed( true ) )
449
handleMinSizeChanged();
452
if( m_buttonLabelSelection->changed() )
457
if( m_propShowDendrogram->changed( true ) || m_propResizeWithWindow->changed( true ) || m_propDendrogramSizeX->changed( true ) ||
458
m_propDendrogramSizeY->changed( true ) || m_propDendrogramOffsetX->changed( true ) || m_propDendrogramOffsetY->changed( true ) ||
459
m_propPlotHeightByLevel->changed( true ) || m_propShowSelectedButtons->changed() )
461
m_dendrogramDirty = true;
464
if( m_buttonUpdateOutput->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
467
m_buttonUpdateOutput->set( WPVBaseTypes::PV_TRIGGER_READY, false );
470
if( m_propZoomIn->changed( true ) )
473
m_zoomRoot = m_propSelectedCluster->get( true );
474
m_dendrogramDirty = true;
475
m_propZoomIn->set( WPVBaseTypes::PV_TRIGGER_READY, true );
476
m_propZoomIn->get( true );
479
if( m_propZoomOut->changed( true ) )
482
m_dendrogramDirty = true;
483
m_propZoomOut->set( WPVBaseTypes::PV_TRIGGER_READY, true );
489
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_moduleNode );
492
void WMClusterDisplayVoxels::updateAll()
494
switch( m_currentDisplayMode )
497
m_activatedClusters.clear();
498
m_activatedClusters.push_back( m_propSelectedCluster->get( true ) );
499
m_currentDisplayModeString = std::string( "Single selection" );
502
m_activatedClusters = m_tree.findXBiggestClusters( m_propSelectedCluster->get(), m_propXBiggestClusters->get( true ) );
503
m_currentDisplayModeString = std::string( "Biggest clusters" );
506
m_activatedClusters = m_tree.findXClusters( m_propSelectedCluster->get(), m_propXClusters->get( true ) );
507
m_currentDisplayModeString = std::string( "X clusters" );
510
m_activatedClusters = m_tree.findClustersForValue( m_propValue->get( true ) );
511
m_currentDisplayModeString = std::string( "Similarity value selection" );
513
case CDV_LEVELSFROMTOP:
514
m_activatedClusters = m_tree.downXLevelsFromTop( m_propLevelsFromTop->get( true ), m_propHideOutliers->get( true ) );
515
m_currentDisplayModeString = std::string( "Levels from top" );
517
case CDV_MINBRANCHLENGTH:
518
m_activatedClusters = m_tree.findClustersForBranchLength( m_propMinBranchLength->get( true ), m_propMinBranchSize->get( true ) );
519
m_currentDisplayModeString = std::string( "Minimum branch length" );
522
m_activatedClusters = m_loadedPartitions[ m_propSelectedLoadedPartion->get( true ) - 1 ];
523
m_currentDisplayModeString = std::string( "Loaded Partition" );
530
// set colors for cluster in the tree
531
m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
532
for( size_t k = 0; k < m_activatedClusters.size(); ++k )
534
size_t current = m_activatedClusters[k];
535
//m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
536
m_tree.colorCluster( current, m_clusterColors[current] );
539
// redraw the texture
541
m_data.resize( m_grid->size(), 0 );
542
std::vector<size_t> vox = m_tree.getVoxelsForCluster( m_tree.getClusterCount() - 1 );
543
if( m_showNotInClusters->get() )
545
for( size_t k = 0; k < vox.size(); ++k )
547
m_data[vox[k]] = 999999;
550
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
552
std::vector<size_t> voxels = m_tree.getVoxelsForCluster( m_activatedClusters[i] );
554
for( size_t k = 0; k < voxels.size(); ++k )
556
m_data[voxels[k]] = i + 1;
560
unsigned char* data = m_texture->getImage()->data();
561
for( size_t i = 0; i < m_grid->size(); ++i )
563
if( m_data[i] == 999999 )
566
data[i * 3 + 1] = 75;
567
data[i * 3 + 2] = 75;
569
else if( m_data[i] != 0 )
571
WColor color = m_clusterColors[m_activatedClusters[m_data[i]-1]];
572
data[i * 3 ] = color[0] * 255;
573
data[i * 3 + 1] = color[1] * 255;
574
data[i * 3 + 2] = color[2] * 255;
579
data[i * 3 + 1] = 0.0;
580
data[i * 3 + 2] = 0.0;
583
m_texture->dirtyTextureObject();
588
m_selectionChanged = true;
589
m_dendrogramDirty = true;
592
void WMClusterDisplayVoxels::handleMinSizeChanged()
594
m_dendrogramDirty = true;
597
bool WMClusterDisplayVoxels::loadClustering( boost::filesystem::path clusterFile )
599
debugLog() << "start parsing tree file...";
601
WFileParser parser( clusterFile.string() );
602
if( !parser.readFile() )
604
debugLog() << "parser error";
608
std::vector<std::string>lines = parser.getRawLines();
610
if( lines.size() == 0 )
612
debugLog() << "file is empty";
616
std::vector< std::vector< std::string> >coords = parser.getLinesForTagSeparated( "coordinates" );
618
for( size_t i = 0; i < coords.size(); ++i )
620
std::vector< std::string > svec = coords[i];
622
m_tree.addLeaf( m_grid->getVoxelNum( string_utils::fromString< size_t >( svec[0] ),
623
string_utils::fromString< size_t >( svec[1] ),
624
string_utils::fromString< size_t >( svec[2] ) ) );
627
std::vector< std::vector< std::string> >clusters = parser.getLinesForTagSeparated( "clusters" );
629
for( size_t i = 0; i < clusters.size(); ++i )
631
std::vector< std::string > svec = clusters[i];
633
m_tree.addCluster( string_utils::fromString< size_t >( svec[0] ),
634
string_utils::fromString< size_t >( svec[1] ),
635
string_utils::fromString< float >( svec[2] ) );
638
std::vector< std::vector< std::string> >partitions = parser.getLinesForTagSeparated( "partitions" );
640
for( size_t i = 0; i < partitions.size(); ++i )
642
std::vector< std::string > svec = partitions[i];
644
std::vector<size_t>partition;
646
for( size_t k = 0; k < svec.size(); ++k )
648
partition.push_back( string_utils::fromString< size_t >( svec[k] ) );
650
m_loadedPartitions.push_back( partition );
654
m_clusterColors.resize( m_tree.getClusterCount() );
655
initColors( m_tree.getClusterCount() - 1, 0 );
659
void WMClusterDisplayVoxels::initColors( size_t root, size_t index )
661
if( m_tree.size( root ) == 1 )
663
m_clusterColors[root] = wge::getNthHSVColor( index );
666
m_clusterColors[root] = wge::getNthHSVColor( index );
667
size_t left = m_tree.getChildren( root ).first;
668
size_t right = m_tree.getChildren( root ).second;
669
if( m_tree.size( left ) >= m_tree.size( right ) )
671
initColors( left, index );
672
initColors( right, ++m_colorIndex );
676
initColors( left, ++m_colorIndex );
677
initColors( right, index );
681
void WMClusterDisplayVoxels::createTexture()
683
osg::ref_ptr< osg::Image > ima = new osg::Image;
684
ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
685
unsigned char* data = ima->data();
686
m_data.resize( m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(), 0 );
688
for( unsigned int i = 0; i < m_grid->size() * 3; ++i )
693
m_texture = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
694
m_texture->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
695
m_texture->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
696
m_texture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER );
697
m_texture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER );
698
m_texture->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER );
699
m_texture->setImage( ima );
700
m_texture->setResizeNonPowerOfTwoHint( false );
702
WKernel::getRunningKernel()->getSelectionManager()->setTexture( m_texture, m_grid );
703
WKernel::getRunningKernel()->getSelectionManager()->setShader( 0 );
704
WKernel::getRunningKernel()->getSelectionManager()->setUseTexture( true );
706
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
709
// osg::ref_ptr< osg::Image > ima = new osg::Image;
710
// ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
712
// unsigned char* data = ima->data();
713
// m_data.resize( m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(), 0 );
715
// for( unsigned int i = 0; i < m_grid->size() * 3; ++i )
720
// m_texture = osg::ref_ptr< WGETexture3D >( new WGETexture3D( ima ) );
721
// m_texture->setFilterMinMag( osg::Texture3D::LINEAR );
722
// m_texture->setWrapSTR( osg::Texture::CLAMP_TO_BORDER );
723
// m_texture->colormap()->set( m_texture->colormap()->get().newSelector( WItemSelector::IndexList( 1, 4 ) ) );
724
// m_properties->addProperty( m_texture->alpha() );
726
// WGEColormapping::registerTexture( m_texture, "Cluster Texture" );
729
void WMClusterDisplayVoxels::createMesh()
733
for( size_t k = 1; k <= m_activatedClusters.size(); ++k )
735
WMarchingLegoAlgorithm mlAlgo;
736
m_triMeshes.push_back( mlAlgo.genSurfaceOneValue( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(),
737
m_grid->getTransformationMatrix(),
742
if( m_showNotInClusters->get() )
744
WMarchingLegoAlgorithm mlAlgo;
745
m_nonActiveMesh = mlAlgo.genSurfaceOneValue( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(),
746
m_grid->getTransformationMatrix(),
752
void WMClusterDisplayVoxels::renderMesh()
754
if( !m_outputGeodes.empty() )
756
for( size_t i = 0; i < m_outputGeodes.size(); ++i )
758
m_meshNode->remove( m_outputGeodes[i] );
760
m_outputGeodes.clear();
763
if( m_propShowVoxelTriangulation->get( true ) )
765
for( size_t i = 0; i < m_triMeshes.size(); ++i )
767
osg::Geometry* surfaceGeometry = new osg::Geometry();
768
osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
770
outputGeode->setName( ( std::string( "cluster" ) + string_utils::toString( m_activatedClusters[i] ) ).c_str() );
772
surfaceGeometry->setVertexArray( m_triMeshes[i]->getVertexArray() );
774
// ------------------------------------------------
776
surfaceGeometry->setNormalArray( m_triMeshes[i]->getTriangleNormalArray() );
777
surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
779
// ------------------------------------------------
781
osg::Vec4Array* colors = new osg::Vec4Array;
782
colors->push_back( m_clusterColors[m_activatedClusters[i]] );
783
surfaceGeometry->setColorArray( colors );
784
surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
786
osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
788
std::vector< size_t >tris = m_triMeshes[i]->getTriangles();
789
surfaceElement->reserve( tris.size() );
791
for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
793
surfaceElement->push_back( tris[vertId] );
795
surfaceGeometry->addPrimitiveSet( surfaceElement );
796
outputGeode->addDrawable( surfaceGeometry );
798
osg::StateSet* state = outputGeode->getOrCreateStateSet();
799
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
800
lightModel->setTwoSided( true );
801
state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
802
state->setMode( GL_BLEND, osg::StateAttribute::ON );
804
m_meshNode->insert( outputGeode );
805
m_outputGeodes.push_back( outputGeode );
808
if( m_propShowVoxelTriangulation->get( true ) && m_showNotInClusters->get() )
810
osg::Geometry* surfaceGeometry = new osg::Geometry();
811
osg::ref_ptr< osg::Geode >outputGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
813
outputGeode->setName( ( std::string( "non active" ) ).c_str() );
815
surfaceGeometry->setVertexArray( m_nonActiveMesh->getVertexArray() );
817
// ------------------------------------------------
819
surfaceGeometry->setNormalArray( m_nonActiveMesh->getTriangleNormalArray() );
820
surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
822
// ------------------------------------------------
824
osg::Vec4Array* colors = new osg::Vec4Array;
826
colors->push_back( osg::Vec4( 0.3, 0.3, 0.3, 1.0f ) );
827
surfaceGeometry->setColorArray( colors );
828
surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
830
osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
832
std::vector< size_t >tris = m_nonActiveMesh->getTriangles();
833
surfaceElement->reserve( tris.size() );
835
for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
837
surfaceElement->push_back( tris[vertId] );
839
surfaceGeometry->addPrimitiveSet( surfaceElement );
840
outputGeode->addDrawable( surfaceGeometry );
842
osg::StateSet* state = outputGeode->getOrCreateStateSet();
843
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
844
lightModel->setTwoSided( true );
845
state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
846
state->setMode( GL_BLEND, osg::StateAttribute::ON );
848
m_meshNode->insert( outputGeode );
849
m_outputGeodes.push_back( outputGeode );
853
void WMClusterDisplayVoxels::initWidgets()
855
osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
857
int height = viewer->getCamera()->getViewport()->height();
858
int width = viewer->getCamera()->getViewport()->width();
860
m_oldViewHeight = height;
861
m_oldViewWidth = width;
863
m_moduleNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
864
m_dendrogramNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
865
m_meshNode = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
866
m_moduleNode->insert( m_dendrogramNode );
867
m_moduleNode->insert( m_meshNode );
869
m_wm = new osgWidget::WindowManager( viewer, 0.0f, 0.0f, MASK_2D );
871
m_camera = new osg::Camera();
872
m_camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
874
m_camera->setProjectionMatrix( osg::Matrix::ortho2D( 0.0, width, 0.0f, height ) );
875
m_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
876
m_camera->setViewMatrix( osg::Matrix::identity() );
877
m_camera->setClearMask( GL_DEPTH_BUFFER_BIT );
878
m_camera->setRenderOrder( osg::Camera::POST_RENDER );
880
m_dendrogramNode->addChild( m_camera );
881
m_camera->addChild( m_wm );
883
viewer->addEventHandler( new osgWidget::MouseHandler( m_wm ) );
884
viewer->addEventHandler( new osgWidget::KeyboardHandler( m_wm ) );
885
viewer->addEventHandler( new osgWidget::ResizeHandler( m_wm, m_camera ) );
886
viewer->addEventHandler( new osgWidget::CameraSwitchHandler( m_wm, m_camera ) );
887
viewer->addEventHandler( new osgViewer::StatsHandler() );
888
viewer->addEventHandler( new osgViewer::WindowSizeHandler() );
889
viewer->addEventHandler( new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
891
m_wm->resizeAllWindows();
893
m_moduleNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMClusterDisplayVoxels::updateWidgets, this ) ) );
894
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_moduleNode );
897
void WMClusterDisplayVoxels::updateWidgets()
899
osg::ref_ptr<osgViewer::View> viewer = WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getView();
901
int height = viewer->getCamera()->getViewport()->height();
902
int width = viewer->getCamera()->getViewport()->width();
904
int rows = ( height - 20 ) / 20;
905
int buttonWidth = 70;
907
if( ( height != m_oldViewHeight ) || width != m_oldViewWidth )
909
m_oldViewHeight = height;
910
m_oldViewWidth = width;
912
m_dendrogramDirty = true;
915
bool buttonClicked = widgetClicked();
917
if( !buttonClicked && !m_dendrogramDirty )
922
if( m_selectionChanged || m_propShowSelectedButtons->changed() || m_dendrogramDirty )
924
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
926
m_wm->removeChild( m_activeClustersButtonList[i] );
929
m_activeClustersButtonList.clear();
931
if( m_propShowSelectedButtons->get( true ) )
933
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
935
osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
936
osgWidget::Box::VERTICAL, true, true ) );
937
newButton->setPosition( osg::Vec3( 5.f + ( i / rows ) * buttonWidth, ( i % rows ) * 20.f, 0 ) );
938
newButton->setId( m_activatedClusters[i] );
939
newButton->managed( m_wm );
940
m_wm->addChild( newButton );
941
m_activeClustersButtonList.push_back( newButton );
942
newButton->setBackgroundColor( m_clusterColors[m_activatedClusters[i]] );
948
osg::ref_ptr<WOSGButton> newButton = osg::ref_ptr<WOSGButton>( new WOSGButton( std::string( "" ),
949
osgWidget::Box::VERTICAL, true, true ) );
950
newButton->setPosition( osg::Vec3( 5.f, height - 20.f, 0 ) );
951
newButton->setId( 0 );
952
newButton->setLabel( m_currentDisplayModeString );
953
newButton->managed( m_wm );
954
m_wm->addChild( newButton );
955
m_activeClustersButtonList.push_back( newButton );
956
newButton->setBackgroundColor( wge::getNthHSVColor( m_currentDisplayMode ) );
958
m_selectionChanged = false;
960
m_wm->resizeAllWindows();
962
if( m_propShowSelectedButtons && buttonClicked )
964
m_tree.colorCluster( m_tree.getClusterCount() - 1, WColor( 0.3, 0.3, 0.3, 1.0 ) );
965
for( size_t k = 0; k < m_activatedClusters.size(); ++k )
967
if( m_activeClustersButtonList[k]->pushed() )
969
size_t current = m_activatedClusters[k];
970
//m_tree.colorCluster( current, wge::getNthHSVColor( k ) );
971
m_tree.colorCluster( current, m_clusterColors[current] );
974
m_dendrogramDirty = true;
979
if( m_dendrogramDirty )
981
m_camera->removeChild( m_dendrogramGeode );
982
//m_camera->removeChild( 1, 1 );
984
int dwidth = m_propDendrogramSizeX->get( true );
985
int dheight = m_propDendrogramSizeY->get( true );
986
int dxOff = m_propDendrogramOffsetX->get( true );
987
int dyOff = m_propDendrogramOffsetY->get( true );
989
if( m_propShowDendrogram->get( true ) )
991
size_t rootCluster = m_tree.getClusterCount() - 1;
995
rootCluster = m_zoomRoot;
999
if( m_propResizeWithWindow->get( true ) )
1001
if( m_propShowSelectedButtons->get() )
1003
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1004
m_propMinSizeToColor->get(), width - ( ( m_activatedClusters.size() / rows ) + 1 ) * buttonWidth, height / 2 ,
1005
( ( m_activatedClusters.size() / rows ) + 1 ) * buttonWidth );
1009
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1010
m_propMinSizeToColor->get(), width - 20, height / 2 , 10 );
1015
m_dendrogramGeode = new WDendrogramGeode( &m_tree, rootCluster, m_propPlotHeightByLevel->get( true ),
1016
m_propMinSizeToColor->get(), dwidth, dheight, dxOff, dyOff );
1018
m_camera->addChild( m_dendrogramGeode );
1020
m_dendrogramDirty = false;
1024
bool WMClusterDisplayVoxels::widgetClicked()
1026
bool clicked = false;
1027
bool selectionChanged = false;
1029
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
1031
if( m_activeClustersButtonList[i]->clicked() )
1033
if( m_activeClustersButtonList[i]->getId() < 10000000 )
1035
selectionChanged = true;
1041
if( selectionChanged )
1043
std::vector<size_t>activeClusters;
1044
for( size_t i = 0; i < m_activeClustersButtonList.size(); ++i )
1046
if( m_activeClustersButtonList[i]->pushed() )
1048
if( m_outputGeodes.size() > i )
1050
m_outputGeodes[i]->setNodeMask( 0xFFFFFFFF );
1055
if( m_outputGeodes.size() > i )
1057
m_outputGeodes[i]->setNodeMask( 0x00000000 );
1065
void WMClusterDisplayVoxels::dendrogramClick( WPickInfo pickInfo )
1067
if( !m_propShowDendrogram->get() || !( pickInfo.getName() == "nothing" ) )
1071
int x = pickInfo.getPickPixel().x();
1072
int y = pickInfo.getPickPixel().y();
1074
size_t cluster = m_dendrogramGeode->getClickedCluster( x, y );
1075
//std::cout << cluster << std::endl;
1076
m_propSelectedCluster->set( cluster );
1077
m_buttonExecuteSelection->set( WPVBaseTypes::PV_TRIGGER_TRIGGERED );
1080
void WMClusterDisplayVoxels::updateOutDataset()
1082
WAssert( m_dataSet, "" );
1083
WAssert( m_dataSet->getValueSet(), "" );
1084
WAssert( m_dataSet->getGrid(), "" );
1086
boost::shared_ptr< std::vector< float > >ptr( new std::vector< float >( m_data.size() ) );
1088
for( size_t i = 0; i < m_data.size(); ++i )
1090
ptr->at( i ) = static_cast<float>( m_data[i] );
1093
boost::shared_ptr< WValueSet< float > > vs =
1094
boost::shared_ptr< WValueSet< float > >( new WValueSet< float >( 0, 1, ptr, W_DT_FLOAT ) );
1096
m_outData = boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( vs, m_grid ) );
1097
m_output->updateData( m_outData );
1100
void WMClusterDisplayVoxels::setButtonLabels()
1102
if( m_propShowSelectedButtons->get() )
1105
for( size_t i = 0; i < m_activatedClusters.size(); ++i )
1107
if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 0 )
1109
ns = string_utils::toString( m_activatedClusters[i] );
1111
else if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 1 )
1113
ns = string_utils::toString( m_tree.size( m_activatedClusters[i] ) );
1115
else if( m_buttonLabelSelection->get( true ).getItemIndexOfSelected( 0 ) == 2 )
1117
ns = string_utils::toString( m_tree.getLevel( m_activatedClusters[i] ) );
1121
ns = string_utils::toString( m_tree.getCustomData( m_activatedClusters[i] ) );
1124
ns = ns.substr( 0, 8 );
1129
for( size_t k = 8 - ns.size(); k > 0; --k )
1133
ns = std::string( " " ) + ns;
1137
ns = ns + std::string( " " );
1140
if( m_activeClustersButtonList.size() > i )
1142
m_activeClustersButtonList[i]->setLabel( ns );