diff --git a/Documentation/ITK5MigrationGuide.md b/Documentation/ITK5MigrationGuide.md index 708a3528dc2..4d416272133 100644 --- a/Documentation/ITK5MigrationGuide.md +++ b/Documentation/ITK5MigrationGuide.md @@ -334,6 +334,8 @@ ObjectSpace. For example, the `IsInside( point )` function has been replaced b `IsInsideInWorldSpace( point )` functions. As implied above, the changes to SpatialObject are extensive. They include the following: +* Replace use of ComputeMyBoundingBox() with Update(); +* Replace use of ComputeObjectToWorldTransform() with Update(); * Eliminate IndexToX transforms. SpatialObjects exist purely in physical space coordinates * Eliminate vnl TreeNode usage. SpatialObjects now track their transforms, parents, and children directly. * Eliminate AffineGeometryFrame @@ -350,7 +352,22 @@ As implied above, the changes to SpatialObject are extensive. They include the * `RemoveChild()` and `RemoveAllChildren()` fixed to remove all pointers to / from those children to / from the tree * Helper functions simplify the specification of `IsInsideInObjectSpace()`, `ValueAtInObjectSpace()`, and other computations that potentially traverse an SO tree. * Derived classes typically only need to implement `IsInsideInObjectSpace()` and `ComputeMyBoundingBoxInObjectSpace()` member functions. Logic for `ValueAtInObjectSpace()`, `IsInsideInWorldSpace()` and such is improved. -* `ImageMaskSpatialObject::GetAxisAlignedBoundingBoxRegion()` was removed. `GetMyBoundingBoxInObjectSpace()` or `GetMyBoundingBoxInWorldSpace()` should be used instead. If an region in IndexSpace is needed, then consider ITK's LabelMap classes and the [LabelImageToShapelLabelMapFilter](https://itk.org/Doxygen/html/classitk_1_1LabelImageToShapeLabelMapFilter.html). +* `ImageMaskSpatialObject::GetAxisAlignedBoundingBoxRegion()` was removed. `GetMyBoundingBoxInObjectSpace()` or `GetMyBoundingBoxInWorldSpace()` should be used instead. If a region in IndexSpace is needed, then consider ITK's LabelMap classes and the [LabelImageToShapelLabelMapFilter](https://itk.org/Doxygen/html/classitk_1_1LabelImageToShapeLabelMapFilter.html). +``` + //REPLACE typename FixedImageType::RegionType roiRegion = roiMask->GetAxisAlignedBoundingBoxRegion(); + using LabelType = unsigned char; + using ShapeLabelObjectType = itk::ShapeLabelObject< LabelType, Dimension >; + using LabelMapType = itk::LabelMap< ShapeLabelObjectType >; + + using LI2SLMFType = itk::LabelImageToShapeLabelMapFilter; + typename LI2SLMFType::Pointer i2l = LI2SLMFType::New(); + i2l->SetInput(roiImage); + i2l->Update(); + LabelMapType *labelMap = i2l->GetOutput(); + const typename LabelMapType::SizeValueType numLabelObjects = labelMap->GetNumberOfLabelObjects(); + ShapeLabelObjectType *labelObject = labelMap->GetNthLabelObject(1); + typename FixedImageType::RegionType roiRegion = labelObject->GetBoundingBox(); +``` Class changes ------------- diff --git a/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx b/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx index 5843171cb77..560d70aa38b 100644 --- a/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx +++ b/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx @@ -455,17 +455,17 @@ int main( int argc, char *argv[] ) offset[ 1 ] = 40.0; ellipse1->GetObjectToParentTransform()->SetOffset(offset); - ellipse1->ComputeObjectToWorldTransform(); + ellipse1->Update(); offset[ 0 ] = 40.0; offset[ 1 ] = 150.0; ellipse2->GetObjectToParentTransform()->SetOffset(offset); - ellipse2->ComputeObjectToWorldTransform(); + ellipse2->Update(); offset[ 0 ] = 150.0; offset[ 1 ] = 150.0; ellipse3->GetObjectToParentTransform()->SetOffset(offset); - ellipse3->ComputeObjectToWorldTransform(); + ellipse3->Update(); // Software Guide : EndCodeSnippet diff --git a/Examples/RegistrationITKv4/ModelToImageRegistration1.cxx b/Examples/RegistrationITKv4/ModelToImageRegistration1.cxx index c1c21569a75..ad56941f038 100644 --- a/Examples/RegistrationITKv4/ModelToImageRegistration1.cxx +++ b/Examples/RegistrationITKv4/ModelToImageRegistration1.cxx @@ -457,17 +457,17 @@ int main( int argc, char *argv[] ) offset[ 1 ] = 40.0; ellipse1->GetModifiableObjectToParentTransform()->SetOffset(offset); - ellipse1->ComputeObjectToWorldTransform(); + ellipse1->Update(); offset[ 0 ] = 40.0; offset[ 1 ] = 150.0; ellipse2->GetModifiableObjectToParentTransform()->SetOffset(offset); - ellipse2->ComputeObjectToWorldTransform(); + ellipse2->Update(); offset[ 0 ] = 150.0; offset[ 1 ] = 150.0; ellipse3->GetModifiableObjectToParentTransform()->SetOffset(offset); - ellipse3->ComputeObjectToWorldTransform(); + ellipse3->Update(); // Software Guide : EndCodeSnippet diff --git a/Examples/SpatialObjects/GroupSpatialObject.cxx b/Examples/SpatialObjects/GroupSpatialObject.cxx index 160f64f7f79..a052e7d9de5 100644 --- a/Examples/SpatialObjects/GroupSpatialObject.cxx +++ b/Examples/SpatialObjects/GroupSpatialObject.cxx @@ -74,7 +74,7 @@ int main( int , char *[] ) GroupType::VectorType offset; offset.Fill(10); myGroup->GetModifiableObjectToParentTransform()->SetOffset(offset); - myGroup->ComputeObjectToWorldTransform(); + myGroup->Update(); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex diff --git a/Examples/SpatialObjects/SpatialObjectTransforms.cxx b/Examples/SpatialObjects/SpatialObjectTransforms.cxx index 223d6b3be02..966c1c49af9 100644 --- a/Examples/SpatialObjects/SpatialObjectTransforms.cxx +++ b/Examples/SpatialObjects/SpatialObjectTransforms.cxx @@ -48,7 +48,7 @@ // Several member functions and variables are available to every SpatialObject // so that they can readily access the WorldSpace in which they exist: // -// * ComputeObjectToWorldTransform: Composes its ObjectToParentTransform +// * ProtectedComputeObjectToWorldTransform: Composes its ObjectToParentTransform // with its parent's cached ObjectToObjectToWorldTransform, to determine the // transform from the object's ObjectSpace to WorldSpace. This transform is // always invertible. This call will cause all children objects to also @@ -60,7 +60,7 @@ // function must be manually called by users. // // * GetObjectToWorldTransform: Returns the cached ObjectToWorldTransform. -// It is the user's responsibility to call ComputeObjectToWorldTransform when +// It is the user's responsibility to call ProtectedComputeObjectToWorldTransform when // necessary, prior to calling GetObjectToWorldTransform, otherwise the // returned transform may be "stale." // @@ -138,7 +138,7 @@ int main( int , char *[] ) // Software Guide : BeginLatex // // To realize the previous operations on the transformations, we should -// invoke the \code{ComputeObjectToWorldTransform()} that recomputes all +// invoke the \code{ProtectedComputeObjectToWorldTransform()} that recomputes all // dependent transformations. // // By calling this function on object1, it will also descend to its children, @@ -147,7 +147,7 @@ int main( int , char *[] ) // Software Guide : EndLatex // Software Guide : BeginCodeSnippet - object1->ComputeObjectToWorldTransform(); + object1->Update(); // Software Guide : EndCodeSnippet diff --git a/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.h b/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.h index 9cdabca3eaf..b71b0801066 100644 --- a/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.h @@ -74,9 +74,6 @@ class ITK_TEMPLATE_EXPORT ArrowSpatialObject: /** Get the length of the arrow */ itkGetConstReferenceMacro(LengthInObjectSpace, double); - /** Compute the Object bounding box */ - bool ComputeMyBoundingBox() const override; - /** Returns true if the point is inside the line, false otherwise. */ bool IsInsideInObjectSpace(const PointType & point, unsigned int depth=0, const std::string & name="") const override; @@ -87,6 +84,9 @@ class ITK_TEMPLATE_EXPORT ArrowSpatialObject: protected: + /** Compute the Object bounding box */ + void ProtectedComputeMyBoundingBox() const override; + ArrowSpatialObject(); ~ArrowSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.hxx index 5436702d266..3c21cceac65 100644 --- a/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkArrowSpatialObject.hxx @@ -43,9 +43,9 @@ ArrowSpatialObject< TDimension > /** Compute the bounding box */ template< unsigned int TDimension > -bool +void ArrowSpatialObject< TDimension > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing Rectangle bounding box"); @@ -53,8 +53,6 @@ ArrowSpatialObject< TDimension > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMinimum(pnt); this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum(pnt); - - return true; } /** Check if a given point is on the arrow */ diff --git a/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.h b/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.h index 3b612e9065d..04ca617664d 100644 --- a/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.h @@ -70,12 +70,13 @@ class ITK_TEMPLATE_EXPORT BoxSpatialObject: bool IsInsideInObjectSpace(const PointType & point, unsigned int depth = 0, const std::string & name = "" ) const override; +protected: + /** Get the boundaries of a specific object. This function needs to * be called every time one of the object's components is * changed. */ - bool ComputeMyBoundingBox() const override; + void ProtectedComputeMyBoundingBox() const override; -protected: BoxSpatialObject(); ~BoxSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.hxx index 04732d6616b..b4136f8ec04 100644 --- a/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkBoxSpatialObject.hxx @@ -32,7 +32,7 @@ BoxSpatialObject< TDimension > m_SizeInObjectSpace.Fill(1); m_PositionInObjectSpace.Fill(0); - this->ComputeMyBoundingBox(); + this->Update(); } /** Test whether a point is inside or outside the object */ @@ -62,9 +62,9 @@ BoxSpatialObject< TDimension > /** Compute the bounds of the box */ template< unsigned int TDimension > -bool +void BoxSpatialObject< TDimension > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing BoxSpatialObject bounding box"); @@ -80,8 +80,6 @@ BoxSpatialObject< TDimension > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum(pnt1); this->GetModifiableMyBoundingBoxInObjectSpace()->ConsiderPoint(pnt2); this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** InternalClone */ diff --git a/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.h b/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.h index 9c786680ae4..931879e7ec0 100644 --- a/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.h @@ -82,12 +82,12 @@ class ITK_TEMPLATE_EXPORT EllipseSpatialObject: bool IsInsideInObjectSpace(const PointType & point, unsigned int depth=0, const std::string & name="" ) const override; +protected: /** Get the boundaries of a specific object. This function needs to * be called every time one of the object's components is * changed. */ - bool ComputeMyBoundingBox() const override; + void ProtectedComputeMyBoundingBox() const override; -protected: EllipseSpatialObject(); ~EllipseSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.hxx index bbc088f44c0..3eae223e405 100644 --- a/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkEllipseSpatialObject.hxx @@ -100,9 +100,9 @@ EllipseSpatialObject< TDimension > /** Compute the bounds of the ellipse */ template< unsigned int TDimension > -bool +void EllipseSpatialObject< TDimension > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing ellipse bounding box"); @@ -118,8 +118,6 @@ EllipseSpatialObject< TDimension > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum(pnt1); this->GetModifiableMyBoundingBoxInObjectSpace()->ConsiderPoint(pnt2); this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** InternalClone */ diff --git a/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.h b/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.h index dfa8f7a923c..0935c3a77a8 100644 --- a/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.h @@ -88,10 +88,6 @@ class ITK_TEMPLATE_EXPORT GaussianSpatialObject: bool IsInsideInObjectSpace(const PointType & point, unsigned int depth = 0, const std::string & name = "") const override; - /** This function needs to be called every time one of the object's - * components is changed. */ - bool ComputeMyBoundingBox() const override; - /** Returns the value of the Gaussian at the given point. */ bool ValueAtInObjectSpace(const PointType & point, double & value, unsigned int depth = 0, const std::string & name = "") const override; @@ -101,6 +97,10 @@ class ITK_TEMPLATE_EXPORT GaussianSpatialObject: typename EllipseSpatialObject< TDimension >::Pointer GetEllipsoid() const; protected: + /** This function needs to be called every time one of the object's + * components is changed. */ + void ProtectedComputeMyBoundingBox() const override; + GaussianSpatialObject(); ~GaussianSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.hxx index a9d1af135ad..421057b53d0 100644 --- a/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkGaussianSpatialObject.hxx @@ -34,7 +34,7 @@ GaussianSpatialObject< TDimension > m_SigmaInObjectSpace = 1.0; m_Maximum = 1.0; - this->ComputeMyBoundingBox(); + this->Update(); } /** The z-score is the root mean square of the z-scores along @@ -109,9 +109,9 @@ GaussianSpatialObject< TDimension > /** Compute the bounds of the Gaussian (as determined by the * specified radius). */ template< unsigned int TDimension > -bool +void GaussianSpatialObject< TDimension > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing Guassian bounding box"); @@ -127,8 +127,6 @@ GaussianSpatialObject< TDimension > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum(pnt1); this->GetModifiableMyBoundingBoxInObjectSpace()->ConsiderPoint(pnt2); this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** Returns the value at one point. */ @@ -179,7 +177,7 @@ GaussianSpatialObject< TDimension > ellipse->GetModifiableObjectToWorldTransform()->SetParameters( this->GetObjectToWorldTransform()->GetParameters() ); - ellipse->ComputeMyBoundingBox(); + ellipse->Update(); return ellipse; } diff --git a/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.h b/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.h index 7687e1c9cce..43eb2575126 100644 --- a/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.h @@ -71,12 +71,12 @@ class ITK_TEMPLATE_EXPORT ImageMaskSpatialObject: bool IsInsideInObjectSpace(const PointType & point, unsigned int depth=0, const std::string & name="") const override; +protected: /** Get the boundaries of a specific object. This function needs to * be called every time one of the object's components is * changed. */ - bool ComputeMyBoundingBox() const override; + void ProtectedComputeMyBoundingBox() const override; -protected: ImageMaskSpatialObject(); ~ImageMaskSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx index 23a7f126683..a74a69499fb 100644 --- a/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx @@ -71,9 +71,9 @@ ImageMaskSpatialObject< TDimension, TPixel > } template< unsigned int TDimension, typename TPixel > -bool +void ImageMaskSpatialObject< TDimension, TPixel > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { using IteratorType = ImageRegionConstIteratorWithIndex< ImageType >; IteratorType it( this->GetImage(), @@ -131,16 +131,14 @@ ImageMaskSpatialObject< TDimension, TPixel > if( first ) { tmpPoint.Fill( - NumericTraits< typename BoundingBoxType::PointType::ValueType >:: - ZeroValue() ); + NumericTraits< typename BoundingBoxType::PointType::ValueType >::ZeroValue() ); this->GetModifiableMyBoundingBoxInObjectSpace()->SetMinimum( tmpPoint ); this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum( tmpPoint ); - return false; + // NOT AN EXCEPTION!!!, used to return false, but never checked + // itkExceptionMacro(<< "ImageMask bounding box computation failed.") } - - return true; } /** InternalClone */ diff --git a/Modules/Core/SpatialObjects/include/itkImageSpatialObject.h b/Modules/Core/SpatialObjects/include/itkImageSpatialObject.h index 8130b80e1c8..f741b890e53 100644 --- a/Modules/Core/SpatialObjects/include/itkImageSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkImageSpatialObject.h @@ -80,9 +80,6 @@ class ITK_TEMPLATE_EXPORT ImageSpatialObject: /** Get a pointer to the image currently attached to the object. */ const ImageType * GetImage() const; - /** Compute the boundaries of the image spatial object. */ - bool ComputeMyBoundingBox() const override; - /** Returns true if the point is inside, false otherwise. */ bool IsInsideInObjectSpace(const PointType & point, unsigned int depth=0, const std::string & name = "") const override; @@ -112,6 +109,8 @@ class ITK_TEMPLATE_EXPORT ImageSpatialObject: itkGetConstMacro(Interpolator, InterpolatorType *); protected: + /** Compute the boundaries of the image spatial object. */ + void ProtectedComputeMyBoundingBox() const override; ImageSpatialObject(); ~ImageSpatialObject() override; diff --git a/Modules/Core/SpatialObjects/include/itkImageSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkImageSpatialObject.hxx index 1928899a9e3..295906fa249 100644 --- a/Modules/Core/SpatialObjects/include/itkImageSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkImageSpatialObject.hxx @@ -129,9 +129,9 @@ ImageSpatialObject< TDimension, PixelType > /** Compute the bounds of the image */ template< unsigned int TDimension, typename PixelType > -bool +void ImageSpatialObject< TDimension, PixelType > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing ImageSpatialObject bounding box"); @@ -153,8 +153,6 @@ ImageSpatialObject< TDimension, PixelType > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum(pnt1); this->GetModifiableMyBoundingBoxInObjectSpace()->ConsiderPoint(pnt2); this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } diff --git a/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.h b/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.h index f9bc9f69f0d..51d8a47d8a7 100644 --- a/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.h @@ -74,9 +74,6 @@ class ITK_TEMPLATE_EXPORT MeshSpatialObject: bool IsInsideInObjectSpace(const PointType & point, unsigned int depth=0, const std::string & name="") const override; - /** Compute the boundaries of the iamge spatial object. */ - bool ComputeMyBoundingBox() const override; - /** Returns the latest modified time of the object and its component. */ ModifiedTimeType GetMTime() const override; @@ -96,6 +93,8 @@ class ITK_TEMPLATE_EXPORT MeshSpatialObject: itkGetConstMacro(IsInsidePrecisionInObjectSpace, double); protected: + /** Compute the boundaries of the iamge spatial object. */ + void ProtectedComputeMyBoundingBox() const override; MeshSpatialObject(); ~MeshSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.hxx index 315e12be167..2e127698870 100644 --- a/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkMeshSpatialObject.hxx @@ -94,9 +94,9 @@ MeshSpatialObject< TMesh > /** Compute the bounds of the object which is the same as the internal mesh */ template< typename TMesh > -bool +void MeshSpatialObject< TMesh > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { PointType pnt1; PointType pnt2; @@ -111,8 +111,6 @@ MeshSpatialObject< TMesh > this->GetModifiableMyBoundingBoxInObjectSpace()->SetMaximum( m_Mesh->GetBoundingBox()->GetMaximum() ); this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** Set the Mesh in the spatial object */ diff --git a/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.h b/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.h index bee2e82d12a..02fbeceb30d 100644 --- a/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.h @@ -102,10 +102,10 @@ class ITK_TEMPLATE_EXPORT PointBasedSpatialObject: bool IsInsideInObjectSpace(const PointType & worldPoint, unsigned int depth=0, const std::string & name="") const override; +protected: /** Compute the boundaries of the Blob. */ - bool ComputeMyBoundingBox() const override; + void ProtectedComputeMyBoundingBox() const override; -protected: PointBasedSpatialObject(); ~PointBasedSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.hxx index fdafde9e2ff..16c249833db 100644 --- a/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkPointBasedSpatialObject.hxx @@ -136,9 +136,9 @@ PointBasedSpatialObject< TDimension, TSpatialObjectPointType > /** Compute bounding box of just this object */ template< unsigned int TDimension, class TSpatialObjectPointType > -bool +void PointBasedSpatialObject< TDimension, TSpatialObjectPointType > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing blob bounding box"); @@ -147,7 +147,7 @@ PointBasedSpatialObject< TDimension, TSpatialObjectPointType > if ( it == end ) { - return false; + itkExceptionMacro(<< "Blob bounding box computation failed.") } PointType pt = ( *it ).GetPositionInObjectSpace(); @@ -162,8 +162,6 @@ PointBasedSpatialObject< TDimension, TSpatialObjectPointType > it++; } this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** Test if a world-coordinate point is inside of this object or its diff --git a/Modules/Core/SpatialObjects/include/itkSpatialObject.h b/Modules/Core/SpatialObjects/include/itkSpatialObject.h index a80de811633..8c0df436f1e 100644 --- a/Modules/Core/SpatialObjects/include/itkSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkSpatialObject.h @@ -175,11 +175,6 @@ class ITK_TEMPLATE_EXPORT SpatialObject: itkGetModifiableObjectMacro(ObjectToWorldTransform, TransformType); const TransformType * GetObjectToWorldTransformInverse() const; - /** Compute the World transform when the local transform is set - * This function should be called each time the local transform - * has been modified */ - void ComputeObjectToWorldTransform(); - /** Transforms points from the object-specific "physical" space * to the "physical" space of its parent object. */ void SetObjectToParentTransform( const TransformType *transform); @@ -192,7 +187,7 @@ class ITK_TEMPLATE_EXPORT SpatialObject: /**********************************************************************/ /* These are the three member functions that a subclass will typically * overwrite. - * * ComputeMyBoundingBox + * * ProtectedComputeMyBoundingBox (protected:) * * IsInsideInObjectSpace * * Update * Optionally, a subclass may also wish to overwrite @@ -201,9 +196,6 @@ class ITK_TEMPLATE_EXPORT SpatialObject: */ /**********************************************************************/ - /** Compute bounding box for the object in world space */ - virtual bool ComputeMyBoundingBox() const; - /** Returns true if a point is inside the object in world space. */ virtual bool IsInsideInObjectSpace(const PointType & point, unsigned int depth = 0, @@ -502,9 +494,22 @@ class ITK_TEMPLATE_EXPORT SpatialObject: bool Evaluate(const PointType & point) const { return this->IsInsideInWorldSpace(point); } + itkLegacyMacro( void ComputeObjectToWorldTransform() ) + { this->Update(); /* Update() should be used instead of ProtectedComputeObjectToWorldTransform() */ } + + itkLegacyMacro( void ComputeMyBoundingBox() ) + { this->Update(); /* Update() should be used instead of ProtectedComputeMyBoundingBox() */} protected: + /** Compute the World transform when the local transform is set + * This function should be called each time the local transform + * has been modified */ + void ProtectedComputeObjectToWorldTransform(); + + /** Compute bounding box for the object in world space */ + virtual void ProtectedComputeMyBoundingBox() const; + /** Constructor. */ SpatialObject(); diff --git a/Modules/Core/SpatialObjects/include/itkSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkSpatialObject.hxx index a39cb03c507..211a938448e 100644 --- a/Modules/Core/SpatialObjects/include/itkSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkSpatialObject.hxx @@ -538,7 +538,7 @@ SpatialObject< TDimension > m_ObjectToParentTransform->SetParameters( transform->GetParameters() ); - ComputeObjectToWorldTransform(); + ProtectedComputeObjectToWorldTransform(); } /** Set the local to global transformation */ @@ -559,7 +559,7 @@ SpatialObject< TDimension > template< unsigned int TDimension > void SpatialObject< TDimension > -::ComputeObjectToWorldTransform() +::ProtectedComputeObjectToWorldTransform() { m_ObjectToWorldTransform->SetFixedParameters( this->GetObjectToParentTransform()->GetFixedParameters() ); @@ -574,7 +574,7 @@ SpatialObject< TDimension > if( !m_ObjectToWorldTransform->GetInverse( m_ObjectToWorldTransformInverse ) ) { ExceptionObject e(__FILE__); - e.SetLocation( "SpatialObject::ComputeObjectToWorldTransform()" ); + e.SetLocation( "SpatialObject::ProtectedComputeObjectToWorldTransform()" ); e.SetDescription( "Transform must be invertible." ); throw e; } @@ -583,7 +583,7 @@ SpatialObject< TDimension > typename ChildrenListType::iterator it = m_ChildrenList.begin(); while ( it != m_ChildrenList.end() ) { - ( *it )->ComputeObjectToWorldTransform(); + (*it)->Update(); it++; } @@ -609,7 +609,7 @@ SpatialObject< TDimension > m_ObjectToWorldTransform->SetParameters( transform->GetParameters() ); ComputeObjectToParentTransform(); - ComputeObjectToWorldTransform(); + ProtectedComputeObjectToWorldTransform(); } /** Set the local to global transformation */ @@ -662,8 +662,7 @@ SpatialObject< TDimension > e.SetDescription("ObjectToParentTransform not invertible."); throw e; } - - ComputeObjectToWorldTransform(); + ProtectedComputeObjectToWorldTransform(); } /** Get the modification time */ @@ -692,9 +691,9 @@ SpatialObject< TDimension > } template< unsigned int TDimension > -bool +void SpatialObject< TDimension > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { typename BoundingBoxType::PointType pnt; pnt.Fill( NumericTraits< typename BoundingBoxType::PointType::ValueType >:: @@ -707,8 +706,6 @@ SpatialObject< TDimension > this->Modified(); } - - return false; } /** Get the bounds of the object */ @@ -1135,7 +1132,7 @@ SpatialObject< TDimension > { m_ParentId = -1; this->SetObjectToParentTransform( oldObjectWorldTransform ); - this->ComputeObjectToWorldTransform(); + this->Update(); } if( oldParent != nullptr ) @@ -1321,14 +1318,14 @@ SpatialObject< TDimension > { Superclass::Update(); - this->ComputeMyBoundingBox(); + this->ProtectedComputeMyBoundingBox(); m_FamilyBoundingBoxInObjectSpace->SetMinimum( m_MyBoundingBoxInObjectSpace->GetMinimum() ); m_FamilyBoundingBoxInObjectSpace->SetMaximum( m_MyBoundingBoxInObjectSpace->GetMaximum() ); - this->ComputeObjectToWorldTransform(); + this->ProtectedComputeObjectToWorldTransform(); } /** Return the type of the spatial object as a string diff --git a/Modules/Core/SpatialObjects/include/itkSpatialObjectToImageStatisticsCalculator.hxx b/Modules/Core/SpatialObjects/include/itkSpatialObjectToImageStatisticsCalculator.hxx index 5fdf5a4054c..5b09605433c 100644 --- a/Modules/Core/SpatialObjects/include/itkSpatialObjectToImageStatisticsCalculator.hxx +++ b/Modules/Core/SpatialObjects/include/itkSpatialObjectToImageStatisticsCalculator.hxx @@ -170,7 +170,7 @@ SpatialObjectToImageStatisticsCalculator< TInputImage, TInputSpatialObject, { // Get the bounding box m_SpatialObject->ComputeFamilyBoundingBox(SpatialObjectType::MaximumDepth); - m_SpatialObject->ComputeObjectToWorldTransform(); + m_SpatialObject->Update(); const typename SpatialObjectType::BoundingBoxType::BoundsArrayType bounds = m_SpatialObject->GetFamilyBoundingBoxInWorldSpace()->GetBounds(); diff --git a/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.h b/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.h index 9bb3e6d2847..a0148398526 100644 --- a/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.h +++ b/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.h @@ -99,14 +99,15 @@ class ITK_TEMPLATE_EXPORT TubeSpatialObject: * tube network in the scene */ itkGetConstMacro(Root, bool); - /** Compute the boundaries of the tube. */ - bool ComputeMyBoundingBox() const override; - /** Returns true if the point is inside the tube, false otherwise. */ bool IsInsideInObjectSpace(const PointType & point, unsigned int depth = 0, const std::string & name = "") const override; protected: + + /** Compute the boundaries of the tube. */ + void ProtectedComputeMyBoundingBox() const override; + TubeSpatialObject(); ~TubeSpatialObject() override = default; diff --git a/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.hxx b/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.hxx index acd8584205f..222b1dd454c 100644 --- a/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.hxx +++ b/Modules/Core/SpatialObjects/include/itkTubeSpatialObject.hxx @@ -81,9 +81,9 @@ TubeSpatialObject< TDimension, TTubePointType > /** Compute the bounds of the tube */ template< unsigned int TDimension, typename TTubePointType > -bool +void TubeSpatialObject< TDimension, TTubePointType > -::ComputeMyBoundingBox() const +::ProtectedComputeMyBoundingBox() const { itkDebugMacro("Computing tube bounding box"); @@ -92,7 +92,7 @@ TubeSpatialObject< TDimension, TTubePointType > if ( it == end ) { - return false; + itkExceptionMacro(<< "Tube bounding box computation failed.") } PointType pt = it->GetPositionInObjectSpace(); @@ -133,8 +133,6 @@ TubeSpatialObject< TDimension, TTubePointType > it++; } this->GetModifiableMyBoundingBoxInObjectSpace()->ComputeBoundingBox(); - - return true; } /** Test whether a point is inside or outside the object diff --git a/Modules/Core/SpatialObjects/test/itkArrowSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkArrowSpatialObjectTest.cxx index a3b8a06aa45..4e00642484d 100644 --- a/Modules/Core/SpatialObjects/test/itkArrowSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkArrowSpatialObjectTest.cxx @@ -102,7 +102,7 @@ int itkArrowSpatialObjectTest(int, char* []) std::cout<<"[PASSED]"<GetMyBoundingBoxInWorldSpace(); diff --git a/Modules/Core/SpatialObjects/test/itkBoxSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkBoxSpatialObjectTest.cxx index 1dddaa03a6d..b767d7d79a5 100644 --- a/Modules/Core/SpatialObjects/test/itkBoxSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkBoxSpatialObjectTest.cxx @@ -74,9 +74,9 @@ int itkBoxSpatialObjectTest( int argc, char *argv[] ) box2->SetPositionInObjectSpace( offset2 ); box2->Update(); - scene->ComputeObjectToWorldTransform(); + scene->Update(); - std::cout <<"Test ComputeMyBoundingBox: " << std::endl; + std::cout <<"Test Update(): " << std::endl; std::cout << box1->GetMyBoundingBoxInWorldSpace()->GetBounds() << std::endl; std::cout << box2->GetMyBoundingBoxInWorldSpace()->GetBounds() << std::endl; const BoxType::BoundingBoxType * boundingBox diff --git a/Modules/Core/SpatialObjects/test/itkContourSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkContourSpatialObjectTest.cxx index a4275e13fe5..c3fba37ec04 100644 --- a/Modules/Core/SpatialObjects/test/itkContourSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkContourSpatialObjectTest.cxx @@ -62,11 +62,6 @@ int itkContourSpatialObjectTest(int, char* []) SpatialObjectType::Pointer contour = SpatialObjectType::New(); - // - // Test ComputeMyBoundingBox before data added - // - contour->Update(); - // // Test Control Points (SetControlPoints, GetControlPoints, // GetNumberOfControlPoints, GetControlPoint) @@ -79,6 +74,11 @@ int itkContourSpatialObjectTest(int, char* []) contour->SetControlPoints(controlPointList); + // + // Test Update() before data added + // + contour->Update(); + // check number of points if (contour->GetNumberOfControlPoints() != 4) { @@ -261,14 +261,18 @@ int itkContourSpatialObjectTest(int, char* []) // - // Test ComputeLocalBoundingBox + // Test Update() // - if (!contour->ComputeMyBoundingBox()) + try + { + contour->Update(); + } + catch ( itk::ExceptionObject excp ) { - std::cout << "[FAILED] faild bounding box computation" << std::endl; + std::cout << "[FAILED] failed Update()" << std::endl; return EXIT_FAILURE; } - std::cout << "[PASSED] ComputeLocalBoundingBox" << std::endl; + std::cout << "[PASSED] Update()" << std::endl; // diff --git a/Modules/Core/SpatialObjects/test/itkEllipseSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkEllipseSpatialObjectTest.cxx index 8615c961126..48d6d450a92 100644 --- a/Modules/Core/SpatialObjects/test/itkEllipseSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkEllipseSpatialObjectTest.cxx @@ -127,17 +127,19 @@ int itkEllipseSpatialObjectTest(int, char* []) } std::cout<<"[PASSED]"<Update(); myEllipse->ComputeFamilyBoundingBox( EllipseType::MaximumDepth ); - myEllipse->ComputeObjectToWorldTransform(); const EllipseType::BoundingBoxType * boundingBox = myEllipse->GetFamilyBoundingBoxInWorldSpace(); std::cout << "Bounds = " << boundingBox->GetBounds() << std::endl; - std::cout << "ComputeMyBoundingBox: "; + std::cout << "Update(): "; for(unsigned int i=0;i<3;i++) { - if( itk::Math::NotAlmostEquals(boundingBox->GetBounds()[2*i], 7 ) - || itk::Math::NotAlmostEquals(boundingBox->GetBounds()[2*i+1], 16 ) + const EllipseType::BoundingBoxType::BoundsArrayType bounds = boundingBox->GetBounds(); + if( itk::Math::NotAlmostEquals(bounds[2*i], 7 ) + || itk::Math::NotAlmostEquals(bounds[2*i+1], 16 ) // this is 13 if Update() and ComputeFamilyBoundingBox are reversed order. ) { std::cout<<"[FAILED]"<ComputeObjectToWorldTransform(); + myGaussian->Update(); std::cout << "SetOffset" << std::endl; + const GaussianType::TransformType::OffsetType::ValueType offset10 = 10.0; GaussianType::TransformType::OffsetType offset; - offset.Fill(10); + offset.Fill(offset10); myGaussian->GetModifiableObjectToWorldTransform()->SetOffset(offset); myGaussian->ComputeObjectToParentTransform(); // Once you change an object's transform, you must call ComputeObjectToWorld // for it and its children to update their cached transforms - myGaussian->ComputeObjectToWorldTransform(); + myGaussian->Update(); std::cout << "SetOffset2" << std::endl; + const GaussianType::TransformType::OffsetType::ValueType offset15 = 15.0; GaussianType::TransformType::OffsetType offset2; - offset2.Fill(15); + offset2.Fill(offset15); myGaussian2->GetModifiableObjectToWorldTransform()->SetOffset(offset2); myGaussian2->ComputeObjectToParentTransform(); // Once you change an object's transform, you must call ComputeObjectToWorld // for it and its children to update their cached transforms - myGaussian2->ComputeObjectToWorldTransform(); + myGaussian2->Update(); GaussianType::TransformType::OffsetType offset3; offset3 = myGaussian2->GetObjectToParentTransform()->GetOffset(); - if( itk::Math::NotAlmostEquals(offset3[0], 5.0) - || itk::Math::NotAlmostEquals(offset3[1], 5.0) - || itk::Math::NotAlmostEquals(offset3[2], 5.0) - || itk::Math::NotAlmostEquals(offset3[3], 5.0) + if( itk::Math::NotAlmostEquals(offset3[0], offset15-offset10) + || itk::Math::NotAlmostEquals(offset3[1], offset15-offset10) + || itk::Math::NotAlmostEquals(offset3[2], offset15-offset10) + || itk::Math::NotAlmostEquals(offset3[3], offset15-offset10) ) { - std::cout<<"[FAILED]"<SetImage(image); maskSO->Update(); - maskSO->ComputeObjectToWorldTransform(); - Iterator itr( image, region ); itr.GoToBegin(); diff --git a/Modules/Core/SpatialObjects/test/itkImageMaskSpatialObjectTest2.cxx b/Modules/Core/SpatialObjects/test/itkImageMaskSpatialObjectTest2.cxx index f709eb7ad3a..7dabee5a30c 100644 --- a/Modules/Core/SpatialObjects/test/itkImageMaskSpatialObjectTest2.cxx +++ b/Modules/Core/SpatialObjects/test/itkImageMaskSpatialObjectTest2.cxx @@ -112,8 +112,6 @@ int itkImageMaskSpatialObjectTest2(int, char* []) maskSO->SetImage(image); maskSO->Update(); - maskSO->ComputeObjectToWorldTransform(); - Iterator itr( image, region ); itr.GoToBegin(); @@ -255,8 +253,6 @@ int itkImageMaskSpatialObjectTest2(int, char* []) maskSO->SetImage(image); maskSO->Update(); - maskSO->ComputeObjectToWorldTransform(); - Iterator2 itr( image, region ); itr.GoToBegin(); diff --git a/Modules/Core/SpatialObjects/test/itkImageSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkImageSpatialObjectTest.cxx index af59c1f7089..5e667eb7701 100644 --- a/Modules/Core/SpatialObjects/test/itkImageSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkImageSpatialObjectTest.cxx @@ -76,7 +76,7 @@ int itkImageSpatialObjectTest(int, char* []) offset.Fill(5); imageSO->GetModifiableObjectToParentTransform()->SetOffset(offset); - imageSO->ComputeObjectToWorldTransform(); + imageSO->Update(); PointType q; PointType r; @@ -86,7 +86,6 @@ int itkImageSpatialObjectTest(int, char* []) r.Fill(9); q.Fill(15); - imageSO->ComputeMyBoundingBox(); std::cout << "Bounding Box = " << imageSO->GetMyBoundingBoxInWorldSpace()->GetBounds() << std::endl; std::cout<<"IsInside()..."; diff --git a/Modules/Core/SpatialObjects/test/itkLineSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkLineSpatialObjectTest.cxx index 6fb039cc052..44b111342d9 100644 --- a/Modules/Core/SpatialObjects/test/itkLineSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkLineSpatialObjectTest.cxx @@ -62,7 +62,7 @@ int itkLineSpatialObjectTest(int, char* []) Line->GetProperty().SetName("Line 1"); Line->SetId(1); Line->SetPoints(list); - Line->ComputeMyBoundingBox(); + Line->Update(); // Number of points std::cout << "Testing Consistency: " << std::endl; diff --git a/Modules/Core/SpatialObjects/test/itkSpatialObjectToImageFilterTest.cxx b/Modules/Core/SpatialObjects/test/itkSpatialObjectToImageFilterTest.cxx index 272e2977be1..1cc5cbc9f9f 100644 --- a/Modules/Core/SpatialObjects/test/itkSpatialObjectToImageFilterTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkSpatialObjectToImageFilterTest.cxx @@ -42,7 +42,7 @@ int itkSpatialObjectToImageFilterTest(int, char* [] ) EllipseType::TransformType::OffsetType offset; offset.Fill(25); ellipse->GetModifiableObjectToParentTransform()->SetOffset(offset); - ellipse->ComputeObjectToWorldTransform(); + ellipse->Update(); using ImageType = itk::Image; diff --git a/Modules/Core/SpatialObjects/test/itkTubeSpatialObjectTest.cxx b/Modules/Core/SpatialObjects/test/itkTubeSpatialObjectTest.cxx index ee7adda190a..eeb3e7e975f 100644 --- a/Modules/Core/SpatialObjects/test/itkTubeSpatialObjectTest.cxx +++ b/Modules/Core/SpatialObjects/test/itkTubeSpatialObjectTest.cxx @@ -60,7 +60,6 @@ int itkTubeSpatialObjectTest(int, char * [] ) TubeType::TransformType::OffsetType offset; offset.Fill(10); tube1->GetModifiableObjectToParentTransform()->SetOffset(offset); - tube1->ComputeObjectToWorldTransform(); for( unsigned int i=0; i<10; i++) { @@ -77,7 +76,7 @@ int itkTubeSpatialObjectTest(int, char * [] ) p.Print(std::cout); tube1->SetPoints(list); - tube1->ComputeMyBoundingBox(); + tube1->Update(); in.Fill(15); out.Fill(5); @@ -144,13 +143,13 @@ int itkTubeSpatialObjectTest(int, char * [] ) tube2->GetProperty().SetName("Tube 2"); tube2->SetId(2); tube2->SetPoints(list); - tube2->ComputeMyBoundingBox(); + tube2->Update(); TubePointer tube3 = TubeType::New(); tube3->GetProperty().SetName("Tube 3"); tube3->SetId(3); tube3->SetPoints(list); - tube3->ComputeMyBoundingBox(); + tube3->Update(); GroupPointer tubeNet1 = GroupType::New(); tubeNet1->GetProperty().SetName("tube network 1"); @@ -284,7 +283,7 @@ int itkTubeSpatialObjectTest(int, char * [] ) std::cout<<"[PASSED]"<ComputeMyBoundingBox(); + tubeNet1->Update(); std::cout<<"HasParent()..."; if( !tube2->HasParent() ) @@ -299,17 +298,17 @@ int itkTubeSpatialObjectTest(int, char * [] ) translation.Fill(10); tubeNet1->GetModifiableObjectToParentTransform()->Translate(translation,false); - tubeNet1->ComputeObjectToWorldTransform(); + tubeNet1->Update(); axis.Fill(0); axis[1] = 1; angle = itk::Math::pi_over_2; tube2->GetModifiableObjectToParentTransform()->Rotate3D(axis,angle); - tube2->ComputeObjectToWorldTransform(); + tube2->Update(); angle = -itk::Math::pi_over_2; tube3->GetModifiableObjectToParentTransform()->Rotate3D(axis,angle); - tube3->ComputeObjectToWorldTransform(); + tube3->Update(); in.Fill(25); out.Fill(15); @@ -477,8 +476,12 @@ int itkTubeSpatialObjectTest(int, char * [] ) std::cout << "Testing PointBasedSO: "; using PointBasedType = itk::PointBasedSpatialObject<3>; PointBasedType::Pointer pBSO = PointBasedType::New(); + PointBasedType::SpatialObjectPointType pnt; + PointBasedType::SpatialObjectPointListType ll; + ll.push_back(pnt); + pBSO->SetPoints(ll); pBSO->GetPoint(0); - pBSO->ComputeMyBoundingBox(); + pBSO->Update(); std::cout << "[PASSED]" << std::endl; std::cout << "[DONE]" << std::endl; diff --git a/Modules/Filtering/ImageStatistics/test/CMakeLists.txt b/Modules/Filtering/ImageStatistics/test/CMakeLists.txt index 98b323467de..cda8f2bf8a8 100644 --- a/Modules/Filtering/ImageStatistics/test/CMakeLists.txt +++ b/Modules/Filtering/ImageStatistics/test/CMakeLists.txt @@ -51,8 +51,10 @@ itk_add_test(NAME itkStandardDeviationProjectionImageFilterTest --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/HeadMRVolumeStandardDeviationProjection.tif} ${ITK_TEST_OUTPUT_DIR}/HeadMRVolumeStandardDeviationProjection.tif itkStandardDeviationProjectionImageFilterTest DATA{${ITK_DATA_ROOT}/Input/HeadMRVolume.mhd,HeadMRVolume.raw} ${ITK_TEST_OUTPUT_DIR}/HeadMRVolumeStandardDeviationProjection.tif) -itk_add_test(NAME itkImageMomentsTest - COMMAND ITKImageStatisticsTestDriver itkImageMomentsTest) +itk_add_test(NAME itkImageMomentsNoMaskTest + COMMAND ITKImageStatisticsTestDriver itkImageMomentsTest nomask) +itk_add_test(NAME itkImageMomentsWithMaskTest + COMMAND ITKImageStatisticsTestDriver itkImageMomentsTest mask) itk_add_test(NAME itkImageToHistogramFilterTest COMMAND ITKImageStatisticsTestDriver itkImageToHistogramFilterTest) itk_add_test(NAME itkImageToHistogramFilterTest2 diff --git a/Modules/Filtering/ImageStatistics/test/itkImageMomentsTest.cxx b/Modules/Filtering/ImageStatistics/test/itkImageMomentsTest.cxx index cd32c20f605..78aad338b01 100644 --- a/Modules/Filtering/ImageStatistics/test/itkImageMomentsTest.cxx +++ b/Modules/Filtering/ImageStatistics/test/itkImageMomentsTest.cxx @@ -18,6 +18,7 @@ #include "itkImageMomentsCalculator.h" +#include "itkImageMaskSpatialObject.h" using PixelType = unsigned short; using VectorType = itk::Vector; @@ -28,8 +29,15 @@ using AffineTransformType = CalculatorType::AffineTransformType; int -itkImageMomentsTest( int itkNotUsed(argc), char * itkNotUsed(argv) [] ) +itkImageMomentsTest( int argc, char * argv [] ) { + if(argc != 2 ) + { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return EXIT_FAILURE; + } + const std::string maskCondition{argv[1]}; + /* Define acceptable (absolute) error in computed results. All the calculations are done in double and are well-conditioned, so we should be able to get within a few epsilon of the right @@ -39,7 +47,7 @@ itkImageMomentsTest( int itkNotUsed(argc), char * itkNotUsed(argv) [] ) reasonably close but might deserve investigation some day when all the worse problems have been fixed. */ // double maxerr = 1.9e-15; - double maxerr = 5.0e-15; + constexpr double maxerr = 5.0e-15; /* Define the image size and physical coordinates */ itk::Size<3> size = {{20, 40, 80}}; @@ -107,6 +115,32 @@ itkImageMomentsTest( int itkNotUsed(argc), char * itkNotUsed(argv) [] ) /* Compute the moments */ CalculatorType::Pointer moments = CalculatorType::New(); moments->SetImage( image ); + if( maskCondition == std::string("mask") ) + { + //Test the mask spatial object for masked ImageMomentsTest + // Make a mask that covers the entire image space + using MaskImageType = itk::Image; + MaskImageType::Pointer maskimg = MaskImageType::New(); + maskimg->CopyInformation(image); + maskimg->SetRegions(image->GetLargestPossibleRegion()); + maskimg->Allocate(); + // Masking the entire image should not change the computation results. + maskimg->FillBuffer( itk::NumericTraits::OneValue() ); + + // convert mask image to mask + using LFFImageMaskSpatialObjectType = typename itk::ImageMaskSpatialObject; + typename LFFImageMaskSpatialObjectType::Pointer mask = LFFImageMaskSpatialObjectType::New(); + mask->SetImage(maskimg.GetPointer()); + mask->Update(); + //Purposefully use the base class type + typename itk::SpatialObject::Pointer test = + dynamic_cast *>( mask.GetPointer() ); + if( test.IsNull() ) + { + itkGenericExceptionMacro(<< "Failed conversion to SpatialObject base class."); + } + moments->SetSpatialObjectMask( test.GetPointer() ); + } moments->Compute(); /* Printout info */ diff --git a/Modules/Registration/Common/test/itkPointSetToSpatialObjectDemonsRegistrationTest.cxx b/Modules/Registration/Common/test/itkPointSetToSpatialObjectDemonsRegistrationTest.cxx index a715f923155..0675230dea8 100644 --- a/Modules/Registration/Common/test/itkPointSetToSpatialObjectDemonsRegistrationTest.cxx +++ b/Modules/Registration/Common/test/itkPointSetToSpatialObjectDemonsRegistrationTest.cxx @@ -40,7 +40,7 @@ int itkPointSetToSpatialObjectDemonsRegistrationTest(int, char* [] ) offset[1] = 50; offset[2] = 50; - ellipse->ComputeObjectToWorldTransform(); + ellipse->Update(); using PointSetType = itk::Mesh< float, Dimension >;