00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdint.h>
00026
00027 #include <string>
00028 #include <vector>
00029
00030 #include <boost/array.hpp>
00031
00032 #include "../common/WAssert.h"
00033 #include "WDataSetSingle.h"
00034 #include "WDataSetVector.h"
00035
00036
00037 boost::shared_ptr< WPrototyped > WDataSetVector::m_prototype = boost::shared_ptr< WPrototyped >();
00038
00039 WDataSetVector::WDataSetVector( boost::shared_ptr< WValueSetBase > newValueSet,
00040 boost::shared_ptr< WGrid > newGrid )
00041 : WDataSetSingle( newValueSet, newGrid )
00042 {
00043 WAssert( newValueSet, "No value set given." );
00044 WAssert( newGrid, "No grid given." );
00045 WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
00046 WAssert( newValueSet->order() == 1, "The value set does not contain vectors." );
00047 }
00048
00049 WDataSetVector::WDataSetVector()
00050 : WDataSetSingle()
00051 {
00052 }
00053
00054 WDataSetVector::~WDataSetVector()
00055 {
00056 }
00057
00058 WDataSetSingle::SPtr WDataSetVector::clone( boost::shared_ptr< WValueSetBase > newValueSet ) const
00059 {
00060 return WDataSetSingle::SPtr( new WDataSetVector( newValueSet, getGrid() ) );
00061 }
00062
00063 WDataSetSingle::SPtr WDataSetVector::clone( boost::shared_ptr< WGrid > newGrid ) const
00064 {
00065 return WDataSetSingle::SPtr( new WDataSetVector( getValueSet(), newGrid ) );
00066 }
00067
00068 WDataSetSingle::SPtr WDataSetVector::clone() const
00069 {
00070 return WDataSetSingle::SPtr( new WDataSetVector( getValueSet(), getGrid() ) );
00071 }
00072
00073 boost::shared_ptr< WPrototyped > WDataSetVector::getPrototype()
00074 {
00075 if( !m_prototype )
00076 {
00077 m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetVector() );
00078 }
00079
00080 return m_prototype;
00081 }
00082
00083 namespace
00084 {
00085 boost::array< double, 8 > computePrefactors( const WPosition& pos, boost::shared_ptr< const WGrid > i_grid,
00086 boost::shared_ptr< const WValueSetBase > i_valueSet, bool *success, boost::shared_ptr< std::vector< size_t > > vertexIds )
00087 {
00088 boost::shared_ptr< const WGridRegular3D > grid = boost::shared_dynamic_cast< const WGridRegular3D >( i_grid );
00089
00090 WAssert( grid, "This data set has a grid whose type is not yet supported for interpolation." );
00091 WAssert( grid->isNotRotated(), "Only feasible for grids that are only translated or scaled so far." );
00092 WAssert( ( i_valueSet->order() == 1 && i_valueSet->dimension() == 3 ),
00093 "Only implemented for 3D Vectors so far." );
00094 boost::array< double, 8 > h;
00095
00096 bool isInside = true;
00097 size_t cellId = grid->getCellId( pos, &isInside );
00098
00099 if( !isInside )
00100 {
00101 *success = false;
00102 return h;
00103 }
00104 *success = true;
00105
00106 *vertexIds = grid->getCellVertexIds( cellId );
00107
00108 WPosition localPos = pos - grid->getPosition( ( *vertexIds )[0] );
00109
00110 double lambdaX = localPos[0] / grid->getOffsetX();
00111 double lambdaY = localPos[1] / grid->getOffsetY();
00112 double lambdaZ = localPos[2] / grid->getOffsetZ();
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00124 h[1] = ( lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00125 h[2] = ( 1 - lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ );
00126 h[3] = ( lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ );
00127 h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ );
00128 h[5] = ( lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ );
00129 h[6] = ( 1 - lambdaX ) * ( lambdaY ) * ( lambdaZ );
00130 h[7] = ( lambdaX ) * ( lambdaY ) * ( lambdaZ );
00131
00132 return h;
00133 }
00134 }
00135
00136 WVector3d WDataSetVector::interpolate( const WPosition& pos, bool *success ) const
00137 {
00138 boost::shared_ptr< std::vector< size_t > > vertexIds( new std::vector< size_t > );
00139 boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds );
00140 WVector3d result( 0.0, 0.0, 0.0 );
00141
00142 if( *success )
00143 {
00144 for( size_t i = 0; i < 8; ++i )
00145 {
00146 result += h[i] * getVectorAt( ( *vertexIds )[i] );
00147 }
00148 }
00149
00150 return result;
00151 }
00152
00153 WVector3d WDataSetVector::eigenVectorInterpolate( const WPosition& pos, bool *success ) const
00154 {
00155 boost::shared_ptr< std::vector< size_t > > vertexIds( new std::vector< size_t > );
00156 boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds );
00157 WVector3d result( 0.0, 0.0, 0.0 );
00158
00159 if( *success )
00160 {
00161 for( size_t i = 0; i < 8; ++i )
00162 {
00163 double sign = 1.0;
00164 if( dot( getVectorAt( ( *vertexIds )[0] ), getVectorAt( ( *vertexIds )[i] ) ) < 0.0 )
00165 {
00166 sign = -1.0;
00167 }
00168 result += h[i] * sign * getVectorAt( ( *vertexIds )[i] );
00169 }
00170 }
00171
00172 return result;
00173 }
00174
00175 WVector3d WDataSetVector::getVectorAt( size_t index ) const
00176 {
00177 switch( getValueSet()->getDataType() )
00178 {
00179 case W_DT_UNSIGNED_CHAR:
00180 {
00181 return boost::shared_dynamic_cast< WValueSet< uint8_t > >( getValueSet() )->getVector3D( index );
00182 }
00183 case W_DT_INT16:
00184 {
00185 return boost::shared_dynamic_cast< WValueSet< int16_t > >( getValueSet() )->getVector3D( index );
00186 }
00187 case W_DT_SIGNED_INT:
00188 {
00189 return boost::shared_dynamic_cast< WValueSet< int32_t > >( getValueSet() )->getVector3D( index );
00190 }
00191 case W_DT_FLOAT:
00192 {
00193 return boost::shared_dynamic_cast< WValueSet< float > >( getValueSet() )->getVector3D( index );
00194 }
00195 case W_DT_DOUBLE:
00196 {
00197 return boost::shared_dynamic_cast< WValueSet< double > >( getValueSet() )->getVector3D( index );
00198 }
00199 default:
00200 WAssert( false, "Unknow data type in dataset." );
00201 }
00202
00203 return WVector3d( 0, 0, 0 );
00204 }
00205
00206 bool WDataSetVector::isTexture() const
00207 {
00208 return true;
00209 }
00210