freCenteredEuler3DTransformController.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freCenteredEuler3DTransformController.cxx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 
00023 #include "freCenteredEuler3DTransformController.h"
00024 #include "freTransformSetupAdaptor.h"
00025 #include "freTransformInitializer.h"
00026 
00027 namespace FREE
00028 {
00029 
00033 
00034 DefineParameterMacro(CenteredEuler3DTransformController, InitializeRotation, "InitializeRotation", "Indicates if rotation is initialized via point set (true) or set via ITV (false).");
00035 
00036 CenteredEuler3DTransformController::
00037 CenteredEuler3DTransformController()
00038 {
00039   this->UpdateControllerID(ControllerID::CenteredEuler3DTransformController);
00040   this->m_Description = "A combination of rotation and translation in 3 dimensions.";
00041 };
00042 
00043 void
00044 CenteredEuler3DTransformController::
00045 GenerateProfile(CtrlProfile::ControllerProfile& profile, 
00046                 const SessionComponentCache* pComponentCache,
00047                 bool bRegardOldSetup) const
00048 {
00049   Superclass::GenerateProfile(profile,pComponentCache,bRegardOldSetup);
00050 
00051   //Parameters
00052   profile.Parameters().AddParameter(cParam_InitialTransformValues,CtrlProfile::Parameter::PVTDouble,"1..3: rotation angel (in radian)\n4..6: x/y/z center\n7..9: x/y/z translation",9,"0");
00053   profile.Parameters().AddParameter(cParam_CurrentTransformValues,CtrlProfile::Parameter::PVTDouble,"1..3: rotation angel (in radian)\n4..6: x/y/z center\n7..9: x/y/z translation",9,"0");
00054   profile.Parameters().AddParameter(cParam_TransformScale,CtrlProfile::Parameter::PVTDouble,"1..3: rotation angel (in radian)\n4..6: x/y/z center\n7..9: x/y/z translation",9,"1",-1,true);
00055   profile.Parameters().AddParameter(cParam_InitializeRotation,CtrlProfile::Parameter::PVTBool,cParamDsc_InitializeRotation,1,"true");
00056   profile.Parameters().AddParameter("InitialRotationAxis",Parameter::PVTInteger,"Indicates the rotiation axis used for initialisation, if the reference initialisation is used. The order of rotation is always z y x. \n-1: z y x (smart)\n0: z y x.\n1: x\n2: y\n3: y x\n4: z\n5: z x\n6: z y",1,"0");
00057 };
00058 
00059 bool
00060 CenteredEuler3DTransformController::
00061 SetInitialTransformValues( ComponentType* pTransformComponent,
00062                            SessionComponentCache* pComponentCache,
00063                            SessionInfo* pSessionInfo,
00064                            const int& iInitializeByITV) const
00065 {
00066   //let the transform be initialized by MatrixOffsetTransformController
00067   Superclass::SetInitialTransformValues( pTransformComponent, pComponentCache, pSessionInfo, iInitializeByITV);
00068 
00069   int iCenterType;
00070   bool bInitializeRotation;
00071 
00072   if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cannot initialize transform values, transform setup is not assigned in cache.");
00073   ComponentSetup* pTransformSetup = pComponentCache->Setup();
00074 
00075   if (!pTransformSetup->Parameters().GetParameterValue(cParam_CenterInitializationType,iCenterType)) throwExceptionMacro("Missing parameter: " << "CenterType");
00076   if (!pTransformSetup->Parameters().GetParameterValue(cParam_InitializeRotation,bInitializeRotation)) throwExceptionMacro("Missing parameter: " << cParam_InitializeRotation);
00077 
00078   TransformSetupAdaptor adaptor(pTransformSetup);
00079   ParameterArrayType itv = adaptor.GetInitialTransformParameters();
00080 
00081   //set current transform values to initial transform values by default
00082   for (int iIndex=0; iIndex<itv.Size(); iIndex++)
00083   {
00084     pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,itv[iIndex],iIndex);
00085   };
00086 
00087   if (iCenterType>0)
00088   { //the center was initialized by controller and not defined
00089     //by ITV so copy translation to current transform values
00090     for (int iIndex=0; iIndex<3; iIndex++)
00091     {
00092       pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,pTransformComponent->GetCenter().GetElement(iIndex),iIndex+3);
00093     }
00094   }
00095 
00096   if (iCenterType>1)
00097   { //the translation was initialized by controller and not defined
00098     //by ITV so copy translation to current transform values
00099     for (int iIndex=0; iIndex<3; iIndex++)
00100     {
00101       pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,pTransformComponent->GetTranslation().GetElement(iIndex),iIndex+6);
00102     }
00103   }
00104 
00105   if (bInitializeRotation)
00106         { //Rotation should be calculated
00107 
00108     //TODO: old version insufficient initializer use VersorRigidTransform instead or freTensoInitializer
00109     ReferencePointsAccessor<3> pointsAccessor(pComponentCache);
00110 
00111           ParameterArrayType fixedCenter(3);
00112           ParameterArrayType movingCenter(3);
00113 
00114     //get fixed center and moving center from the transformation
00115           for (int iIndex=0; iIndex<3; iIndex++)
00116           {
00117             fixedCenter[iIndex] = pTransformComponent->GetCenter().GetElement(iIndex);
00118             movingCenter[iIndex] = pTransformComponent->GetTranslation().GetElement(iIndex) - pTransformComponent->GetCenter().GetElement(iIndex);
00119           };
00120       
00121     if (!pointsAccessor.MovingPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via reference points. No moving reference point set defined. Please check media linkage.");
00122     if (!pointsAccessor.FixedPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via via reference points. No fixed reference point set defined. Please check media linkage.");
00123 
00124           RotationInitializer<3> rotationInitializer;
00125           
00126           rotationInitializer.SetCenterPair(movingCenter,fixedCenter);
00127 
00128           //Add all references
00129           int iIndex = 0;
00130           if (iCenterType==0) iIndex = 1; //first reference is the center point;
00131           for (iIndex; iIndex<pointsAccessor.GetFixedPointsCount(); iIndex++)
00132           {
00133                 rotationInitializer.AddReferencePair(pointsAccessor.GetMovingPointArray(iIndex),pointsAccessor.GetFixedPointArray(iIndex));
00134           };
00135 
00136           //set schedule
00137           int iInitialRotationAxis;
00138           if (!pTransformSetup->Parameters().GetParameterValue("InitialRotationAxis",iInitialRotationAxis)) throwExceptionMacro("Missing parameter: " << "InitialRotationAxis");
00139 
00140           rotationInitializer.ClearSchedule(false);
00141           if ((iInitialRotationAxis<1) | (4 == (iInitialRotationAxis & 4))) rotationInitializer.AddToSchedule(RA_Z);
00142           if ((iInitialRotationAxis<1) | (2 == (iInitialRotationAxis & 2))) rotationInitializer.AddToSchedule(RA_Y);
00143           if ((iInitialRotationAxis<1) | (1 == (iInitialRotationAxis & 1))) rotationInitializer.AddToSchedule(RA_X);
00144 
00145           rotationInitializer.SetUseRotationWeight(iInitialRotationAxis==-1);
00146 
00147           rotationInitializer.ComputeRotations();
00148 
00149           //add angel to the parameters. Angel must be inverted, because itk uses back transform
00150           //(fixed to moving) and the initial calculation uses forward transform to allow an intuitive
00151           //parameter setting
00152         pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_X),0);
00153           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_Y),1);
00154           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_Z),2);
00155   }
00156 
00157   return true;
00158 };
00159 
00160 } //end of namespace free

Generated at Sat Oct 13 15:27:41 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000