OpenWalnut  1.5.0dev
WDataSetVector.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <memory>
26 #include <stdint.h>
27 #include <string>
28 #include <vector>
29 
30 #include <boost/array.hpp>
31 
32 #include "../common/WAssert.h"
33 #include "WDataSetSingle.h"
34 #include "WDataSetVector.h"
35 
36 // prototype instance as singleton
37 std::shared_ptr< WPrototyped > WDataSetVector::m_prototype = std::shared_ptr< WPrototyped >();
38 
39 WDataSetVector::WDataSetVector( std::shared_ptr< WValueSetBase > newValueSet,
40  std::shared_ptr< WGrid > newGrid )
41  : WDataSetSingle( newValueSet, newGrid )
42 {
43  WAssert( newValueSet, "No value set given." );
44  WAssert( newGrid, "No grid given." );
45  WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
46  WAssert( newValueSet->order() == 1, "The value set does not contain vectors." );
47 }
48 
50  : WDataSetSingle()
51 {
52 }
53 
55 {
56 }
57 
58 WDataSetSingle::SPtr WDataSetVector::clone( std::shared_ptr< WValueSetBase > newValueSet, std::shared_ptr< WGrid > newGrid ) const
59 {
60  return WDataSetSingle::SPtr( new WDataSetVector( newValueSet, newGrid ) );
61 }
62 
63 WDataSetSingle::SPtr WDataSetVector::clone( std::shared_ptr< WValueSetBase > newValueSet ) const
64 {
65  return WDataSetSingle::SPtr( new WDataSetVector( newValueSet, getGrid() ) );
66 }
67 
68 WDataSetSingle::SPtr WDataSetVector::clone( std::shared_ptr< WGrid > newGrid ) const
69 {
70  return WDataSetSingle::SPtr( new WDataSetVector( getValueSet(), newGrid ) );
71 }
72 
74 {
76 }
77 
78 std::shared_ptr< WPrototyped > WDataSetVector::getPrototype()
79 {
80  if( !m_prototype )
81  {
82  m_prototype = std::shared_ptr< WPrototyped >( new WDataSetVector() );
83  }
84 
85  return m_prototype;
86 }
87 
88 namespace
89 {
90  boost::array< double, 8 > computePrefactors( const WPosition& pos,
91  std::shared_ptr< const WGrid > i_grid,
92  std::shared_ptr< const WValueSetBase > i_valueSet,
93  bool *success,
94  std::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds )
95  {
96  std::shared_ptr< const WGridRegular3D > grid = std::dynamic_pointer_cast< const WGridRegular3D >( i_grid );
97 
98  WAssert( grid, "This data set has a grid whose type is not yet supported for interpolation." );
99  WAssert( ( i_valueSet->order() == 1 && i_valueSet->dimension() == 3 ),
100  "Only implemented for 3D Vectors so far." );
101  boost::array< double, 8 > h;
102 
103  bool isInside = true;
104  size_t cellId = grid->getCellId( pos, &isInside );
105 
106  if( !isInside )
107  {
108  *success = false;
109  return h;
110  }
111  *success = true; // set it here, before the real work is done, because this cannot fail anymore.
112 
113  *vertexIds = grid->getCellVertexIds( cellId );
114 
115  WPosition localPos = grid->getTransform().directionToGridSpace( pos - grid->getPosition( ( *vertexIds )[0] ) );
116 
117  double lambdaX = localPos[0];
118  double lambdaY = localPos[1];
119  double lambdaZ = localPos[2];
120 
121  // lZ lY
122  // | /
123  // | 6___/_7
124  // |/: /|
125  // 4_:___5 |
126  // | :...|.|
127  // |.2 | 3
128  // |_____|/ ____lX
129  // 0 1
130  h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
131  h[1] = ( lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
132  h[2] = ( 1 - lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ );
133  h[3] = ( lambdaX ) * ( lambdaY ) * ( 1 - lambdaZ );
134  h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ );
135  h[5] = ( lambdaX ) * ( 1 - lambdaY ) * ( lambdaZ );
136  h[6] = ( 1 - lambdaX ) * ( lambdaY ) * ( lambdaZ );
137  h[7] = ( lambdaX ) * ( lambdaY ) * ( lambdaZ );
138 
139  return h;
140  }
141 }
142 
143 WVector3d WDataSetVector::interpolate( const WPosition& pos, bool *success ) const
144 {
145  std::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds( new WGridRegular3D::CellVertexArray );
146  boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds );
147  WVector3d result( 0.0, 0.0, 0.0 );
148 
149  if( *success ) // only if pos was iniside the grid, we proivde a result different to 0.0, 0.0, 0.0
150  {
151  for( size_t i = 0; i < 8; ++i )
152  {
153  result += h[i] * getVectorAt( ( *vertexIds )[i] );
154  }
155  }
156 
157  return result;
158 }
159 
161 {
162  std::shared_ptr< WGridRegular3D::CellVertexArray > vertexIds( new WGridRegular3D::CellVertexArray );
163  boost::array< double, 8 > h = computePrefactors( pos, m_grid, m_valueSet, success, vertexIds );
164  WVector3d result( 0.0, 0.0, 0.0 );
165 
166  if( *success ) // only if pos was iniside the grid, we proivde a result different to 0.0, 0.0, 0.0
167  {
168  for( size_t i = 0; i < 8; ++i )
169  {
170  double sign = 1.0;
171  if( dot( getVectorAt( ( *vertexIds )[0] ), getVectorAt( ( *vertexIds )[i] ) ) < 0.0 )
172  {
173  sign = -1.0;
174  }
175  result += h[i] * sign * getVectorAt( ( *vertexIds )[i] );
176  }
177  }
178 
179  return result;
180 }
181 
183 {
184  switch( getValueSet()->getDataType() )
185  {
186  case W_DT_UNSIGNED_CHAR:
187  {
188  return std::dynamic_pointer_cast< WValueSet< uint8_t > >( getValueSet() )->getVector3D( index );
189  }
190  case W_DT_INT16:
191  {
192  return std::dynamic_pointer_cast< WValueSet< int16_t > >( getValueSet() )->getVector3D( index );
193  }
194  case W_DT_SIGNED_INT:
195  {
196  return std::dynamic_pointer_cast< WValueSet< int32_t > >( getValueSet() )->getVector3D( index );
197  }
198  case W_DT_FLOAT:
199  {
200  return std::dynamic_pointer_cast< WValueSet< float > >( getValueSet() )->getVector3D( index );
201  }
202  case W_DT_DOUBLE:
203  {
204  return std::dynamic_pointer_cast< WValueSet< double > >( getValueSet() )->getVector3D( index );
205  }
206  default:
207  WAssert( false, "Unknow data type in dataset." );
208  }
209 
210  return WVector3d( 0, 0, 0 );
211 }
212 
214 {
215  return true;
216 }
217 
A data set consisting of a set of values based on a grid.
std::shared_ptr< WValueSetBase > getValueSet() const
std::shared_ptr< WGrid > m_grid
Stores the reference of the WGrid of this DataSetSingle instance.
std::shared_ptr< WGrid > getGrid() const
std::shared_ptr< WValueSetBase > m_valueSet
Stores the reference of the WValueSet of this DataSetSingle instance.
std::shared_ptr< WDataSetSingle > SPtr
Convenience typedef for a std::shared_ptr.
static std::shared_ptr< WPrototyped > m_prototype
The prototype as singleton.
virtual bool isTexture() const
Determines whether this dataset can be used as a texture.
virtual WDataSetSingle::SPtr clone() const
Creates a copy (clone) of this instance.
WVector3d eigenVectorInterpolate(const WPosition &pos, bool *success) const
Interpolates the very same way as interpolate but it assures that all vecs are aligned to point into ...
static std::shared_ptr< WPrototyped > getPrototype()
Returns a prototype instantiated with the true type of the deriving class.
virtual ~WDataSetVector()
Destroys this DataSet instance.
WDataSetVector()
Construct an empty and unusable instance.
WVector3d getVectorAt(size_t index) const
Get the vector on the given position in value set.
WVector3d interpolate(const WPosition &pos, bool *success) const
Interpolates the vector field at the given position.
boost::array< size_t, 8 > CellVertexArray
Convenience typedef for a boost::array< size_t, 8 >.
This only is a 3d double vector.