ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkSpatialObject.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkSpatialObject_h
00019 #define __itkSpatialObject_h
00020 
00021 // Disable warning for lengthy symbol names in this file only
00022 
00023 #include "itkAffineGeometryFrame.h"
00024 #include "itkCovariantVector.h"
00025 #include "itkExceptionObject.h"
00026 #include <list>
00027 #include "itkSpatialObjectProperty.h"
00028 #include "itkProcessObject.h"
00029 #include "itkIndex.h"
00030 #include "itkImageRegion.h"
00031 #include "itkSpatialObjectTreeNode.h"
00032 
00033 namespace itk
00034 {
00055 template< unsigned int VDimension >
00056 class SpatialObjectTreeNode;
00057 
00058 template< unsigned int VDimension = 3 >
00059 class SpatialObject:
00060   public DataObject
00061 {
00062 public:
00063 
00064   typedef double ScalarType;
00065 
00066   itkStaticConstMacro(MaximumDepth, unsigned int, 9999999);
00067 
00070   unsigned int GetMaximumDepth() { return MaximumDepth; }
00071 
00072   typedef SpatialObject< VDimension > Self;
00073   typedef DataObject                  Superclass;
00074 
00075   typedef SmartPointer< Self >       Pointer;
00076   typedef SmartPointer< const Self > ConstPointer;
00077 
00078   typedef Point< ScalarType, VDimension > PointType;
00079   // Spatial Function Iterator needs the following typedef
00080   typedef Point< ScalarType, VDimension > InputType;
00081   typedef PointType *                     PointPointer;
00082 
00083   typedef Vector< ScalarType, VDimension >          VectorType;
00084   typedef CovariantVector< ScalarType, VDimension > CovariantVectorType;
00085   typedef VectorType *                              VectorPointer;
00086 
00087   typedef double *SpacingType;
00088 
00089   typedef CovariantVector< double, VDimension > OutputVectorType;
00090   typedef OutputVectorType *                    OutputVectorPointer;
00091 
00092   typedef ScalableAffineTransform< double, VDimension > TransformType;
00093   typedef typename TransformType::Pointer               TransformPointer;
00094   typedef const TransformType *                         TransformConstPointer;
00095 
00096   typedef VectorContainer< IdentifierType, PointType >  VectorContainerType;
00097 
00098   typedef BoundingBox< IdentifierType, VDimension, ScalarType, VectorContainerType > BoundingBoxType;
00099   typedef typename BoundingBoxType::Pointer                                          BoundingBoxPointer;
00100 
00101   typedef AffineGeometryFrame< double, VDimension > AffineGeometryFrameType;
00102   typedef typename AffineGeometryFrameType::Pointer AffineGeometryFramePointer;
00103 
00105   typedef std::list< Pointer > ChildrenListType;
00106   typedef ChildrenListType *   ChildrenListPointer;
00107 
00109   typedef Index< VDimension >                IndexType;
00110 
00113   typedef Offset< VDimension >                 OffsetType;
00114   typedef ImageRegion< VDimension >            RegionType;
00115   typedef Size< VDimension >                   SizeType;
00116   typedef SpatialObjectProperty< float >       PropertyType;
00117   typedef typename PropertyType::Pointer       PropertyPointer;
00118 
00119   typedef SpatialObjectTreeNode< VDimension > TreeNodeType;
00120 
00123   virtual bool HasParent(void) const;
00124 
00126   virtual const char * GetTypeName(void) const { return m_TypeName.c_str(); }
00127 
00131   itkStaticConstMacro(ObjectDimension, unsigned int, VDimension);
00132 
00134   unsigned int GetObjectDimension(void) const { return VDimension; }
00135 
00137   itkNewMacro(Self);
00138 
00140   itkTypeMacro(SpatialObject, DataObject);
00141 
00143   itkGetConstObjectMacro(AffineGeometryFrame, AffineGeometryFrameType);
00144   itkSetObjectMacro(AffineGeometryFrame, AffineGeometryFrameType);
00146 
00149   void SetObjectToWorldTransform(TransformType *transform);
00150 
00151   itkGetObjectMacro(ObjectToWorldTransform, TransformType);
00152   itkGetConstObjectMacro(ObjectToWorldTransform, TransformType);
00153   itkGetObjectMacro(IndexToWorldTransform, TransformType);
00154   itkGetConstObjectMacro(IndexToWorldTransform, TransformType);
00155 
00159   void ComputeObjectToWorldTransform(void);
00160 
00162   void ComputeObjectToParentTransform(void);
00163 
00165   unsigned long GetTransformMTime(void);
00166 
00168   unsigned long GetWorldTransformMTime(void);
00169 
00171   virtual bool ValueAt(const PointType & point, double & value,
00172                        unsigned int depth = 0,
00173                        char *name = NULL) const;
00174 
00181   virtual bool IsEvaluableAt(const PointType & point,
00182                              unsigned int depth = 0,
00183                              char *name = NULL) const;
00184 
00186   virtual bool IsInside(const PointType & point,
00187                         unsigned int depth = 0,
00188                         char *name = NULL) const;
00189 
00194   bool Evaluate(const PointType & point) const
00195   {
00196     return this->IsInside(point);
00197   }
00198 
00200   virtual void DerivativeAt(const PointType & point,
00201                             short unsigned int order,
00202                             OutputVectorType & value,
00203                             unsigned int depth = 0,
00204                             char *name = NULL);
00205 
00208   unsigned long GetMTime(void) const;
00209 
00212   unsigned long GetObjectMTime(void) const
00213   {
00214     return Superclass::GetMTime();
00215   }
00216 
00223   virtual void SetLargestPossibleRegion(const RegionType & region);
00224 
00231   virtual const RegionType & GetLargestPossibleRegion() const
00232   { return m_LargestPossibleRegion; }
00233 
00237   virtual void SetBufferedRegion(const RegionType & region);
00238 
00242   virtual const RegionType & GetBufferedRegion() const
00243   { return m_BufferedRegion; }
00244 
00249   virtual void SetRequestedRegion(const RegionType & region);
00250 
00255   virtual void SetRequestedRegion(const DataObject *data);
00256 
00261   virtual const RegionType & GetRequestedRegion() const
00262   { return m_RequestedRegion; }
00263 
00273   const OffsetValueType * GetOffsetTable() const { return m_OffsetTable; }
00275 
00278   OffsetValueType ComputeOffset(const IndexType & ind) const
00279   {
00280     // need to add bounds checking for the region/buffer?
00281     OffsetValueType   offset = 0;
00282     const IndexType & bufferedRegionIndex = m_BufferedRegion.GetIndex();
00284 
00285     // data is arranged as [][][][slice][row][col]
00286     // with Index[0] = col, Index[1] = row, Index[2] = slice
00287     for ( int i = VDimension - 1; i > 0; i-- )
00288       {
00289       offset += ( ind[i] - bufferedRegionIndex[i] ) * m_OffsetTable[i];
00290       }
00291     offset += ( ind[0] - bufferedRegionIndex[0] );
00292 
00293     return offset;
00294   }
00295 
00298   IndexType ComputeIndex(OffsetValueType offset) const
00299   {
00300     IndexType         index;
00301     const IndexType & bufferedRegionIndex = m_BufferedRegion.GetIndex();
00303 
00304     for ( int i = VDimension - 1; i > 0; i-- )
00305       {
00306       index[i] = static_cast< IndexValueType >( offset / m_OffsetTable[i] );
00307       offset -= ( index[i] * m_OffsetTable[i] );
00308       index[i] += bufferedRegionIndex[i];
00309       }
00310     index[0] = bufferedRegionIndex[0] + static_cast< IndexValueType >( offset );
00311 
00312     return index;
00313   }
00314 
00324   virtual void CopyInformation(const DataObject *data);
00325 
00333   virtual void UpdateOutputInformation();
00334 
00338   virtual void SetRequestedRegionToLargestPossibleRegion();
00339 
00349   virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
00350 
00359   virtual bool VerifyRequestedRegion();
00360 
00362   PropertyType * GetProperty(void);
00363 
00364   const PropertyType * GetProperty(void) const { return m_Property; }
00365 
00367   void SetProperty(PropertyType *property);
00368 
00370   itkGetConstReferenceMacro(Id, int);
00371   itkSetMacro(Id, int);
00373 
00375   itkSetMacro(ParentId, int);
00376   itkGetConstReferenceMacro(ParentId, int);
00378 
00380   virtual void Update(void);
00381 
00383   itkSetObjectMacro(TreeNode, TreeNodeType)
00384 
00385 
00386   itkGetObjectMacro(TreeNode, TreeNodeType);
00387   itkGetConstObjectMacro(TreeNode, TreeNodeType);
00389 
00393   void SetSpacing(const double
00394                   spacing[itkGetStaticConstMacro(ObjectDimension)])
00395   { this->GetIndexToObjectTransform()->SetScale(spacing); }
00396 
00398   virtual const double * GetSpacing() const
00399   { return this->GetIndexToObjectTransform()->GetScale(); }
00400 
00406   TransformType * GetIndexToObjectTransform(void);
00407 
00408   const TransformType * GetIndexToObjectTransform(void) const;
00409 
00413   void SetObjectToParentTransform(TransformType *transform);
00414 
00415   TransformType * GetObjectToParentTransform(void);
00416 
00417   const TransformType * GetObjectToParentTransform(void) const;
00418 
00422   TransformType * GetObjectToNodeTransform(void);
00423 
00424   const TransformType * GetObjectToNodeTransform(void) const;
00425 
00430   void AddSpatialObject(Self *pointer);
00431 
00436   void RemoveSpatialObject(Self *object);
00437 
00439   virtual const Self * GetParent(void) const;
00440 
00442   virtual Self * GetParent(void);
00443 
00449   virtual ChildrenListType * GetChildren(unsigned int depth = 0,
00450                                          char *name = NULL) const;
00451 
00453   unsigned int GetNumberOfChildren(unsigned int depth = 0,
00454                                    char *name = NULL) const;
00455 
00457   void SetChildren(ChildrenListType & children);
00458 
00461   virtual void Clear(void);
00462 
00485   virtual bool ComputeBoundingBox() const;
00486 
00487   virtual bool ComputeLocalBoundingBox() const
00488   {
00489     std::cerr << "SpatialObject::ComputeLocalBoundingBox Not Implemented!"
00490               << std::endl;
00491     return false;
00492   }
00493 
00496   virtual BoundingBoxType * GetBoundingBox() const;
00497 
00499   itkSetMacro(BoundingBoxChildrenDepth, unsigned int);
00500   itkGetConstReferenceMacro(BoundingBoxChildrenDepth, unsigned int);
00502 
00505   itkSetMacro(BoundingBoxChildrenName, std::string);
00506   itkGetConstReferenceMacro(BoundingBoxChildrenName, std::string);
00508 
00511   void SetParent(Self *parent);
00512 
00514   void SetNodeToParentNodeTransform(TransformType *transform);
00515 
00516   TransformType * GetNodeToParentNodeTransform(void);
00517 
00518   const TransformType * GetNodeToParentNodeTransform(void) const;
00519 
00522   itkSetMacro(DefaultInsideValue, double);
00523   itkGetConstMacro(DefaultInsideValue, double);
00525 
00528   itkSetMacro(DefaultOutsideValue, double);
00529   itkGetConstMacro(DefaultOutsideValue, double);
00531 
00534   virtual std::string GetSpatialObjectTypeAsString() const;
00535 
00536 protected:
00537 
00539   SpatialObject();
00540 
00542   virtual ~SpatialObject();
00543 
00544   virtual void PrintSelf(std::ostream & os, Indent indent) const;
00545 
00550   void ComputeOffsetTable();
00551 
00552   itkSetMacro(Dimension, unsigned int);
00553   itkGetConstReferenceMacro(Dimension, unsigned int)
00554   itkSetMacro(TypeName, std::string);
00555   itkGetConstObjectMacro(Bounds, BoundingBoxType);
00556   itkGetConstObjectMacro(InternalInverseTransform, TransformType);
00557 
00564   bool SetInternalInverseTransformToWorldToIndexTransform() const;
00565 
00566 private:
00567 
00568   SpatialObject(const Self &);  //purposely not implemented
00569   void operator=(const Self &); //purposely not implemented
00570 
00571   BoundingBoxPointer    m_Bounds;
00572   mutable unsigned long m_BoundsMTime;
00573 
00574   TransformPointer m_ObjectToParentTransform;
00575   TransformPointer m_ObjectToWorldTransform;
00576   TransformPointer m_IndexToWorldTransform;
00577 
00579   std::string m_TypeName;
00580 
00581   unsigned int m_Dimension;
00582 
00583   OffsetValueType m_OffsetTable[3 + 1];
00584 
00585   RegionType m_LargestPossibleRegion;
00586   RegionType m_RequestedRegion;
00587   RegionType m_BufferedRegion;
00588 
00589   std::string     m_BoundingBoxChildrenName;
00590   unsigned int    m_BoundingBoxChildrenDepth;
00591   PropertyPointer m_Property;
00592 
00594   int m_Id;
00595   int m_ParentId;
00596 
00598   typename TreeNodeType::Pointer m_TreeNode;
00599 
00601   AffineGeometryFramePointer m_AffineGeometryFrame;
00602 
00605   ChildrenListType m_InternalChildrenList;
00606 
00609   TransformPointer m_InternalInverseTransform;
00610 
00612   double m_DefaultInsideValue;
00613 
00615   double m_DefaultOutsideValue;
00616 };
00617 } // end of namespace itk
00618 
00619 #if !defined( CABLE_CONFIGURATION )
00620 #ifndef ITK_MANUAL_INSTANTIATION
00621 #include "itkSpatialObject.hxx"
00622 #endif
00623 #endif
00624 
00625 #endif // __itkSpatialObject_h
00626