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

25
#include <set>
26
#include <string>
27
#include <vector>
28

29
#include "../../common/WAssert.h"
30
#include "../../common/WColor.h"
31
#include "../../graphicsEngine/WGEGeodeUtils.h"
32 33 34
#include "../../graphicsEngine/WGEGeometryUtils.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../kernel/WKernel.h"
35 36
#include "WMClusterSlicer.h"

37 38 39
// This line is needed by the module loader to actually find your module.
W_LOADABLE_MODULE( WMClusterSlicer )

40 41 42
WMClusterSlicer::WMClusterSlicer()
    : WModule(),
      m_rootNode( osg::ref_ptr< WGEGroupNode >( new WGEGroupNode() ) )
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
{
}

WMClusterSlicer::~WMClusterSlicer()
{
}

boost::shared_ptr< WModule > WMClusterSlicer::factory() const
{
    return boost::shared_ptr< WModule >( new WMClusterSlicer() );
}

const std::string WMClusterSlicer::getName() const
{
    return "Cluster Slicer";
}

const std::string WMClusterSlicer::getDescription() const
{
    return "Slices a cluster";
}

void WMClusterSlicer::connectors()
{
67 68 69 70 71
    m_inputCluster = boost::shared_ptr< InputClusterType >( new InputClusterType( shared_from_this(), "cluster", "A cluster of fibers" ) );
    addConnector( m_inputCluster );

    m_inputDataSet = boost::shared_ptr< InputDataSetType >( new InputDataSetType( shared_from_this(), "dataset", "DataSet derived from a cluster" ) );
    addConnector( m_inputDataSet );
72 73 74 75 76 77

    WModule::connectors();
}

void WMClusterSlicer::properties()
{
78
    m_drawISOVoxels = m_properties->addProperty( "Show or hide iso voxels", "En/Disables to draw the voxels within a given isourface.", true );
79
    m_isoValue      = m_properties->addProperty( "Iso value", "", 0.01 );
80 81 82 83
}

void WMClusterSlicer::moduleMain()
{
84 85
    WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );

86
    m_moduleState.setResetable( true, true );
87 88 89
    m_moduleState.add( m_inputDataSet->getDataChangedCondition() );
    m_moduleState.add( m_isoValue->getCondition() );
    m_moduleState.add( m_drawISOVoxels->getCondition() );
90 91 92 93 94 95 96 97 98 99 100

    ready();

    while( !m_shutdownFlag() )
    {
        m_moduleState.wait();

        if( m_shutdownFlag() )
        {
            break;
        }
101 102 103 104

        boost::shared_ptr< WDataSetSingle > newDataSet = m_inputDataSet->getData();
        boost::shared_ptr< WFiberCluster > newCluster = m_inputCluster->getData();
        bool dataChanged = ( m_dataSet != newDataSet ) || ( m_cluster != newCluster );
105
        bool dataValid = m_dataSet && m_cluster;
106 107 108 109
        if( dataChanged )
        {
            m_dataSet = newDataSet;
            m_cluster = newCluster;
110
            dataValid = m_dataSet && m_cluster;
111 112 113 114 115
            if( !m_dataSet || !m_cluster )
            {
                continue;
            }

116
            WAssert( m_dataSet, "Invalid dataset to compute JoinTree on" );
117 118 119 120 121 122
            m_joinTree = boost::shared_ptr< WJoinContourTree >( new WJoinContourTree( m_dataSet ) );
            m_joinTree->buildJoinTree();
        }

        if( ( m_isoValue->changed() || dataChanged ) && m_joinTree )
        {
123
            WAssert( m_dataSet, "JoinTree cannot be valid since there is no valid m_dataSet." );
124 125 126 127 128
            m_isoVoxels = m_joinTree->getVolumeVoxelsEnclosedByISOSurface( m_isoValue->get() );
        }

        if( m_drawISOVoxels->changed() || m_isoValue->changed() || dataChanged )
        {
129 130 131 132
            if( dataValid )
            {
                updateDisplay();
            }
133
        }
134 135 136 137 138
    }

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

139 140
void WMClusterSlicer::updateDisplay()
{
141 142 143 144
    m_rootNode->remove( m_isoVoxelGeode );
    m_isoVoxelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() ); // discard old geode

    if( m_drawISOVoxels->get( true ) )
145
    {
146
        WAssert( m_isoVoxels, "JoinTree cannot be valid since there is no valid m_dataSet." );
147
        m_isoVoxelGeode = generateISOVoxelGeode();
148 149 150 151
        m_rootNode->insert( m_isoVoxelGeode );
    }
}

152
osg::ref_ptr< osg::Geode > WMClusterSlicer::generateISOVoxelGeode() const
153
{
154 155 156 157 158 159 160
    using osg::ref_ptr;
    ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
    ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
    ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
    ref_ptr< osg::Vec3Array > normals = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );

    boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
161
    WAssert( grid != 0, "No valid regualr 3d grid given!" );
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    std::set< size_t >::const_iterator cit;
    for( cit = m_isoVoxels->begin(); cit != m_isoVoxels->end(); ++cit )
    {
        boost::shared_ptr< std::vector< wmath::WPosition > > voxelCornerVertices = grid->getVoxelVertices( grid->getPosition( *cit ), 0.01 );
        osg::ref_ptr< osg::Vec3Array > ver = wge::generateCuboidQuads( *voxelCornerVertices );
        vertices->insert( vertices->end(), ver->begin(), ver->end() );
        osg::ref_ptr< osg::Vec3Array > nor = wge::generateCuboidQuadNormals( *voxelCornerVertices );
        normals->insert( normals->end(), nor->begin(), nor->end() );
        geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, vertices->size() - ver->size(), ver->size() ) );
        for( size_t j = 0; j < ver->size(); ++j )
        {
            colors->push_back( wge::osgColor( WColor( 1, 0, 0 ) ) );
        }
    }

    geometry->setVertexArray( vertices );
    colors->push_back( wge::osgColor( WColor( 1, 0, 0 ) ) );
    geometry->setColorArray( colors );
    geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
    geometry->setNormalArray( normals );
    geometry->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
    osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
    geode->addDrawable( geometry );

    return geode;
187 188
}

189 190 191 192
void WMClusterSlicer::activate()
{
    if( m_rootNode )
    {
193
        if( m_active->get() )
194 195 196 197 198 199 200 201 202 203 204
        {
            m_rootNode->setNodeMask( 0xFFFFFFFF );
        }
        else
        {
            m_rootNode->setNodeMask( 0x0 );
        }
    }

    WModule::activate();
}