MITK ships a private ITK branch consisting of upstream v5.4.6 plus one commit that switches itk::BoundingBox, itk::VectorContainer and itk::ScalableAffineTransform from itkNewMacro to itkFactorylessNewMacro. It has never been proposed here. Should ITK adopt it?
To be clear up front: this is not a report of an ignored contribution — no PR, issue, or Discourse topic for it exists. It is a downstream-held patch that looks upstreamable, and this issue is to decide whether it is.
Provenance
MITK's CMakeExternals/ITK.cmake pins:
GIT_REPOSITORY https://github.com/MITK/ITK.git
GIT_TAG 2d98b3bdbe663a03f335939696f7ec70e21603b1 # branch: v5.4.6-patched
git rev-list --count v5.4.6..2d98b3bd on that fork is 1:
- "Use factoryless instance creation for frequently used basic types"
- Stefan Dinkelacker (DKFZ / MITK), 2025-05-10
- 4 insertions, 3 deletions, 3 files
The diff in full:
Modules/Core/Common/include/itkBoundingBox.h
- itkNewMacro(Self);
+ itkFactorylessNewMacro(Self);
Modules/Core/Common/include/itkVectorContainer.h
- itkNewMacro(Self);
+ itkFactorylessNewMacro(Self);
Modules/Core/Transform/include/itkScalableAffineTransform.h
- itkNewMacro(Self);
+ itkFactorylessNewMacro(Self);
+ itkCloneMacro(Self);
As of main (2026-07-29) all three still use itkNewMacro(Self).
Why it looks upstreamable
Established pattern. 64 headers under Modules/**/include/ already use itkFactorylessNewMacro, including itkMetaDataObject.h in Core/Common.
No override conflicts. Searching Modules/** for factory overrides of these three types returns zero for all three.
Transform IO is unaffected — the obvious objection for ScalableAffineTransform, which is registered (Modules/IO/TransformFactory/src/itkTransformFactoryBaseRegister.hxx:148). TransformFactory<T>::RegisterTransform() keys on T::New()->GetTransformTypeAsString(), i.e. "ScalableAffineTransform_double_3_3", whereas itkNewMacro's New() looks up the bare class name. Different keys; making New() factoryless does not disturb the reader path.
Related prior work in this area: #4453, #4481.
Open questions for reviewers
- Benchmark. No measured benefit has been published. What is the actual gain, and on what workload?
VectorContainer and BoundingBox are plausible hot-path allocations; a number should precede a merge.
- Behavior change. This removes the
ObjectFactory substitution hook for three public classes. An external consumer who registered an override for them would silently stop receiving it. Is that acceptable under ITK's compatibility policy for main, and does it warrant a release note?
- Scope. The
itkCloneMacro(Self) addition to ScalableAffineTransform is an unrelated feature (adds Clone()), and should probably be a separate commit if this is pursued.
- Coverage. If the pattern is right for these three, are there other frequently instantiated basic types that warrant the same treatment? A principled sweep may beat a three-file patch.
- Targeting. If accepted,
main seems the right target rather than a release-5.4.x backport, since it is an optimization with a behavior change rather than a bug fix. Worth confirming.
How this surfaced
Found while adding MITK as a headless downstream consumer to a local ITK build-matrix testbed (MITK's PythonWheel build configuration, configured against a locally built ITK via ITK_DIR). Inspecting MITK's ITK pin surfaced the one-commit delta.
Credit for the patch belongs to Stefan Dinkelacker and the MITK team; I have no connection to it beyond noticing it. If there is interest here, they would be the right people to ask about motivation and measurements.
MITK ships a private ITK branch consisting of upstream
v5.4.6plus one commit that switchesitk::BoundingBox,itk::VectorContaineranditk::ScalableAffineTransformfromitkNewMacrotoitkFactorylessNewMacro. It has never been proposed here. Should ITK adopt it?To be clear up front: this is not a report of an ignored contribution — no PR, issue, or Discourse topic for it exists. It is a downstream-held patch that looks upstreamable, and this issue is to decide whether it is.
Provenance
MITK's
CMakeExternals/ITK.cmakepins:git rev-list --count v5.4.6..2d98b3bdon that fork is 1:The diff in full:
As of
main(2026-07-29) all three still useitkNewMacro(Self).Why it looks upstreamable
Established pattern. 64 headers under
Modules/**/include/already useitkFactorylessNewMacro, includingitkMetaDataObject.hin Core/Common.No override conflicts. Searching
Modules/**for factory overrides of these three types returns zero for all three.Transform IO is unaffected — the obvious objection for
ScalableAffineTransform, which is registered (Modules/IO/TransformFactory/src/itkTransformFactoryBaseRegister.hxx:148).TransformFactory<T>::RegisterTransform()keys onT::New()->GetTransformTypeAsString(), i.e."ScalableAffineTransform_double_3_3", whereasitkNewMacro'sNew()looks up the bare class name. Different keys; makingNew()factoryless does not disturb the reader path.Related prior work in this area: #4453, #4481.
Open questions for reviewers
VectorContainerandBoundingBoxare plausible hot-path allocations; a number should precede a merge.ObjectFactorysubstitution hook for three public classes. An external consumer who registered an override for them would silently stop receiving it. Is that acceptable under ITK's compatibility policy formain, and does it warrant a release note?itkCloneMacro(Self)addition toScalableAffineTransformis an unrelated feature (addsClone()), and should probably be a separate commit if this is pursued.mainseems the right target rather than arelease-5.4.xbackport, since it is an optimization with a behavior change rather than a bug fix. Worth confirming.How this surfaced
Found while adding MITK as a headless downstream consumer to a local ITK build-matrix testbed (MITK's
PythonWheelbuild configuration, configured against a locally built ITK viaITK_DIR). Inspecting MITK's ITK pin surfaced the one-commit delta.Credit for the patch belongs to Stefan Dinkelacker and the MITK team; I have no connection to it beyond noticing it. If there is interest here, they would be the right people to ask about motivation and measurements.