Commit 6585cbe4 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - updated texture creation mechanism

parent 5f2f9f8d
......@@ -6,9 +6,9 @@ FILE( GLOB DATAHANDLER_EXCEPTIONS_SRC "exceptions/*.[c,h]pp" )
FILE( GLOB DATAHANDLER_IO_SRC "io/*.[c,h]pp" ) # former WLoader
ADD_LIBRARY( dataHandler SHARED ${DATAHANDLER_SRC} ${DATAHANDLER_EXCEPTIONS_SRC} ${DATAHANDLER_IO_SRC} )
TARGET_LINK_LIBRARIES( dataHandler common math ${Boost_LIBRARIES} niftiio biosig)
TARGET_LINK_LIBRARIES( dataHandler common math ${Boost_LIBRARIES} niftiio biosig ${OPENSCENEGRAPH_LIBRARIES})
# Unit tests
IF( CXXTEST_FOUND )
CXXTEST_ADD_TESTS_FROM_LIST( "${DATAHANDLER_SRC}" "dataHandler" )
CXXTEST_ADD_TESTS_FROM_LIST( "${DATAHANDLER_SRC}" "dataHandler" "WDataTexture3D.cpp" )
ENDIF( CXXTEST_FOUND )
......@@ -24,6 +24,10 @@
#include <string>
#include "exceptions/WDHException.h"
#include "WDataTexture3D.h"
#include "WDataSet.h"
WDataSet::WDataSet()
......@@ -42,3 +46,13 @@ std::string WDataSet::getFileName() const
return m_fileName;
}
bool WDataSet::isTexture() const
{
return false;
}
boost::shared_ptr< WDataTexture3D > WDataSet::getTexture()
{
throw WDHException( "This dataset does not provide a texture." );
}
......@@ -28,6 +28,8 @@
#include <string>
#include <boost/shared_ptr.hpp>
class WDataTexture3D;
/**
* Base class for all data set types. This class has a number of subclasses
* specifying the different types of data sets. Two of the dataset types
......@@ -62,6 +64,21 @@ public:
*/
std::string getFileName() const;
/**
* Determines whether this dataset can be used as a texture.
*
* \return true if usable as texture.
*/
// TODO(seralph): pure virtual? Are WDataSet instances useful?
virtual bool isTexture() const;
/**
* Returns the texture- representation of the dataset. May throw an exception if no texture is available.
*
* \return The texture.
*/
virtual boost::shared_ptr< WDataTexture3D > getTexture();
protected:
private:
/**
......
......@@ -47,6 +47,11 @@ void WDataSetFibers::erase( const std::vector< bool > &unused )
m_fibers->erase( useable, m_fibers->end() );
}
bool WDataSetFibers::isTexture() const
{
return false;
}
WDataSetFibers::WDataSetFibers( boost::shared_ptr< std::vector< wmath::WFiber > > fibs ) : m_fibers( fibs )
{
}
......@@ -61,8 +66,3 @@ const wmath::WFiber& WDataSetFibers::operator[]( const size_t index ) const
assert( index < m_fibers->size() );
return (*m_fibers)[index];
}
......@@ -64,6 +64,13 @@ public:
*/
void erase( const std::vector< bool > &unused );
/**
* Determines whether this dataset can be used as a texture.
*
* \return true if usable as texture.
*/
virtual bool isTexture() const;
protected:
private:
boost::shared_ptr< std::vector< wmath::WFiber > > m_fibers;
......
......@@ -22,10 +22,12 @@
//
//---------------------------------------------------------------------------
#include "WDataSetSingle.h"
#include "WDataTexture3D.h"
#include "WValueSet.hpp"
#include "WGrid.h"
#include "WDataSetSingle.h"
WDataSetSingle::WDataSetSingle( boost::shared_ptr<WValueSetBase> newValueSet,
boost::shared_ptr<WGrid> newGrid )
: WDataSet()
......@@ -36,6 +38,7 @@ WDataSetSingle::WDataSetSingle( boost::shared_ptr<WValueSetBase> newValueSet,
m_valueSet = newValueSet;
m_grid = newGrid;
m_texture3D = boost::shared_ptr< WDataTexture3D >( new WDataTexture3D( m_valueSet, m_grid ) );
}
WDataSetSingle::~WDataSetSingle()
......@@ -51,3 +54,15 @@ boost::shared_ptr<WGrid> WDataSetSingle::getGrid() const
{
return m_grid;
}
bool WDataSetSingle::isTexture() const
{
// TODO(seralph): this is not sophisticated. This should depend on type of data (vectors? scalars? tensors?)
return true;
}
boost::shared_ptr< WDataTexture3D > WDataSetSingle::getTexture()
{
return m_texture3D;
}
......@@ -33,6 +33,8 @@
#include "WDataSet.h"
class WDataTexture3D;
/**
* A data set consisting of a set of values based on a grid.
* \ingroup dataHandler
......@@ -78,6 +80,20 @@ public:
return v;
}
/**
* Determines whether this dataset can be used as a texture.
*
* \return true if usable as texture.
*/
virtual bool isTexture() const;
/**
* Returns the texture- representation of the dataset. May throw an exception if no texture is available.
*
* \return The texture.
*/
virtual boost::shared_ptr< WDataTexture3D > getTexture();
private:
/**
* Stores the reference of the WGrid of this DataSetSingle instance.
......@@ -88,6 +104,11 @@ private:
* Stores the reference of the WValueSet of this DataSetSingle instance.
*/
boost::shared_ptr< WValueSetBase > m_valueSet;
/**
* The 3D texture representing this dataset.
*/
boost::shared_ptr< WDataTexture3D > m_texture3D;
};
#endif // WDATASETSINGLE_H
......@@ -47,3 +47,9 @@ WEEG::WEEG( const WEEGSegmentArray& data,
m_electrodeLibrary = electrodeLib;
m_channelLabels = channelLabels;
}
bool WEEG::isTexture() const
{
return false;
}
......@@ -123,10 +123,18 @@ public:
*/
std::string getChannelLabel( size_t channelId ) const
{
// TODO(wiebel): put code into cpp file
// TODO(wiebel): what is done with the second string of the label?
return m_channelLabels[channelId].first;
}
/**
* Determines whether this dataset can be used as a texture.
*
* \return true if usable as texture.
*/
virtual bool isTexture() const;
protected:
private:
/**
......
......@@ -89,7 +89,9 @@ boost::shared_ptr< WDataSet > WLoaderNIfTI::load()
unsigned int order = ( ( vDim == 1 ) ? 0 : 1 ); // TODO(all): Does recognize vectors and scalars only so far.
unsigned int countVoxels = columns * rows * frames;
#ifdef DEBUG
nifti_image_infodump( header );
#endif
switch( header->datatype )
{
......
......@@ -100,11 +100,15 @@ public:
*/
virtual void addModuleToBrowser( boost::shared_ptr< WModule > module ) = 0;
/**
* returns a vector of pointers to the loaded datasets for a given subject
* returns a vector of pointers to the loaded datasets for a given subject.
*
* \param subjectId the ID of the subject to get the list for.
* \param onlyTextures true if only textures should be returned.
*
* \return list of datasets.
*/
virtual std::vector< boost::shared_ptr< WModule > >getDataSetList( int subjectId ) = 0;
virtual std::vector< boost::shared_ptr< WDataSet > > getDataSetList( int subjectId, bool onlyTextures = false ) = 0;
/**
* getter functions for the signales proved by the gui
......
......@@ -178,9 +178,9 @@ void WQt4Gui::addModuleToBrowser( boost::shared_ptr< WModule > module )
}
std::vector< boost::shared_ptr< WModule > >WQt4Gui::getDataSetList( int subjectId )
std::vector< boost::shared_ptr< WDataSet > > WQt4Gui::getDataSetList( int subjectId, bool onlyTextures )
{
return m_gui->getDatasetBrowser()->getDataSetList( subjectId );
return m_gui->getDatasetBrowser()->getDataSetList( subjectId, onlyTextures );
}
boost::signal1< void, std::vector< std::string > >* WQt4Gui::getLoadButtonSignal()
......
......@@ -79,11 +79,15 @@ public:
*/
void addModuleToBrowser( boost::shared_ptr< WModule > module );
/**
* returns a vector of pointers to the loaded datasets for a given subject
* returns a vector of pointers to the loaded datasets for a given subject.
*
* \param subjectId the ID of the subject to get the list for.
* \param onlyTextures true if only textures should be returned.
*
* \return list of datasets.
*/
virtual std::vector< boost::shared_ptr< WModule > >getDataSetList( int subjectId );
virtual std::vector< boost::shared_ptr< WDataSet > > getDataSetList( int subjectId, bool onlyTextures = false );
/**
* getter functions for the signales proved by the gui
......
......@@ -31,11 +31,16 @@
#include "../../../common/WLogger.h"
#include "../../../dataHandler/WDataSet.h"
#include "WQtDatasetBrowser.h"
#include "WQtNumberEdit.h"
#include "WQtCheckBox.h"
#include "WQtModuleHeaderTreeItem.h"
#include "../../../modules/data/WMData.h"
WQtDatasetBrowser::WQtDatasetBrowser( QWidget* parent )
: QDockWidget( parent )
{
......@@ -242,10 +247,9 @@ void WQtDatasetBrowser::slotSetStringProperty( QString name, QString value )
}
}
std::vector< boost::shared_ptr< WModule > >WQtDatasetBrowser::getDataSetList( int subjectId )
std::vector< boost::shared_ptr< WDataSet > > WQtDatasetBrowser::getDataSetList( int subjectId, bool onlyTextures )
{
std::vector< boost::shared_ptr< WModule > >moduleList;
std::vector< boost::shared_ptr< WDataSet > >moduleList;
if ( m_treeWidget->invisibleRootItem()->childCount() < subjectId + 1)
{
......@@ -255,8 +259,16 @@ std::vector< boost::shared_ptr< WModule > >WQtDatasetBrowser::getDataSetList( in
for ( int i = 0 ; i < count ; ++i )
{
moduleList.push_back( ( ( WQtDatasetTreeItem* )
m_treeWidget->invisibleRootItem()->child( subjectId + 1 )->child( i ) )->getModule() );
boost::shared_ptr< WMData > dm = boost::shared_dynamic_cast< WMData >( ( ( WQtDatasetTreeItem* )m_treeWidget->invisibleRootItem()->child(
subjectId + 1 )->child( i ) )->getModule() );
if ( !onlyTextures || dm->getDataSet()->isTexture() )
{
if ( dm->getProperties()->getValue<bool>( "active" ) )
{
moduleList.push_back( dm->getDataSet() );
}
}
}
return moduleList;
}
......
......@@ -38,6 +38,8 @@
#include "WQtModuleTreeItem.h"
#include "WQtTreeWidget.h"
#include "../../../dataHandler/WDataSet.h"
/**
* container widget for a tree widget with context menu and some control widgets
*/
......@@ -75,13 +77,24 @@ public:
*/
WQtDatasetTreeItem* addDataset( boost::shared_ptr< WModule > module, int subjectId = 0 );
/**
* Adds a module to the dataset browser.
*
* \param module the module to add.
*
* \return the representation in dataset browser.
*/
WQtModuleTreeItem* addModule( boost::shared_ptr< WModule > module );
/**
* returns a vector of pointers to the loaded datasets for a given subject
* Returns a vector of pointers to the loaded datasets for a given subject.
*
* \param subjectId The ID of the subject to get the list for.
* \param onlyTextures True if only textures should be returned.
*
* \return the list of datasets.
*/
std::vector< boost::shared_ptr< WModule > >getDataSetList( int subjectId );
std::vector< boost::shared_ptr< WDataSet > > getDataSetList( int subjectId, bool onlyTextures = false );
/**
* helper funtion to connect all qt widgets with their functions
......
......@@ -38,6 +38,7 @@
#include "../modules/marchingCubes/WMMarchingCubes.h"
#include "../modules/distanceMap/WMDistanceMap.h"
#include "../modules/eegTest/WMEEGTest.h"
#include "../modules/textureList/WMTextureList.h"
#include "exceptions/WPrototypeUnknown.h"
#include "exceptions/WPrototypeNotUnique.h"
......@@ -75,6 +76,7 @@ void WModuleFactory::load()
m_prototypes.insert( boost::shared_ptr< WModule >( new WMEEGTest() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMMarchingCubes() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDistanceMap() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMTextureList() ) );
lock.unlock();
......
......@@ -277,12 +277,11 @@ osg::ref_ptr<osg::Geometry> WMCoordinateSystem::createGeometryNode()
void WMCoordinateSystem::findBoundingBox()
{
std::vector< boost::shared_ptr< WModule > > datasetList = WKernel::getRunningKernel()->getGui()->getDataSetList( 0 );
std::vector< boost::shared_ptr< WDataSet > > dsl = WKernel::getRunningKernel()->getGui()->getDataSetList( 0, true );
if ( datasetList.size() > 0 )
if ( dsl.size() > 0 )
{
boost::shared_ptr< WMData > module = boost::shared_dynamic_cast< WMData >( datasetList[0] );
boost::shared_ptr< WDataSetSingle > ds = boost::shared_dynamic_cast< WDataSetSingle >( module->getDataSet() );
boost::shared_ptr< WDataSetSingle > ds = boost::shared_dynamic_cast< WDataSetSingle >( dsl[0] );
if ( ds->getValueSet()->getDataType() != 2 )
{
......
......@@ -177,179 +177,3 @@ void WMData::moduleMain()
waitForStop(); // WThreadedRunner offers this for us. It uses boost::condition to avoid wasting CPU cycles with while loops.
}
osg::ref_ptr<osg::Texture3D> WMData::getTexture3D()
{
if ( !m_texture3D )
{
boost::shared_ptr< WDataSetSingle > ds = boost::shared_dynamic_cast< WDataSetSingle >( m_dataSet );
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
if ( ds->getValueSet()->getDataType() == 2 )
{
boost::shared_ptr< WValueSet< unsigned char > > vs = boost::shared_dynamic_cast< WValueSet< unsigned char > >( ds->getValueSet() );
unsigned char* source = const_cast< unsigned char* > ( vs->rawData() );
m_texture3D = createTexture3D( source, grid, ds->getValueSet()->dimension() );
}
else if ( ds->getValueSet()->getDataType() == 4 )
{
boost::shared_ptr< WValueSet< int16_t > > vs = boost::shared_dynamic_cast< WValueSet< int16_t > >( ds->getValueSet() );
int16_t* source = const_cast< int16_t* > ( vs->rawData() );
m_texture3D = createTexture3D( source, grid, ds->getValueSet()->dimension() );
}
else if ( ds->getValueSet()->getDataType() == 16 )
{
boost::shared_ptr< WValueSet< float > > vs = boost::shared_dynamic_cast< WValueSet< float > >( ds->getValueSet() );
float* source = const_cast< float* > ( vs->rawData() );
m_texture3D = createTexture3D( source, grid, ds->getValueSet()->dimension() );
}
}
return m_texture3D;
}
osg::ref_ptr<osg::Texture3D> WMData::createTexture3D( unsigned char* source, boost::shared_ptr<WGridRegular3D> grid, int components )
{
if ( components == 1 )
{
osg::ref_ptr< osg::Image > ima = new osg::Image;
ima->allocateImage( grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(), GL_LUMINANCE, GL_UNSIGNED_BYTE );
unsigned char* data = ima->data();
for ( unsigned int i = 0; i < grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ(); ++i )
{
data[i] = source[i];
}
osg::ref_ptr<osg::Texture3D> texture3D = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
texture3D->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
texture3D->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
texture3D->setWrap( osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT );
texture3D->setImage( ima );
texture3D->setResizeNonPowerOfTwoHint( false );
return texture3D;
}
else if ( components == 3 )
{
osg::ref_ptr< osg::Image > ima = new osg::Image;
ima->allocateImage( grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(), GL_RGB, GL_UNSIGNED_BYTE );
unsigned char* data = ima->data();
for ( unsigned int i = 0; i < grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ() * 3; ++i )
{
data[i] = source[i];
}
osg::ref_ptr<osg::Texture3D> texture3D = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
texture3D->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
texture3D->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
texture3D->setWrap( osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT );
texture3D->setImage( ima );
texture3D->setResizeNonPowerOfTwoHint( false );
return texture3D;
}
return 0;
}
osg::ref_ptr<osg::Texture3D> WMData::createTexture3D( int16_t* source, boost::shared_ptr<WGridRegular3D> grid, int components )
{
if ( components == 1)
{
int nSize = grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ();
std::vector<int16_t> tempSource( nSize );
for ( int i = 0; i < nSize; ++i )
{
tempSource[i] = static_cast<int16_t>( source[i] );
}
int max = 0;
std::vector< int > histo( 65536, 0 );
for ( int i = 0; i < nSize; ++i )
{
if ( max < tempSource[i])
{
max = tempSource[i];
}
++histo[tempSource[i]];
}
int fivepercent = static_cast<int>( nSize * 0.001 );
int newMax = 65535;
int adder = 0;
for ( int i = 65535; i > 0; --i )
{
adder += histo[i];
newMax = i;
if ( adder > fivepercent )
break;
}
for ( int i = 0; i < nSize; ++i )
{
if ( tempSource[i] > newMax )
{
tempSource[i] = newMax;
}
}
int mult = 65535 / newMax;
std::cout << "mult:" << mult << std::endl;
std::cout << "newMax:" << newMax << std::endl;
for ( int i = 0; i < nSize; ++i )
{
tempSource[i] *= mult;
}
osg::ref_ptr< osg::Image > ima = new osg::Image;
ima->allocateImage( grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(), GL_LUMINANCE, GL_UNSIGNED_SHORT );
unsigned char* data = ima->data();
unsigned char* charSource = ( unsigned char* )&tempSource[0];
for ( unsigned int i = 0; i < grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ() * 2 ; ++i )
{
data[i] = charSource[i];
}
osg::ref_ptr<osg::Texture3D> texture3D = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
texture3D->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
texture3D->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
texture3D->setWrap( osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT );
texture3D->setImage( ima );
texture3D->setResizeNonPowerOfTwoHint( false );
return texture3D;
}
return 0;
}
osg::ref_ptr<osg::Texture3D> WMData::createTexture3D( float* source, boost::shared_ptr<WGridRegular3D> grid, int components )
{
if ( components == 1)
{
osg::ref_ptr< osg::Image > ima = new osg::Image;
ima->allocateImage( grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(), GL_LUMINANCE, GL_FLOAT );
unsigned char* data = ima->data();
unsigned char* charSource = ( unsigned char* )source;
for ( unsigned int i = 0; i < grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ() * 4 ; ++i )
{
data[i] = charSource[i];
}
osg::ref_ptr<osg::Texture3D> texture3D = osg::ref_ptr<osg::Texture3D>( new osg::Texture3D );
texture3D->setFilter( osg::Texture3D::MIN_FILTER, osg::Texture3D::LINEAR );
texture3D->setFilter( osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR );
texture3D->setWrap( osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT );
texture3D->setImage( ima );
texture3D->setResizeNonPowerOfTwoHint( false );
return texture3D;
}
return 0;
}
......@@ -68,19 +68,16 @@ public:
virtual const std::string getDescription() const;
/**
* getter for the dataset
* Getter for the dataset.
*
* \return the dataset encapsulated by this module.
*/
virtual boost::shared_ptr< WDataSet > getDataSet();
/**
* getter for the 3d texture, which will be created on demand
*/
virtual osg::ref_ptr<osg::Texture3D> getTexture3D();
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
* should never be initialized or modified in some other way. A simple new instance is required.
*
*
* \return the prototype used to create every module in OpenWalnut.
*/
virtual boost::shared_ptr< WModule > factory() const;
......@@ -135,22 +132,6 @@ protected: