00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date$ 00006 Version: $Revision$ 00007 00008 Copyright (c) German Cancer Research Center, Division of Medical and 00009 Biological Informatics. All rights reserved. 00010 See MITKCopyright.txt or https://www.mitk.org/copyright.html for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 00018 00019 #ifndef BASEDATA_H_HEADER_INCLUDED_C1EBB6FA 00020 #define BASEDATA_H_HEADER_INCLUDED_C1EBB6FA 00021 00022 #include <itkDataObject.h> 00023 00024 #include "mitkBaseProcess.h" 00025 #include "mitkTimeSlicedGeometry.h" 00026 #include "mitkCommon.h" 00027 #include "mitkOperationActor.h" 00028 #include "mitkPropertyList.h" 00029 00030 namespace mitk { 00031 00032 class BaseProcess; 00033 00034 //##Documentation 00035 //## @brief Base of all data objects 00036 //## 00037 //## Base of all data objects, e.g., images, contours, surfaces etc. Inherits 00038 //## from itk::DataObject and thus can be included in a pipeline. 00039 //## Inherits also from OperationActor and can be used as a destination for Undo 00040 //## @ingroup Data 00041 class MITK_CORE_EXPORT BaseData : public itk::DataObject, public OperationActor 00042 { 00043 public: 00044 mitkClassMacro(BaseData,itk::DataObject) 00045 00046 //##Documentation 00047 //## @brief Return the TimeSlicedGeometry of the data as const pointer. 00048 //## 00049 //## \warning No update will be called. Use GetUpdatedGeometry() if you cannot 00050 //## be sure that the geometry is up-to-date. 00051 //## 00052 //## Normally used in GenerateOutputInformation of subclasses of BaseProcess. 00053 const mitk::TimeSlicedGeometry* GetTimeSlicedGeometry() const 00054 { 00055 return m_TimeSlicedGeometry.GetPointer(); 00056 } 00057 00058 //##Documentation 00059 //## @brief Return the TimeSlicedGeometry of the data as pointer. 00060 //## 00061 //## \warning No update will be called. Use GetUpdatedGeometry() if you cannot 00062 //## be sure that the geometry is up-to-date. 00063 //## 00064 //## Normally used in GenerateOutputInformation of subclasses of BaseProcess. 00065 mitk::TimeSlicedGeometry* GetTimeSlicedGeometry() 00066 { 00067 return m_TimeSlicedGeometry.GetPointer(); 00068 } 00069 00070 //##Documentation 00071 //## @brief Return the Geometry3D of the data. 00072 //## 00073 //## The method does not simply return the value of the m_TimeSlicedGeometry 00074 //## member. Before doing this, it makes sure that the TimeSlicedGeometry 00075 //## is up-to-date (by setting the update extent to largest possible and 00076 //## calling UpdateOutputInformation). 00077 const mitk::TimeSlicedGeometry* GetUpdatedTimeSlicedGeometry(); 00078 00079 //##Documentation 00080 //## @brief Expands the TimeSlicedGeometry to a number of TimeSteps. 00081 //## 00082 //## The method expands the TimeSlicedGeometry to the given number of TimeSteps, 00083 //## filling newly created elements with empty geometries. Sub-classes should override 00084 //## this method to handle the elongation of their data vectors, too. 00085 //## Note that a shrinking is neither possible nor intended. 00086 virtual void Expand( unsigned int timeSteps ); 00087 00088 //##Documentation 00089 //## @brief Return the Geometry3D of the data at time \a t. 00090 //## 00091 //## The method does not simply return 00092 //## m_TimeSlicedGeometry->GetGeometry(t). 00093 //## Before doing this, it makes sure that the Geometry3D is up-to-date 00094 //## (by setting the update extent appropriately and calling 00095 //## UpdateOutputInformation). 00096 //## 00097 //## @todo Appropriate setting of the update extent is missing. 00098 const mitk::Geometry3D* GetUpdatedGeometry(int t=0); 00099 00100 //##Documentation 00101 //## @brief Return the geometry, which is a TimeSlicedGeometry, of the data 00102 //## as non-const pointer. 00103 //## 00104 //## \warning No update will be called. Use GetUpdatedGeometry() if you cannot 00105 //## be sure that the geometry is up-to-date. 00106 //## 00107 //## Normally used in GenerateOutputInformation of subclasses of BaseProcess. 00108 mitk::Geometry3D* GetGeometry(int t=0) const 00109 { 00110 if(m_TimeSlicedGeometry.IsNull()) 00111 return NULL; 00112 return m_TimeSlicedGeometry->GetGeometry3D(t); 00113 } 00114 00115 //##Documentation 00116 //## @brief Helps to deal with the weak-pointer-problem. 00117 virtual void UnRegister() const; 00118 00119 //##Documentation 00120 //## @brief for internal use only. Helps to deal with the 00121 //## weak-pointer-problem. 00122 virtual int GetExternalReferenceCount() const; 00123 00124 //##Documentation 00125 //## @brief Update the information for this BaseData (the geometry in particular) 00126 //## so that it can be used as an output of a BaseProcess. 00127 //## 00128 //## This method is used in the pipeline mechanism to propagate information and 00129 //## initialize the meta data associated with a BaseData. Any implementation 00130 //## of this method in a derived class is assumed to call its source's 00131 //## BaseProcess::UpdateOutputInformation() which determines modified 00132 //## times, LargestPossibleRegions, and any extra meta data like spacing, 00133 //## origin, etc. Default implementation simply call's it's source's 00134 //## UpdateOutputInformation(). 00135 //## \note Implementations of this methods in derived classes must take care 00136 //## that the geometry is updated by calling 00137 //## GetTimeSlicedGeometry()->UpdateInformation() 00138 //## \em after calling its source's BaseProcess::UpdateOutputInformation(). 00139 void UpdateOutputInformation(); 00140 00141 //##Documentation 00142 //## @brief Set the RequestedRegion to the LargestPossibleRegion. 00143 //## 00144 //## This forces a filter to produce all of the output in one execution 00145 //## (i.e. not streaming) on the next call to Update(). 00146 void SetRequestedRegionToLargestPossibleRegion()=0; 00147 00148 //##Documentation 00149 //## @brief Determine whether the RequestedRegion is outside of the BufferedRegion. 00150 //## 00151 //## This method returns true if the RequestedRegion 00152 //## is outside the BufferedRegion (true if at least one pixel is 00153 //## outside). This is used by the pipeline mechanism to determine 00154 //## whether a filter needs to re-execute in order to satisfy the 00155 //## current request. If the current RequestedRegion is already 00156 //## inside the BufferedRegion from the previous execution (and the 00157 //## current filter is up to date), then a given filter does not need 00158 //## to re-execute 00159 bool RequestedRegionIsOutsideOfTheBufferedRegion()=0; 00160 00161 //##Documentation 00162 //## @brief Verify that the RequestedRegion is within the LargestPossibleRegion. 00163 //## 00164 //## If the RequestedRegion is not within the LargestPossibleRegion, 00165 //## then the filter cannot possibly satisfy the request. This method 00166 //## returns true if the request can be satisfied (even if it will be 00167 //## necessary to process the entire LargestPossibleRegion) and 00168 //## returns false otherwise. This method is used by 00169 //## PropagateRequestedRegion(). PropagateRequestedRegion() throws a 00170 //## InvalidRequestedRegionError exception if the requested region is 00171 //## not within the LargestPossibleRegion. 00172 virtual bool VerifyRequestedRegion() = 0; 00173 00174 //##Documentation 00175 //## @brief Copy information from the specified data set. 00176 //## 00177 //## This method is part of the pipeline execution model. By default, a 00178 //## BaseProcess will copy meta-data from the first input to all of its 00179 //## outputs. See ProcessObject::GenerateOutputInformation(). Each 00180 //## subclass of DataObject is responsible for being able to copy 00181 //## whatever meta-data it needs from another DataObject. 00182 //## The default implementation of this method copies the time sliced geometry 00183 //## and the property list of an object. If a subclass overrides this 00184 //## method, it should always call its superclass' version. 00185 void CopyInformation(const itk::DataObject* data); 00186 00187 //##Documentation 00188 //## @brief Check whether the data has been initialized, i.e., 00189 //## at least the Geometry and other header data has been set 00190 //## 00191 //## \warning Set to \a true by default for compatibility reasons. 00192 //## Set m_Initialized=false in constructors of sub-classes that 00193 //## support distinction between initialized and uninitialized state. 00194 virtual bool IsInitialized() const; 00195 00196 //##Documentation 00197 //## @brief Calls ClearData() and InitializeEmpty(); 00198 //## \warning Only use in subclasses that reimplemented these methods. 00199 //## Just calling Clear from BaseData will reset an object to a not initialized, 00200 //## invalid state. 00201 virtual void Clear(); 00202 00203 //##Documentation 00204 //## @brief Check whether object contains data (at 00205 //## a specified time), e.g., a set of points may be empty 00206 //## 00207 //## \warning Returns IsInitialized()==false by default for 00208 //## compatibility reasons. Override in sub-classes that 00209 //## support distinction between empty/non-empty state. 00210 virtual bool IsEmpty(unsigned int t) const; 00211 00212 //##Documentation 00213 //## @brief Check whether object contains data (at 00214 //## least at one point in time), e.g., a set of points 00215 //## may be empty 00216 //## 00217 //## \warning Returns IsInitialized()==false by default for 00218 //## compatibility reasons. Override in sub-classes that 00219 //## support distinction between empty/non-empty state. 00220 virtual bool IsEmpty() const; 00221 00222 //##Documentation 00223 //## @brief Set the requested region from this data object to match the requested 00224 //## region of the data object passed in as a parameter. 00225 //## 00226 //## This method is implemented in the concrete subclasses of BaseData. 00227 void SetRequestedRegion(itk::DataObject *data)=0; 00228 00229 //##Documentation 00230 //##@brief overwrite if the Data can be called by an Interactor (StateMachine). 00231 //## 00232 //## Empty by default. Overwrite and implement all the necessary operations here 00233 //## and get the necessary information from the parameter operation. 00234 void ExecuteOperation(Operation* operation); 00235 00236 //##Documentation 00237 //## @brief Set the Geometry3D of the data, which will be referenced (not copied!). 00238 //## Assumes the data object has only 1 time step ( is a 3D object ). 00239 //## 00240 //## For convenience (and historic) reasons, it is also possible to set a complete 00241 //## mitk::TimeSlicedGeometry*, which will be referenced (not copied!). 00242 //## 00243 //## @warning This method will normally be called internally by the sub-class of BaseData 00244 //## during initialization. 00245 //## \sa SetClonedGeometry 00246 virtual void SetGeometry(Geometry3D* aGeometry3D); 00247 00248 //##Documentation 00249 //## @brief Set the Geometry3D of a given time step, which will be referenced (not copied!). 00250 //## 00251 //## @warning This method will normally be called internally by the sub-class of BaseData 00252 //## during initialization. 00253 //## \sa SetClonedGeometry 00254 virtual void SetGeometry(Geometry3D* aGeometry3D, unsigned int time); 00255 00256 //##Documentation 00257 //## @brief Set a clone of the provided geometry as Geometry3D of the data. 00258 //## Assumes the data object has only 1 time step ( is a 3D object ) 00259 //## 00260 //## \sa SetGeometry 00261 virtual void SetClonedGeometry(const Geometry3D* aGeometry3D); 00262 00263 //##Documentation 00264 //## @brief Set a clone of the provided geometry as Geometry3D of a given time step. 00265 //## 00266 //## \sa SetGeometry 00267 virtual void SetClonedGeometry(const Geometry3D* aGeometry3D, unsigned int time); 00268 00269 //##Documentation 00270 //## @brief Get the data's property list 00271 //## @sa GetProperty 00272 //## @sa m_PropertyList 00273 mitk::PropertyList::Pointer GetPropertyList() const; 00274 00275 //##Documentation 00276 //## @brief Set the data's property list 00277 //## @sa SetProperty 00278 //## @sa m_PropertyList 00279 void SetPropertyList(PropertyList* propertyList); 00280 00281 //##Documentation 00282 //## @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList, 00283 //## and set it to this, respectively; 00284 //## @sa GetPropertyList 00285 //## @sa m_PropertyList 00286 //## @sa m_MapOfPropertyLists 00287 mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const; 00288 00289 void SetProperty(const char *propertyKey, BaseProperty* property); 00290 00291 //##Documentation 00292 //## @brief Convenience method for setting the origin of 00293 //## the Geometry3D instances of all time steps 00294 //## 00295 //## \warning Geometries contained in the Geometry3D will 00296 //## \em not be changed, e.g. in case the Geometry3D is a 00297 //## SlicedGeometry3D the origin will \em not be propagated 00298 //## to the contained slices. The sub-class SlicedData 00299 //## does this for the case that the SlicedGeometry3D is 00300 //## evenly spaced. 00301 virtual void SetOrigin(const Point3D& origin); 00302 00316 itk::SmartPointerForwardReference<mitk::BaseProcess> GetSource() const; 00317 00318 //##Documentation 00319 //## @brief Get the number of time steps from the Timeslicedgeometry 00320 //## As the base data has not a data vector given by itself, the number 00321 //## of time steps is defined over the time sliced geometry. In sub classes, 00322 //## a better implementation could be over the length of the data vector. 00323 unsigned int GetTimeSteps() const 00324 { 00325 return m_TimeSlicedGeometry->GetTimeSteps(); 00326 }; 00327 00328 00329 //##Documentation 00330 //## @brief Get the modified time of the last change of the contents 00331 //## this data object or its geometry. 00332 virtual unsigned long GetMTime() const; 00333 00334 protected: 00335 BaseData(); 00336 ~BaseData(); 00337 00338 //##Documentation 00339 //## @brief Initialize the TimeSlicedGeometry for a number of time steps. 00340 //## The TimeSlicedGeometry is initialized empty and evenly timed. 00341 //## In many cases it will be necessary to overwrite this in sub-classes. 00342 virtual void InitializeTimeSlicedGeometry( unsigned int timeSteps = 1 ); 00343 00344 //##Documentation 00345 //## @brief reset to non-initialized state, release memory 00346 virtual void ClearData(); 00347 00348 //##Documentation 00349 //## @brief Pure virtual; Must be used in subclasses to get a data object to a 00350 //## valid state. Should at least create one empty object and call 00351 //## Superclass::InitializeTimeSlicedGeometry() to ensure an existing valid geometry 00352 virtual void InitializeEmpty(){}; 00353 00354 00355 virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; 00356 00357 bool m_RequestedRegionInitialized; 00358 bool m_LastRequestedRegionWasOutsideOfTheBufferedRegion; 00359 00360 mutable itk::SmartPointer<mitk::BaseProcess> m_SmartSourcePointer; 00361 mutable unsigned int m_SourceOutputIndexDuplicate; 00362 //##Documentation 00363 //## @brief for internal use only. Helps to deal with the 00364 //## weak-pointer-problem. 00365 virtual void ConnectSource(itk::ProcessObject *arg, unsigned int idx) const; 00366 00367 bool m_Initialized; 00368 00369 private: 00370 //##Documentation 00371 //## @brief Helps to deal with the weak-pointer-problem. 00372 mutable bool m_Unregistering; 00373 //##Documentation 00374 //## @brief Helps to deal with the weak-pointer-problem. 00375 mutable bool m_CalculatingExternalReferenceCount; 00376 //##Documentation 00377 //## @brief Helps to deal with the weak-pointer-problem. 00378 mutable int m_ExternalReferenceCount; 00379 00380 //##Documentation 00381 //## @brief PropertyList, f.e. to hold pic-tags, tracking-data,.. 00382 //## 00383 PropertyList::Pointer m_PropertyList; 00384 00385 TimeSlicedGeometry::Pointer m_TimeSlicedGeometry; 00386 00387 //##Documentation 00388 //## @brief Helps to deal with the weak-pointer-problem. 00389 friend class mitk::BaseProcess; 00390 }; 00391 00392 } // namespace mitk 00393 00394 00395 #endif /* BASEDATA_H_HEADER_INCLUDED_C1EBB6FA */