cmtkXformList.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2482 $
00026 //
00027 //  $LastChangedDate: 2010-10-20 15:52:48 -0700 (Wed, 20 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkXformList.h"
00034 
00035 void
00036 cmtk::XformList::Add
00037 ( const Xform::SmartConstPtr& xform, const bool inverse, const Types::Coordinate globalScale  )
00038 {
00039   this->push_back( XformListEntry::SmartConstPtr( new XformListEntry( xform, inverse, globalScale ) ) );
00040 }
00041 
00042 void
00043 cmtk::XformList::AddToFront
00044 ( const Xform::SmartConstPtr& xform, const bool inverse, const Types::Coordinate globalScale  )
00045 {
00046   this->push_front( XformListEntry::SmartConstPtr( new XformListEntry( xform, inverse, globalScale ) ) );
00047 }
00048 
00049 bool
00050 cmtk::XformList::ApplyInPlace( Xform::SpaceVectorType& v ) const
00051 {
00052   for ( const_iterator it = this->begin(); it != this->end(); ++it ) 
00053     {
00054     if ( (*it)->Inverse ) 
00055       {
00056       if ( (*it)->m_WarpXform ) 
00057         {
00058         // yes: use approximate inverse
00059         if ( ! (*it)->m_WarpXform->ApplyInverseInPlace( v, this->m_Epsilon ) ) 
00060           {
00061           // if that fails, return failure flag
00062           return false;
00063           }
00064         } 
00065       else
00066         {
00067         // is this an affine transformation that has an inverse?
00068         if ( (*it)->InverseAffineXform ) 
00069           // apply inverse
00070           (*it)->InverseAffineXform->ApplyInPlace( v );
00071         else
00072           // nothing else we can do: exit with failure flag
00073           return false;
00074         }
00075       } 
00076     else
00077       {
00078       // are we outside xform domain? then return failure.
00079       if ( !(*it)->m_Xform->InDomain( v ) ) return false;
00080       (*it)->m_Xform->ApplyInPlace( v );
00081       }
00082     }
00083   return true;
00084 }
00085 
00086 bool
00087 cmtk::XformList::GetJacobian
00088 ( const Xform::SpaceVectorType& v, Types::DataItem& jacobian, const bool correctGlobalScale ) const
00089 {
00090   Xform::SpaceVectorType vv( v );
00091 
00092   jacobian = static_cast<Types::DataItem>( 1.0 );
00093   for ( const_iterator it = this->begin(); it != this->end(); ++it ) 
00094     {
00095     if ( (*it)->Inverse ) 
00096       {
00097       if ( correctGlobalScale )
00098         jacobian *= static_cast<Types::DataItem>( (*it)->GlobalScale );
00099 
00100       // is this a spline transformation?
00101       if ( (*it)->m_WarpXform ) 
00102         {
00103         // yes: use approximate inverse
00104         if ( (*it)->m_WarpXform->ApplyInverseInPlace( vv, this->m_Epsilon ) ) 
00105           // compute Jacobian at destination and invert
00106           jacobian /= static_cast<Types::DataItem>( (*it)->m_Xform->GetJacobianDeterminant( vv ) );     
00107         else
00108           // if that fails, return failure flag
00109           return false;
00110         } 
00111       else
00112         {
00113         // is this an affine transformation that has an inverse?
00114         if ( (*it)->InverseAffineXform ) 
00115           // apply inverse
00116           (*it)->InverseAffineXform->ApplyInPlace( vv );
00117         else
00118           // nothing else we can do: exit with failure flag
00119           return false;
00120         }
00121       } 
00122     else 
00123       {
00124       // are we outside xform domain? then return failure.
00125       if ( !(*it)->m_Xform->InDomain( v ) ) return false;
00126 
00127       jacobian *= static_cast<Types::DataItem>( (*it)->m_Xform->GetJacobianDeterminant( vv ) );
00128       if ( correctGlobalScale )
00129         jacobian /= static_cast<Types::DataItem>( (*it)->GlobalScale );
00130       (*it)->m_Xform->ApplyInPlace( vv );
00131       }
00132     }
00133   return true;
00134 }
00135 
00136 bool
00137 cmtk::XformList::AllAffine() const
00138 {
00139   for ( const_iterator it = this->begin(); it != this->end(); ++it ) 
00140     {
00141     if ( !(*it)->IsAffine() )
00142       return false;
00143     }
00144   return true;
00145 }
00146 
00147 cmtk::XformList
00148 cmtk::XformList::MakeAllAffine() const
00149 {
00150   cmtk::XformList allAffine;
00151 
00152   for ( const_iterator it = this->begin(); it != this->end(); ++it ) 
00153     {
00154     allAffine.push_back( (*it)->CopyAsAffine() );
00155     }
00156 
00157   return allAffine;
00158 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines