~ubuntu-branches/ubuntu/vivid/openwalnut/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/boost153/src/modules/atlasSurfaces/WMAtlasSurfaces.cpp

  • Committer: Package Import Robot
  • Author(s): Sebastian Eichelbaum
  • Date: 2014-03-19 17:46:12 UTC
  • mfrom: (3.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140319174612-e4mgtr1avbq3f7ph
Tags: 1.4.0~rc1+hg3a3147463ee2-1
* Major functionality and stability improvements.
* Several bug fixes
* Changed ttf-liberation dependency to fonts-liberation (Closes: #722405)
* OpenWalnut now works properly with OpenSceneGraph 3.2 (Closes: #718381)
* See http://www.openwalnut.org/versions/2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//---------------------------------------------------------------------------
2
 
//
3
 
// Project: OpenWalnut ( http://www.openwalnut.org )
4
 
//
5
 
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
6
 
// For more information see http://www.openwalnut.org/copying
7
 
//
8
 
// This file is part of OpenWalnut.
9
 
//
10
 
// OpenWalnut is free software: you can redistribute it and/or modify
11
 
// it under the terms of the GNU Lesser General Public License as published by
12
 
// the Free Software Foundation, either version 3 of the License, or
13
 
// (at your option) any later version.
14
 
//
15
 
// OpenWalnut is distributed in the hope that it will be useful,
16
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
// GNU Lesser General Public License for more details.
19
 
//
20
 
// You should have received a copy of the GNU Lesser General Public License
21
 
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22
 
//
23
 
//---------------------------------------------------------------------------
24
 
 
25
 
#include <string>
26
 
#include <fstream>
27
 
#include <vector>
28
 
#include <utility>
29
 
 
30
 
#include <boost/regex.hpp>
31
 
 
32
 
#include <osg/Geode>
33
 
#include <osg/Geometry>
34
 
#include <osg/LightModel>
35
 
#include <osg/Material>
36
 
#include <osg/PolygonMode>
37
 
#include <osg/StateAttribute>
38
 
#include <osg/StateSet>
39
 
 
40
 
#include "core/common/WAssert.h"
41
 
#include "core/common/WPathHelper.h"
42
 
#include "core/common/WThreadedFunction.h"
43
 
#include "core/common/WStringUtils.h"
44
 
#include "core/dataHandler/WDataSetScalar.h"
45
 
#include "core/graphicsEngine/algorithms/WMarchingCubesAlgorithm.h"
46
 
#include "core/graphicsEngine/algorithms/WMarchingLegoAlgorithm.h"
47
 
#include "core/graphicsEngine/WGEGroupNode.h"
48
 
#include "core/graphicsEngine/WGEUtils.h"
49
 
#include "core/graphicsEngine/WROI.h"
50
 
#include "core/graphicsEngine/WROIArbitrary.h"
51
 
#include "core/graphicsEngine/WTriangleMesh.h"
52
 
#include "core/kernel/WKernel.h"
53
 
#include "core/kernel/WROIManager.h"
54
 
#include "WCreateSurfaceJob.h"
55
 
#include "WMAtlasSurfaces.h"
56
 
#include "WMAtlasSurfaces.xpm"
57
 
 
58
 
// This line is needed by the module loader to actually find your module.
59
 
W_LOADABLE_MODULE( WMAtlasSurfaces )
60
 
 
61
 
WMAtlasSurfaces::WMAtlasSurfaces():
62
 
    WModule(),
63
 
    m_dataSet(),
64
 
    m_moduleNode( new WGEGroupNode() ),
65
 
    m_dirty( false ),
66
 
    m_labelsLoaded( false )
67
 
{
68
 
}
69
 
 
70
 
WMAtlasSurfaces::~WMAtlasSurfaces()
71
 
{
72
 
    // Cleanup!
73
 
}
74
 
 
75
 
boost::shared_ptr< WModule > WMAtlasSurfaces::factory() const
76
 
{
77
 
    // See "src/modules/template/" for an extensively documented example.
78
 
    return boost::shared_ptr< WModule >( new WMAtlasSurfaces() );
79
 
}
80
 
 
81
 
const char** WMAtlasSurfaces::getXPMIcon() const
82
 
{
83
 
    return atlas_xpm;
84
 
}
85
 
 
86
 
const std::string WMAtlasSurfaces::getName() const
87
 
{
88
 
    // Specify your module name here. This name must be UNIQUE!
89
 
    return "Atlas Surfaces";
90
 
}
91
 
 
92
 
const std::string WMAtlasSurfaces::getDescription() const
93
 
{
94
 
    return "Use a scalar data set that stores numbers for atlas regions and a "
95
 
        "corresponding text file with labels for the numbers to create "
96
 
        "surfaces bounding the atlas regions. The surfaces can be picked to reveal "
97
 
        "their name in the HUD (module). Regions can be used as ROIs for fiber selection.";
98
 
}
99
 
 
100
 
void WMAtlasSurfaces::connectors()
101
 
{
102
 
    // initialize connectors
103
 
    m_input = boost::shared_ptr< WModuleInputData < WDataSetScalar > >(
104
 
        new WModuleInputData< WDataSetScalar >( shared_from_this(), "in", "Dataset to create atlas surfaces from." ) );
105
 
    // add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
106
 
    addConnector( m_input );
107
 
 
108
 
    // call WModules initialization
109
 
    WModule::connectors();
110
 
}
111
 
 
112
 
void WMAtlasSurfaces::properties()
113
 
{
114
 
    WPropertyBase::PropertyChangeNotifierType propertyCallback = boost::bind( &WMAtlasSurfaces::propertyChanged, this );
115
 
    m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
116
 
 
117
 
    m_labelFile = m_properties->addProperty( "Label file", "", boost::filesystem::path( "" ), m_propCondition );
118
 
    WPropertyHelper::PC_PATHEXISTS::addTo( m_labelFile );
119
 
 
120
 
    m_propCreateRoiTrigger = m_properties->addProperty( "Create Roi",  "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
121
 
 
122
 
    WModule::properties();
123
 
}
124
 
 
125
 
void WMAtlasSurfaces::moduleMain()
126
 
{
127
 
    // use the m_input "data changed" flag
128
 
    m_moduleState.setResetable( true, true );
129
 
    m_moduleState.add( m_propCondition );
130
 
    m_moduleState.add( m_active->getUpdateCondition() );
131
 
    m_moduleState.add( m_input->getDataChangedCondition() );
132
 
 
133
 
    // signal ready state
134
 
    ready();
135
 
 
136
 
    // loop until the module container requests the module to quit
137
 
    while( !m_shutdownFlag() )
138
 
    {
139
 
        m_moduleState.wait();
140
 
 
141
 
        if( m_shutdownFlag() )
142
 
        {
143
 
            break;
144
 
        }
145
 
 
146
 
        if( m_dataSet != m_input->getData() || m_labelFile->changed() )
147
 
        {
148
 
            // acquire data from the input connector
149
 
            m_dataSet = m_input->getData();
150
 
 
151
 
            if( m_labelFile->get( true ) == boost::filesystem::path( "" ) )
152
 
            {
153
 
                std::string fn = m_dataSet->getFilename();
154
 
 
155
 
                std::string ext( "" );
156
 
                if( fn.find( ".nii.gz" ) != std::string::npos )
157
 
                {
158
 
                    ext = ".nii.gz";
159
 
                }
160
 
                else if( fn.find( ".nii" ) != std::string::npos )
161
 
                {
162
 
                    ext = ".nii";
163
 
                }
164
 
 
165
 
                std::string csvExt( ".csv" );
166
 
                if( ext != "" )
167
 
                {
168
 
                    //                    fn.replace( fn.find( ext ), ext.size(), csvExt );
169
 
                }
170
 
                else
171
 
                {
172
 
                    fn.append( csvExt );
173
 
                }
174
 
                m_labelFile->set( fn );
175
 
            }
176
 
 
177
 
            if( !boost::filesystem::exists( m_labelFile->get() ) )
178
 
            {
179
 
                wlog::warn( "Atlas Surfaces" ) << "Expected label file does not exist! (" <<  m_labelFile->get().string() << ")";
180
 
                continue;
181
 
            }
182
 
 
183
 
            loadLabels( m_labelFile->get( true ).string() );
184
 
 
185
 
            switch( ( *m_dataSet ).getValueSet()->getDataType() )
186
 
            {
187
 
                case W_DT_UNSIGNED_CHAR:
188
 
                case W_DT_INT16:
189
 
                case W_DT_SIGNED_INT:
190
 
                    debugLog() << "Starting creating region meshes";
191
 
                    createSurfaces();
192
 
                    debugLog() << "Finished creating region meshes";
193
 
                    debugLog() << "Starting creating OSG nodes";
194
 
                    createOSGNode();
195
 
                    debugLog() << "Finished creating OSG nodes";
196
 
                    m_dirty = true;
197
 
                    break;
198
 
                case W_DT_FLOAT:
199
 
                case W_DT_DOUBLE:
200
 
                default:
201
 
                    WAssert( false, "Wrong data type in AtlasSurfaces module" );
202
 
            }
203
 
        }
204
 
 
205
 
        if( m_active->changed() )
206
 
        {
207
 
            if( m_active->get( true ) )
208
 
            {
209
 
                m_moduleNode->setNodeMask( 0xFFFFFFFF );
210
 
            }
211
 
            else
212
 
            {
213
 
                m_moduleNode->setNodeMask( 0x0 );
214
 
            }
215
 
        }
216
 
 
217
 
        if( m_propCreateRoiTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
218
 
        {
219
 
             m_propCreateRoiTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
220
 
             createRoi();
221
 
        }
222
 
    }
223
 
    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_moduleNode );
224
 
}
225
 
 
226
 
void WMAtlasSurfaces::createSurfaces()
227
 
{
228
 
    boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
229
 
 
230
 
    boost::shared_ptr<WProgressCombiner> newProgress = boost::shared_ptr<WProgressCombiner>( new WProgressCombiner() );
231
 
    boost::shared_ptr<WProgress>pro = boost::shared_ptr<WProgress>( new WProgress( "dummy", m_dataSet->getMax() ) );
232
 
    m_progress->addSubProgress( pro );
233
 
 
234
 
    boost::shared_ptr<WThreadedJobs<WDataSetScalar, size_t> >job;
235
 
 
236
 
    m_regionMeshes2 = boost::shared_ptr< std::vector< boost::shared_ptr< WTriangleMesh > > >(
237
 
            new std::vector< boost::shared_ptr< WTriangleMesh > >( m_dataSet->getMax() + 1 ) );
238
 
 
239
 
    switch( ( *m_dataSet ).getValueSet()->getDataType() )
240
 
    {
241
 
        case W_DT_UNSIGNED_CHAR:
242
 
            job = boost::shared_ptr<WCreateSurfaceJob<unsigned char> >(
243
 
                    new WCreateSurfaceJob<unsigned char>( m_dataSet, m_regionMeshes2, newProgress, pro ) );
244
 
            break;
245
 
        case W_DT_INT16:
246
 
            job = boost::shared_ptr<WCreateSurfaceJob<int16_t> >(
247
 
                    new WCreateSurfaceJob<int16_t>( m_dataSet, m_regionMeshes2, newProgress, pro ) );
248
 
            break;
249
 
        case W_DT_SIGNED_INT:
250
 
            job = boost::shared_ptr<WCreateSurfaceJob<int> >(
251
 
                    new WCreateSurfaceJob<int>( m_dataSet, m_regionMeshes2, newProgress, pro ) );
252
 
            break;
253
 
        case W_DT_FLOAT:
254
 
        case W_DT_DOUBLE:
255
 
        default:
256
 
            WAssert( false, "Unknown data type in AtlasSurfaces module" );
257
 
    }
258
 
 
259
 
    WThreadedFunction< WThreadedJobs<WDataSetScalar, size_t> >threadPool( 4, job );
260
 
    threadPool.run();
261
 
    threadPool.wait();
262
 
 
263
 
    pro->finish();
264
 
 
265
 
    m_possibleSelections = boost::shared_ptr< WItemSelection >( new WItemSelection() );
266
 
 
267
 
    for(size_t i = 1; i < m_dataSet->getMax() + 1; ++i )
268
 
    {
269
 
        std::string label = string_utils::toString( i ) + std::string( " " ) + m_labels[i].second;
270
 
        m_possibleSelections->addItem( label, "" );
271
 
    }
272
 
 
273
 
    m_properties->removeProperty( m_aMultiSelection ); // clear before re-adding
274
 
    m_aMultiSelection  = m_properties->addProperty( "Regions", "Regions", m_possibleSelections->getSelectorAll(),
275
 
                                                                        m_propCondition );
276
 
}
277
 
 
278
 
void WMAtlasSurfaces::createOSGNode()
279
 
{
280
 
    for( size_t i = 1; i < m_regionMeshes2->size(); ++i )
281
 
    {
282
 
        osg::Geometry* surfaceGeometry = new osg::Geometry();
283
 
        osg::ref_ptr< osg::Geode > outputGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
284
 
 
285
 
        std::string label = string_utils::toString( i ) + std::string( " " ) + m_labels[i].second;
286
 
        outputGeode->setName( label );
287
 
 
288
 
        surfaceGeometry->setUseDisplayList( false );
289
 
        surfaceGeometry->setUseVertexBufferObjects( true );
290
 
 
291
 
        surfaceGeometry->setVertexArray( ( *m_regionMeshes2 )[i]->getVertexArray() );
292
 
 
293
 
        // ------------------------------------------------
294
 
        // normals
295
 
        surfaceGeometry->setNormalArray( ( *m_regionMeshes2 )[i]->getVertexNormalArray() );
296
 
        surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
297
 
 
298
 
        // ------------------------------------------------
299
 
        // colors
300
 
        osg::Vec4Array* colors = new osg::Vec4Array;
301
 
 
302
 
        colors->push_back( wge::createColorFromIndex( i ) );
303
 
 
304
 
        surfaceGeometry->setColorArray( colors );
305
 
        surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
306
 
 
307
 
        osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
308
 
 
309
 
        std::vector< size_t >tris = ( *m_regionMeshes2 )[i]->getTriangles();
310
 
        surfaceElement->reserve( tris.size() );
311
 
 
312
 
        for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
313
 
        {
314
 
            surfaceElement->push_back( tris[vertId] );
315
 
        }
316
 
        surfaceGeometry->addPrimitiveSet( surfaceElement );
317
 
        outputGeode->addDrawable( surfaceGeometry );
318
 
 
319
 
        osg::StateSet* state = outputGeode->getOrCreateStateSet();
320
 
        osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
321
 
        lightModel->setTwoSided( true );
322
 
        state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
323
 
        state->setMode(  GL_BLEND, osg::StateAttribute::ON );
324
 
 
325
 
        m_moduleNode->insert( outputGeode );
326
 
    }
327
 
    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_moduleNode );
328
 
    m_moduleNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMAtlasSurfaces::updateGraphics, this ) ) );
329
 
}
330
 
 
331
 
void WMAtlasSurfaces::propertyChanged()
332
 
{
333
 
    m_dirty = true;
334
 
}
335
 
 
336
 
void WMAtlasSurfaces::updateGraphics()
337
 
{
338
 
    if( !m_dirty && !m_aMultiSelection->changed() )
339
 
    {
340
 
        return;
341
 
    }
342
 
 
343
 
    WItemSelector s = m_aMultiSelection->get( true );
344
 
    for( size_t i = 0; i < m_moduleNode->getNumChildren(); ++i )
345
 
    {
346
 
        m_moduleNode->getChild( i )->setNodeMask( 0x0 );
347
 
 
348
 
        for( size_t j = 0; j < s.size(); ++j )
349
 
        {
350
 
            if( s.getItemIndexOfSelected(j) == i )
351
 
            {
352
 
                m_moduleNode->getChild( i )->setNodeMask( 0xFFFFFFFF );
353
 
            }
354
 
        }
355
 
    }
356
 
 
357
 
    m_dirty = false;
358
 
}
359
 
 
360
 
std::vector< std::string > WMAtlasSurfaces::readFile( const std::string fileName )
361
 
{
362
 
    std::ifstream ifs( fileName.c_str(), std::ifstream::in );
363
 
 
364
 
    std::vector< std::string > lines;
365
 
 
366
 
    std::string line;
367
 
 
368
 
    while( !ifs.eof() )
369
 
    {
370
 
        getline( ifs, line );
371
 
 
372
 
        lines.push_back( std::string( line ) );
373
 
    }
374
 
 
375
 
    ifs.close();
376
 
 
377
 
    return lines;
378
 
}
379
 
 
380
 
void WMAtlasSurfaces::loadLabels( std::string fileName )
381
 
{
382
 
    std::vector<std::string> lines;
383
 
 
384
 
    lines = readFile( fileName );
385
 
 
386
 
    if( lines.size() == 0 )
387
 
    {
388
 
        m_labelsLoaded = false;
389
 
        return;
390
 
    }
391
 
 
392
 
    std::vector<std::string>svec;
393
 
 
394
 
    try
395
 
    {
396
 
        for( size_t i = 0; i < lines.size(); ++i )
397
 
        {
398
 
            svec.clear();
399
 
            boost::regex reg( "," );
400
 
            boost::sregex_token_iterator it( lines[i].begin(), lines[i].end(), reg, -1 );
401
 
            boost::sregex_token_iterator end;
402
 
            while( it != end )
403
 
            {
404
 
                svec.push_back( *it++ );
405
 
            }
406
 
            if( svec.size() == 3 )
407
 
            {
408
 
                std::pair< std::string, std::string >newLabel( svec[1], svec[2] );
409
 
                m_labels[ string_utils::fromString< size_t >( svec[0] )] = newLabel;
410
 
            }
411
 
        }
412
 
        m_labelsLoaded = true;
413
 
    }
414
 
    catch( const std::exception& e )
415
 
    {
416
 
        // print this message AFTER creation of WException to have the backtrace before the message
417
 
        WLogger::getLogger()->addLogMessage(
418
 
            std::string( "Problem while loading label file. Probably not suitable content.  Message: " ) + e.what(),
419
 
            "Module (" + getName() + ")", LL_ERROR );
420
 
        m_labels.clear();
421
 
        m_labelsLoaded = false;
422
 
    }
423
 
}
424
 
 
425
 
void WMAtlasSurfaces::createRoi()
426
 
{
427
 
    WItemSelector s = m_aMultiSelection->get( true );
428
 
    for( size_t i = 0; i < m_moduleNode->getNumChildren(); ++i )
429
 
    {
430
 
        for( size_t j = 0; j < s.size(); ++j )
431
 
        {
432
 
            if( s.getItemIndexOfSelected(j) == i )
433
 
            {
434
 
                debugLog() << i << " selected";
435
 
                cutArea( i + 1 );
436
 
            }
437
 
        }
438
 
    }
439
 
}
440
 
 
441
 
void WMAtlasSurfaces::cutArea( int index )
442
 
{
443
 
    boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
444
 
 
445
 
    size_t order = ( *m_dataSet ).getValueSet()->order();
446
 
    size_t vDim = ( *m_dataSet ).getValueSet()->dimension();
447
 
 
448
 
    boost::shared_ptr< WValueSet< unsigned char > > vals;
449
 
    vals =  boost::shared_dynamic_cast< WValueSet< unsigned char > >( ( *m_dataSet ).getValueSet() );
450
 
 
451
 
    boost::shared_ptr< std::vector< float > > newVals = boost::shared_ptr< std::vector< float > >( new std::vector< float >( grid->size(), 0 ) );
452
 
 
453
 
    for( size_t i = 0; i < newVals->size(); ++i )
454
 
    {
455
 
         if( static_cast<int>( vals->getScalar( i ) ) == index )
456
 
         {
457
 
             ( *newVals )[i] = 1.0;
458
 
         }
459
 
    }
460
 
 
461
 
    boost::shared_ptr< WValueSet< float > > newValueSet =
462
 
            boost::shared_ptr< WValueSet< float > >( new WValueSet< float >( order, vDim, newVals, W_DT_FLOAT ) );
463
 
    WMarchingLegoAlgorithm mlAlgo;
464
 
 
465
 
    osg::ref_ptr< WROI > newRoi = osg::ref_ptr< WROI >( new WROIArbitrary(  grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(),
466
 
                                                                            grid->getTransformationMatrix(),
467
 
                                                                            *newValueSet->rawDataVectorPointer(),
468
 
                                                                            1.0, wge::createColorFromIndex( index ) ) );
469
 
    if( m_labelsLoaded )
470
 
    {
471
 
        newRoi->setName( m_labels[index].second );
472
 
    }
473
 
    else
474
 
    {
475
 
        newRoi->setName( std::string( "region " ) + string_utils::toString( index ) );
476
 
    }
477
 
 
478
 
    if( WKernel::getRunningKernel()->getRoiManager()->getSelectedRoi() == NULL )
479
 
    {
480
 
        WKernel::getRunningKernel()->getRoiManager()->addRoi( newRoi );
481
 
    }
482
 
    else
483
 
    {
484
 
        WKernel::getRunningKernel()->getRoiManager()->addRoi( newRoi, WKernel::getRunningKernel()->getRoiManager()->getSelectedRoi() );
485
 
    }
486
 
}