From 20ce8fb373b3fd91ca870410225d8f863e52a1a6 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 21 May 2024 18:39:02 +0200 Subject: [PATCH 1/3] ENH: Add protected helper function, `ProcessObject::MakeRequiredOutputs` Meant to be used in constructors of derived classes that would otherwise directly call `MakeOutput` for each of their required outputs. --- Modules/Core/Common/include/itkProcessObject.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Modules/Core/Common/include/itkProcessObject.h b/Modules/Core/Common/include/itkProcessObject.h index 80f6630b2f9..d1c5e481902 100644 --- a/Modules/Core/Common/include/itkProcessObject.h +++ b/Modules/Core/Common/include/itkProcessObject.h @@ -926,6 +926,20 @@ class ITKCommon_EXPORT ProcessObject : public Object return static_cast(temp); }; + + /** Sets the required number of outputs, and creates each of them by MakeOutput. */ + template + static void + MakeRequiredOutputs(TSourceObject & sourceObject, const DataObjectPointerArraySizeType numberOfRequiredOutputs) + { + sourceObject.ProcessObject::SetNumberOfRequiredOutputs(numberOfRequiredOutputs); + + for (unsigned int i{}; i < numberOfRequiredOutputs; ++i) + { + sourceObject.ProcessObject::SetNthOutput(i, sourceObject.TSourceObject::MakeOutput(i)); + } + } + /** These ivars are made protected so filters like itkStreamingImageFilter * can access them directly. */ From f249ac5e2895f84ad6967136a20efd40444c8403 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Wed, 22 May 2024 00:15:39 +0200 Subject: [PATCH 2/3] ENH: Declare `MakeOutput` member function of three filters public Paved the way for those filters to use `ProcessObject::MakeRequiredOutputs`. `MakeOutput` member functions are usually declared public, rather than protected. --- .../Statistics/include/itkCovarianceSampleFilter.h | 12 ++++++------ .../itkStandardDeviationPerComponentSampleFilter.h | 12 ++++++------ .../Common/include/itkBlockMatchingImageFilter.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.h b/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.h index 80fdbdc14d4..9bfdb691d39 100644 --- a/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.h +++ b/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.h @@ -121,12 +121,6 @@ class ITK_TEMPLATE_EXPORT CovarianceSampleFilter : public ProcessObject MeasurementVectorSizeType GetMeasurementVectorSize() const; -protected: - CovarianceSampleFilter(); - ~CovarianceSampleFilter() override = default; - void - PrintSelf(std::ostream & os, Indent indent) const override; - /** DataObject pointer */ using DataObjectPointer = DataObject::Pointer; @@ -135,6 +129,12 @@ class ITK_TEMPLATE_EXPORT CovarianceSampleFilter : public ProcessObject DataObjectPointer MakeOutput(DataObjectPointerArraySizeType index) override; +protected: + CovarianceSampleFilter(); + ~CovarianceSampleFilter() override = default; + void + PrintSelf(std::ostream & os, Indent indent) const override; + void GenerateData() override; }; // end of class diff --git a/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.h b/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.h index 47ffb7a5641..54bb9f6e7b7 100644 --- a/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.h +++ b/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.h @@ -98,12 +98,6 @@ class ITK_TEMPLATE_EXPORT StandardDeviationPerComponentSampleFilter : public Pro const MeasurementVectorRealDecoratedType * GetMeanPerComponentOutput() const; -protected: - StandardDeviationPerComponentSampleFilter(); - ~StandardDeviationPerComponentSampleFilter() override = default; - void - PrintSelf(std::ostream & os, Indent indent) const override; - /** DataObject pointer */ using DataObjectPointer = DataObject::Pointer; @@ -112,6 +106,12 @@ class ITK_TEMPLATE_EXPORT StandardDeviationPerComponentSampleFilter : public Pro DataObjectPointer MakeOutput(DataObjectPointerArraySizeType index) override; +protected: + StandardDeviationPerComponentSampleFilter(); + ~StandardDeviationPerComponentSampleFilter() override = default; + void + PrintSelf(std::ostream & os, Indent indent) const override; + void GenerateData() override; diff --git a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.h b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.h index d9426338dae..f8d145d2f12 100644 --- a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.h +++ b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.h @@ -160,12 +160,12 @@ class ITK_TEMPLATE_EXPORT BlockMatchingImageFilter : public MeshToMeshFilter(this->ProcessObject::GetOutput(1)); } -protected: /** MakeOutput is provided for handling multiple outputs */ using Superclass::MakeOutput; DataObject::Pointer MakeOutput(ProcessObject::DataObjectPointerArraySizeType idx) override; +protected: /** We need to create our own GenerateOutputInformation because the * default version from ProcessObject result in a dynamic_cast of the input * pointer to the output pointer type in PointSet::CopyInformation. This does From ddbed4adfe208e276e61b6ecbbe795c3307d1b3a Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 21 May 2024 15:45:29 +0200 Subject: [PATCH 3/3] STYLE: Simplify code by calling `ProcessObject::MakeRequiredOutputs` Reduced amount of duplicate code in constructors that "make" all of their required outputs. --- .../include/itkDanielssonDistanceMapImageFilter.hxx | 12 ++---------- .../itkSignedDanielssonDistanceMapImageFilter.hxx | 12 ++---------- .../Eigen/include/itkEigenAnalysis2DImageFilter.hxx | 5 +---- .../Statistics/include/itkCovarianceSampleFilter.hxx | 5 +---- .../itkStandardDeviationPerComponentSampleFilter.hxx | 5 +---- .../Common/include/itkBlockMatchingImageFilter.hxx | 9 ++------- .../Watersheds/include/itkWatershedSegmenter.hxx | 10 +++------- 7 files changed, 12 insertions(+), 46 deletions(-) diff --git a/Modules/Filtering/DistanceMap/include/itkDanielssonDistanceMapImageFilter.hxx b/Modules/Filtering/DistanceMap/include/itkDanielssonDistanceMapImageFilter.hxx index 9b7f4e8d46d..ea4615aa69f 100644 --- a/Modules/Filtering/DistanceMap/include/itkDanielssonDistanceMapImageFilter.hxx +++ b/Modules/Filtering/DistanceMap/include/itkDanielssonDistanceMapImageFilter.hxx @@ -30,16 +30,8 @@ namespace itk template DanielssonDistanceMapImageFilter::DanielssonDistanceMapImageFilter() { - this->SetNumberOfRequiredOutputs(3); - - // distance map - this->SetNthOutput(0, this->MakeOutput(0)); - - // voronoi map - this->SetNthOutput(1, this->MakeOutput(1)); - - // distance vectors - this->SetNthOutput(2, this->MakeOutput(2)); + // Make the outputs (distance map, voronoi map, distance vectors). + ProcessObject::MakeRequiredOutputs(*this, 3); m_SquaredDistance = false; m_InputIsBinary = false; diff --git a/Modules/Filtering/DistanceMap/include/itkSignedDanielssonDistanceMapImageFilter.hxx b/Modules/Filtering/DistanceMap/include/itkSignedDanielssonDistanceMapImageFilter.hxx index 54fa81308b8..8061e30f59f 100644 --- a/Modules/Filtering/DistanceMap/include/itkSignedDanielssonDistanceMapImageFilter.hxx +++ b/Modules/Filtering/DistanceMap/include/itkSignedDanielssonDistanceMapImageFilter.hxx @@ -32,16 +32,8 @@ template SignedDanielssonDistanceMapImageFilter:: SignedDanielssonDistanceMapImageFilter() { - this->SetNumberOfRequiredOutputs(3); - - // distance map - this->SetNthOutput(0, static_cast(this->MakeOutput(0).GetPointer())); - - // voronoi map - this->SetNthOutput(1, static_cast(this->MakeOutput(1).GetPointer())); - - // distance vectors - this->SetNthOutput(2, static_cast(this->MakeOutput(2).GetPointer())); + // Make the outputs (distance map, voronoi map, distance vectors). + ProcessObject::MakeRequiredOutputs(*this, 3); // Default values this->m_SquaredDistance = false; // Should we remove this ? diff --git a/Modules/Numerics/Eigen/include/itkEigenAnalysis2DImageFilter.hxx b/Modules/Numerics/Eigen/include/itkEigenAnalysis2DImageFilter.hxx index 024b05c59ac..d24b1978914 100644 --- a/Modules/Numerics/Eigen/include/itkEigenAnalysis2DImageFilter.hxx +++ b/Modules/Numerics/Eigen/include/itkEigenAnalysis2DImageFilter.hxx @@ -28,10 +28,7 @@ template ::EigenAnalysis2DImageFilter() { this->SetNumberOfRequiredInputs(3); - this->SetNumberOfRequiredOutputs(3); - this->SetNthOutput(0, this->MakeOutput(0)); - this->SetNthOutput(1, this->MakeOutput(1)); - this->SetNthOutput(2, this->MakeOutput(2)); + ProcessObject::MakeRequiredOutputs(*this, 3); static_assert(EigenVectorType::Dimension == 2, "Error: PixelType of EigenVector Image must have exactly 2 elements!"); } diff --git a/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.hxx b/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.hxx index bc97c35d6d0..18673fffef0 100644 --- a/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.hxx +++ b/Modules/Numerics/Statistics/include/itkCovarianceSampleFilter.hxx @@ -28,10 +28,7 @@ template CovarianceSampleFilter::CovarianceSampleFilter() { this->ProcessObject::SetNumberOfRequiredInputs(1); - this->ProcessObject::SetNumberOfRequiredOutputs(2); - - this->ProcessObject::SetNthOutput(0, this->MakeOutput(0)); - this->ProcessObject::SetNthOutput(1, this->MakeOutput(1)); + ProcessObject::MakeRequiredOutputs(*this, 2); } template diff --git a/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.hxx b/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.hxx index 5c5fa9f1a50..0acbde85b42 100644 --- a/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.hxx +++ b/Modules/Numerics/Statistics/include/itkStandardDeviationPerComponentSampleFilter.hxx @@ -29,10 +29,7 @@ template StandardDeviationPerComponentSampleFilter::StandardDeviationPerComponentSampleFilter() { this->ProcessObject::SetNumberOfRequiredInputs(1); - this->ProcessObject::SetNumberOfRequiredOutputs(2); - - this->ProcessObject::SetNthOutput(0, this->MakeOutput(0)); - this->ProcessObject::SetNthOutput(1, this->MakeOutput(1)); + ProcessObject::MakeRequiredOutputs(*this, 2); } template diff --git a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx index d4320bf1989..e700bd1cec3 100644 --- a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx +++ b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx @@ -39,13 +39,8 @@ BlockMatchingImageFilterm_BlockRadius.Fill(2); this->m_SearchRadius.Fill(3); - // make the outputs - this->ProcessObject::SetNumberOfRequiredOutputs(2); - typename DisplacementsType::Pointer displacements = - static_cast(this->MakeOutput(0).GetPointer()); - this->SetNthOutput(0, displacements.GetPointer()); - typename SimilaritiesType::Pointer similarities = static_cast(this->MakeOutput(1).GetPointer()); - this->SetNthOutput(1, similarities.GetPointer()); + // Make the outputs (Displacements, Similarities). + ProcessObject::MakeRequiredOutputs(*this, 2); // all inputs are required this->SetPrimaryInputName("FeaturePoints"); diff --git a/Modules/Segmentation/Watersheds/include/itkWatershedSegmenter.hxx b/Modules/Segmentation/Watersheds/include/itkWatershedSegmenter.hxx index c9dc49178d4..4b0eebaedf3 100644 --- a/Modules/Segmentation/Watersheds/include/itkWatershedSegmenter.hxx +++ b/Modules/Segmentation/Watersheds/include/itkWatershedSegmenter.hxx @@ -1354,13 +1354,9 @@ Segmenter::Segmenter() m_SortEdgeLists = true; m_Connectivity.direction = nullptr; m_Connectivity.index = nullptr; - typename OutputImageType::Pointer img = static_cast(this->MakeOutput(0).GetPointer()); - typename SegmentTableType::Pointer st = static_cast(this->MakeOutput(1).GetPointer()); - typename BoundaryType::Pointer bd = static_cast(this->MakeOutput(2).GetPointer()); - this->SetNumberOfRequiredOutputs(3); - this->ProcessObject::SetNthOutput(0, img.GetPointer()); - this->ProcessObject::SetNthOutput(1, st.GetPointer()); - this->ProcessObject::SetNthOutput(2, bd.GetPointer()); + + // Make the outputs (OutputImage, SegmentTable, Boundary). + ProcessObject::MakeRequiredOutputs(*this, 3); // Allocate memory for connectivity m_Connectivity.size = 2 * ImageDimension;