| 1 |
|
/*========================================================================= |
| 2 |
|
|
| 3 |
|
Program: Insight Segmentation & Registration Toolkit |
| 4 |
|
Module: $RCSfile: itkDataObject.h.html,v $ |
| 5 |
|
Language: C++ |
| 6 |
|
Date: $Date: 2006/01/17 19:15:34 $ |
| 7 |
|
Version: $Revision: 1.4 $ |
| 8 |
|
|
| 9 |
|
Copyright (c) Insight Software Consortium. All rights reserved. |
| 10 |
|
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. |
| 11 |
|
|
| 12 |
|
Portions of this code are covered under the VTK copyright. |
| 13 |
|
See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. |
| 14 |
|
|
| 15 |
|
This software is distributed WITHOUT ANY WARRANTY; without even |
| 16 |
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 17 |
IND |
*****PURPOSE. See the above copyright notices for more information. |
| 18 |
|
|
| 19 |
|
=========================================================================*/ |
| 20 |
|
#ifndef __itkDataObject_h |
| 21 |
|
#define __itkDataObject_h |
| 22 |
|
|
| 23 |
|
#include "itkObject.h" |
| 24 |
|
#include "itkSmartPointerForwardReference.h" |
| 25 |
|
#include "itkWeakPointer.h" |
| 26 |
|
#include "itkExceptionObject.h" |
| 27 |
|
|
| 28 |
|
namespace itk |
| 29 |
|
{ |
| 30 |
|
|
| 31 |
|
class ProcessObject; |
| 32 |
|
class DataObject; |
| 33 |
|
|
| 34 |
|
/*--------------------Data Object Exceptions---------------------------*/ |
| 35 |
|
|
| 36 |
|
/** \brief Exception object for DataObject exceptions */ |
| 37 |
MCM |
class ITKCommon_EXPORT DataObjectError : public ExceptionObject |
| 38 |
|
{ |
| 39 |
|
public: |
| 40 |
|
/** Default constructor. Needed to ensure the exception object can be |
| 41 |
|
* copied. */ |
| 42 |
|
DataObjectError(); |
| 43 |
|
|
| 44 |
|
/** Destructor. Need to specify empty throw() to avoid warnings. */ |
| 45 |
|
virtual ~DataObjectError() throw() {} |
| 46 |
|
|
| 47 |
|
/** Constructor. Needed to ensure the exception object can be copied. */ |
| 48 |
|
DataObjectError(const char *file, unsigned int lineNumber); |
| 49 |
|
|
| 50 |
|
/** Constructor. Needed to ensure the exception object can be copied. */ |
| 51 |
|
DataObjectError(const std::string& file, unsigned int lineNumber); |
| 52 |
|
|
| 53 |
|
/** Copy constructor. Needed to ensure the exception object can be copied. */ |
| 54 |
|
DataObjectError(const DataObjectError &orig); |
| 55 |
|
|
| 56 |
|
/** Operator=. Needed to ensure the exception object can be copied. */ |
| 57 |
|
DataObjectError& operator=( const DataObjectError& orig); |
| 58 |
|
|
| 59 |
|
/** Standard type macro */ |
| 60 |
|
itkTypeMacro(DataObjectError, ExceptionObject); |
| 61 |
|
|
| 62 |
|
/** Set the data object that is throwing this exception. */ |
| 63 |
|
void SetDataObject(DataObject *dobj); |
| 64 |
|
|
| 65 |
|
/** Get the data object that is throwing this exception. */ |
| 66 |
|
DataObject* GetDataObject(); |
| 67 |
|
|
| 68 |
|
protected: |
| 69 |
|
/** Print exception information. This method can be overridden by |
| 70 |
|
* specific exception subtypes. The default is to print out the |
| 71 |
|
* location where the exception was first thrown and any description |
| 72 |
|
* provided by the ``thrower''. */ |
| 73 |
|
virtual void PrintSelf(std::ostream& os, Indent indent) const; |
| 74 |
|
|
| 75 |
|
private: |
| 76 |
|
DataObject *m_DataObject; |
| 77 |
|
}; |
| 78 |
|
|
| 79 |
|
|
| 80 |
|
/** |
| 81 |
|
* Exception object for invalid requested region |
| 82 |
|
*/ |
| 83 |
MCM |
class ITKCommon_EXPORT InvalidRequestedRegionError : public DataObjectError |
| 84 |
|
{ |
| 85 |
IND |
*public: |
| 86 |
LEN |
/** Default constructor. Needed to ensure the exception object can be copied. */ |
| 87 |
|
InvalidRequestedRegionError(); |
| 88 |
|
|
| 89 |
|
/** Destructor. Need to specify empty throw() to avoid warnings. */ |
| 90 |
|
virtual ~InvalidRequestedRegionError() throw() {} |
| 91 |
|
|
| 92 |
|
/** Constructor. Needed to ensure the exception object can be copied. */ |
| 93 |
|
InvalidRequestedRegionError(const char *file, unsigned int lineNumber); |
| 94 |
|
|
| 95 |
|
/** Constructor. Needed to ensure the exception object can be copied. */ |
| 96 |
|
InvalidRequestedRegionError(const std::string& file, unsigned int lineNumber); |
| 97 |
|
|
| 98 |
|
/** Copy constructor. Needed to ensure the exception object can be copied. */ |
| 99 |
|
InvalidRequestedRegionError(const InvalidRequestedRegionError &orig); |
| 100 |
|
|
| 101 |
|
/** Operator=. Needed to ensure the exception object can be copied. */ |
| 102 |
LEN |
InvalidRequestedRegionError& operator=( const InvalidRequestedRegionError& orig); |
| 103 |
|
|
| 104 |
|
/** Standard type macro */ |
| 105 |
|
itkTypeMacro(InvalidRequestedRegionError, DataObjectError); |
| 106 |
|
|
| 107 |
|
protected: |
| 108 |
|
/** Print exception information. This method can be overridden by |
| 109 |
|
* specific exception subtypes. The default is to print out the |
| 110 |
|
* location where the exception was first thrown and any description |
| 111 |
|
* provided by the ``thrower''. */ |
| 112 |
|
virtual void PrintSelf(std::ostream& os, Indent indent) const; |
| 113 |
|
|
| 114 |
|
}; |
| 115 |
|
|
| 116 |
|
|
| 117 |
|
/*----------------------------Data Object--------------------------------*/ |
| 118 |
|
|
| 119 |
|
/** \class DataObject |
| 120 |
|
* \brief Base class for all data objects in ITK. |
| 121 |
|
* |
| 122 |
|
* This is the base class for all data objects in the Insight data |
| 123 |
|
* processing pipeline. A data object is an object that represents and |
| 124 |
|
* provides access to data. ProcessObjects (i.e., filters) operate on |
| 125 |
|
* input data objects, producing new data objects as output. |
| 126 |
|
* ProcessObject and DataObject are connected together into data flow |
| 127 |
|
* pipelines. |
| 128 |
|
* |
| 129 |
|
* The data flow pipeline architecture requires that DataObjects and |
| 130 |
|
* ProcessObjects negotiate the flow of information. When the tail of |
| 131 |
|
* a pipeline is instructed to Update(), a series of requests are |
| 132 |
|
* propagated up the pipeline (from a ProcessObject to its inputs |
| 133 |
|
* (DataObjects), from these inputs to their sources (ProcessObjects), |
| 134 |
|
* etc.). A call to Update() entails 3 passes up the pipeline (though |
| 135 |
|
* not all passes will traverse the entire pipeline). The first pass |
| 136 |
|
* up the pipeline determines when various components of the pipeline |
| 137 |
|
* were last modified and hence which components will need to be |
| 138 |
|
* updated. As this first pass in unwinding, meta information about |
| 139 |
|
* the DataObjects (for instance image spacing and data size) are |
| 140 |
|
* passed down the pipeline. The second pass up the pipeline |
| 141 |
|
* propagates a request for a specific piece of information (for |
| 142 |
|
* instance a sub-region of an image). A request for a piece of a |
| 143 |
|
* DataObject is propagated to its source, from there to its inputs, |
| 144 |
|
* etc. allowing each ProcessObject to determine whether (1) it can |
| 145 |
|
* already satisfy the request (the requested block of data is already |
| 146 |
|
* available) or (2) the ProcessObject will need to request a new |
| 147 |
|
* block of data on input to satisfy the output request. Finally, a |
| 148 |
|
* pass is made up the pipeline to actually calculate the values for |
| 149 |
|
* the various blocks of data requested (i.e. pixel values are finally |
| 150 |
|
* calculated). This final pass will only traverse up the pipeline as |
| 151 |
|
* far as the first two passes have identified. For instance, to |
| 152 |
|
* satisfy a given request at the tail of a pipeline, only the lower |
| 153 |
|
* few ProcessObjects may have to re-execute. |
| 154 |
|
* |
| 155 |
|
* There are three types of information negotiated by the pipeline |
| 156 |
|
* (prior to actual calculation of the bulk data): modified times, |
| 157 |
|
* meta data, and regions. The modified times keep track of when |
| 158 |
|
* various data objects were last modified and/updated and the when |
| 159 |
|
* the various process objects were modified. The meta data is any |
| 160 |
|
* extra information about the data object that is not part of the |
| 161 |
|
* bulk data. For instance, an Image maintains pixel spacing and |
| 162 |
|
* origin meta data. Finally, the pipeline negotiation process passes |
| 163 |
|
* requests up the pipeline in the form of Regions. A DataObject can |
| 164 |
|
* have as many as three regions (which themselves could be considered |
| 165 |
|
* meta data): LargestPossibleRegion, RequestedRegion, and |
| 166 |
|
* BufferedRegion. The LargestPossibleRegion is the entirety of the |
| 167 |
|
* dataset (for instance how big is the dataset on disk). |
| 168 |
|
* LargestPossibleRegions are negotiated during the first pass of a |
| 169 |
|
* pipeline update (via the method |
| 170 |
|
* ProcessObject::GenerateOutputInformation() which is called from |
| 171 |
|
* ProcessObject::UpdateOutputInformation(). The RequestedRegion is |
| 172 |
|
* the amount of the DataObject that is requested by the user or |
| 173 |
|
* pipeline. RequestedRegions are negotiated during the second pass of |
| 174 |
|
* a pipeline update (via the methods |
| 175 |
|
* ProcessObject::EnlargeOutputRequestedRegion(), |
| 176 |
|
* ProcessObject::GenerateOutputRequestedRegion(), |
| 177 |
|
* ProcessObject::GenerateInputRequestedRegion() which are called from |
| 178 |
|
* ProcessObject::PropagateRequestedRegion()). The BufferedRegion is |
| 179 |
|
* the amount of the DataObject that is currently in memory. |
| 180 |
|
* BufferedRegions are defined during the final pass of a pipeline |
| 181 |
|
* update (when ProcessObjects finally calculate the bulk data via the |
| 182 |
|
* methods ProcessObject::GenerateData() or |
| 183 |
|
* ProcessObject::ThreadedGenerateData() which are called by |
| 184 |
|
* ProcessObject::UpdateOutputData()). These three regions can be |
| 185 |
|
* different but must satisfy the relationship RequestedRegion <= |
| 186 |
|
* BufferedRegion <= LargestPossibleRegion. For instance, an Image |
| 187 |
|
* could be 512x512x200 on disk (LargestPossibleRegion) but the |
| 188 |
|
* application may only have a 256x256x50 section of the dataset in |
| 189 |
|
* memory (BufferedRegion) and the user wants to operate on a |
| 190 |
|
* 100x100x1 section of the buffer (RequestedRegion). |
| 191 |
|
* |
| 192 |
|
* Region negotiation is not applicable for all types of DataObjects. |
| 193 |
|
* For instance, an EquivalencyTable of segmentation labels can be |
| 194 |
|
* passed from ProcessObject to ProcessObject as any other DataObject |
| 195 |
|
* but an EquivalencyTable does not support the concept of a |
| 196 |
|
* sub-region. Therefore, the region negotiations at the DataObject |
| 197 |
|
* (superclass) level are implemented as "abstract" concepts (not to |
| 198 |
|
* be confused with a C++ abstract methods), allowing subclasses to |
| 199 |
|
* provide specialized implementations on an as needed basis. There |
| 200 |
|
* are five methods provided in DataObject that a subclass of |
| 201 |
|
* DataObject may have to override for that particular type of |
| 202 |
|
* DataObject to flow through the pipeline. These methods should only |
| 203 |
|
* have to be specialized for DataObjects that do support |
| 204 |
|
* regions. These methods are: |
| 205 |
|
* |
| 206 |
|
* void UpdateOutputInformation(): This method implements the first |
| 207 |
|
* pass of the pipeline update mechanism outlined above. It is |
| 208 |
|
* responsible for identifying when upstream components of the |
| 209 |
|
* pipeline have been change (ModifiedTimes and Pipeline |
| 210 |
|
* ModifiedTimes) and is responsible for propagating meta data through |
| 211 |
|
* the pipeline. In the simplest case, this method simply calls the |
| 212 |
|
* DataObject's source's UpdateOutputInformation() method (this is the |
| 213 |
|
* default implementation). For DataObjects that support streaming, |
| 214 |
|
* this method also propagates LargestPossibleRegions to downstream |
| 215 |
|
* ProcessObjects. |
| 216 |
|
* |
| 217 |
|
* bool VerifyRequestedRegion(): Verify that the RequestedRegion is |
| 218 |
|
* within the LargestPossibleRegion. For DataObjects that do not |
| 219 |
|
* support Regions, this method always returns true. |
| 220 |
|
* |
| 221 |
|
* bool RequestedRegionIsOutsideOfTheBufferedRegion(): Determine |
| 222 |
|
* whether the RequestedRegion is outside of the current |
| 223 |
|
* BufferedRegion. This method is used by the second pass of a |
| 224 |
|
* pipeline update outlined above. It is used to determine whether a |
| 225 |
|
* filter needs to re-execute in order to satisfy a given request. For |
| 226 |
|
* DataObjects that do not support Regions, this method always returns |
| 227 |
|
* false. By always returning false, these types of DataObjects will |
| 228 |
|
* update solely on the basis of modified times (wherease Images |
| 229 |
|
* update based on either modified times or the RequestedRegion |
| 230 |
|
* needs). If this method always returned true, the DataObject would |
| 231 |
|
* be updated on every single call to Update() (not recommended). |
| 232 |
|
* |
| 233 |
|
* void SetRequestedRegion(DataObject *): Sets the RequestedRegion of |
| 234 |
|
* this DataObject to match the RequestedRegion of the DataObject that |
| 235 |
|
* is passed in as a parameter. This method is used by |
| 236 |
|
* ProcessObject::GenerateOutputRequestedRegion() and by |
| 237 |
|
* ProcessObject::SetNthOutput(). In the former case, it used as an |
| 238 |
|
* abstract API so that a ProcessObject can copy a requested region |
| 239 |
|
* from one output to all its outputs without knowing the particular |
| 240 |
|
* subclass of DataObject. In the latter case, it used when a |
| 241 |
|
* ProcessObject has to create an output object to replace one of its |
| 242 |
|
* outputs (and needs to copy the former object's RequestedRegion). In |
| 243 |
|
* either case, it allows ProcessObject to perform these actions |
| 244 |
|
* without knowing the specifics about the particular subclass of |
| 245 |
|
* DataObject. For DataObjects that do not support Regions, this |
| 246 |
|
* method does nothing. |
| 247 |
|
* |
| 248 |
|
* void SetRequestedRegionToLargestPossibleRegion(): Sets the |
| 249 |
|
* RequestedRegion of this DataObject to match its |
| 250 |
|
* LargestPossibleRegion. This method is used to force a filter to |
| 251 |
|
* produce all of its output on the next call to Update(). For |
| 252 |
|
* DataObjects that do not support Regions, this method does nothing. |
| 253 |
|
* |
| 254 |
|
* |
| 255 |
|
* \sa ProcessObject |
| 256 |
|
* \sa ImageBase |
| 257 |
|
* \sa Mesh |
| 258 |
|
* \ingroup DataRepresentation |
| 259 |
|
* \ingroup ITKSystemObjects |
| 260 |
|
*/ |
| 261 |
|
class ITKCommon_EXPORT DataObject : public Object |
| 262 |
|
{ |
| 263 |
|
public: |
| 264 |
|
/** Standard class typedefs. */ |
| 265 |
|
typedef DataObject Self; |
| 266 |
TDA |
typedef Object Superclass; |
| 267 |
|
typedef SmartPointer<Self> Pointer; |
| 268 |
TDA |
typedef SmartPointer<const Self> ConstPointer; |
| 269 |
|
|
| 270 |
|
/** Run-time type information (and related methods). */ |
| 271 |
|
itkTypeMacro(DataObject,Object); |
| 272 |
|
|
| 273 |
|
/** Separate this data object from the pipeline. This routine disconnects |
| 274 |
|
* a data object from the upstream pipeline. Hence an Update() from |
| 275 |
|
* downstream will not propagate back past this data object. To completely |
| 276 |
|
* isolate this data object from the pipeline, the application must remove |
| 277 |
|
* this data object from any filters which it is connected as the input. */ |
| 278 |
|
void DisconnectPipeline(); |
| 279 |
|
|
| 280 |
|
/** Get the process object that generated this data object. |
| 281 |
|
* If there is no process object, then the data object has |
| 282 |
|
* been disconnected from the pipeline, or the data object |
| 283 |
|
* was created manually. (Note: we cannot use the GetObjectMacro() |
| 284 |
|
* defined in itkMacro because the mutual dependency of |
| 285 |
|
* DataObject and ProcessObject causes compile problems. Also, |
| 286 |
|
* a forward reference smart pointer is returned, not a smart pointer, |
| 287 |
|
* because of the circular dependency between the process and data object.) |
| 288 |
|
* |
| 289 |
|
* GetSource() returns a SmartPointerForwardReference and not a WeakPointer |
| 290 |
|
* because it is assumed the code calling GetSource() wants to hold a |
| 291 |
|
* long term reference to the source. */ |
| 292 |
|
SmartPointerForwardReference<ProcessObject> GetSource() const; |
| 293 |
|
|
| 294 |
|
/** Which of the source's outputs corresponds to this data object? */ |
| 295 |
|
unsigned int GetSourceOutputIndex() const; |
| 296 |
|
|
| 297 |
|
/** Restore the data object to its initial state. This means releasing |
| 298 |
|
* memory. */ |
| 299 |
|
virtual void Initialize(); |
| 300 |
|
|
| 301 |
|
/** Turn on/off a flag to control whether this object's data is released |
| 302 |
|
* after being used by a filter. */ |
| 303 |
|
void SetReleaseDataFlag(bool flag) |
| 304 |
|
{ |
| 305 |
IND |
******m_ReleaseDataFlag = flag; |
| 306 |
|
} |
| 307 |
|
itkGetConstReferenceMacro(ReleaseDataFlag,bool); |
| 308 |
|
itkBooleanMacro(ReleaseDataFlag); |
| 309 |
|
|
| 310 |
|
/** Turn on/off a flag to control whether every object releases its data |
| 311 |
|
* after being used by a filter. Being a global flag, it controls the |
| 312 |
|
* behavior of all DataObjects and ProcessObjects. */ |
| 313 |
|
static void SetGlobalReleaseDataFlag(const bool val); |
| 314 |
|
static bool GetGlobalReleaseDataFlag(); |
| 315 |
|
void GlobalReleaseDataFlagOn() |
| 316 |
|
{this->SetGlobalReleaseDataFlag(true);} |
| 317 |
|
void GlobalReleaseDataFlagOff() |
| 318 |
|
{this->SetGlobalReleaseDataFlag(false);} |
| 319 |
|
|
| 320 |
|
/** Release data back to system to conserve memory resource. Used during |
| 321 |
|
* pipeline execution. Releasing this data does not make |
| 322 |
|
* down-stream data invalid, so it does not modify the MTime of this data |
| 323 |
|
* object. */ |
| 324 |
|
void ReleaseData(); |
| 325 |
|
|
| 326 |
|
/** Return flag indicating whether data should be released after use |
| 327 |
|
* by a filter. */ |
| 328 |
|
bool ShouldIReleaseData() const; |
| 329 |
|
|
| 330 |
|
/** Get the flag indicating the data has been released. */ |
| 331 |
|
bool GetDataReleased() const |
| 332 |
|
{return m_DataReleased;} |
| 333 |
|
|
| 334 |
|
/** Provides opportunity for the data object to insure internal |
| 335 |
|
* consistency before access. Also causes owning source/filter (if |
| 336 |
|
* any) to update itself. The Update() method is composed of |
| 337 |
|
* UpdateOutputInformation(), PropagateRequestedRegion(), and |
| 338 |
|
* UpdateOutputData(). This method may call methods that throw an |
| 339 |
|
* InvalidRequestedRegionError exception. This exception will leave |
| 340 |
|
* the pipeline in an inconsistent state. You will need to call |
| 341 |
|
* ResetPipeline() on the last ProcessObject in your pipeline in |
| 342 |
|
* order to restore the pipeline to a state where you can call |
| 343 |
|
* Update() again. */ |
| 344 |
|
virtual void Update(); |
| 345 |
|
|
| 346 |
|
/** Update the information for this DataObject so that it can be used |
| 347 |
|
* as an output of a ProcessObject. This method is used in the pipeline |
| 348 |
|
* mechanism to propagate information and initialize the meta data |
| 349 |
|
* associated with a DataObject. Any implementation of this method in |
| 350 |
|
* a derived class is assumed to call its source's |
| 351 |
|
* ProcessObject::UpdateOutputInformation() which determines modified |
| 352 |
|
* times, LargestPossibleRegions, and any extra meta data like spacing, |
| 353 |
|
* origin, etc. Default implementation simply call's it's source's |
| 354 |
|
* UpdateOutputInformation(). */ |
| 355 |
|
virtual void UpdateOutputInformation(); |
| 356 |
|
|
| 357 |
|
/** Methods to update the pipeline. Called internally by the |
| 358 |
|
* pipeline mechanism. */ |
| 359 |
|
virtual void PropagateRequestedRegion() throw (InvalidRequestedRegionError); |
| 360 |
|
virtual void UpdateOutputData(); |
| 361 |
|
|
| 362 |
|
/** Reset the pipeline. If an exception is thrown during an Update(), |
| 363 |
|
* the pipeline may be in an inconsistent state. This method clears |
| 364 |
|
* the internal state of the pipeline so Update() can be called. */ |
| 365 |
|
virtual void ResetPipeline(); |
| 366 |
|
|
| 367 |
|
/** The maximum MTime of all upstream filters and data objects. |
| 368 |
|
* This does not include the MTime of this data object. */ |
| 369 |
|
void SetPipelineMTime(unsigned long time) |
| 370 |
|
{m_PipelineMTime = time;} |
| 371 |
|
itkGetConstReferenceMacro(PipelineMTime,unsigned long); |
| 372 |
|
|
| 373 |
|
/** MTime for the last time this DataObject was generated. */ |
| 374 |
|
virtual unsigned long GetUpdateMTime() const; |
| 375 |
|
|
| 376 |
|
/** Setup a DataObject to receive new data. This method is called |
| 377 |
|
* by the pipeline mechanism on each output of filter that needs |
| 378 |
|
* to execute. The default implementation is to return a DataObject |
| 379 |
|
* to its initial state. This may involve releasing previously |
| 380 |
|
* allocated bulk data. Subclasses of DataObject may want to |
| 381 |
|
* override this method and/or the Initialize() method if they |
| 382 |
|
* want a different default behavior (for instance a DataObject |
| 383 |
|
* might want finer control over its bulk data memory management). */ |
| 384 |
|
virtual void PrepareForNewData() |
| 385 |
|
{this->Initialize();} |
| 386 |
|
|
| 387 |
|
/** Inform the pipeline mechanism that data has been generated. This |
| 388 |
|
* method is called by ProcessObject::UpdateOutputData() once the |
| 389 |
|
* process object has finished generating its data. This essentially |
| 390 |
|
* marks the DataObject as being updated and ready for use. */ |
| 391 |
|
void DataHasBeenGenerated(); |
| 392 |
|
|
| 393 |
|
|
| 394 |
|
/** Set the RequestedRegion to the LargestPossibleRegion. This |
| 395 |
|
* forces a filter to produce all of the output in one execution |
| 396 |
|
* (i.e. not streaming) on the next call to Update(). */ |
| 397 |
|
virtual void SetRequestedRegionToLargestPossibleRegion() {}; |
| 398 |
|
|
| 399 |
|
/** Determine whether the RequestedRegion is outside of the |
| 400 |
|
* BufferedRegion. This method returns true if the RequestedRegion |
| 401 |
|
* is outside the BufferedRegion (true if at least one pixel is |
| 402 |
|
* outside). This is used by the pipeline mechanism to determine |
| 403 |
|
* whether a filter needs to re-execute in order to satisfy the |
| 404 |
|
* current request. If the current RequestedRegion is already |
| 405 |
|
* inside the BufferedRegion from the previous execution (and the |
| 406 |
|
* current filter is up to date), then a given filter does not need |
| 407 |
|
* to re-execute */ |
| 408 |
|
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() |
| 409 |
|
{ return false; } |
| 410 |
|
|
| 411 |
|
/** Verify that the RequestedRegion is within the LargestPossibleRegion. |
| 412 |
|
* |
| 413 |
|
* If the RequestedRegion is not within the LargestPossibleRegion, |
| 414 |
|
* then the filter cannot possibly satisfy the request. This method |
| 415 |
|
* returns true if the request can be satisfied (even if it will be |
| 416 |
|
* necessary to process the entire LargestPossibleRegion) and |
| 417 |
|
* returns false otherwise. This method is used by |
| 418 |
|
* PropagateRequestedRegion(). PropagateRequestedRegion() throws a |
| 419 |
|
* InvalidRequestedRegionError exception if the requested region is |
| 420 |
|
* not within the LargestPossibleRegion. Default implementation |
| 421 |
|
* simply returns true in order to support DataObjects that do not |
| 422 |
|
* need regions (for instance itk::EquivalencyTable). */ |
| 423 |
|
virtual bool VerifyRequestedRegion() { return true; }; |
| 424 |
|
|
| 425 |
|
/** Copy information from the specified data set. This method is |
| 426 |
|
* part of the pipeline execution model. By default, a ProcessObject |
| 427 |
|
* will copy meta-data from the first input to all of its |
| 428 |
|
* outputs. See ProcessObject::GenerateOutputInformation(). Each |
| 429 |
|
* subclass of DataObject is responsible for being able to copy |
| 430 |
WCM |
* whatever meta-data it needs from from another DataObject. |
| 431 |
|
* The default implementation of this method is empty. If a subclass |
| 432 |
|
* overrides this method, it should always call its superclass' |
| 433 |
|
* version. */ |
| 434 |
|
virtual void CopyInformation(const DataObject*) {}; |
| 435 |
|
|
| 436 |
|
/** Set the requested region from this data object to match the requested |
| 437 |
|
* region of the data object passed in as a parameter. For |
| 438 |
|
* DataObject's that do not support Regions, this method does |
| 439 |
|
* nothing. Subclasses of DataObject that do support Regions, |
| 440 |
|
* provide an alternative implementation. */ |
| 441 |
|
virtual void SetRequestedRegion(DataObject *) {}; |
| 442 |
|
|
| 443 |
|
/** Method for grafting the content of one data object into another one. |
| 444 |
|
* This method is intended to be overloaded by derived classes. Each one of |
| 445 |
|
* them should use dynamic_casting in order to verify that the grafted |
| 446 |
|
* object is actually of the same type as the class on which the Graft() |
| 447 |
|
* method was invoked. */ |
| 448 |
|
virtual void Graft( const DataObject *) {}; |
| 449 |
|
|
| 450 |
|
protected: |
| 451 |
|
DataObject(); |
| 452 |
|
~DataObject(); |
| 453 |
|
void PrintSelf(std::ostream& os, Indent indent) const; |
| 454 |
|
|
| 455 |
|
/** Propagate a call to ResetPipeline(). Called only from ProcessObject. */ |
| 456 |
|
virtual void PropagateResetPipeline(); |
| 457 |
|
|
| 458 |
|
private: |
| 459 |
|
DataObject(const Self&); //purposely not implemented |
| 460 |
|
void operator=(const Self&); //purposely not implemented |
| 461 |
|
|
| 462 |
|
/** Who generated this data? */ |
| 463 |
|
mutable WeakPointer<ProcessObject> m_Source; |
| 464 |
|
mutable unsigned int m_SourceOutputIndex; |
| 465 |
|
|
| 466 |
|
/** When was this data last generated? */ |
| 467 |
|
TimeStamp m_UpdateMTime; |
| 468 |
|
|
| 469 |
|
bool m_ReleaseDataFlag; //Data will release after use by a filter if on |
| 470 |
|
bool m_DataReleased; //Keep track of data release during pipeline execution |
| 471 |
|
|
| 472 |
|
/** The maximum MTime of all upstream filters and data objects. |
| 473 |
|
* This does not include the MTime of this data object. */ |
| 474 |
|
unsigned long m_PipelineMTime; |
| 475 |
|
|
| 476 |
|
/** Static member that controls global data release after use by filter. */ |
| 477 |
|
static bool m_GlobalReleaseDataFlag; |
| 478 |
|
|
| 479 |
|
/** Connect the specified process object to the data object. This |
| 480 |
|
* should only be called from a process object. The second parameter |
| 481 |
|
* indicates which of the source's outputs corresponds to this data |
| 482 |
|
* object. */ |
| 483 |
|
bool ConnectSource(ProcessObject *s, unsigned int idx) const; |
| 484 |
|
|
| 485 |
|
/** Disconnect the specified process object from the data |
| 486 |
|
* object. This should only be called from a process object. An |
| 487 |
|
* application should call DataObject::DisconnectPipeline() if it |
| 488 |
|
* wants to disconnect a data object from a pipeline. The second |
| 489 |
|
* parameter indicates which of the source's outputs corresponds to |
| 490 |
|
* this data object. If the specified source output index does not |
| 491 |
|
* match the index cached when the data object was connected to the |
| 492 |
|
* pipeline (see ConnectSource), then nothing is done. */ |
| 493 |
|
bool DisconnectSource(ProcessObject *s, unsigned int idx) const; |
| 494 |
|
|
| 495 |
|
/** Friends of DataObject */ |
| 496 |
|
friend class ProcessObject; |
| 497 |
|
friend class DataObjectError; |
| 498 |
IND |
**}; |
| 499 |
|
|
| 500 |
|
} // end namespace itk |
| 501 |
|
|
| 502 |
|
#endif |
| 503 |
|
|