OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 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 // prototype instance as singleton 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, 00086 boost::shared_ptr< const WGrid > i_grid, 00087 boost::shared_ptr< const WValueSetBase > i_valueSet, 00088 bool *success, 00089 boost::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds ) 00090 { 00091 boost::shared_ptr< const WGridRegular3D > grid = boost::dynamic_pointer_cast< const WGridRegular3D >( i_grid ); 00092 00093 WAssert( grid, "This data set has a grid whose type is not yet supported for interpolation." ); 00094 WAssert( ( i_valueSet->order() == 1 && i_valueSet->dimension() == 3 ), 00095 "Only implemented for 3D Vectors so far." ); 00096 boost::array< double, 8 > h; 00097 00098 bool isInside = true; 00099 size_t cellId = grid->getCellId( pos, &isInside ); 00100 00101 if( !isInside ) 00102 { 00103 *success = false; 00104 return h; 00105 } 00106 *success = true; // set it here, before the real work is done, because this cannot fail anymore. 00107 00108 *vertexIds = grid->getCellVertexIds( cellId ); 00109 00110 WPosition localPos = grid->getTransform().positionToGridSpace( pos - grid->getPosition( ( *vertexIds )[0] ) ); 00111 00112 double lambdaX = localPos[0]; 00113 double lambdaY = localPos[1]; 00114 double lambdaZ = localPos[2]; 00115 00116 // lZ lY 00117 // | / 00118 // | 6___/_7 00119 // |/: /| 00120 // 4_:___5 | 00121 // | :...|.| 00122 // |.2 | 3 00123 // |_____|/ ____lX 00124 // 0 1 00125 h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ ); 00126 h[1] = ( lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ ); 00127 h[2] = ( 1 - lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ ); 00128 h[3] = ( lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ ); 00129 h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ ); 00130 h[5] = ( lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ ); 00131 h[6] = ( 1 - lambdaX ) * ( lambdaY ) * ( lambdaZ ); 00132 h[7] = ( lambdaX ) * ( lambdaY ) * ( lambdaZ ); 00133 00134 return h; 00135 } 00136 } 00137 00138 WVector3d WDataSetVector::interpolate( const WPosition& pos, bool *success ) const 00139 { 00140 boost::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds( new WGridRegular3D::CellVertexArray ); 00141 boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds ); 00142 WVector3d result( 0.0, 0.0, 0.0 ); 00143 00144 if( *success ) // only if pos was iniside the grid, we proivde a result different to 0.0, 0.0, 0.0 00145 { 00146 for( size_t i = 0; i < 8; ++i ) 00147 { 00148 result += h[i] * getVectorAt( ( *vertexIds )[i] ); 00149 } 00150 } 00151 00152 return result; 00153 } 00154 00155 WVector3d WDataSetVector::eigenVectorInterpolate( const WPosition& pos, bool *success ) const 00156 { 00157 boost::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds( new WGridRegular3D::CellVertexArray ); 00158 boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds ); 00159 WVector3d result( 0.0, 0.0, 0.0 ); 00160 00161 if( *success ) // only if pos was iniside the grid, we proivde a result different to 0.0, 0.0, 0.0 00162 { 00163 for( size_t i = 0; i < 8; ++i ) 00164 { 00165 double sign = 1.0; 00166 if( dot( getVectorAt( ( *vertexIds )[0] ), getVectorAt( ( *vertexIds )[i] ) ) < 0.0 ) 00167 { 00168 sign = -1.0; 00169 } 00170 result += h[i] * sign * getVectorAt( ( *vertexIds )[i] ); 00171 } 00172 } 00173 00174 return result; 00175 } 00176 00177 WVector3d WDataSetVector::getVectorAt( size_t index ) const 00178 { 00179 switch( getValueSet()->getDataType() ) 00180 { 00181 case W_DT_UNSIGNED_CHAR: 00182 { 00183 return boost::dynamic_pointer_cast< WValueSet< uint8_t > >( getValueSet() )->getVector3D( index ); 00184 } 00185 case W_DT_INT16: 00186 { 00187 return boost::dynamic_pointer_cast< WValueSet< int16_t > >( getValueSet() )->getVector3D( index ); 00188 } 00189 case W_DT_SIGNED_INT: 00190 { 00191 return boost::dynamic_pointer_cast< WValueSet< int32_t > >( getValueSet() )->getVector3D( index ); 00192 } 00193 case W_DT_FLOAT: 00194 { 00195 return boost::dynamic_pointer_cast< WValueSet< float > >( getValueSet() )->getVector3D( index ); 00196 } 00197 case W_DT_DOUBLE: 00198 { 00199 return boost::dynamic_pointer_cast< WValueSet< double > >( getValueSet() )->getVector3D( index ); 00200 } 00201 default: 00202 WAssert( false, "Unknow data type in dataset." ); 00203 } 00204 00205 return WVector3d( 0, 0, 0 ); 00206 } 00207 00208 bool WDataSetVector::isTexture() const 00209 { 00210 return true; 00211 } 00212