ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkIndex_h 00019 #define __itkIndex_h 00020 00021 #include "itkOffset.h" 00022 #include "itkFixedArray.h" 00023 #include "itkMath.h" 00024 00025 #include <memory> 00026 00027 00028 namespace itk 00029 { 00030 namespace Functor 00031 { 00032 template< unsigned int VIndexDimension > 00033 class IndexLexicographicCompare; 00034 } 00035 00071 template< unsigned int VIndexDimension = 2 > 00072 class Index 00073 { 00074 public: 00076 typedef Index Self; 00077 00079 typedef Index< VIndexDimension > IndexType; 00080 typedef ::itk::IndexValueType IndexValueType; 00081 00083 itkStaticConstMacro(Dimension, unsigned int, VIndexDimension); 00084 00086 static unsigned int GetIndexDimension() { return VIndexDimension; } 00087 00089 typedef Size< VIndexDimension > SizeType; 00090 00092 typedef Offset< VIndexDimension > OffsetType; 00093 typedef ::itk::OffsetValueType OffsetValueType; 00094 00096 typedef Functor::IndexLexicographicCompare< VIndexDimension > LexicographicCompare; 00097 00099 const Self 00100 operator+(const SizeType & size) const 00101 { 00102 Self result; 00103 00104 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00105 { result[i] = m_Index[i] + static_cast< IndexValueType >( size[i] ); } 00106 return result; 00107 } 00108 00110 const Self & 00111 operator+=(const SizeType & size) 00112 { 00113 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00114 { m_Index[i] += static_cast< IndexValueType >( size[i] ); } 00115 return *this; 00116 } 00118 00121 const Self 00122 operator-(const SizeType & size) const 00123 { 00124 Self result; 00125 00126 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00127 { result[i] = m_Index[i] - static_cast< IndexValueType >( size[i] ); } 00128 return result; 00129 } 00130 00132 const Self & 00133 operator-=(const SizeType & size) 00134 { 00135 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00136 { m_Index[i] -= static_cast< IndexValueType >( size[i] ); } 00137 return *this; 00138 } 00140 00142 const Self 00143 operator+(const OffsetType & offset) const 00144 { 00145 Self result; 00146 00147 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00148 { result[i] = m_Index[i] + offset[i]; } 00149 return result; 00150 } 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 & offset) 00165 { 00166 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00167 { m_Index[i] -= offset[i]; } 00168 return *this; 00169 } 00171 00173 const Self 00174 operator-(const OffsetType & off) const 00175 { 00176 Self result; 00177 00178 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00179 { result[i] = m_Index[i] - off.m_Offset[i]; } 00180 return result; 00181 } 00182 00184 const OffsetType 00185 operator-(const Self & vec) const 00186 { 00187 OffsetType result; 00188 00189 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00190 { result[i] = m_Index[i] - vec.m_Index[i]; } 00191 return result; 00192 } 00193 00196 const Self 00197 operator*(const SizeType & vec) const 00198 { 00199 Self result; 00200 00201 for ( unsigned int i = 0; i < VIndexDimension; i++ ) 00202 { result[i] = m_Index[i] * static_cast< IndexValueType >( vec.m_Size[i] ); } 00203 return result; 00204 } 00205 00207 bool 00208 operator==(const Self & vec) const 00209 { 00210 bool same = true; 00211 00212 for ( unsigned int i = 0; i < VIndexDimension && same; i++ ) 00213 { same = ( m_Index[i] == vec.m_Index[i] ); } 00214 return same; 00215 } 00216 00218 bool 00219 operator!=(const Self & vec) const 00220 { 00221 bool same = true; 00222 00223 for ( unsigned int i = 0; i < VIndexDimension && same; i++ ) 00224 { same = ( m_Index[i] == vec.m_Index[i] ); } 00225 return !same; 00226 } 00227 00230 IndexValueType & operator[](unsigned int dim) 00231 { return m_Index[dim]; } 00232 00236 IndexValueType operator[](unsigned int dim) const 00237 { return m_Index[dim]; } 00238 00241 const IndexValueType * GetIndex() const { return m_Index; } 00242 00247 void SetIndex(const IndexValueType val[VIndexDimension]) 00248 { memcpy(m_Index, val, sizeof( IndexValueType ) * VIndexDimension); } 00249 00256 void SetElement(unsigned long element, IndexValueType val) 00257 { m_Index[element] = val; } 00258 00265 IndexValueType GetElement(unsigned long element) const 00266 { return m_Index[element]; } 00267 00271 static Self GetBasisIndex(unsigned int dim); 00272 00275 void Fill(IndexValueType value) 00276 { for ( unsigned int i = 0; i < VIndexDimension; ++i ) { m_Index[i] = value; } } 00277 00283 IndexValueType m_Index[VIndexDimension]; 00284 00286 template< class TCoordRep > 00287 inline void CopyWithRound(const FixedArray< TCoordRep, VIndexDimension > & point) 00288 { 00289 itkForLoopRoundingAndAssignmentMacro(IndexType, 00290 ContinuousIndexType, 00291 IndexValueType, 00292 m_Index, 00293 point, 00294 VIndexDimension); 00295 /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version 00296 * Leaving here for documentation purposes 00297 * for ( unsigned int i = 0; i < VIndexDimension; ++i ) 00298 * { 00299 * m_Index[i] = Math::Round< IndexValueType >(point[i]); 00300 * } 00301 */ 00302 } 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 // force gccxml to find the constructors found before the internal upgrade to 00317 // gcc 4.2 00318 #if defined( CABLE_CONFIGURATION ) 00319 Index(); //purposely not implemented 00320 Index(const Self &); //purposely not implemented 00321 void operator=(const Self &); //purposely not implemented 00322 00323 #endif 00324 }; 00325 00326 namespace Functor 00327 { 00336 template< unsigned int VIndexDimension > 00337 class IndexLexicographicCompare 00338 { 00339 public: 00340 bool operator()(Index< VIndexDimension > const & l, 00341 Index< VIndexDimension > const & r) const 00342 { 00343 for ( unsigned int i = 0; i < VIndexDimension; ++i ) 00344 { 00345 if ( l.m_Index[i] < r.m_Index[i] ) 00346 { 00347 return true; 00348 } 00349 else if ( l.m_Index[i] > r.m_Index[i] ) 00350 { 00351 return false; 00352 } 00353 } 00354 return false; 00355 } 00356 }; 00357 } 00358 00359 template< unsigned int VIndexDimension > 00360 Index< VIndexDimension > 00361 Index< VIndexDimension > 00362 ::GetBasisIndex(unsigned int dim) 00363 { 00364 Self ind; 00365 00366 memset(ind.m_Index, 0, sizeof( IndexValueType ) * VIndexDimension); 00367 ind.m_Index[dim] = 1; 00368 return ind; 00369 } 00370 00371 template< unsigned int VIndexDimension > 00372 std::ostream & operator<<(std::ostream & os, const Index< VIndexDimension > & ind) 00373 { 00374 os << "["; 00375 for ( unsigned int i = 0; i + 1 < VIndexDimension; ++i ) 00376 { 00377 os << ind[i] << ", "; 00378 } 00379 if ( VIndexDimension >= 1 ) 00380 { 00381 os << ind[VIndexDimension - 1]; 00382 } 00383 os << "]"; 00384 return os; 00385 } 00386 } // end namespace itk 00387 00388 #endif 00389