SourceTransformWarp.h

Go to the documentation of this file.
00001 // $Id$
00002 
00003 #ifndef __SOURCETRANSFORMWARP_H__
00004 #define __SOURCETRANSFORMWARP_H__
00005 
00006 #include "SourceGenerics.h"
00007 #include "SourceMemory.h"
00008 #include "SourceTransform.h"
00009 #include "SourceTransformScale.h"
00010 #include "SourceAccessorNearestNeighbor.h"
00011 #include "SourceAccessorLinearInterpolate.h"
00012 #include "SourceAccessorCubicInterpolate.h"
00013 #include <math.h>
00014 #include "libInterpolatedSource.h"
00015 
00016 #undef DEBUG
00017 #define DEBUG 0
00018 #include "libDebug.h"
00019 
00020 //============================================================================
00021 //============================================================================
00022 template<int DIMENSIONALITY>
00023 class WarpControlPointsBaseOf: public SourceMemoryOf<PointOf<DIMENSIONALITY,
00024     Real> , DIMENSIONALITY>
00025 {
00026 public:
00027 };
00028 
00029 //============================================================================
00030 //============================================================================
00031 template<int DIMENSIONALITY>
00032 class WarpControlPointsOf: public WarpControlPointsBaseOf<DIMENSIONALITY>
00033 {
00034 };
00035 
00036 //============================================================================
00037 //============================================================================
00038 template<>
00039 class WarpControlPointsOf<2> : public WarpControlPointsBaseOf<2>
00040 {
00041   typedef Point2DReal DATA;
00042   typedef int PRECISION;
00043 
00044 public:
00045 SOURCE_ACTUALS_2D  ;
00046 
00047   virtual String Describe() const
00048     {
00049     String s;
00050     Real cX=this->m_ptSize.X();
00051     Real cY=this->m_ptSize.Y();
00052     if (cX * cY < 32)
00053       {
00054       for (int nY=0; nY<cY; nY++)
00055         {
00056         s=s+_LINE;
00057         for (int nX=0; nX<cX; nX++)
00058           {
00059           Point2DReal pt;
00060           this->Get(pt,nX,nY);
00061           s=s+ pt.X() + "," + pt.Y() + INDENT;
00062           }
00063         s=s+LINE_;
00064         }
00065       }
00066 
00067     return (
00068         _LINE + "WarpControlPoints" + LINE_ +
00069         this->DescribeCommon() +
00070         (_INDENT + s)
00071     );
00072     }
00073 
00074   void Get(Point2DReal& dataOut, Real rX, Real rY) const
00075     {
00076     Real cX=this->m_ptSize.X();
00077     Real cY=this->m_ptSize.Y();
00078 
00079     if ( (rX<0) || (rY<0) || (rX>=cX) || (rY>=cY))
00080       {
00081       dataOut=Point2DReal(0.);
00082       return;
00083       }
00084 
00085     SourceMemoryOf<Point2DReal,2>::Get(dataOut,rX,rY);
00086     }
00087 
00088   void Set(Real rX, Real rY, const Point2DReal& data)
00089     {
00090     Real cX=this->m_ptSize.X();
00091     Real cY=this->m_ptSize.Y();
00092 
00093     if ( (rX<0) || (rY<0) || (rX>=cX) || (rY>=cY))
00094       {
00095       return;
00096       }
00097 
00098     return SourceMemoryOf<Point2DReal,2>::Set(rX,rY,data);
00099     }
00100   };
00101 
00102 //============================================================================
00103 //============================================================================
00104 template<>
00105 class WarpControlPointsOf<3> : public WarpControlPointsBaseOf<3>
00106 {
00107   typedef Point3DReal DATA;
00108   typedef int PRECISION;
00109 
00110 public:
00111 SOURCE_ACTUALS_3D  ;
00112 
00113   virtual String Describe() const
00114     {
00115     String s;
00116     Real cX=this->m_ptSize.X();
00117     Real cY=this->m_ptSize.Y();
00118     Real cZ=this->m_ptSize.Z();
00119 
00120     if (cX * cY *cZ < 128)
00121       {
00122       for (int nZ=0; nZ<cZ; nZ++)
00123         {
00124         s=s+_LINE;
00125         for (int nY=0; nY<cY; nY++)
00126           {
00127           s=s+_LINE;
00128           for (int nX=0; nX<cX; nX++)
00129             {
00130             Point3DReal pt;
00131             this->Get(pt,nX,nY,nZ);
00132             s=s+ pt.X() + "," + pt.Y() + "," + pt.Z() + INDENT;
00133             }
00134           s=s+LINE_;
00135           }
00136         if (nZ!=cZ-1)
00137           {
00138           s=s+LINE_;
00139           }
00140         }
00141       }
00142 
00143     return (
00144         _LINE + "WarpControlPoints(3D)" + LINE_ +
00145         this->DescribeCommon() +
00146         (_INDENT2 + s)
00147     );
00148     }
00149 
00150   void Get(Point3DReal& dataOut, int rX, int rY, int rZ) const
00151     {
00152     int cX=this->m_ptSize.X();
00153     int cY=this->m_ptSize.Y();
00154     int cZ=this->m_ptSize.Z();
00155 
00156     if ( (rX<0) || (rY<0) || (rX>=cX) || (rY>=cY) || (rZ<0) || (rZ>=cZ))
00157       {
00158       dataOut=Point3DReal(0.);
00159       return;
00160       }
00161 
00162     SourceMemoryOf<Point3DReal,3>::Get(dataOut,rX,rY,rZ);
00163     }
00164 
00165   void Set(int rX, int rY, int rZ, const Point3DReal& data)
00166     {
00167     int cX=this->m_ptSize.X();
00168     int cY=this->m_ptSize.Y();
00169     int cZ=this->m_ptSize.Z();
00170 
00171     if ( (rX<0) || (rY<0) || (rX>=cX) || (rY>=cY) || (rZ<0) || (rZ>=cZ))
00172       {
00173       return;
00174       }
00175 
00176     return SourceMemoryOf<Point3DReal,3>::Set(rX,rY,rZ,data);
00177     }
00178 
00179   };
00180 
00181 //============================================================================
00182 //============================================================================
00183 typedef WarpControlPointsOf<2> WarpControlPoints2D;
00184 typedef WarpControlPointsOf<3> WarpControlPoints3D;
00185 
00186 typedef SourceAccessorCubicInterpolateOf<Point2DReal, 2, int,
00187     WarpControlPoints2D> WarpfieldCubicSpline2D;
00188 typedef SourceAccessorCubicInterpolateOf<Point2DReal, 3, int,
00189     WarpControlPoints3D> WarpfieldCubicSpline3D;
00190 
00191 typedef SourceAccessorCubicInterpolateOf<Point2DReal, 2, Real,
00192     WarpControlPoints2D> WarpfieldCubicSpline2DReal;
00193 typedef SourceAccessorCubicInterpolateOf<Point2DReal, 3, Real,
00194     WarpControlPoints3D> WarpfieldCubicSpline3DReal;
00195 
00196 //============================================================================
00197 //============================================================================
00198 template<class DATA, int DIMENSIONALITY, class PRECISION, class SOURCE>
00199 class SourceTransformWarpBaseOf: public SourceTransformOf<DATA, DIMENSIONALITY,
00200     PRECISION, SOURCE>
00201 {
00202 protected:
00203   typedef PointOf<DIMENSIONALITY, Real> WARPPOINT;
00204   typedef WarpControlPointsOf<DIMENSIONALITY> WARPCONTROLPOINTS;
00205   typedef SourceAccessorCubicInterpolateOf<WARPPOINT, DIMENSIONALITY, Real,
00206       WARPCONTROLPOINTS> WARPINTERPOLATEDCONTROLPOINTS;
00207   typedef SourceTransformScaleOf<WARPPOINT, DIMENSIONALITY, PRECISION,
00208       WARPINTERPOLATEDCONTROLPOINTS> WARPFIELD;
00209 
00210   mutable WARPFIELD* m_pwarpfield;
00211 
00212 public:
00213   typedef PointOf<DIMENSIONALITY, Real> WarpPoint;
00214   typedef WarpControlPointsOf<DIMENSIONALITY> WarpControlPoints;
00215   typedef SourceAccessorCubicInterpolateOf<WARPPOINT, DIMENSIONALITY, Real,
00216       WARPCONTROLPOINTS> WarpInterpolatedControlPoints;
00217   typedef SourceTransformScaleOf<WARPPOINT, DIMENSIONALITY, PRECISION,
00218       WARPINTERPOLATEDCONTROLPOINTS> Warpfield;
00219 
00220   SourceTransformWarpBaseOf() :
00221     SourceTransformOf<DATA, DIMENSIONALITY, PRECISION, SOURCE> (),
00222         m_pwarpfield(NULL)
00223   {
00224   }
00225 
00226   virtual ~SourceTransformWarpBaseOf()
00227   {
00228     if (Counted::AboutToDie())
00229       {
00230       ReleasePointer(m_pwarpfield);
00231       }
00232   }
00233 
00234   void AllocateWarpfield(PointOf<DIMENSIONALITY, int> ptSizeWarp, InterpolationType it =
00235       Cubic)
00236   {
00237     ReleasePointer(m_pwarpfield);
00238 
00239     WarpControlPointsOf<DIMENSIONALITY> *pcp = new WarpControlPointsOf<
00240         DIMENSIONALITY> ;
00241     pcp->Allocate(ptSizeWarp);
00242     pcp->Fill(PointOf<DIMENSIONALITY, Real> (0.));
00243 
00244     HandoffPointer(pcp);
00245     m_pwarpfield = new WARPFIELD;
00246     //      m_pwarpfield->SetSource(NewInterpolatedSource(pcp,it));
00247     m_pwarpfield->SetSource(CubicInterpolation(pcp));
00248   }
00249 
00250   void SetWarpfieldInterpolation(InterpolationType it = Cubic)
00251   {
00252     WARPCONTROLPOINTS* pcp = GetPWarpControlPoints();
00253     ClaimPointer(pcp);
00254     ReleasePointer(m_pwarpfield);
00255 
00256     HandoffPointer(pcp);
00257     m_pwarpfield = new WARPFIELD;
00258     //      m_pwarpfield->SetSource(NewInterpolatedSource(pcp,it));
00259     m_pwarpfield->SetSource(CubicInterpolation(pcp));
00260   }
00261 
00262   void SetWarpControlPoints(WARPCONTROLPOINTS* pwarpcontrolpoints)
00263   {
00264     m_pwarpfield->PSource()->SetSource(pwarpcontrolpoints);
00265   }
00266 
00267   WARPCONTROLPOINTS* GetPWarpControlPoints() const
00268   {
00269     return m_pwarpfield->PSource()->PSource();
00270   }
00271 
00272   WARPINTERPOLATEDCONTROLPOINTS* GetPInterpolatedWarpControlPoints() const
00273   {
00274     return m_pwarpfield->PSource();
00275   }
00276 
00277   virtual String Describe() const
00278   {
00279     return (_LINE + "SourceTransformWarp" + LINE_ + (_INDENT + "with field: "
00280         + LINE_) + (_INDENT2 + m_pwarpfield->Describe())
00281         + this->DescribeCommon());
00282   }
00283 
00284   virtual void RegisterParameters(RegistryOfParameters& reg)
00285   {
00286     m_pwarpfield->RegisterDataAsParameters(reg);
00287   }
00288 
00289   void PrepareForAccessAction() const
00290   {
00291     ASSERTf(m_pwarpfield, "Null warpfield");
00292     // prepare the warp for access to allow all of the warp's
00293     // sources to compute their final sizes
00294     m_pwarpfield->PrepareForAccess();
00295 
00296     // then adjust the scaling of the warp
00297     m_pwarpfield->SetScale(PointOf<DIMENSIONALITY, Real> (
00298         this->PSource()->Size()) / m_pwarpfield->PSource()->Size());
00299 
00300     // and allow it to readjust
00301     m_pwarpfield->PrepareForAccess();
00302 
00303     // and finally set our own size;
00304     this->m_ptSize = this->PSource()->Size();
00305   }
00306 
00307   static String SerializationId()
00308   {
00309     return String("SourceTransformWarp(") + DIMENSIONALITY + "D)";
00310   }
00311 
00312   void SerializeSelf(Stream& st) const
00313   {
00314     ::SerializePointer(st, m_pwarpfield->PSource());
00315   }
00316 
00317   void DeserializeSelf(Stream& st)
00318   {
00319     ::DeserializePointer(st, m_pwarpfield->PSource());
00320   }
00321 };
00322 
00323 //============================================================================
00324 //============================================================================
00325 template<class DATA, int DIMENSIONALITY, class PRECISION, class SOURCE>
00326 class SourceTransformWarpOf: public SourceTransformWarpBaseOf<DATA,
00327     DIMENSIONALITY, PRECISION, SOURCE>
00328 {
00329 };
00330 
00331 //============================================================================
00332 //============================================================================
00333 template<class DATA, class PRECISION, class SOURCE>
00334 class SourceTransformWarpOf<DATA, 2, PRECISION, SOURCE> : public SourceTransformWarpBaseOf<
00335     DATA, 2, PRECISION, SOURCE>
00336 {
00337 public:
00338 SOURCE_ACTUALS_2D  ;
00339 
00340 private:
00341   typedef PointOf<DIMENSIONALITY, Real> WARPPOINT;
00342   typedef SourceOf<WARPPOINT, DIMENSIONALITY, PRECISION> WARPCONTROLPOINTS;
00343   typedef SourceTransformScaleOf<WARPPOINT, DIMENSIONALITY, PRECISION, WARPCONTROLPOINTS> WARPFIELD;
00344 
00345 public:
00346   void Get(DATA& dataOut, const PRECISION& rX, const PRECISION& rY) const
00347     {
00348     if (this->m_pwarpfield->Size().X() < 4)
00349       {
00350       return ::Get(
00351           *(this->m_psource),
00352           dataOut,
00353           rX,
00354           rY
00355       );
00356       }
00357 
00358     WARPPOINT dpt;
00359     this->m_pwarpfield->Get(dpt,rX,rY);
00360 
00361     ::Get(
00362         *(this->m_psource),
00363         dataOut,
00364         (rX - dpt.X()*this->Size().X()),
00365         (rY - dpt.Y()*this->Size().Y())
00366     );
00367     }
00368 
00369   void Set(const PRECISION& rX, const PRECISION& rY, const DATA& data)
00370     {
00371     WARPPOINT dpt;
00372     this->m_pwarpfield->Get(dpt,rX,rY);
00373 
00374     ::Set(
00375         *(this->m_psource),
00376         (rX - dpt.X()*this->Size().X()),
00377         (rY - dpt.Y()*this->Size().Y()),
00378         data
00379     );
00380     }
00381   };
00382 
00383 //============================================================================
00384 //============================================================================
00385 template<class DATA, class PRECISION, class SOURCE>
00386 class SourceTransformWarpOf<DATA, 3, PRECISION, SOURCE> : public SourceTransformWarpBaseOf<
00387     DATA, 3, PRECISION, SOURCE>
00388 {
00389 public:
00390 SOURCE_ACTUALS_3D  ;
00391 
00392 private:
00393   typedef PointOf<DIMENSIONALITY, Real> WARPPOINT;
00394   typedef SourceOf<WARPPOINT, DIMENSIONALITY, PRECISION> WARPCONTROLPOINTS;
00395   typedef SourceTransformScaleOf<WARPPOINT, DIMENSIONALITY, PRECISION, WARPCONTROLPOINTS> WARPFIELD;
00396 
00397 public:
00398   void Get(DATA& dataOut, const PRECISION& rX, const PRECISION& rY, const PRECISION& rZ) const
00399     {
00400     if (this->m_pwarpfield->Size().X() < 4)
00401       {
00402       return ::Get(
00403           *(this->m_psource),
00404           dataOut,
00405           rX,
00406           rY,
00407           rZ
00408       );
00409       }
00410 
00411     WARPPOINT dpt;
00412     this->m_pwarpfield->Get(dpt,rX,rY,rZ);
00413 
00414     ::Get(
00415         *(this->m_psource),
00416         dataOut,
00417         (rX - dpt.X()*this->Size().X()),
00418         (rY - dpt.Y()*this->Size().Y()),
00419         (rZ - dpt.Z()*this->Size().Z())
00420     );
00421     }
00422 
00423   void Set(const PRECISION& rX, const PRECISION& rY, const PRECISION& rZ, const DATA& data)
00424     {
00425     WARPPOINT dpt;
00426     this->m_pwarpfield->Get(dpt,rX,rY,rZ);
00427 
00428     ::Set(
00429         *(this->m_psource),
00430         (rX - dpt.X()*this->Size().X()),
00431         (rY - dpt.Y()*this->Size().Y()),
00432         (rZ - dpt.Z()*this->Size().Z()),
00433         data
00434     );
00435     }
00436 
00437   };
00438 
00439 //============================================================================
00440 //============================================================================
00441 template<class DATA, int DIMENSIONALITY, class PRECISION, class SOURCE>
00442 void IncreaseWarpfieldControlPointResolution(SourceTransformWarpOf<DATA,
00443     DIMENSIONALITY, PRECISION, SOURCE> &srcWarp, const PointOf<DIMENSIONALITY,
00444     Real> &ptSize, int nInterpType = 3)
00445 {
00446   D("increasing resolution of warpfield control points");
00447   srcWarp.PrepareForAccess();
00448   srcWarp.SetWarpControlPoints(RasterizeInto(HandoffPointer(
00449       new typename SourceTransformWarpOf<DATA, DIMENSIONALITY, PRECISION,
00450           SOURCE>::WarpControlPoints), ScaleTo(ptSize,
00451       srcWarp.GetPInterpolatedWarpControlPoints())));
00452   srcWarp.SetWarpfieldInterpolation(InterpolationType(nInterpType));
00453 }
00454 
00455 #endif // __SOURCETRANSFORMWARP_H__

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1