OpenWalnut 1.2.5
WDataSetScalar.cpp
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 <string>
00026 #include <vector>
00027 
00028 #include "../common/WAssert.h"
00029 #include "../common/WLimits.h"
00030 #include "datastructures/WValueSetHistogram.h"
00031 #include "WDataSetSingle.h"
00032 
00033 #include "WDataSetScalar.h"
00034 
00035 // prototype instance as singleton
00036 boost::shared_ptr< WPrototyped > WDataSetScalar::m_prototype = boost::shared_ptr< WPrototyped >();
00037 
00038 WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
00039                                 boost::shared_ptr< WGrid > newGrid )
00040     : WDataSetSingle( newValueSet, newGrid )
00041 {
00042     WAssert( newValueSet, "No value set given." );
00043     WAssert( newGrid, "No grid given." );
00044     WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
00045     WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );
00046 }
00047 
00048 WDataSetScalar::WDataSetScalar()
00049     : WDataSetSingle()
00050 {
00051     // default constructor used by the prototype mechanism
00052 }
00053 
00054 WDataSetScalar::~WDataSetScalar()
00055 {
00056 }
00057 
00058 WDataSetSingle::SPtr WDataSetScalar::clone( boost::shared_ptr< WValueSetBase > newValueSet ) const
00059 {
00060     return WDataSetSingle::SPtr( new WDataSetScalar( newValueSet, getGrid() ) );
00061 }
00062 
00063 WDataSetSingle::SPtr WDataSetScalar::clone( boost::shared_ptr< WGrid > newGrid ) const
00064 {
00065     return WDataSetSingle::SPtr( new WDataSetScalar( getValueSet(), newGrid ) );
00066 }
00067 
00068 WDataSetSingle::SPtr WDataSetScalar::clone() const
00069 {
00070     return WDataSetSingle::SPtr( new WDataSetScalar( getValueSet(), getGrid() ) );
00071 }
00072 
00073 double WDataSetScalar::getMax() const
00074 {
00075     return m_valueSet->getMaximumValue();
00076 }
00077 
00078 double WDataSetScalar::getMin() const
00079 {
00080     return m_valueSet->getMinimumValue();
00081 }
00082 
00083 boost::shared_ptr< WPrototyped > WDataSetScalar::getPrototype()
00084 {
00085     if( !m_prototype )
00086     {
00087         m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetScalar() );
00088     }
00089 
00090     return m_prototype;
00091 }
00092 
00093 double WDataSetScalar::interpolate( const WPosition& pos, bool* success ) const
00094 {
00095     boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_grid );
00096 
00097     WAssert( grid, "This data set has a grid whose type is not yet supported for interpolation." );
00098     WAssert( grid->isNotRotated(), "Only feasible for grids that are only translated or scaled so far." );
00099     WAssert( ( m_valueSet->order() == 0 &&  m_valueSet->dimension() == 1 ),
00100              "Only implemented for scalar values so far." );
00101 
00102     bool isInside = true;
00103     size_t cellId = grid->getCellId( pos, &isInside );
00104 
00105     if( !isInside )
00106     {
00107         *success = false;
00108         return 0.0;
00109     }
00110 
00111     std::vector< size_t > vertexIds = grid->getCellVertexIds( cellId );
00112 
00113     WPosition localPos = pos - grid->getPosition( vertexIds[0] );
00114 
00115     double lambdaX = localPos[0] / grid->getOffsetX();
00116     double lambdaY = localPos[1] / grid->getOffsetY();
00117     double lambdaZ = localPos[2] / grid->getOffsetZ();
00118     std::vector< double > h( 8 );
00119 //         lZ     lY
00120 //         |      /
00121 //         | 6___/_7
00122 //         |/:    /|
00123 //         4_:___5 |
00124 //         | :...|.|
00125 //         |.2   | 3
00126 //         |_____|/ ____lX
00127 //        0      1
00128     h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00129     h[1] = (     lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00130     h[2] = ( 1 - lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00131     h[3] = (     lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00132     h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00133     h[5] = (     lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00134     h[6] = ( 1 - lambdaX ) * (     lambdaY ) * (     lambdaZ );
00135     h[7] = (     lambdaX ) * (     lambdaY ) * (     lambdaZ );
00136 
00137     double result = 0;
00138     for( size_t i = 0; i < 8; ++i )
00139     {
00140         result += h[i] * WDataSetSingle::getValueAt( vertexIds[i] );
00141     }
00142 
00143     *success = true;
00144     return result;
00145 }
00146 
00147 double WDataSetScalar::getValueAt( int x, int y, int z ) const
00148 {
00149     boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_grid );
00150     size_t id = x + y * grid->getNbCoordsX() + z * grid->getNbCoordsX() * grid->getNbCoordsY();
00151 
00152     return WDataSetSingle::getValueAt( id );
00153 }
00154 
00155 boost::shared_ptr< const WValueSetHistogram > WDataSetScalar::getHistogram( size_t buckets )
00156 {
00157     boost::lock_guard<boost::mutex> lock( m_histogramLock );
00158 
00159     if( m_histograms.count( buckets ) != 0 )
00160     {
00161         return m_histograms[ buckets ];
00162     }
00163 
00164     // create if not yet existing
00165     m_histograms[ buckets ] = boost::shared_ptr< WValueSetHistogram >( new WValueSetHistogram( m_valueSet, buckets ) );
00166 
00167     return m_histograms[ buckets ];
00168 }
00169 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends