00001
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
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
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
00293
00294 m_pwarpfield->PrepareForAccess();
00295
00296
00297 m_pwarpfield->SetScale(PointOf<DIMENSIONALITY, Real> (
00298 this->PSource()->Size()) / m_pwarpfield->PSource()->Size());
00299
00300
00301 m_pwarpfield->PrepareForAccess();
00302
00303
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__