OpenWalnut  1.4.0
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 std::string const WDataSetScalar::getName() const
00074 {
00075     return "WDataSetScalar";
00076 }
00077 
00078 std::string const WDataSetScalar::getDescription() const
00079 {
00080     return "A scalar dataset, i.e. one scalar value per voxel.";
00081 }
00082 
00083 double WDataSetScalar::getMax() const
00084 {
00085     return m_valueSet->getMaximumValue();
00086 }
00087 
00088 double WDataSetScalar::getMin() const
00089 {
00090     return m_valueSet->getMinimumValue();
00091 }
00092 
00093 boost::shared_ptr< WPrototyped > WDataSetScalar::getPrototype()
00094 {
00095     if( !m_prototype )
00096     {
00097         m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetScalar() );
00098     }
00099 
00100     return m_prototype;
00101 }
00102 
00103 double WDataSetScalar::interpolate( const WPosition& pos, bool* success ) const
00104 {
00105     boost::shared_ptr< WGridRegular3D > grid = boost::dynamic_pointer_cast< WGridRegular3D >( m_grid );
00106 
00107     WAssert( grid, "This data set has a grid whose type is not yet supported for interpolation." );
00108     WAssert( ( m_valueSet->order() == 0 &&  m_valueSet->dimension() == 1 ),
00109              "Only implemented for scalar values so far." );
00110 
00111     bool isInside = true;
00112     size_t cellId = grid->getCellId( pos, &isInside );
00113 
00114     if( !isInside )
00115     {
00116         *success = false;
00117         return 0.0;
00118     }
00119 
00120     WGridRegular3D::CellVertexArray vertexIds = grid->getCellVertexIds( cellId );
00121 
00122     WPosition localPos = grid->getTransform().positionToGridSpace( pos - grid->getPosition( vertexIds[0] ) );
00123 
00124     double lambdaX = localPos[0];
00125     double lambdaY = localPos[1];
00126     double lambdaZ = localPos[2];
00127     std::vector< double > h( 8 );
00128 //         lZ     lY
00129 //         |      /
00130 //         | 6___/_7
00131 //         |/:    /|
00132 //         4_:___5 |
00133 //         | :...|.|
00134 //         |.2   | 3
00135 //         |_____|/ ____lX
00136 //        0      1
00137     h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00138     h[1] = (     lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00139     h[2] = ( 1 - lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00140     h[3] = (     lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00141     h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00142     h[5] = (     lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00143     h[6] = ( 1 - lambdaX ) * (     lambdaY ) * (     lambdaZ );
00144     h[7] = (     lambdaX ) * (     lambdaY ) * (     lambdaZ );
00145 
00146     double result = 0;
00147     for( size_t i = 0; i < 8; ++i )
00148     {
00149         result += h[i] * WDataSetSingle::getValueAt( vertexIds[i] );
00150     }
00151 
00152     *success = true;
00153     return result;
00154 }
00155 
00156 double WDataSetScalar::getValueAt( int x, int y, int z ) const
00157 {
00158     boost::shared_ptr< WGridRegular3D > grid = boost::dynamic_pointer_cast< WGridRegular3D >( m_grid );
00159     size_t id = x + y * grid->getNbCoordsX() + z * grid->getNbCoordsX() * grid->getNbCoordsY();
00160 
00161     return WDataSetSingle::getValueAt( id );
00162 }
00163 
00164 boost::shared_ptr< const WValueSetHistogram > WDataSetScalar::getHistogram( size_t buckets )
00165 {
00166     boost::lock_guard<boost::mutex> lock( m_histogramLock );
00167 
00168     if( m_histograms.count( buckets ) != 0 )
00169     {
00170         return m_histograms[ buckets ];
00171     }
00172 
00173     // create if not yet existing
00174     m_histograms[ buckets ] = boost::shared_ptr< WValueSetHistogram >( new WValueSetHistogram( m_valueSet, buckets ) );
00175 
00176     return m_histograms[ buckets ];
00177 }
00178