//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-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 "core/common/WTransferFunction.h" #include "core/dataHandler/datastructures/WValueSetHistogram.h" #include "core/dataHandler/WDataSetScalar.h" #include "core/dataHandler/WGrid.h" #include "core/dataHandler/WGridRegular3D.h" #include "core/dataHandler/WValueSet.h" #include "core/dataHandler/WValueSetBase.h" #include "core/kernel/WKernel.h" #include "WMTransferFunction1D.xpm" #include "WMTransferFunction1D.h" // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here. W_LOADABLE_MODULE( WMTransferFunction1D ) WMTransferFunction1D::WMTransferFunction1D(): WModule() { } WMTransferFunction1D::~WMTransferFunction1D() { // Cleanup! } boost::shared_ptr< WModule > WMTransferFunction1D::factory() const { return boost::shared_ptr< WModule >( new WMTransferFunction1D() ); } const char** WMTransferFunction1D::getXPMIcon() const { return WMTransferFunction1D_xpm; } const std::string WMTransferFunction1D::getName() const { return "Transfer Function 1D"; } const std::string WMTransferFunction1D::getDescription() const { return "A module to modify a transfer function."; } void WMTransferFunction1D::connectors() { // the data set we use for displaying the histogram m_input = WModuleInputData < WDataSetSingle >::createAndAdd( shared_from_this(), "histogram input", "The data set used to display a histogram." ); // an output connector for the transfer function created m_output = WModuleOutputData < WDataSetSingle >::createAndAdd( shared_from_this(), "transferFunction1D", "The selected transfer function" ); WModule::connectors(); } void WMTransferFunction1D::properties() { m_propCondition = boost::shared_ptr< WCondition >( new WCondition() ); WTransferFunction tf; tf.addAlpha( 0.0, 0.0 ); tf.addColor( 0.0, WColor( 0.0, 0.0, 0.0, 0.0 ) ); tf.addAlpha( 1.0, 0.5 ); tf.addColor( 1.0, WColor( 1.0, 0.0, 0.0, 0.0 ) ); m_transferFunction = m_properties->addProperty( "Transfer Function", "The transfer function editor.", tf, m_propCondition, false ); m_binSize = m_properties->addProperty( "Histogram Resolution", "Number of bins in histogram.", 64, m_propCondition ); m_binSize->setMin( 2 ); m_binSize->setMax( 512 ); m_resolution = m_properties->addProperty( "Number of Samples", "Number of samples in the transfer function. " "Some modules connected to the output may have additional restrictions. Volume rendering, e.g., requires a power of two " "samples at the moment." , 128, m_propCondition ); m_resolution->setMin( 4 ); m_resolution->setMax( 1024 ); WModule::properties(); } void WMTransferFunction1D::requirements() { //m_requirements.push_back( new WGERequirement() ); } void WMTransferFunction1D::moduleMain() { m_moduleState.setResetable( true, true ); m_moduleState.add( m_input->getDataChangedCondition() ); m_moduleState.add( m_propCondition ); ready(); while( !m_shutdownFlag() ) { m_moduleState.wait(); if( m_shutdownFlag() ) break; bool tfChanged = m_transferFunction->changed(); WTransferFunction tf = m_transferFunction->get( true ); debugLog() << "Current transfer function " << tf.numAlphas() << " alphas."; if( m_input->updated() || m_binSize->changed() ) { boost::shared_ptr< WDataSetSingle > dataSet= m_input->getData(); bool dataValid = ( dataSet ); if( !dataValid ) { // FIXME: invalidate histogram in GUI tf.removeHistogram(); } else { int binsize = m_binSize->get( true ); boost::shared_ptr< WValueSetBase > values = dataSet->getValueSet(); WValueSetHistogram histogram( values, 0, 255, binsize ); // because of the current semantics of WTransferFunction, // we have to create a copy of the data here. std::vector vhistogram( histogram.size() ); for( int i = 0; i < binsize; ++i ) { vhistogram[ i ] = histogram[ i ]; } tf.setHistogram( vhistogram ); } // either way, we changed the data and want to update the TF m_transferFunction->set( tf ); } if( m_resolution->changed() || tfChanged ) { // debugLog() << "resampling transfer function"; unsigned int resolution = m_resolution->get( true ); // debugLog() << "new resolution: " << resolution; boost::shared_ptr< std::vector > data( new std::vector( resolution * 4 ) ); // FIXME: get transfer function and publish the function tf.sample1DTransferFunction( &( *data )[ 0 ], resolution, 0.0, 1.0 ); boost::shared_ptr< WValueSetBase > newValueSet( new WValueSet( 1, 4, data, W_DT_UNSIGNED_CHAR ) ); WGridTransformOrtho transform; boost::shared_ptr< WGridRegular3D > newGrid( new WGridRegular3D( resolution, 1, 1, transform ) ); boost::shared_ptr< WDataSetSingle > newData( new WDataSetSingle( newValueSet, newGrid ) ); m_output->updateData( newData ); } } }