ExtractSlice.hpp

00001 #ifndef __FIBEROPERATIONS_EXTRACT_SLICE
00002 #define __FIBEROPERATIONS_EXTRACT_SLICE
00003 
00004 #include <field/MemBase.hpp>
00005 #include <meta/LIST.hpp>
00006 #include "SliceSelection.hpp"
00007 
00008 namespace Fiber
00009 {
00010 
00011 template <class Array2D>
00012 struct  ArrayCollector
00013 {
00014         typedef RefPtr<Array2D> result_t;
00015 
00016         result_t        result;
00017         Array2D & dst;
00018 
00019         ArrayCollector(const MultiIndex<2>&Dims)
00020         : result( new Array2D(Dims) )
00021         , dst( *result )
00022         {
00023 
00024         }
00025 
00026         template <class ElementType>
00027         void collect(const MultiIndex<2>&Dims, const ElementType&T)
00028         {
00029                 dst[ Dims ] = T;
00030         }
00031 
00032 static  result_t Invalid()
00033         {
00034                 return MemCore::NullPtr();
00035         }
00036 };
00037 
00038 template <class Operator, class Array3D>
00039 struct  ExtractSlice
00040 {
00041 
00042 static  typename Operator::result_t get(const MultiIndex<3>&Dims,
00043                                         const RefPtr<MemBase>&Data, const SliceSelection&GO,
00044                                         index_t SliceID, const MultiIndex<3>&FragmentOffset)
00045         {
00046         RefPtr<Array3D> src = Data; 
00047                 if (!src)
00048                         return Operator::Invalid();
00049 
00050         index_t Xsize = Dims[ GO.X ];
00051         index_t Ysize = Dims[ GO.Y ];
00052 
00053         Operator Op( MIndex(Xsize, Ysize) ); 
00054 
00055         const Array3D&Src = *src;
00056 
00057                 for(index_t iy = 0; iy<Ysize; iy++)
00058                 for(index_t ix = 0; ix<Xsize; ix++)
00059                 {
00060                 MultiIndex<3> P = FragmentOffset;
00061                         P[GO.X] += ix; P[GO.Y] += iy; P[GO.Z] += SliceID;
00062 
00063                 MultiIndex<2> Pdst;
00064                         Pdst[ 0 ] = ix;
00065                         Pdst[ 1 ] = iy;
00066 
00067                         Op.collect( Pdst, Src[ P ] );
00068                 } 
00069 
00070                 return Op.result;
00071         }
00072 };
00073 
00074 template <class Operator, class Array3D, class NEXT>
00075 struct  ExtractSlice<Operator, META::LIST<Array3D, NEXT> >
00076 {
00077 
00078 static  typename Operator::result_t get(const MultiIndex<3>&Dims,
00079                                         const RefPtr<MemBase>&Data, const SliceSelection&O,
00080                                         index_t SliceID, const MultiIndex<3>&FragmentOffset)
00081         {
00082                 if (typename Operator::result_t result =
00083                     ExtractSlice<Operator, Array3D>::get(Dims, Data, O, SliceID, FragmentOffset) )
00084                 {
00085                         return result;
00086                 }
00087                 return ExtractSlice<Operator, NEXT>::get(Dims, Data, O, SliceID, FragmentOffset);
00088         }
00089 };
00090 
00091 template <class Operator>
00092 struct  ExtractSlice<Operator, META::NIL >
00093 {
00094 
00095 static  typename Operator::result_t get(const MultiIndex<3>&Dims,
00096                                         const RefPtr<MemBase>&Data, const SliceSelection&O,
00097                                         index_t SliceID, const MultiIndex<3>&FragmentOffset)
00098         {
00099                 return Operator::Invalid();
00100         }
00101 };
00102 
00103 } // namespace Fiber
00104 
00105 #endif //__FIBEROPERATIONS_EXTRACT_SLICE