Go to the documentation of this file.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 #include "itkMath.h"
00025
00026 #include <memory>
00027
00028 #include "itkExceptionObject.h"
00029
00030 namespace itk
00031 {
00032
00033 namespace Functor
00034 {
00035 template<unsigned int VIndexDimension> class IndexLexicographicCompare;
00036 }
00037
00067 template<unsigned int VIndexDimension=2>
00068 class Index {
00069 public:
00071 typedef Index Self;
00072
00074 typedef Index<VIndexDimension> IndexType;
00075 typedef long IndexValueType;
00076
00078 static unsigned int GetIndexDimension() { return VIndexDimension; }
00079
00081 typedef Size<VIndexDimension> SizeType;
00082
00084 typedef Offset<VIndexDimension> OffsetType;
00085 typedef typename OffsetType::OffsetValueType OffsetValueType;
00086
00088 typedef Functor::IndexLexicographicCompare<VIndexDimension> LexicographicCompare;
00089
00091 const Self
00092 operator+(const SizeType &size) const
00093 {
00094 Self result;
00095 for (unsigned int i=0; i < VIndexDimension; i++)
00096 { result[i] = m_Index[i] + static_cast<IndexValueType>(size[i]); }
00097 return result;
00098 }
00100
00102 const Self &
00103 operator+=(const SizeType &size)
00104 {
00105 for (unsigned int i=0; i < VIndexDimension; i++)
00106 { m_Index[i] += static_cast<IndexValueType>(size[i]); }
00107 return *this;
00108 }
00110
00112 const Self
00113 operator-(const SizeType &size) const
00114 {
00115 Self result;
00116 for (unsigned int i=0; i < VIndexDimension; i++)
00117 { result[i] = m_Index[i] - static_cast<IndexValueType>(size[i]); }
00118 return result;
00119 }
00121
00123 const Self &
00124 operator-=(const SizeType &size)
00125 {
00126 for (unsigned int i=0; i < VIndexDimension; i++)
00127 { m_Index[i] -= static_cast<IndexValueType>(size[i]); }
00128 return *this;
00129 }
00131
00133 const Self
00134 operator+(const OffsetType &offset) const
00135 {
00136 Self result;
00137 for (unsigned int i=0; i < VIndexDimension; i++)
00138 { result[i] = m_Index[i] + offset[i]; }
00139 return result;
00140 }
00142
00144 const Self &
00145 operator+=(const OffsetType &offset)
00146 {
00147 for (unsigned int i=0; i < VIndexDimension; i++)
00148 { m_Index[i] += offset[i]; }
00149 return *this;
00150 }
00152
00154 const Self &
00155 operator-=(const OffsetType &offset)
00156 {
00157 for (unsigned int i=0; i < VIndexDimension; i++)
00158 { m_Index[i] -= offset[i]; }
00159 return *this;
00160 }
00162
00164 const Self
00165 operator-(const OffsetType &off) const
00166 {
00167 Self result;
00168 for (unsigned int i=0; i < VIndexDimension; i++)
00169 { result[i] = m_Index[i] - off.m_Offset[i]; }
00170 return result;
00171 }
00173
00175 const OffsetType
00176 operator-(const Self &vec) const
00177 {
00178 OffsetType result;
00179 for (unsigned int i=0; i < VIndexDimension; i++)
00180 { result[i] = m_Index[i] - vec.m_Index[i]; }
00181 return result;
00182 }
00184
00187 const Self
00188 operator*(const SizeType &vec) const
00189 {
00190 Self result;
00191 for (unsigned int i=0; i < VIndexDimension; i++)
00192 { result[i] = m_Index[i] * static_cast<IndexValueType>(vec.m_Size[i]); }
00193 return result;
00194 }
00196
00198 bool
00199 operator==(const Self &vec) const
00200 {
00201 bool same=true;
00202 for (unsigned int i=0; i < VIndexDimension && same; i++)
00203 { same = (m_Index[i] == vec.m_Index[i]); }
00204 return same;
00205 }
00207
00209 bool
00210 operator!=(const Self &vec) const
00211 {
00212 bool same=true;
00213 for (unsigned int i=0; i < VIndexDimension && same; i++)
00214 { same = (m_Index[i] == vec.m_Index[i]); }
00215 return !same;
00216 }
00218
00221 IndexValueType & operator[](unsigned int dim)
00222 { return m_Index[dim]; }
00223
00227 IndexValueType operator[](unsigned int dim) const
00228 { return m_Index[dim]; }
00229
00232 const IndexValueType *GetIndex() const { return m_Index; };
00233
00238 void SetIndex(const IndexValueType val[VIndexDimension])
00239 { memcpy(m_Index, val, sizeof(IndexValueType)*VIndexDimension); }
00240
00247 void SetElement(unsigned long element, IndexValueType val )
00248 { m_Index[ element ] = val; }
00249
00256 IndexValueType GetElement( unsigned long element ) const
00257 { return m_Index[ element ]; }
00258
00262 static Self GetBasisIndex(unsigned int dim);
00263
00266 void Fill(IndexValueType value)
00267 { for(unsigned int i=0;i < VIndexDimension; ++i) m_Index[i] = value; }
00268
00274 IndexValueType m_Index[VIndexDimension];
00275
00277 template <class TCoordRep>
00278 inline void CopyWithRound( const FixedArray<TCoordRep,VIndexDimension> & point )
00279 {
00280 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00281 itkForLoopRoundingAndAssignmentMacro(IndexType,ContinuousIndexType,IndexValueType,m_Index,point,VIndexDimension);
00282 #else
00283 for(unsigned int i=0;i < VIndexDimension; ++i)
00284 {
00285 m_Index[i] = Math::Round<IndexValueType>( point[i] );
00286 }
00287 #endif
00288 }
00290
00292 template <class TCoordRep>
00293 inline void CopyWithCast( const FixedArray<TCoordRep,VIndexDimension> & point )
00294 {
00295 for(unsigned int i=0;i < VIndexDimension; ++i)
00296 {
00297 m_Index[i] = static_cast< IndexValueType>( point[i] );
00298 }
00299 }
00301
00302
00303 #if defined(CABLE_CONFIGURATION)
00304 Index();
00305 Index(const Self&);
00306 void operator=(const Self&);
00307 #endif
00308
00309 };
00310
00311 namespace Functor
00312 {
00320 template<unsigned int VIndexDimension>
00321 class IndexLexicographicCompare
00322 {
00323 public:
00324 bool operator()(Index<VIndexDimension> const& l,
00325 Index<VIndexDimension> const& r) const
00326 {
00327 for(unsigned int i=0; i < VIndexDimension; ++i)
00328 {
00329 if(l.m_Index[i] < r.m_Index[i])
00330 {
00331 return true;
00332 }
00333 else if(l.m_Index[i] > r.m_Index[i])
00334 {
00335 return false;
00336 }
00337 }
00338 return false;
00339 }
00340 };
00341 }
00342
00343 template<unsigned int VIndexDimension>
00344 Index<VIndexDimension>
00345 Index<VIndexDimension>
00346 ::GetBasisIndex(unsigned int dim)
00347 {
00348 Self ind;
00349
00350 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension);
00351 ind.m_Index[dim] = 1;
00352 return ind;
00353 }
00354
00355 template<unsigned int VIndexDimension>
00356 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind)
00357 {
00358 os << "[";
00359 for (unsigned int i=0; i+1 < VIndexDimension; ++i)
00360 {
00361 os << ind[i] << ", ";
00362 }
00363 if (VIndexDimension >= 1)
00364 {
00365 os << ind[VIndexDimension-1];
00366 }
00367 os << "]";
00368 return os;
00369 }
00370
00371 }
00372
00373 #endif
00374