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
00024 #include <memory>
00025
00026 #include "itkExceptionObject.h"
00027
00028 namespace itk
00029 {
00030
00031 namespace Functor
00032 {
00033 template<unsigned int VIndexDimension> class IndexLexicographicCompare;
00034 }
00035
00065 template<unsigned int VIndexDimension=2>
00066 class Index {
00067 public:
00069 typedef Index Self;
00070
00072 typedef Index<VIndexDimension> IndexType;
00073 typedef long IndexValueType;
00074
00076 static unsigned int GetIndexDimension() { return VIndexDimension; }
00077
00079 typedef Size<VIndexDimension> SizeType;
00080
00082 typedef Offset<VIndexDimension> OffsetType;
00083 typedef typename OffsetType::OffsetValueType OffsetValueType;
00084
00086 typedef Functor::IndexLexicographicCompare<VIndexDimension> LexicographicCompare;
00087
00089 const Self
00090 operator+(const SizeType &size) const
00091 {
00092 Self result;
00093 for (unsigned int i=0; i < VIndexDimension; i++)
00094 { result[i] = m_Index[i] + static_cast<IndexValueType>(size[i]); }
00095 return result;
00096 }
00098
00100 const Self &
00101 operator+=(const SizeType &size)
00102 {
00103 for (unsigned int i=0; i < VIndexDimension; i++)
00104 { m_Index[i] += static_cast<IndexValueType>(size[i]); }
00105 return *this;
00106 }
00108
00110 const Self
00111 operator-(const SizeType &size) const
00112 {
00113 Self result;
00114 for (unsigned int i=0; i < VIndexDimension; i++)
00115 { result[i] = m_Index[i] - static_cast<IndexValueType>(size[i]); }
00116 return result;
00117 }
00119
00121 const Self &
00122 operator-=(const SizeType &size)
00123 {
00124 for (unsigned int i=0; i < VIndexDimension; i++)
00125 { m_Index[i] -= static_cast<IndexValueType>(size[i]); }
00126 return *this;
00127 }
00129
00131 const Self
00132 operator+(const OffsetType &offset) const
00133 {
00134 Self result;
00135 for (unsigned int i=0; i < VIndexDimension; i++)
00136 { result[i] = m_Index[i] + offset[i]; }
00137 return result;
00138 }
00140
00142 const Self &
00143 operator+=(const OffsetType &offset)
00144 {
00145 for (unsigned int i=0; i < VIndexDimension; i++)
00146 { m_Index[i] += offset[i]; }
00147 return *this;
00148 }
00150
00152 const Self &
00153 operator-=(const OffsetType &offset)
00154 {
00155 for (unsigned int i=0; i < VIndexDimension; i++)
00156 { m_Index[i] -= offset[i]; }
00157 return *this;
00158 }
00160
00162 const Self
00163 operator-(const OffsetType &off) const
00164 {
00165 Self result;
00166 for (unsigned int i=0; i < VIndexDimension; i++)
00167 { result[i] = m_Index[i] - off.m_Offset[i]; }
00168 return result;
00169 }
00171
00173 const OffsetType
00174 operator-(const Self &vec) const
00175 {
00176 OffsetType result;
00177 for (unsigned int i=0; i < VIndexDimension; i++)
00178 { result[i] = m_Index[i] - vec.m_Index[i]; }
00179 return result;
00180 }
00182
00185 const Self
00186 operator*(const SizeType &vec) const
00187 {
00188 Self result;
00189 for (unsigned int i=0; i < VIndexDimension; i++)
00190 { result[i] = m_Index[i] * static_cast<IndexValueType>(vec.m_Size[i]); }
00191 return result;
00192 }
00194
00196 bool
00197 operator==(const Self &vec) const
00198 {
00199 bool same=true;
00200 for (unsigned int i=0; i < VIndexDimension && same; i++)
00201 { same = (m_Index[i] == vec.m_Index[i]); }
00202 return same;
00203 }
00205
00207 bool
00208 operator!=(const Self &vec) const
00209 {
00210 bool same=true;
00211 for (unsigned int i=0; i < VIndexDimension && same; i++)
00212 { same = (m_Index[i] == vec.m_Index[i]); }
00213 return !same;
00214 }
00216
00219 IndexValueType & operator[](unsigned int dim)
00220 { return m_Index[dim]; }
00221
00225 IndexValueType operator[](unsigned int dim) const
00226 { return m_Index[dim]; }
00227
00230 const IndexValueType *GetIndex() const { return m_Index; };
00231
00236 void SetIndex(const IndexValueType val[VIndexDimension])
00237 { memcpy(m_Index, val, sizeof(IndexValueType)*VIndexDimension); }
00238
00245 void SetElement(unsigned long element, IndexValueType val )
00246 { m_Index[ element ] = val; }
00247
00254 IndexValueType GetElement( unsigned long element ) const
00255 { return m_Index[ element ]; }
00256
00260 static Self GetBasisIndex(unsigned int dim);
00261
00264 void Fill(IndexValueType value)
00265 { for(unsigned int i=0;i < VIndexDimension; ++i) m_Index[i] = value; }
00266
00272 IndexValueType m_Index[VIndexDimension];
00273
00274
00275
00276 IndexValueType __getitem__(unsigned long dim) const
00277 {
00278 if (dim >= VIndexDimension)
00279 {throw ExceptionObject(__FILE__, __LINE__, "itk::ERROR: Index: index out of range");}
00280 return m_Index[ dim ];
00281 }
00282 void __setitem__(unsigned long dim, IndexValueType value)
00283 {
00284 if (dim >= VIndexDimension)
00285 {throw ExceptionObject(__FILE__, __LINE__, "itk::ERROR: Index: index out of range");}
00286 m_Index[ dim ] = value;
00287 }
00288
00289 const unsigned int __len__() const
00290 {
00291 return VIndexDimension;
00292 }
00293
00294 const char * __str__() const
00295 {
00296 OStringStream msg;
00297 msg << "<Index " << *this << ">";
00298 return msg.str().c_str();
00299 }
00300
00301 };
00302
00303 namespace Functor
00304 {
00312 template<unsigned int VIndexDimension>
00313 class IndexLexicographicCompare
00314 {
00315 public:
00316 bool operator()(Index<VIndexDimension> const& l,
00317 Index<VIndexDimension> const& r) const
00318 {
00319 for(unsigned int i=0; i < VIndexDimension; ++i)
00320 {
00321 if(l.m_Index[i] < r.m_Index[i])
00322 {
00323 return true;
00324 }
00325 else if(l.m_Index[i] > r.m_Index[i])
00326 {
00327 return false;
00328 }
00329 }
00330 return false;
00331 }
00332 };
00333 }
00334
00335 template<unsigned int VIndexDimension>
00336 Index<VIndexDimension>
00337 Index<VIndexDimension>
00338 ::GetBasisIndex(unsigned int dim)
00339 {
00340 Self ind;
00341
00342 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension);
00343 ind.m_Index[dim] = 1;
00344 return ind;
00345 }
00346
00347 template<unsigned int VIndexDimension>
00348 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind)
00349 {
00350 os << "[";
00351 for (unsigned int i=0; i+1 < VIndexDimension; ++i)
00352 {
00353 os << ind[i] << ", ";
00354 }
00355 if (VIndexDimension >= 1)
00356 {
00357 os << ind[VIndexDimension-1];
00358 }
00359 os << "]";
00360 return os;
00361 }
00362
00363 }
00364
00365 #endif
00366