/vol/vipdata/irtk/packages/transformation/include/irtkEigenFreeFormTransformation.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkEigenFreeFormTransformation.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKEIGENFREEFORMTRANSFORMATION_H
00014 
00015 #define _IRTKEIGENFREEFORMTRANSFORMATION_H
00016 
00017 #include <irtkGeometry.h>
00018 
00019 #undef NORMAL
00020 
00029 class irtkEigenFreeFormTransformation : public irtkBSplineFreeFormTransformation3D
00030 {
00031 
00032 protected:
00033 
00035   irtkVector *_EigenValues;
00036 
00038   irtkMatrix *_EigenVectors;
00039 
00041   irtkVector *_ShapeVector;
00042 
00044   int *_label;
00045 
00046 public:
00047 
00048   //
00049   // Constructors and destructor
00050   //
00051 
00053   irtkEigenFreeFormTransformation();
00054 
00056   irtkEigenFreeFormTransformation(const irtkBSplineFreeFormTransformation3D &,
00057                                   const irtkVector&,
00058                                   const irtkMatrix&,
00059                                   const irtkVector&);
00060 
00062   irtkEigenFreeFormTransformation(const irtkEigenFreeFormTransformation &);
00063 
00065   virtual ~irtkEigenFreeFormTransformation();
00066 
00067   // Access parameters
00068   virtual SetMacro(EigenValues,  irtkVector *);
00069   virtual GetMacro(EigenValues,  irtkVector *);
00070   virtual SetMacro(EigenVectors, irtkMatrix *);
00071   virtual GetMacro(EigenVectors, irtkMatrix *);
00072   virtual SetMacro(ShapeVector,  irtkVector *);
00073   virtual GetMacro(ShapeVector,  irtkVector *);
00074 
00075   //
00076   // Methods to manipulate the status/labels of the control points
00077   //
00078 
00080   virtual _Status GetStatus(int) const;
00081 
00083   virtual int GetLabel(int);
00084 
00086   void PutLabel(int, int);
00087 
00088   //
00089   // Methods for element access
00090   //
00091 
00093   virtual int  NumberOfElements() const;
00094 
00096   virtual void GetElement(int, int*);
00097 
00099   virtual int *GetElement(int);
00100 
00101   //
00102   // Inherited methods from irtkTransformation to be implemented
00103   //
00104 
00106   virtual int    NumberOfDOFs() const;
00107 
00109   virtual double Get(int) const;
00110 
00112   virtual void   Put(int, double);
00113 
00115   void Info();
00116 
00118   virtual void   Print();
00119 
00121   static int     CheckHeader(char *);
00122 
00124   static int     CheckKeyword(char *);
00125 
00127   virtual const char  *NameOfClass();
00128 
00130   virtual irtkCifstream& Import(irtkCifstream&);
00131 
00133   virtual irtkCofstream& Export(irtkCofstream&);
00134 
00136   virtual istream& Import(istream&);
00137 
00139   virtual ostream& Export(ostream&);
00140 };
00141 
00142 //
00143 // Instantiated inline methods
00144 //
00145 
00146 inline int irtkEigenFreeFormTransformation::NumberOfElements() const
00147 {
00148   if (_z > 1) {
00149     return (_x - 1) * (_y - 1) * (_z - 1);
00150   } else {
00151     return (_x - 1) * (_y - 1);
00152   }
00153 }
00154 
00155 inline void irtkEigenFreeFormTransformation::GetElement(int index, int *element)
00156 {
00157   int i, j, k;
00158 
00159   if ((index < 0) || (index >= this->NumberOfElements())) {
00160     cerr << "irtkEigenFreeFormTransformation::GetElement() : index out of range\n";
00161     exit(0);
00162   }
00163   if (element == NULL) {
00164     cerr << "irtkEigenFreeFormTransformation::GetElement() : invalid field passsed\n";
00165     exit(0);
00166   }
00167 
00168   // Find top left node of element (=N1)
00169   // See vtkStructuredGrid::GetCell()
00170   if (_z > 1) {
00171     // 3D (case VTK_XYZ_GRID) - still needs checking!
00172     i =  index % ( _x - 1);
00173     j = (index / ( _x - 1)) % (_y - 1);
00174     k =  index / ((_x - 1)  * (_y - 1));
00175   } else {
00176     // 2D (case VTK_XY_PLANE)
00177     i = index % ( _x - 1);
00178     j = index / ( _x - 1);
00179     k = 0;
00180   }
00181 
00182   // In-plane element node indices
00183   element[0] = this->LatticeToIndex(i+1, j,   k);
00184   element[1] = this->LatticeToIndex(i,   j,   k);
00185   element[2] = this->LatticeToIndex(i,   j+1, k);
00186   element[3] = this->LatticeToIndex(i+1, j+1, k);
00187 
00188   // Through-plane element node indices, if applicable
00189   if (_z > 1) {
00190     element[4] = this->LatticeToIndex(i+1, j,   k+1);
00191     element[5] = this->LatticeToIndex(i,   j,   k+1);
00192     element[6] = this->LatticeToIndex(i,   j+1, k+1);
00193     element[7] = this->LatticeToIndex(i+1, j+1, k+1);
00194   }
00195 
00196   return;
00197 }
00198 
00199 inline int *irtkEigenFreeFormTransformation::GetElement(int index)
00200 {
00201   int *element = NULL;
00202 
00203   // Allocate 2D or 3D element
00204   if (_z > 1) {
00205     element = new int[8];
00206   } else {
00207     element = new int[4];
00208   }
00209 
00210   // Overloaded call
00211   this->GetElement(index, element);
00212 
00213   // Return element
00214   return element;
00215 }
00216 
00217 inline _Status irtkEigenFreeFormTransformation::GetStatus(int index) const
00218 {
00219   return _Active;
00220 }
00221 
00222 inline int irtkEigenFreeFormTransformation::GetLabel(int index)
00223 {
00224   // Bound checking
00225   if ((index < 0) || (index >= this->NumberOfElements())) {
00226     cerr << "irtkEigenFreeFormTransformation::GetLabel(): index out of range\n";
00227     exit(1);
00228   }
00229 
00230   // One label per element
00231   return _label[index];
00232 }
00233 
00234 inline void irtkEigenFreeFormTransformation::PutLabel(int index, int label)
00235 {
00236   // Bound checking
00237   if ((index < 0) || (index >= this->NumberOfElements())) {
00238     cerr << "irtkEigenFreeFormTransformation::PutLabel(): index out of range\n";
00239     exit(1);
00240   }
00241 
00242   // One label per element
00243   _label[index] = label;
00244 }
00245 
00246 inline int irtkEigenFreeFormTransformation::NumberOfDOFs() const
00247 {
00248   return _ShapeVector->Rows();
00249 }
00250 
00251 inline double irtkEigenFreeFormTransformation::Get(int index) const
00252 {
00253   if (index >= this->NumberOfDOFs()) {
00254     cerr << "irtkEigenFreeFormTransformation::Get: No such dof" << endl;
00255     exit(1);
00256   }
00257   return _ShapeVector->Get(index);
00258 }
00259 
00260 inline int irtkEigenFreeFormTransformation::CheckKeyword(char *header)
00261 {
00262   if (strcmp(header, "EFFD:") == 0) {
00263     return True;
00264   } else {
00265     return False;
00266   }
00267 }
00268 
00269 inline const char *irtkEigenFreeFormTransformation::NameOfClass()
00270 {
00271   return "irtkEigenFreeFormTransformation";
00272 }
00273 
00274 #endif