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 #ifndef ITK_USE_PORTABLE_ROUND
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 #if (defined (VCL_VC) && !defined(__GCCXML__)) || (defined(_MSC_VER) && (_MSC_VER <= 1310))
00286 #define vnl_math_rnd_halfintup(x) ((x>=0.0)?(int)(x + 0.5):(int)(x - 0.5))
00287 #endif
00288 #endif
00289
00290 template <class TCoordRep>
00291 inline void CopyWithRound( const FixedArray<TCoordRep,VIndexDimension> & point )
00292 {
00293 #ifdef ITK_USE_TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING
00294 itkForLoopRoundingAndAssignmentMacro(IndexType,ContinuousIndexType,IndexValueType,m_Index,point,VIndexDimension);
00295 #else
00296 for(unsigned int i=0;i < VIndexDimension; ++i)
00297 {
00298 #ifdef ITK_USE_PORTABLE_ROUND
00299 m_Index[i] = static_cast< IndexValueType>( itk::Math::Round( point[i] ) );
00300 #else
00301 m_Index[i] = static_cast< IndexValueType>( vnl_math_rnd_halfintup( point[i] ) );
00302 #endif
00303 }
00304 #endif
00305 }
00306 #ifndef ITK_USE_PORTABLE_ROUND
00307 #if (defined (VCL_VC) && !defined(__GCCXML__)) || (defined(_MSC_VER) && (_MSC_VER <= 1310))
00308 #undef vnl_math_rnd_halfintup
00309 #endif
00310 #endif
00311
00312
00314 template <class TCoordRep>
00315 inline void CopyWithCast( const FixedArray<TCoordRep,VIndexDimension> & point )
00316 {
00317 for(unsigned int i=0;i < VIndexDimension; ++i)
00318 {
00319 m_Index[i] = static_cast< IndexValueType>( point[i] );
00320 }
00321 }
00323
00324
00325 #if defined(CABLE_CONFIGURATION)
00326 Index();
00327 Index(const Self&);
00328 void operator=(const Self&);
00329 #endif
00330
00331 };
00332
00333 namespace Functor
00334 {
00342 template<unsigned int VIndexDimension>
00343 class IndexLexicographicCompare
00344 {
00345 public:
00346 bool operator()(Index<VIndexDimension> const& l,
00347 Index<VIndexDimension> const& r) const
00348 {
00349 for(unsigned int i=0; i < VIndexDimension; ++i)
00350 {
00351 if(l.m_Index[i] < r.m_Index[i])
00352 {
00353 return true;
00354 }
00355 else if(l.m_Index[i] > r.m_Index[i])
00356 {
00357 return false;
00358 }
00359 }
00360 return false;
00361 }
00362 };
00363 }
00364
00365 template<unsigned int VIndexDimension>
00366 Index<VIndexDimension>
00367 Index<VIndexDimension>
00368 ::GetBasisIndex(unsigned int dim)
00369 {
00370 Self ind;
00371
00372 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension);
00373 ind.m_Index[dim] = 1;
00374 return ind;
00375 }
00376
00377 template<unsigned int VIndexDimension>
00378 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind)
00379 {
00380 os << "[";
00381 for (unsigned int i=0; i+1 < VIndexDimension; ++i)
00382 {
00383 os << ind[i] << ", ";
00384 }
00385 if (VIndexDimension >= 1)
00386 {
00387 os << ind[VIndexDimension-1];
00388 }
00389 os << "]";
00390 return os;
00391 }
00392
00393 }
00394
00395 #endif
00396