//--------------------------------------------------------------------------- // // 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 . // //--------------------------------------------------------------------------- #include #include #include #include "../../common/WAssert.h" #include "../../common/WColor.h" #include "../../graphicsEngine/WGEGeodeUtils.h" #include "../../graphicsEngine/WGEGeometryUtils.h" #include "../../graphicsEngine/WGEUtils.h" #include "../../kernel/WKernel.h" #include "WMClusterSlicer.h" // This line is needed by the module loader to actually find your module. W_LOADABLE_MODULE( WMClusterSlicer ) WMClusterSlicer::WMClusterSlicer() : WModule(), m_rootNode( osg::ref_ptr< WGEGroupNode >( new WGEGroupNode() ) ) { } 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() { 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 ); WModule::connectors(); } void WMClusterSlicer::properties() { m_drawISOVoxels = m_properties->addProperty( "Show or hide iso voxels", "En/Disables to draw the voxels within a given isourface.", true ); m_isoValue = m_properties->addProperty( "Iso value", "", 0.01 ); } void WMClusterSlicer::moduleMain() { WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode ); m_moduleState.setResetable( true, true ); m_moduleState.add( m_inputDataSet->getDataChangedCondition() ); m_moduleState.add( m_isoValue->getCondition() ); m_moduleState.add( m_drawISOVoxels->getCondition() ); ready(); while( !m_shutdownFlag() ) { m_moduleState.wait(); if( m_shutdownFlag() ) { break; } boost::shared_ptr< WDataSetSingle > newDataSet = m_inputDataSet->getData(); boost::shared_ptr< WFiberCluster > newCluster = m_inputCluster->getData(); bool dataChanged = ( m_dataSet != newDataSet ) || ( m_cluster != newCluster ); bool dataValid = m_dataSet && m_cluster; if( dataChanged ) { m_dataSet = newDataSet; m_cluster = newCluster; dataValid = m_dataSet && m_cluster; if( !m_dataSet || !m_cluster ) { continue; } WAssert( m_dataSet, "Invalid dataset to compute JoinTree on" ); m_joinTree = boost::shared_ptr< WJoinContourTree >( new WJoinContourTree( m_dataSet ) ); m_joinTree->buildJoinTree(); } if( ( m_isoValue->changed() || dataChanged ) && m_joinTree ) { WAssert( m_dataSet, "JoinTree cannot be valid since there is no valid m_dataSet." ); m_isoVoxels = m_joinTree->getVolumeVoxelsEnclosedByISOSurface( m_isoValue->get() ); } if( m_drawISOVoxels->changed() || m_isoValue->changed() || dataChanged ) { if( dataValid ) { updateDisplay(); } } } WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode ); } void WMClusterSlicer::updateDisplay() { m_rootNode->remove( m_isoVoxelGeode ); m_isoVoxelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() ); // discard old geode if( m_drawISOVoxels->get( true ) ) { WAssert( m_isoVoxels, "JoinTree cannot be valid since there is no valid m_dataSet." ); m_isoVoxelGeode = generateISOVoxelGeode(); m_rootNode->insert( m_isoVoxelGeode ); } } osg::ref_ptr< osg::Geode > WMClusterSlicer::generateISOVoxelGeode() const { 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() ); WAssert( grid != 0, "No valid regualr 3d grid given!" ); 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; } void WMClusterSlicer::activate() { if( m_rootNode ) { if( m_active->get() ) { m_rootNode->setNodeMask( 0xFFFFFFFF ); } else { m_rootNode->setNodeMask( 0x0 ); } } WModule::activate(); }