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 }
00097
00099 const Self &
00100 operator+=(const SizeType &size)
00101 {
00102 for (unsigned int i=0; i < VIndexDimension; i++)
00103 { m_Index[i] += static_cast<IndexValueType>(size[i]); }
00104 return *this;
00105 }
00106
00108 const Self
00109 operator-(const SizeType &size) const
00110 {
00111 Self result;
00112 for (unsigned int i=0; i < VIndexDimension; i++)
00113 { result[i] = m_Index[i] - static_cast<IndexValueType>(size[i]); }
00114 return result;
00115 }
00116
00118 const Self &
00119 operator-=(const SizeType &size)
00120 {
00121 for (unsigned int i=0; i < VIndexDimension; i++)
00122 { m_Index[i] -= static_cast<IndexValueType>(size[i]); }
00123 return *this;
00124 }
00125
00127 const Self
00128 operator+(const OffsetType &offset) const
00129 {
00130 Self result;
00131 for (unsigned int i=0; i < VIndexDimension; i++)
00132 { result[i] = m_Index[i] + offset[i]; }
00133 return result;
00134 }
00135
00137 const Self &
00138 operator+=(const OffsetType &offset)
00139 {
00140 for (unsigned int i=0; i < VIndexDimension; i++)
00141 { m_Index[i] += offset[i]; }
00142 return *this;
00143 }
00144
00146 const Self &
00147 operator-=(const OffsetType &offset)
00148 {
00149 for (unsigned int i=0; i < VIndexDimension; i++)
00150 { m_Index[i] -= offset[i]; }
00151 return *this;
00152 }
00153
00155 const Self
00156 operator-(const OffsetType &off) const
00157 {
00158 Self result;
00159 for (unsigned int i=0; i < VIndexDimension; i++)
00160 { result[i] = m_Index[i] - off.m_Offset[i]; }
00161 return result;
00162 }
00163
00165 const OffsetType
00166 operator-(const Self &vec) const
00167 {
00168 OffsetType result;
00169 for (unsigned int i=0; i < VIndexDimension; i++)
00170 { result[i] = m_Index[i] - vec.m_Index[i]; }
00171 return result;
00172 }
00173
00176 const Self
00177 operator*(const SizeType &vec) const
00178 {
00179 Self result;
00180 for (unsigned int i=0; i < VIndexDimension; i++)
00181 { result[i] = m_Index[i] * static_cast<IndexValueType>(vec.m_Size[i]); }
00182 return result;
00183 }
00184
00186 bool
00187 operator==(const Self &vec) const
00188 {
00189 bool same=true;
00190 for (unsigned int i=0; i < VIndexDimension && same; i++)
00191 { same = (m_Index[i] == vec.m_Index[i]); }
00192 return same;
00193 }
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 }
00204
00207 IndexValueType & operator[](unsigned int dim)
00208 { return m_Index[dim]; }
00209
00213 IndexValueType operator[](unsigned int dim) const
00214 { return m_Index[dim]; }
00215
00218 const IndexValueType *GetIndex() const { return m_Index; };
00219
00224 void SetIndex(const IndexValueType val[VIndexDimension])
00225 { memcpy(m_Index, val, sizeof(IndexValueType)*VIndexDimension); }
00226
00233 void SetElement(unsigned long element, IndexValueType val )
00234 { m_Index[ element ] = val; }
00235
00242 IndexValueType GetElement( unsigned long element )
00243 { return m_Index[ element ]; }
00244
00248 static Self GetBasisIndex(unsigned int dim);
00249
00252 void Fill(IndexValueType value)
00253 { for(unsigned int i=0;i < VIndexDimension; ++i) m_Index[i] = value; }
00254
00260 IndexValueType m_Index[VIndexDimension];
00261
00262 };
00263
00264 namespace Functor
00265 {
00273 template<unsigned int VIndexDimension>
00274 class IndexLexicographicCompare
00275 {
00276 public:
00277 bool operator()(Index<VIndexDimension> const& l,
00278 Index<VIndexDimension> const& r) const
00279 {
00280 for(unsigned int i=0; i < VIndexDimension; ++i)
00281 {
00282 if(l.m_Index[i] < r.m_Index[i])
00283 {
00284 return true;
00285 }
00286 else if(l.m_Index[i] > r.m_Index[i])
00287 {
00288 return false;
00289 }
00290 }
00291 return false;
00292 }
00293 };
00294 }
00295
00296 template<unsigned int VIndexDimension>
00297 Index<VIndexDimension>
00298 Index<VIndexDimension>
00299 ::GetBasisIndex(unsigned int dim)
00300 {
00301 Self ind;
00302
00303 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension);
00304 ind.m_Index[dim] = 1;
00305 return ind;
00306 }
00307
00308 template<unsigned int VIndexDimension>
00309 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind)
00310 {
00311 os << "[";
00312 for (unsigned int i=0; i+1 < VIndexDimension; ++i)
00313 {
00314 os << ind[i] << ", ";
00315 }
00316 if (VIndexDimension >= 1)
00317 {
00318 os << ind[VIndexDimension-1];
00319 }
00320 os << "]";
00321 return os;
00322 }
00323
00324 #ifdef ITK_EXPLICIT_INSTANTIATION
00325 extern template class Index<1>;
00326 extern template class Index<2>;
00327 extern template class Index<3>;
00328 extern template class Index<4>;
00329 extern template class Index<5>;
00330 extern template std::ostream & operator<<(std::ostream &os, const Index<1> &ind);
00331 extern template std::ostream & operator<<(std::ostream &os, const Index<2> &ind);
00332 extern template std::ostream & operator<<(std::ostream &os, const Index<3> &ind);
00333 extern template std::ostream & operator<<(std::ostream &os, const Index<4> &ind);
00334 extern template std::ostream & operator<<(std::ostream &os, const Index<5> &ind);
00335 #endif
00336
00337
00338 }
00339
00340 #endif