Commit 699888bd authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[CHANGE] - value set now calculates min and max values. This saves gvim...

[CHANGE] - value set now calculates min and max values. This saves gvim dataHandler/WDataTexture3D.*twogvim dataHandler/WDataTexture3D.* other min/max calculations in WDataTexture3D and WDataSetScalar.
parent ff304736
......@@ -27,6 +27,7 @@
#include "../common/WAssert.h"
#include "../common/WLimits.h"
#include "datastructures/WValueSetHistogram.h"
#include "WDataSetSingle.h"
#include "WDataSetScalar.h"
......@@ -43,16 +44,8 @@ WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );
m_histogram = boost::shared_ptr< WHistogram >( new WHistogram( newValueSet ) );
m_maximum = m_histogram->getMax();
m_minimum = m_histogram->getMin();
// TEST
//boost::shared_ptr< WHistogram > hist( new WHistogram( *m_histogram, 15 ) );
//m_histogram->setInterval( 20.0 );
//m_histogram->test();
//hist->setInterval( 15.0 );
//hist->test();
// the histogram gets calculated on demand
m_histogram = boost::shared_ptr< WValueSetHistogram >();
}
WDataSetScalar::WDataSetScalar()
......@@ -61,38 +54,18 @@ WDataSetScalar::WDataSetScalar()
// default constructor used by the prototype mechanism
}
WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
boost::shared_ptr< WGrid > newGrid,
double max,
double min )
: WDataSetSingle( newValueSet, newGrid )
{
WAssert( newValueSet, "No value set given." );
WAssert( newGrid, "No grid given." );
WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );
WAssert( max >= min, "max must be at least as large as min." );
// TODO(ebaum, rfrohl): WHistogram calculates min/max, change constructor
m_histogram = boost::shared_ptr< WHistogram >( new WHistogram( newValueSet ) );
m_maximum = max;
m_minimum = min;
}
WDataSetScalar::~WDataSetScalar()
{
}
double WDataSetScalar::getMax() const
{
//change to whistogram->getMax()?
return m_maximum;
return m_valueSet->getMaximumValue();
}
double WDataSetScalar::getMin() const
{
//change to whistogram->getMin()?
return m_minimum;
return m_valueSet->getMinimumValue();
}
boost::shared_ptr< WPrototyped > WDataSetScalar::getPrototype()
......@@ -164,3 +137,18 @@ double WDataSetScalar::getValueAt( int x, int y, int z ) const
return WDataSetSingle::getValueAt( id );
}
boost::shared_ptr< const WValueSetHistogram > WDataSetScalar::getHistogram()
{
if ( m_histogram )
{
return m_histogram;
}
boost::lock_guard<boost::mutex> lock( m_histogramLock );
std::cout << " -------------------------------------------------- " << std::endl;
//m_histogram = boost::shared_ptr< WValueSetHistogram >( new WValueSetHistogram( m_valueSet ) );
return m_histogram;
}
......@@ -25,7 +25,9 @@
#ifndef WDATASETSCALAR_H
#define WDATASETSCALAR_H
#include "datastructures/WHistogram.h"
#include <boost/thread.hpp>
#include "datastructures/WValueSetHistogram.h"
#include "WDataSetSingle.h"
......@@ -47,20 +49,6 @@ public:
WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
boost::shared_ptr< WGrid > newGrid );
/**
* Constructs an instance out of an appropriate value set and a grid.
* Computes the maximum an minimum values stored as member variables.
*
* \param newValueSet the scalar value set to use
* \param newGrid the grid which maps world space to the value set
* \param min a priori known smallest scalar value in newValueSet
* \param max a priori known largest scalar value in newValueSet
*/
WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
boost::shared_ptr< WGrid > newGrid,
double min,
double max );
/**
* Construct an empty and unusable instance. This is needed for the prototype mechanism.
*/
......@@ -81,6 +69,13 @@ public:
*/
double getMin() const;
/**
* Returns the histogram of this dataset's valueset. If it does not exist yet, it will be created.
*
* \return the histogram.
*/
boost::shared_ptr< const WValueSetHistogram > getHistogram();
/**
* Interpolate the value fo the valueset at the given position.
* If interpolation fails, the success parameter will be false
......@@ -127,13 +122,16 @@ protected:
static boost::shared_ptr< WPrototyped > m_prototype;
private:
double m_maximum; //!< Largest scalar of data set.
double m_minimum; //!< Smallest scalar of data set.
/**
* The histogram for later use.
**/
boost::shared_ptr< WHistogram > m_histogram;
boost::shared_ptr< WValueSetHistogram > m_histogram;
/**
* The lock used for securely creating m_histogram on demand.
*/
boost::mutex m_histogramLock;
};
template< typename T > T WDataSetScalar::getValueAt( int x, int y, int z ) const
......
......@@ -40,9 +40,13 @@ WDataTexture3D::WDataTexture3D( boost::shared_ptr<WValueSetBase> valueSet, boost
m_changeCondition( new WCondition() ),
m_globalActive( true ),
m_interpolation( true ),
m_cmap( 0 )
m_cmap( 0 ),
m_minValue( static_cast< float >( valueSet->getMinimumValue() ) ),
m_maxValue( static_cast< float >( valueSet->getMaximumValue() ) ),
m_scale( m_maxValue - m_minValue )
{
// initialize members
wlog::debug( "WDataTexture3D" ) << "Texture scaling information for data in [" << m_minValue << ", "<< m_maxValue << "]: scaling factor=" << m_scale;
}
WDataTexture3D::~WDataTexture3D()
......@@ -110,8 +114,6 @@ osg::ref_ptr< osg::Texture3D > WDataTexture3D::getTexture()
osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( unsigned char* source, int components )
{
findMinMax( source, components );
osg::ref_ptr< osg::Image > ima = new osg::Image;
if ( components == 1 )
......@@ -149,8 +151,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( unsigned char* sourc
osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( int16_t* source, int components )
{
findMinMax( source, components );
osg::ref_ptr< osg::Image > ima = new osg::Image;
if( components == 1 )
{
......@@ -225,8 +225,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( int16_t* source, int
osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( int* source, int components )
{
findMinMax( source, components );
osg::ref_ptr< osg::Image > ima = new osg::Image;
if( components == 1 )
{
......@@ -264,7 +262,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( float* source, int c
osg::ref_ptr< osg::Image > ima = new osg::Image;
if ( components == 1)
{
findMinMax( source, components );
wlog::debug( "WDataTexture3D" ) << "Texture for scalar float data set.";
// OpenGL just supports float textures
ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_LUMINANCE, GL_FLOAT );
......@@ -278,7 +275,7 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( float* source, int c
}
else if ( components == 3 )
{
// we cannot use findMinMax her because of the possibly negative values.
// we cannot use m_minValue and m_maxValue here because of the possibly negative values.
m_scale = 1.;
m_minValue = 0.;
m_maxValue = 1.;
......@@ -300,7 +297,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( float* source, int c
}
else if ( components == 4 )
{
findMinMax( source, components );
wlog::debug( "WDataTexture3D" ) << "Texture for 4-vector float data set.";
// OpenGL just supports float textures
ima->allocateImage( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(), GL_RGBA, GL_FLOAT );
......@@ -327,8 +323,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( float* source, int c
osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( double* source, int components )
{
findMinMax( source, components );
osg::ref_ptr< osg::Image > ima = new osg::Image;
if ( components == 1)
{
......@@ -384,116 +378,6 @@ osg::ref_ptr< osg::Image > WDataTexture3D::createTexture3D( double* source, int
return ima;
}
void WDataTexture3D::findMinMax( double* source, int components )
{
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset.";
double minV = source[ 0 ];
double maxV = source[ 0 ];
// Go through each value and find min/max
for ( unsigned int i = 0; i < components * m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(); ++i )
{
double val = source[ i ];
minV = val < minV ? val : minV;
maxV = val > maxV ? val : maxV;
}
m_scale = static_cast< float >( maxV - minV );
m_minValue = static_cast< float >( minV );
m_maxValue = static_cast< float >( maxV );
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset: done! Values are in [" << m_minValue << "," << m_maxValue << "].";
}
void WDataTexture3D::findMinMax( unsigned char* source, int components )
{
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset.";
double minV = source[ 0 ];
double maxV = source[ 0 ];
// Go through each value and find min/max
for ( unsigned int i = 0; i < components * m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(); ++i )
{
double val = source[ i ];
minV = val < minV ? val : minV;
maxV = val > maxV ? val : maxV;
}
m_scale = static_cast< float >( maxV - minV );
m_minValue = static_cast< float >( minV );
m_maxValue = static_cast< float >( maxV );
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset: done! Values are in [" << m_minValue << "," << m_maxValue << "].";
}
void WDataTexture3D::findMinMax( int16_t* source, int components )
{
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset.";
double minV = source[ 0 ];
double maxV = source[ 0 ];
// Go through each value and find min/max
for ( unsigned int i = 0; i < components * m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(); ++i )
{
double val = source[ i ];
minV = val < minV ? val : minV;
maxV = val > maxV ? val : maxV;
}
m_scale = static_cast< float >( maxV - minV );
m_minValue = static_cast< float >( minV );
m_maxValue = static_cast< float >( maxV );
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset: done! Values are in [" << m_minValue << "," << m_maxValue << "].";
}
void WDataTexture3D::findMinMax( int* source, int components )
{
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset.";
double minV = source[ 0 ];
double maxV = source[ 0 ];
// Go through each value and find min/max
for ( unsigned int i = 0; i < components * m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(); ++i )
{
double val = source[ i ];
minV = val < minV ? val : minV;
maxV = val > maxV ? val : maxV;
}
m_scale = static_cast< float >( maxV - minV );
m_minValue = static_cast< float >( minV );
m_maxValue = static_cast< float >( maxV );
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset: done! Values are in [" << m_minValue << "," << m_maxValue << "].";
}
void WDataTexture3D::findMinMax( float* source, int components )
{
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset.";
float minV = source[ 0 ];
float maxV = source[ 0 ];
// Go through each value and find min/max
for ( unsigned int i = 0; i < components * m_grid->getNbCoordsX() * m_grid->getNbCoordsY() * m_grid->getNbCoordsZ(); ++i )
{
float val = source[ i ];
minV = val < minV ? val : minV;
maxV = val > maxV ? val : maxV;
}
m_scale = maxV - minV;
m_minValue = minV;
m_maxValue = maxV;
wlog::debug( "WDataTexture3D" ) << "Calculating min/max values for dataset: done! Values are in [" << m_minValue << "," << m_maxValue << "].";
}
void WDataTexture3D::createTexture()
{
boost::unique_lock< boost::shared_mutex > lock( m_creationLock );
......
......@@ -301,47 +301,6 @@ protected:
*/
int m_cmap;
/**
* This method finds the minimum and maximum value of a dataset. These values get used to scale the texture to use the maximum precision.
*
* \param source the data
* \param components the number of components
*/
virtual void findMinMax( float* source, int components );
/**
* This method finds the minimum and maximum value of a dataset. These values get used to scale the texture to use the maximum precision.
*
* \param source the data
* \param components the number of components
*/
virtual void findMinMax( double* source, int components );
/**
* This method finds the minimum and maximum value of a dataset. These values get used to scale the texture to use the maximum precision.
*
* \param source the data
* \param components the number of components
*/
virtual void findMinMax( unsigned char* source, int components );
/**
* This method finds the minimum and maximum value of a dataset. These values get used to scale the texture to use the maximum precision.
*
* \param source the data
* \param components the number of components
*/
virtual void findMinMax( int16_t* source, int components );
/**
* This method finds the minimum and maximum value of a dataset. These values get used to scale the texture to use the maximum precision.
*
* \param source the data
* \param components the number of components
*/
virtual void findMinMax( int* source, int components );
/**
* The smallest value inside the dataset
*/
......
......@@ -31,6 +31,7 @@
#include "../common/math/WValue.h"
#include "../common/math/WVector3D.h"
#include "../common/WAssert.h"
#include "../common/WLimits.h"
#include "WDataHandlerEnums.h"
#include "WValueSetBase.h"
......@@ -111,6 +112,15 @@ public:
: WValueSetBase( order, dimension, inDataType ),
m_data( data )
{
// calculate min and max
// Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ...
m_minimum = wlimits::MAX_DOUBLE;
m_maximum = wlimits::MIN_DOUBLE;
for ( typename std::vector< T >::const_iterator iter = data.begin(); iter != data.end(); ++iter )
{
m_minimum = m_minimum > *iter ? *iter : m_minimum;
m_maximum = m_maximum < *iter ? *iter : m_maximum;
}
}
/**
......@@ -213,8 +223,40 @@ public:
return SubArray( rawData() + start, size );
}
/**
* This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
* smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
*
* \return the smallest value in the data.
*/
virtual double getMinimumValue() const
{
return m_minimum;
}
/**
* This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
* largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
*
* \return the largest value in the data.
*/
virtual double getMaximumValue() const
{
return m_maximum;
}
protected:
/**
* The smallest value in m_data.
*/
T m_minimum;
/**
* The largest value in m_data.
*/
T m_maximum;
private:
/**
* Stores the values of type T as simple array which never should be modified.
......
......@@ -101,6 +101,22 @@ public:
return m_dataType;
}
/**
* This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
* smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
*
* \return the smallest value in the data.
*/
virtual double getMinimumValue() const = 0;
/**
* This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
* largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
*
* \return the largest value in the data.
*/
virtual double getMaximumValue() const = 0;
protected:
/**
* The order of the tensors for this ValueSet
......
......@@ -53,11 +53,12 @@ WValueSetHistogram::WValueSetHistogram( boost::shared_ptr< WValueSetBase > value
// create base histogram
m_nInitialBuckets = ( ( m_maximum - m_minimum ) / minDistance ) + 1;
std::cout << "m_nInitialBuckets" <<m_nInitialBuckets << std::endl;
m_bucketSize = minDistance;
unsigned int* initialBuckets = new unsigned int[m_nInitialBuckets];
// initialize array to zero
memset( initialBuckets, 0, m_nInitialBuckets * sizeof( unsigned int ) );
//*initialBuckets = { 0 }; // this should works with C++0x (instead memset), TEST IT!
//initialBuckets = { 0 }; // this should works with C++0x (instead memset), TEST IT!
m_initialBuckets = boost::shared_array< unsigned int >( initialBuckets );
m_nMappedBuckets = 0;
......@@ -65,10 +66,10 @@ WValueSetHistogram::WValueSetHistogram( boost::shared_ptr< WValueSetBase > value
for( size_t i = 0; i < valueSet->size(); ++i )
{
double tmp = valueSet->getScalarDouble( i );
increment( tmp );
// increment( tmp );
}
}
/*
WValueSetHistogram::WValueSetHistogram( const WValueSetBase& valueSet )
{
// calculate min max
......@@ -126,7 +127,7 @@ WValueSetHistogram::WValueSetHistogram( const WValueSetHistogram& histogram, dou
WAssert( intervalSize > 0.0, "WValueSetHistogram::WValueSetHistogram : intervalSize has to be greater then zero." );
calculateMapping( intervalSize );
}
}
}*/
WValueSetHistogram::~WValueSetHistogram()
{
......
......@@ -57,7 +57,7 @@ public:
*
* \param valueSet source of the data for the histogram
*/
explicit WValueSetHistogram( const WValueSetBase& valueSet );
//explicit WValueSetHistogram( const WValueSetBase& valueSet );
/**
* Copy constructor. If another interval size is given setInterval() is called and
......@@ -66,7 +66,7 @@ public:
* \param histogram another WValueSetHistogram
* \param intervalSize the size of one bucket in the mapped histogram
*/
explicit WValueSetHistogram( const WValueSetHistogram& histogram, double intervalSize = 0.0 );
//explicit WValueSetHistogram( const WValueSetHistogram& histogram, double intervalSize = 0.0 );
/**
* Destructor.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment