00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkIndex_h
00018 #define __itkIndex_h
00019
00020 #include "itkMacro.h"
00021 #include "itkOffset.h"
00022 #include "itkSize.h"
00023 #include "itkFixedArray.h"
00024
00025 #include <memory>
00026
00027 #include "itkExceptionObject.h"
00028
00029 namespace itk
00030 {
00031
00032 namespace Functor
00033 {
00034 template<unsigned int VIndexDimension> class IndexLexicographicCompare;
00035 }
00036
00066 template<unsigned int VIndexDimension=2>
00067 class Index {
00068 public:
00070 typedef Index Self;
00071
00073 typedef Index<VIndexDimension> IndexType;
00074 typedef long IndexValueType;
00075
00077 static unsigned int GetIndexDimension() { return VIndexDimension; }
00078
00080 typedef Size<VIndexDimension> SizeType;
00081
00083 typedef Offset<VIndexDimension> OffsetType;
00084 typedef typename OffsetType::OffsetValueType OffsetValueType;
00085
00087 typedef Functor::IndexLexicographicCompare<VIndexDimension> LexicographicCompare;
00088
00090 const Self
00091 operator+(const SizeType &size) const
00092 {
00093 Self result;
00094 for (unsigned int i=0; i < VIndexDimension; i++)
00095 { result[i] = m_Index[i] + static_cast<IndexValueType>(size[i]); }
00096 return result;
00097 }
00099
00101 const Self &
00102 operator+=(const SizeType &size)
00103 {
00104 for (unsigned int i=0; i < VIndexDimension; i++)
00105 { m_Index[i] += static_cast<IndexValueType>(size[i]); }
00106 return *this;
00107 }
00109
00111 const Self
00112 operator-(const SizeType &size) const
00113 {
00114 Self result;
00115 for (unsigned int i=0; i < VIndexDimension; i++)
00116 { result[i] = m_Index[i] - static_cast<IndexValueType>(size[i]); }
00117 return result;
00118 }
00120
00122 const Self &
00123 operator-=(const SizeType &size)
00124 {
00125 for (unsigned int i=0; i < VIndexDimension; i++)
00126 { m_Index[i] -= static_cast<IndexValueType>(size[i]); }
00127 return *this;
00128 }
00130
00132 const Self
00133 operator+(const OffsetType &offset) const
00134 {
00135 Self result;
00136 for (unsigned int i=0; i < VIndexDimension; i++)
00137 { result[i] = m_Index[i] + offset[i]; }
00138 return result;
00139 }
00141
00143 const Self &
00144 operator+=(const OffsetType &offset)
00145 {
00146 for (unsigned int i=0; i < VIndexDimension; i++)
00147 { m_Index[i] += offset[i]; }
00148 return *this;
00149 }
00151
00153 const Self &
00154 operator-=(const OffsetType &offset)
00155 {
00156 for (unsigned int i=0; i < VIndexDimension; i++)
00157 { m_Index[i] -= offset[i]; }
00158 return *this;
00159 }
00161
00163 const Self
00164 operator-(const OffsetType &off) const
00165 {
00166 Self result;
00167 for (unsigned int i=0; i < VIndexDimension; i++)
00168 { result[i] = m_Index[i] - off.m_Offset[i]; }
00169 return result;
00170 }
00172
00174 const OffsetType
00175 operator-(const Self &vec) const
00176 {
00177 OffsetType result;
00178 for (unsigned int i=0; i < VIndexDimension; i++)
00179 { result[i] = m_Index[i] - vec.m_Index[i]; }
00180 return result;
00181 }
00183
00186 const Self
00187 operator*(const SizeType &vec) const
00188 {
00189 Self result;
00190 for (unsigned int i=0; i < VIndexDimension; i++)
00191 { result[i] = m_Index[i] * static_cast<IndexValueType>(vec.m_Size[i]); }
00192 return result;
00193 }
00195
00197 bool
00198 operator==(const Self &vec) const
00199 {
00200 bool same=true;
00201 for (unsigned int i=0; i < VIndexDimension && same; i++)
00202 { same = (m_Index[i] == vec.m_Index[i]); }
00203 return same;
00204 }
00206
00208 bool
00209 operator!=(const Self &vec) const
00210 {
00211 bool same=true;
00212 for (unsigned int i=0; i < VIndexDimension && same; i++)
00213 { same = (m_Index[i] == vec.m_Index[i]); }
00214 return !same;
00215 }
00217
00220 IndexValueType & operator[](unsigned int dim)
00221 { return m_Index[dim]; }
00222
00226 IndexValueType operator[](unsigned int dim) const
00227 { return m_Index[dim]; }
00228
00231 const IndexValueType *GetIndex() const { return m_Index; };
00232
00237 void SetIndex(const IndexValueType val[VIndexDimension])
00238 { memcpy(m_Index, val, sizeof(IndexValueType)*VIndexDimension); }
00239
00246 void SetElement(unsigned long element, IndexValueType val )
00247 { m_Index[ element ] = val; }
00248
00255 IndexValueType GetElement( unsigned long element )
00256 { return m_Index[ element ]; }
00257
00261 static Self GetBasisIndex(unsigned int dim);
00262
00265 void Fill(IndexValueType value)
00266 { for(unsigned int i=0;i < VIndexDimension; ++i) m_Index[i] = value; }
00267
00273 IndexValueType m_Index[VIndexDimension];
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 #if (defined (VCL_VC) && !defined(__GCCXML__)) || (defined(_MSC_VER) && (_MSC_VER <= 1310))
00285 #define vnl_math_rnd(x) ((x>=0.0)?(int)(x + 0.5):(int)(x - 0.5))
00286 #endif
00287
00288 template <class TCoordRep>
00289 inline void CopyWithRound( const FixedArray<TCoordRep,VIndexDimension> & point )
00290 {
00291 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00292 itkFoorLoopRoundingAndAssignmentMacro(IndexType,ContinuousIndexType,IndexValueType,m_Index,point,VIndexDimension);
00293 #else
00294 for(unsigned int i=0;i < VIndexDimension; ++i)
00295 {
00296 m_Index[i] = static_cast< IndexValueType>( vnl_math_rnd( point[i] ) );
00297 }
00298 #endif
00299 }
00300 #if (defined (VCL_VC) && !defined(__GCCXML__)) || (defined(_MSC_VER) && (_MSC_VER <= 1310))
00301 #undef vnl_math_rnd
00302 #endif
00303
00304
00306 template <class TCoordRep>
00307 inline void CopyWithCast( const FixedArray<TCoordRep,VIndexDimension> & point )
00308 {
00309 for(unsigned int i=0;i < VIndexDimension; ++i)
00310 {
00311 m_Index[i] = static_cast< IndexValueType>( point[i] );
00312 }
00313 }
00315
00316
00317 #if defined(CABLE_CONFIGURATION)
00318 Index();
00319 Index(const Self&);
00320 void operator=(const Self&);
00321 #endif
00322
00323 };
00324
00325 namespace Functor
00326 {
00334 template<unsigned int VIndexDimension>
00335 class IndexLexicographicCompare
00336 {
00337 public:
00338 bool operator()(Index<VIndexDimension> const& l,
00339 Index<VIndexDimension> const& r) const
00340 {
00341 for(unsigned int i=0; i < VIndexDimension; ++i)
00342 {
00343 if(l.m_Index[i] < r.m_Index[i])
00344 {
00345 return true;
00346 }
00347 else if(l.m_Index[i] > r.m_Index[i])
00348 {
00349 return false;
00350 }
00351 }
00352 return false;
00353 }
00354 };
00355 }
00356
00357 template<unsigned int VIndexDimension>
00358 Index<VIndexDimension>
00359 Index<VIndexDimension>
00360 ::GetBasisIndex(unsigned int dim)
00361 {
00362 Self ind;
00363
00364 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension);
00365 ind.m_Index[dim] = 1;
00366 return ind;
00367 }
00368
00369 template<unsigned int VIndexDimension>
00370 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind)
00371 {
00372 os << "[";
00373 for (unsigned int i=0; i+1 < VIndexDimension; ++i)
00374 {
00375 os << ind[i] << ", ";
00376 }
00377 if (VIndexDimension >= 1)
00378 {
00379 os << ind[VIndexDimension-1];
00380 }
00381 os << "]";
00382 return os;
00383 }
00384
00385 }
00386
00387 #endif
00388