OpenWalnut 1.3.1
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( ( m_valueSet->order() == 0 &&  m_valueSet->dimension() == 1 ),
00099              "Only implemented for scalar values so far." );
00100 
00101     bool isInside = true;
00102     size_t cellId = grid->getCellId( pos, &isInside );
00103 
00104     if( !isInside )
00105     {
00106         *success = false;
00107         return 0.0;
00108     }
00109 
00110     WGridRegular3D::CellVertexArray vertexIds = grid->getCellVertexIds( cellId );
00111 
00112     WPosition localPos = grid->getTransform().positionToGridSpace( pos - grid->getPosition( vertexIds[0] ) );
00113 
00114     double lambdaX = localPos[0];
00115     double lambdaY = localPos[1];
00116     double lambdaZ = localPos[2];
00117     std::vector< double > h( 8 );
00118 //         lZ     lY
00119 //         |      /
00120 //         | 6___/_7
00121 //         |/:    /|
00122 //         4_:___5 |
00123 //         | :...|.|
00124 //         |.2   | 3
00125 //         |_____|/ ____lX
00126 //        0      1
00127     h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00128     h[1] = (     lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00129     h[2] = ( 1 - lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00130     h[3] = (     lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00131     h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00132     h[5] = (     lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00133     h[6] = ( 1 - lambdaX ) * (     lambdaY ) * (     lambdaZ );
00134     h[7] = (     lambdaX ) * (     lambdaY ) * (     lambdaZ );
00135 
00136     double result = 0;
00137     for( size_t i = 0; i < 8; ++i )
00138     {
00139         result += h[i] * WDataSetSingle::getValueAt( vertexIds[i] );
00140     }
00141 
00142     *success = true;
00143     return result;
00144 }
00145 
00146 double WDataSetScalar::getValueAt( int x, int y, int z ) const
00147 {
00148     boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_grid );
00149     size_t id = x + y * grid->getNbCoordsX() + z * grid->getNbCoordsX() * grid->getNbCoordsY();
00150 
00151     return WDataSetSingle::getValueAt( id );
00152 }
00153 
00154 boost::shared_ptr< const WValueSetHistogram > WDataSetScalar::getHistogram( size_t buckets )
00155 {
00156     boost::lock_guard<boost::mutex> lock( m_histogramLock );
00157 
00158     if( m_histograms.count( buckets ) != 0 )
00159     {
00160         return m_histograms[ buckets ];
00161     }
00162 
00163     // create if not yet existing
00164     m_histograms[ buckets ] = boost::shared_ptr< WValueSetHistogram >( new WValueSetHistogram( m_valueSet, buckets ) );
00165 
00166     return m_histograms[ buckets ];
00167 }
00168