66 typename itk::TransformBaseTemplate<T>::Pointer transformItk,
67 double center_LocalRAS[3] =
nullptr);
80 vtkAbstractTransform* transformVtk,
81 itk::Object::Pointer& secondaryTransformItk,
82 int preferITKv3CompatibleTransforms,
83 bool initialize =
true,
84 double center_LocalRAS[3] =
nullptr);
88 vtkOrientedBSplineTransform* bsplineVtk,
89 typename itk::TransformBaseTemplate<T>::Pointer warpTransformItk,
90 typename itk::TransformBaseTemplate<T>::Pointer bulkTransformItk);
94 vtkOrientedGridTransform* grid_Ras,
95 typename itk::DisplacementFieldTransform<T, 3>::DisplacementFieldType::Pointer gridImage_Lps);
101 vtkMatrix4x4* transformVtk_RAS,
102 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS,
103 double center_LocalRAS[3] =
nullptr);
104 static bool SetITKLinearTransformFromVTK(vtkObject* loggerObject, itk::Object::Pointer& transformItk_LPS, vtkMatrix4x4* transformVtk_RAS,
double center_LocalRAS[3] =
nullptr);
106 template <
typename T>
108 vtkOrientedGridTransform* transformVtk_RAS,
109 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS);
113 itk::Object::Pointer& warpTransformItk,
114 itk::Object::Pointer& bulkTransformItk,
115 vtkOrientedBSplineTransform* bsplineVtk,
116 bool alwaysAddBulkTransform);
117 static bool SetITKv4BSplineFromVTK(vtkObject* loggerObject, itk::Object::Pointer& warpTransformItk, vtkOrientedBSplineTransform* bsplineVtk);
119 template <
typename T>
121 vtkThinPlateSplineTransform* transformVtk_RAS,
122 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS);
124 itk::Object::Pointer& transformItk_LPS,
125 vtkThinPlateSplineTransform* transformVtk_RAS,
126 bool initialize =
true);
130 template <
typename BSplineTransformType>
132 vtkOrientedBSplineTransform* bsplineVtk,
133 typename itk::TransformBaseTemplate<typename BSplineTransformType::ScalarType>::Pointer warpTransformItk);
134 template <
typename T>
135 static bool SetVTKBSplineFromITKv4Generic(vtkObject* loggerObject, vtkOrientedBSplineTransform* bsplineVtk,
typename itk::TransformBaseTemplate<T>::Pointer warpTransformItk);
137 template <
typename BSplineTransformType>
139 typename itk::Transform<typename BSplineTransformType::ScalarType, VTKDimension, VTKDimension>::Pointer& warpTransformItk,
140 vtkOrientedBSplineTransform* bsplineVtk);
141 template <
typename T>
143 typename itk::Transform<T, VTKDimension, VTKDimension>::Pointer& warpTransformItk,
144 typename itk::Transform<T, VTKDimension, VTKDimension>::Pointer& bulkTransformItk,
145 vtkOrientedBSplineTransform* bsplineVtk,
146 bool alwaysAddBulkTransform);
147 template <
typename T>
149 typename itk::Transform<T, VTKDimension, VTKDimension>::Pointer& warpTransformItk,
150 vtkOrientedBSplineTransform* bsplineVtk);
156 itk::TransformFactory<InverseDisplacementFieldTransformFloatType>::RegisterTransform();
157 itk::TransformFactory<InverseDisplacementFieldTransformDoubleType>::RegisterTransform();
159 itk::TransformFactory<InverseBSplineTransformFloatITKv3Type>::RegisterTransform();
160 itk::TransformFactory<InverseBSplineTransformFloatITKv4Type>::RegisterTransform();
161 itk::TransformFactory<InverseBSplineTransformDoubleITKv3Type>::RegisterTransform();
162 itk::TransformFactory<InverseBSplineTransformDoubleITKv4Type>::RegisterTransform();
164 itk::TransformFactory<InverseThinPlateSplineTransformFloatType>::RegisterTransform();
165 itk::TransformFactory<InverseThinPlateSplineTransformDoubleType>::RegisterTransform();
167 typedef itk::ThinPlateSplineKernelTransform<float, 3> ThinPlateSplineTransformFloatType;
171 itk::TransformFactory<ThinPlateSplineTransformFloatType>::RegisterTransform();
172 itk::TransformFactory<ThinPlateSplineTransformDoubleType>::RegisterTransform();
178 vtkMatrix4x4* transformVtk_RAS,
179 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS,
180 double center_LocalRAS[3] )
183 typedef itk::MatrixOffsetTransformBase<T, D, D> LinearTransformType;
184 typedef itk::ScaleTransform<T, D> ScaleTransformType;
185 typedef itk::TranslationTransform<T, D> TranslateTransformType;
187 vtkSmartPointer<vtkMatrix4x4> transformVtk_LPS = vtkSmartPointer<vtkMatrix4x4>::New();
189 bool convertedToVtkMatrix =
false;
191 std::string itkTransformClassName = transformItk_LPS->GetNameOfClass();
210 if (itkTransformClassName.find(
"AffineTransform") != std::string::npos ||
211 itkTransformClassName ==
"MatrixOffsetTransformBase" ||
212 itkTransformClassName ==
"Rigid3DTransform" ||
213 itkTransformClassName ==
"Euler3DTransform" ||
214 itkTransformClassName ==
"CenteredEuler3DTransform" ||
215 itkTransformClassName ==
"QuaternionRigidTransform" ||
216 itkTransformClassName ==
"VersorTransform" ||
217 itkTransformClassName ==
"VersorRigid3DTransform" ||
218 itkTransformClassName ==
"ScaleSkewVersor3DTransform" ||
219 itkTransformClassName ==
"ScaleVersor3DTransform" ||
220 itkTransformClassName ==
"Similarity3DTransform" ||
221 itkTransformClassName ==
"ScaleTransform" ||
222 itkTransformClassName ==
"ScaleLogarithmicTransform")
224 typename LinearTransformType::Pointer dlt =
static_cast<LinearTransformType*
>(transformItk_LPS.GetPointer());
225 convertedToVtkMatrix =
true;
226 for (
unsigned int i = 0; i < D; i++)
228 for (
unsigned int j = 0; j < D; j++)
230 transformVtk_LPS->SetElement(i, j, dlt->GetMatrix()[i][j]);
232 transformVtk_LPS->SetElement(i, D, dlt->GetOffset()[i]);
237 auto center_LocalLPS = dlt->GetCenter();
238 center_LocalRAS[0] = -center_LocalLPS[0];
239 center_LocalRAS[1] = -center_LocalLPS[1];
240 center_LocalRAS[2] = center_LocalLPS[2];
245 if (itkTransformClassName ==
"IdentityTransform")
248 convertedToVtkMatrix =
true;
252 if (itkTransformClassName ==
"ScaleTransform")
254 typename ScaleTransformType::Pointer dst =
static_cast<ScaleTransformType*
>(transformItk_LPS.GetPointer());
255 convertedToVtkMatrix =
true;
256 for (
unsigned int i = 0; i < D; i++)
258 transformVtk_LPS->SetElement(i, i, dst->GetScale()[i]);
263 if (itkTransformClassName ==
"TranslationTransform")
265 typename TranslateTransformType::Pointer dtt =
static_cast<TranslateTransformType*
>(transformItk_LPS.GetPointer());
266 convertedToVtkMatrix =
true;
267 for (
unsigned int i = 0; i < D; i++)
269 transformVtk_LPS->SetElement(i, D, dtt->GetOffset()[i]);
278 vtkSmartPointer<vtkMatrix4x4> lps2ras = vtkSmartPointer<vtkMatrix4x4>::New();
279 lps2ras->SetElement(0, 0, -1);
280 lps2ras->SetElement(1, 1, -1);
281 vtkMatrix4x4* ras2lps = lps2ras;
283 vtkMatrix4x4::Multiply4x4(lps2ras, transformVtk_LPS, transformVtk_LPS);
284 vtkMatrix4x4::Multiply4x4(transformVtk_LPS, ras2lps, transformVtk_RAS);
288 for (
int i = 0; i < 3; ++i)
293 double offset_RAS = transformVtk_RAS->GetElement(i, 3);
294 center_LocalRAS[i] = center_LocalRAS[i] + offset_RAS;
298 return convertedToVtkMatrix;
303 itk::Object::Pointer& transformItk_LPS,
304 vtkMatrix4x4* transformVtk_RAS,
305 double center_LocalRAS[3] )
309 if (transformVtk_RAS ==
nullptr)
311 vtkErrorWithObjectMacro(loggerObject,
"vtkITKTransformConverter::SetITKLinearTransformFromVTK failed: invalid input transform");
315 vtkSmartPointer<vtkMatrix4x4> lps2ras = vtkSmartPointer<vtkMatrix4x4>::New();
316 lps2ras->SetElement(0, 0, -1);
317 lps2ras->SetElement(1, 1, -1);
318 vtkMatrix4x4* ras2lps = lps2ras;
324 vtkSmartPointer<vtkMatrix4x4> vtkmat = vtkSmartPointer<vtkMatrix4x4>::New();
326 vtkMatrix4x4::Multiply4x4(ras2lps, transformVtk_RAS, vtkmat);
327 vtkMatrix4x4::Multiply4x4(vtkmat, lps2ras, vtkmat);
329 typedef AffineTransformType::MatrixType MatrixType;
330 typedef AffineTransformType::OutputVectorType OffsetType;
333 OffsetType itkoffset;
339 itkmat[i][j] = vtkmat->GetElement(i, j);
344 AffineTransformType::Pointer affine = AffineTransformType::New();
355 double center_LocalLPS[3] = { -center_LocalRAS[0], -center_LocalRAS[1], center_LocalRAS[2] };
360 vtkMath::Subtract(center_LocalLPS, itkoffset, center_LocalLPS);
361 affine->SetCenter(center_LocalLPS);
363 affine->SetMatrix(itkmat);
364 affine->SetOffset(itkoffset);
366 transformItk_LPS = affine;
392 vtkOrientedBSplineTransform* bsplineVtk,
393 typename itk::TransformBaseTemplate<typename BSplineTransformType::ScalarType>::Pointer warpTransformItk)
398 typedef typename BSplineTransformType::ScalarType T;
399 if (bsplineVtk ==
nullptr)
401 vtkErrorWithObjectMacro(loggerObject,
"vtkMRMLTransformStorageNode::SetVTKBSplineFromITKv4 failed: bsplineVtk is invalid");
404 bool isDoublePrecisionInput =
true;
405 if (
sizeof(T) ==
sizeof(
float))
407 isDoublePrecisionInput =
false;
409 else if (
sizeof(T) ==
sizeof(
double))
411 isDoublePrecisionInput =
true;
415 vtkErrorWithObjectMacro(loggerObject,
"Unsupported scalar type in BSpline transform file (only float and double are supported)");
419 typename BSplineTransformType::Pointer bsplineItk = BSplineTransformType::New();
420 std::string warpTransformItkName = warpTransformItk->GetNameOfClass();
421 std::string requestedWarpTransformItkName = bsplineItk->GetNameOfClass();
422 if (warpTransformItkName != requestedWarpTransformItkName)
426 if (warpTransformItk->GetOutputSpaceDimension() !=
VTKDimension)
428 vtkErrorWithObjectMacro(loggerObject,
429 "Unsupported number of dimensions in BSpline transform file (expected = " <<
VTKDimension
430 <<
", actual = " << warpTransformItk->GetOutputSpaceDimension() <<
")");
433 bsplineItk =
static_cast<BSplineTransformType*
>(warpTransformItk.GetPointer());
441 const typename BSplineTransformType::CoefficientImageArray coefficientImages = bsplineItk->GetCoefficientImages();
445 typename BSplineTransformType::MeshSizeType meshSize = coefficientImages[0]->GetLargestPossibleRegion().GetSize();
448 typename BSplineTransformType::OriginType origin = coefficientImages[0]->GetOrigin();
451 typename BSplineTransformType::SpacingType spacing = coefficientImages[0]->GetSpacing();
454 typename BSplineTransformType::DirectionType direction = coefficientImages[0]->GetDirection();
456 vtkNew<vtkMatrix4x4> gridDirectionMatrix_LPS;
459 for (
unsigned int column = 0; column <
VTKDimension; column++)
461 gridDirectionMatrix_LPS->SetElement(row, column, direction[row][column]);
466 bsplineVtk->SetBorderModeToZero();
468 vtkNew<vtkImageData> bsplineCoefficients;
470 bsplineCoefficients->SetExtent(0, meshSize[0] - 1, 0, meshSize[1] - 1, 0, meshSize[2] - 1);
471 bsplineCoefficients->SetSpacing(spacing[0], spacing[1], spacing[2]);
474 vtkNew<vtkMatrix4x4> lpsToRas;
475 lpsToRas->SetElement(0, 0, -1);
476 lpsToRas->SetElement(1, 1, -1);
478 vtkNew<vtkMatrix4x4> rasToLps;
479 rasToLps->SetElement(0, 0, -1);
480 rasToLps->SetElement(1, 1, -1);
482 vtkNew<vtkMatrix4x4> gridDirectionMatrix_RAS;
483 vtkMatrix4x4::Multiply4x4(lpsToRas.GetPointer(), gridDirectionMatrix_LPS.GetPointer(), gridDirectionMatrix_RAS.GetPointer());
484 bsplineVtk->SetGridDirectionMatrix(gridDirectionMatrix_RAS.GetPointer());
487 double gridOrigin_RAS[3] = { -origin[0], -origin[1], origin[2] };
488 bsplineCoefficients->SetOrigin(gridOrigin_RAS);
490 int bsplineCoefficientsScalarType = VTK_FLOAT;
491 if (isDoublePrecisionInput)
493 bsplineCoefficientsScalarType = VTK_DOUBLE;
496 bsplineCoefficients->AllocateScalars(bsplineCoefficientsScalarType, 3);
498 const unsigned int expectedNumberOfVectors = meshSize[0] * meshSize[1] * meshSize[2];
499 const unsigned int expectedNumberOfParameters = expectedNumberOfVectors *
VTKDimension;
500 const unsigned int actualNumberOfParameters = bsplineItk->GetNumberOfParameters();
502 if (actualNumberOfParameters != expectedNumberOfParameters)
504 vtkErrorWithObjectMacro(loggerObject,
"Mismatch in number of BSpline parameters in the transform file and the MRML node");
507 const T* itkBSplineParams_LPS =
static_cast<const T*
>(bsplineItk->GetParameters().data_block());
508 T* vtkBSplineParams_RAS =
static_cast<T*
>(bsplineCoefficients->GetScalarPointer());
509 for (
unsigned int i = 0; i < expectedNumberOfVectors; i++)
511 *(vtkBSplineParams_RAS++) = -(*(itkBSplineParams_LPS));
512 *(vtkBSplineParams_RAS++) = -(*(itkBSplineParams_LPS + expectedNumberOfVectors));
513 *(vtkBSplineParams_RAS++) = (*(itkBSplineParams_LPS + expectedNumberOfVectors * 2));
514 itkBSplineParams_LPS++;
516 bsplineVtk->SetCoefficientData(bsplineCoefficients.GetPointer());
525 vtkOrientedBSplineTransform* bsplineVtk,
526 typename itk::TransformBaseTemplate<T>::Pointer warpTransformItk,
527 typename itk::TransformBaseTemplate<T>::Pointer bulkTransformItk)
529 if (bsplineVtk ==
nullptr)
531 vtkErrorWithObjectMacro(loggerObject,
"vtkMRMLTransformStorageNode::SetVTKBSplineFromITK failed: bsplineVtk is invalid");
535 bool inverse =
false;
547 vtkDebugWithObjectMacro(loggerObject,
"Not an ITKv3 BSpline transform");
552 if (bulkTransformItk)
554 std::string bulkTransformItkTransformName = bulkTransformItk->GetNameOfClass();
556 typedef itk::AffineTransform<T, 3> BulkTransformType;
558 if (bulkTransformItkTransformName ==
"AffineTransform")
560 BulkTransformType* bulkItkAffine =
static_cast<BulkTransformType*
>(bulkTransformItk.GetPointer());
561 vtkNew<vtkMatrix4x4> bulkMatrix_LPS;
566 bulkMatrix_LPS->SetElement(i, j, bulkItkAffine->GetMatrix()[i][j]);
568 bulkMatrix_LPS->SetElement(i,
VTKDimension, bulkItkAffine->GetOffset()[i]);
570 vtkNew<vtkMatrix4x4> lpsToRas;
571 lpsToRas->SetElement(0, 0, -1);
572 lpsToRas->SetElement(1, 1, -1);
573 vtkNew<vtkMatrix4x4> rasToLps;
574 rasToLps->SetElement(0, 0, -1);
575 rasToLps->SetElement(1, 1, -1);
576 vtkNew<vtkMatrix4x4> bulkMatrix_RAS;
577 vtkMatrix4x4::Multiply4x4(lpsToRas.GetPointer(), bulkMatrix_LPS.GetPointer(), bulkMatrix_RAS.GetPointer());
578 vtkMatrix4x4::Multiply4x4(bulkMatrix_RAS.GetPointer(), rasToLps.GetPointer(), bulkMatrix_RAS.GetPointer());
579 bsplineVtk->SetBulkTransformMatrix(bulkMatrix_RAS.GetPointer());
581 else if (bulkTransformItkTransformName ==
"IdentityTransform")
587 vtkErrorWithObjectMacro(loggerObject,
"Cannot read the 2nd transform in BSplineTransform (expected AffineTransform_double_3_3 or IdentityTransform)");
594 bsplineVtk->Inverse();
632 vtkObject* loggerObject,
633 typename itk::Transform<typename BSplineTransformType::ScalarType, VTKDimension, VTKDimension>::Pointer& warpTransformItk,
634 vtkOrientedBSplineTransform* bsplineVtk)
636 typedef typename BSplineTransformType::ScalarType T;
637 if (bsplineVtk ==
nullptr)
639 vtkErrorWithObjectMacro(loggerObject,
"vtkMRMLTransformStorageNode::SetITKBSplineFromVTK failed: bsplineVtk is invalid");
642 vtkImageData* bsplineCoefficients_RAS = bsplineVtk->GetCoefficientData();
643 if (bsplineCoefficients_RAS ==
nullptr)
645 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file: coefficients are not specified");
649 typename BSplineTransformType::Pointer bsplineItk = BSplineTransformType::New();
650 warpTransformItk = bsplineItk;
657 typename BSplineTransformType::FixedParametersType transformFixedParamsItk;
659 transformFixedParamsItk.SetSize(numberOfFixedParameters);
661 int* gridExtent = bsplineCoefficients_RAS->GetExtent();
662 int gridSize[3] = { gridExtent[1] - gridExtent[0] + 1, gridExtent[3] - gridExtent[2] + 1, gridExtent[5] - gridExtent[4] + 1 };
663 transformFixedParamsItk[0] = gridSize[0];
664 transformFixedParamsItk[1] = gridSize[1];
665 transformFixedParamsItk[2] = gridSize[2];
667 double* gridOrigin_RAS = bsplineCoefficients_RAS->GetOrigin();
668 double gridOrigin_LPS[3] = { -gridOrigin_RAS[0], -gridOrigin_RAS[1], gridOrigin_RAS[2] };
669 transformFixedParamsItk[3] = gridOrigin_LPS[0];
670 transformFixedParamsItk[4] = gridOrigin_LPS[1];
671 transformFixedParamsItk[5] = gridOrigin_LPS[2];
673 double* gridSpacing = bsplineCoefficients_RAS->GetSpacing();
674 transformFixedParamsItk[6] = gridSpacing[0];
675 transformFixedParamsItk[7] = gridSpacing[1];
676 transformFixedParamsItk[8] = gridSpacing[2];
678 vtkNew<vtkMatrix4x4> gridDirectionMatrix_RAS;
679 if (bsplineVtk->GetGridDirectionMatrix() !=
nullptr)
681 gridDirectionMatrix_RAS->DeepCopy(bsplineVtk->GetGridDirectionMatrix());
683 vtkNew<vtkMatrix4x4> lpsToRas;
684 lpsToRas->SetElement(0, 0, -1);
685 lpsToRas->SetElement(1, 1, -1);
686 vtkNew<vtkMatrix4x4> rasToLps;
687 rasToLps->SetElement(0, 0, -1);
688 rasToLps->SetElement(1, 1, -1);
689 vtkNew<vtkMatrix4x4> gridDirectionMatrix_LPS;
690 vtkMatrix4x4::Multiply4x4(rasToLps.GetPointer(), gridDirectionMatrix_RAS.GetPointer(), gridDirectionMatrix_LPS.GetPointer());
694 for (
unsigned int column = 0; column <
VTKDimension; column++)
696 transformFixedParamsItk[fpIndex++] = gridDirectionMatrix_LPS->GetElement(row, column);
700 bsplineItk->SetFixedParameters(transformFixedParamsItk);
704 const unsigned int expectedNumberOfVectors = gridSize[0] * gridSize[1] * gridSize[2];
705 const unsigned int expectedNumberOfParameters = expectedNumberOfVectors *
VTKDimension;
706 if (bsplineItk->GetNumberOfParameters() != expectedNumberOfParameters)
708 vtkErrorWithObjectMacro(loggerObject,
"Mismatch in number of BSpline parameters in the ITK transform and the VTK transform");
712 typename BSplineTransformType::ParametersType transformParamsItk(expectedNumberOfParameters);
713 T* itkBSplineParams_LPS =
static_cast<T*
>(transformParamsItk.data_block());
714 T* vtkBSplineParams_RAS =
static_cast<T*
>(bsplineCoefficients_RAS->GetScalarPointer());
715 double coefficientScale = bsplineVtk->GetDisplacementScale();
716 for (
unsigned int i = 0; i < expectedNumberOfVectors; i++)
718 *(itkBSplineParams_LPS) = -coefficientScale * (*(vtkBSplineParams_RAS++));
719 *(itkBSplineParams_LPS + expectedNumberOfVectors) = -coefficientScale * (*(vtkBSplineParams_RAS++));
720 *(itkBSplineParams_LPS + expectedNumberOfVectors * 2) = coefficientScale * (*(vtkBSplineParams_RAS++));
721 itkBSplineParams_LPS++;
724 bsplineItk->SetParameters(transformParamsItk);
731 typename itk::Transform<T, VTKDimension, VTKDimension>::Pointer& warpTransformItk,
732 typename itk::Transform<T, VTKDimension, VTKDimension>::Pointer& bulkTransformItk,
733 vtkOrientedBSplineTransform* bsplineVtk,
734 bool alwaysAddBulkTransform)
736 if (bsplineVtk ==
nullptr)
738 vtkErrorWithObjectMacro(loggerObject,
"vtkMRMLTransformStorageNode::SetITKBSplineFromVTK failed: bsplineVtk is invalid");
742 bsplineVtk->Update();
743 bool itkTransformSetSuccessfully =
false;
744 if (bsplineVtk->GetInverseFlag())
746 itkTransformSetSuccessfully =
753 if (!itkTransformSetSuccessfully)
755 vtkErrorWithObjectMacro(loggerObject,
"vtkMRMLTransformStorageNode::SetITKBSplineFromVTK failed: cannot determine BSpline parameters");
759 vtkMatrix4x4* bulkMatrix_RAS = bsplineVtk->GetBulkTransformMatrix();
760 if (bulkMatrix_RAS || alwaysAddBulkTransform)
762 vtkNew<vtkMatrix4x4> lpsToRas;
763 lpsToRas->SetElement(0, 0, -1);
764 lpsToRas->SetElement(1, 1, -1);
765 vtkNew<vtkMatrix4x4> rasToLps;
766 rasToLps->SetElement(0, 0, -1);
767 rasToLps->SetElement(1, 1, -1);
768 vtkNew<vtkMatrix4x4> bulkMatrix_LPS;
771 if (bulkMatrix_RAS !=
nullptr)
773 vtkMatrix4x4::Multiply4x4(rasToLps.GetPointer(), bulkMatrix_RAS, bulkMatrix_LPS.GetPointer());
774 vtkMatrix4x4::Multiply4x4(bulkMatrix_LPS.GetPointer(), lpsToRas.GetPointer(), bulkMatrix_LPS.GetPointer());
776 typedef itk::AffineTransform<T, VTKDimension> BulkTransformType;
777 typename BulkTransformType::Pointer affineItk = BulkTransformType::New();
778 bulkTransformItk = affineItk;
780 typename BulkTransformType::MatrixType affineMatrix;
781 typename BulkTransformType::OffsetType affineOffset;
786 affineMatrix[i][j] = bulkMatrix_LPS->GetElement(i, j);
788 affineOffset[i] = bulkMatrix_LPS->GetElement(i,
VTKDimension);
791 affineItk->SetMatrix(affineMatrix);
792 affineItk->SetOffset(affineOffset);
796 bulkTransformItk =
nullptr;
829 itk::Object::Pointer& warpTransformItk,
830 itk::Object::Pointer& bulkTransformItk,
831 vtkOrientedBSplineTransform* bsplineVtk,
832 bool alwaysAddBulkTransform)
834 if (bsplineVtk ==
nullptr)
836 vtkErrorWithObjectMacro(loggerObject,
"Cannot retrieve BSpline transform from node");
840 vtkImageData* bsplineCoefficients = bsplineVtk->GetCoefficientData();
842 if (bsplineCoefficients ==
nullptr)
844 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file: coefficients are not specified");
848 if (bsplineCoefficients->GetScalarType() == VTK_FLOAT)
850 typedef itk::Transform<float, VTKDimension, VTKDimension> ITKTransformType;
851 ITKTransformType::Pointer floatWarpTransformItk;
852 ITKTransformType::Pointer floatBulkTransformItk;
855 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file");
858 warpTransformItk = floatWarpTransformItk.GetPointer();
859 bulkTransformItk = floatBulkTransformItk.GetPointer();
861 else if (bsplineCoefficients->GetScalarType() == VTK_DOUBLE)
863 typedef itk::Transform<double, VTKDimension, VTKDimension> ITKTransformType;
864 ITKTransformType::Pointer doubleWarpTransformItk;
865 ITKTransformType::Pointer doubleBulkTransformItk;
868 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file");
871 warpTransformItk = doubleWarpTransformItk;
872 bulkTransformItk = doubleBulkTransformItk;
876 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file: only float and double coefficient types are supported");
886 if (bsplineVtk ==
nullptr)
888 vtkErrorWithObjectMacro(loggerObject,
"Cannot retrieve BSpline transform from node");
892 vtkImageData* bsplineCoefficients = bsplineVtk->GetCoefficientData();
894 if (bsplineCoefficients ==
nullptr)
896 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file: coefficients are not specified");
900 if (bsplineCoefficients->GetScalarType() == VTK_FLOAT)
902 typedef itk::Transform<float, VTKDimension, VTKDimension> ITKTransformType;
903 ITKTransformType::Pointer floatWarpTransformItk;
906 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file");
909 warpTransformItk = floatWarpTransformItk.GetPointer();
911 else if (bsplineCoefficients->GetScalarType() == VTK_DOUBLE)
913 typedef itk::Transform<double, VTKDimension, VTKDimension> ITKTransformType;
914 ITKTransformType::Pointer doubleWarpTransformItk;
917 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file");
920 warpTransformItk = doubleWarpTransformItk;
924 vtkErrorWithObjectMacro(loggerObject,
"Cannot write BSpline transform to file: only float and double coefficient types are supported");
934 vtkOrientedGridTransform* transformVtk_RAS,
935 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS)
937 typedef itk::DisplacementFieldTransform<T, 3> DisplacementFieldTransformType;
940 if (!transformItk_LPS)
942 vtkErrorWithObjectMacro(loggerObject,
"Cannot set VTK oriented grid transform from ITK: the input transform is nullptr");
945 if (transformItk_LPS->GetOutputSpaceDimension() !=
VTKDimension)
947 vtkErrorWithObjectMacro(loggerObject,
948 "Unsupported number of dimensions in oriented grid transform file (expected = " <<
VTKDimension
949 <<
", actual = " << transformItk_LPS->GetOutputSpaceDimension() <<
")");
953 std::string transformItkClassName = transformItk_LPS->GetNameOfClass();
955 bool inverse =
false;
956 typename DisplacementFieldTransformType::DisplacementFieldType* gridImageItk_Lps =
nullptr;
957 if (transformItkClassName ==
"InverseDisplacementFieldTransform")
959 DisplacementFieldTransformType* inverseDisplacementFieldTransform =
static_cast<InverseDisplacementFieldTransformType*
>(transformItk_LPS.GetPointer());
961 gridImageItk_Lps = inverseDisplacementFieldTransform->GetDisplacementField();
963 else if (transformItkClassName ==
"DisplacementFieldTransform")
965 DisplacementFieldTransformType* displacementFieldTransform =
static_cast<DisplacementFieldTransformType*
>(transformItk_LPS.GetPointer());
967 gridImageItk_Lps = displacementFieldTransform->GetDisplacementField();
971 vtkDebugWithObjectMacro(loggerObject,
"Not a grid transform");
980 transformVtk_RAS->Inverse();
988 GridImageDoubleType::Pointer gridImageItk_Lps;
991 vtkErrorWithObjectMacro(loggerObject,
"vtkITKTransformConverter::SetITKOrientedGridTransformFromVTK failed: input transform is invalid");
995 transformVtk_RAS->Update();
996 if (transformVtk_RAS->GetInverseFlag())
999 gridTransformItk->SetDisplacementField(gridImageItk_Lps);
1000 transformItk_LPS = gridTransformItk;
1004 DisplacementFieldTransformDoubleType::Pointer gridTransformItk = DisplacementFieldTransformDoubleType::New();
1005 gridTransformItk->SetDisplacementField(gridImageItk_Lps);
1006 transformItk_LPS = gridTransformItk;
1014 vtkOrientedGridTransform* grid_Ras,
1015 typename itk::DisplacementFieldTransform<T, 3>::DisplacementFieldType::Pointer gridImage_Lps)
1017 typedef itk::DisplacementFieldTransform<T, 3> DisplacementFieldTransformType;
1018 typedef typename DisplacementFieldTransformType::DisplacementFieldType GridImageType;
1020 vtkNew<vtkImageData> gridImage_Ras;
1023 gridImage_Ras->SetOrigin(-gridImage_Lps->GetOrigin()[0], -gridImage_Lps->GetOrigin()[1], gridImage_Lps->GetOrigin()[2]);
1026 gridImage_Ras->SetSpacing(gridImage_Lps->GetSpacing()[0], gridImage_Lps->GetSpacing()[1], gridImage_Lps->GetSpacing()[2]);
1029 vtkNew<vtkMatrix4x4> gridDirectionMatrix_LPS;
1032 for (
unsigned int column = 0; column <
VTKDimension; column++)
1034 gridDirectionMatrix_LPS->SetElement(row, column, gridImage_Lps->GetDirection()(row, column));
1037 vtkNew<vtkMatrix4x4> lpsToRas;
1038 lpsToRas->SetElement(0, 0, -1);
1039 lpsToRas->SetElement(1, 1, -1);
1040 vtkNew<vtkMatrix4x4> gridDirectionMatrix_RAS;
1041 vtkMatrix4x4::Multiply4x4(lpsToRas.GetPointer(), gridDirectionMatrix_LPS.GetPointer(), gridDirectionMatrix_RAS.GetPointer());
1042 grid_Ras->SetGridDirectionMatrix(gridDirectionMatrix_RAS.GetPointer());
1045 typename GridImageType::SizeType size = gridImage_Lps->GetBufferedRegion().GetSize();
1046 gridImage_Ras->SetDimensions(size[0], size[1], size[2]);
1047 unsigned int numberOfScalarComponents = GridImageType::PixelType::Dimension;
1050 vtkErrorWithObjectMacro(loggerObject,
1051 "Cannot load grid transform: the input displacement field expected to contain " <<
VTKDimension <<
" components but it actually contains "
1052 << numberOfScalarComponents);
1055 gridImage_Ras->AllocateScalars(VTK_DOUBLE, 3);
1057 double* displacementVectors_Ras =
reinterpret_cast<double*
>(gridImage_Ras->GetScalarPointer());
1058 itk::ImageRegionConstIterator<GridImageType> inputIt(gridImage_Lps, gridImage_Lps->GetRequestedRegion());
1059 inputIt.GoToBegin();
1060 while (!inputIt.IsAtEnd())
1062 typename GridImageType::PixelType displacementVectorLps = inputIt.Get();
1063 *(displacementVectors_Ras++) = -displacementVectorLps[0];
1064 *(displacementVectors_Ras++) = -displacementVectorLps[1];
1065 *(displacementVectors_Ras++) = displacementVectorLps[2];
1069 grid_Ras->SetDisplacementGridData(gridImage_Ras.GetPointer());
1072 grid_Ras->SetInterpolationModeToCubic();
1080 if (grid_Ras ==
nullptr)
1082 vtkErrorWithObjectMacro(loggerObject,
"Cannot save grid transform: the input vtkOrientedGridTransform is invalid");
1089 vtkImageData* gridImage_Ras = grid_Ras->GetDisplacementGrid();
1090 if (gridImage_Ras ==
nullptr)
1092 vtkErrorWithObjectMacro(loggerObject,
"Cannot save grid transform: the input vtkOrientedGridTransform does not contain a valid displacement grid");
1095 if (gridImage_Ras->GetNumberOfScalarComponents() !=
static_cast<int>(
VTKDimension))
1097 vtkErrorWithObjectMacro(loggerObject,
1098 "Cannot save grid transform: the input vtkOrientedGridTransform expected to contain " <<
VTKDimension <<
" components but it actually contains "
1099 << gridImage_Ras->GetNumberOfScalarComponents());
1103 gridImage_Lps = GridImageDoubleType::New();
1106 double* origin_Ras = gridImage_Ras->GetOrigin();
1107 double origin_Lps[3] = { -origin_Ras[0], -origin_Ras[1], origin_Ras[2] };
1108 gridImage_Lps->SetOrigin(origin_Lps);
1111 double* spacing = gridImage_Ras->GetSpacing();
1113 gridImage_Lps->SetSpacing(spacing);
1116 vtkNew<vtkMatrix4x4> gridDirectionMatrix_Ras;
1117 if (grid_Ras->GetGridDirectionMatrix() !=
nullptr)
1119 gridDirectionMatrix_Ras->DeepCopy(grid_Ras->GetGridDirectionMatrix());
1121 vtkNew<vtkMatrix4x4> rasToLps;
1122 rasToLps->SetElement(0, 0, -1);
1123 rasToLps->SetElement(1, 1, -1);
1124 vtkNew<vtkMatrix4x4> gridDirectionMatrix_Lps;
1125 vtkMatrix4x4::Multiply4x4(rasToLps.GetPointer(), gridDirectionMatrix_Ras.GetPointer(), gridDirectionMatrix_Lps.GetPointer());
1126 GridImageDoubleType::DirectionType gridDirectionMatrixItk_Lps;
1129 for (
unsigned int column = 0; column <
VTKDimension; column++)
1131 gridDirectionMatrixItk_Lps(row, column) = gridDirectionMatrix_Lps->GetElement(row, column);
1134 gridImage_Lps->SetDirection(gridDirectionMatrixItk_Lps);
1137 GridImageDoubleType::IndexType start;
1138 start[0] = start[1] = start[2] = 0;
1139 int* Nijk = gridImage_Ras->GetDimensions();
1140 GridImageDoubleType::SizeType size;
1144 GridImageDoubleType::RegionType region;
1145 region.SetSize(size);
1146 region.SetIndex(start);
1147 gridImage_Lps->SetRegions(region);
1148 gridImage_Lps->Allocate();
1149 itk::ImageRegionIterator<GridImageDoubleType> gridImageIt_Lps(gridImage_Lps, region);
1150 gridImageIt_Lps.GoToBegin();
1151 GridImageDoubleType::PixelType displacementVectorLps;
1152 double displacementScale = grid_Ras->GetDisplacementScale();
1153 double displacementShift = grid_Ras->GetDisplacementShift();
1155 if (gridImage_Ras->GetScalarType() == VTK_DOUBLE)
1157 double* displacementVectors_Ras =
reinterpret_cast<double*
>(gridImage_Ras->GetScalarPointer());
1158 while (!gridImageIt_Lps.IsAtEnd())
1160 displacementVectorLps[0] = -(displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1161 displacementVectorLps[1] = -(displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1162 displacementVectorLps[2] = (displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1163 gridImageIt_Lps.Set(displacementVectorLps);
1167 else if (gridImage_Ras->GetScalarType() == VTK_FLOAT)
1169 float* displacementVectors_Ras =
reinterpret_cast<float*
>(gridImage_Ras->GetScalarPointer());
1170 while (!gridImageIt_Lps.IsAtEnd())
1172 displacementVectorLps[0] = -(displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1173 displacementVectorLps[1] = -(displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1174 displacementVectorLps[2] = (displacementScale * (*(displacementVectors_Ras++)) + displacementShift);
1175 gridImageIt_Lps.Set(displacementVectorLps);
1181 vtkErrorWithObjectMacro(loggerObject,
"Cannot save grid transform: only float and double scalar types are supported");
1190 vtkThinPlateSplineTransform* transformVtk_RAS,
1191 typename itk::TransformBaseTemplate<T>::Pointer transformItk_LPS)
1193 typedef itk::ThinPlateSplineKernelTransform<T, 3> ThinPlateSplineTransformType;
1196 if (transformVtk_RAS ==
nullptr)
1198 vtkErrorWithObjectMacro(loggerObject,
"Cannot set VTK thin-plate spline transform from ITK: the output vtkThinPlateSplineTransform is invalid");
1202 if (!transformItk_LPS)
1204 vtkErrorWithObjectMacro(loggerObject,
"Cannot set VTK thin-plate spline transform from ITK: the input transform is nullptr");
1208 if (transformItk_LPS->GetOutputSpaceDimension() !=
VTKDimension)
1210 vtkErrorWithObjectMacro(
1212 "Unsupported number of dimensions in thin-plate spline transform file (expected = " <<
VTKDimension <<
", actual = " << transformItk_LPS->GetOutputSpaceDimension() <<
")");
1216 std::string transformItkClassName = transformItk_LPS->GetNameOfClass();
1218 bool inverse =
false;
1219 typename ThinPlateSplineTransformType::PointSetType::Pointer sourceLandmarksItk_Lps;
1220 typename ThinPlateSplineTransformType::PointSetType::Pointer targetLandmarksItk_Lps;
1221 if (transformItkClassName ==
"InverseThinPlateSplineKernelTransform")
1223 ThinPlateSplineTransformType* inverseTpsTransform =
static_cast<InverseThinPlateSplineTransformType*
>(transformItk_LPS.GetPointer());
1225 sourceLandmarksItk_Lps = inverseTpsTransform->GetSourceLandmarks();
1226 targetLandmarksItk_Lps = inverseTpsTransform->GetTargetLandmarks();
1228 else if (transformItkClassName ==
"ThinPlateSplineKernelTransform")
1230 ThinPlateSplineTransformType* tpsTransform =
static_cast<ThinPlateSplineTransformType*
>(transformItk_LPS.GetPointer());
1232 sourceLandmarksItk_Lps = tpsTransform->GetSourceLandmarks();
1233 targetLandmarksItk_Lps = tpsTransform->GetTargetLandmarks();
1237 vtkDebugWithObjectMacro(loggerObject,
"Not a ThinPlateSpline transform");
1241 vtkNew<vtkPoints> sourceLandmarksVtk_Ras;
1242 unsigned int numberOfSourceLandmarks = sourceLandmarksItk_Lps->GetNumberOfPoints();
1243 for (
unsigned int i = 0; i < numberOfSourceLandmarks; i++)
1245 typename ThinPlateSplineTransformType::InputPointType pointItk_Lps;
1246 bool pointExists = sourceLandmarksItk_Lps->GetPoint(i, &pointItk_Lps);
1251 double pointVtk_Ras[3] = { 0 };
1252 pointVtk_Ras[0] = -pointItk_Lps[0];
1253 pointVtk_Ras[1] = -pointItk_Lps[1];
1254 pointVtk_Ras[2] = pointItk_Lps[2];
1255 sourceLandmarksVtk_Ras->InsertNextPoint(pointVtk_Ras);
1258 vtkNew<vtkPoints> targetLandmarksVtk_Ras;
1259 unsigned int numberOfTargetLandmarks = targetLandmarksItk_Lps->GetNumberOfPoints();
1260 for (
unsigned int i = 0; i < numberOfTargetLandmarks; i++)
1262 typename ThinPlateSplineTransformType::InputPointType pointItk_Lps;
1263 bool pointExists = targetLandmarksItk_Lps->GetPoint(i, &pointItk_Lps);
1268 double pointVtk_Ras[3] = { 0 };
1269 pointVtk_Ras[0] = -pointItk_Lps[0];
1270 pointVtk_Ras[1] = -pointItk_Lps[1];
1271 pointVtk_Ras[2] = pointItk_Lps[2];
1272 targetLandmarksVtk_Ras->InsertNextPoint(pointVtk_Ras);
1275 transformVtk_RAS->SetBasisToR();
1276 transformVtk_RAS->SetSourceLandmarks(sourceLandmarksVtk_Ras.GetPointer());
1277 transformVtk_RAS->SetTargetLandmarks(targetLandmarksVtk_Ras.GetPointer());
1281 transformVtk_RAS->Inverse();
1288 itk::Object::Pointer& transformItk_LPS,
1289 vtkThinPlateSplineTransform* transformVtk_RAS,
1292 if (transformVtk_RAS ==
nullptr)
1294 vtkErrorWithObjectMacro(loggerObject,
"Cannot set ITK thin-plate spline transform from VTK: the input vtkThinPlateSplineTransform is invalid");
1299 transformVtk_RAS->Update();
1301 if (transformVtk_RAS->GetBasis() != VTK_RBF_R)
1303 vtkErrorWithObjectMacro(loggerObject,
1304 "Cannot set ITK thin-plate spline transform from VTK: basis function must be R."
1305 " Call SetBasisToR() method of the vtkThinPlateSplineTransform object before attempting to write it to file.");
1309 ThinPlateSplineTransformDoubleType::PointSetType::Pointer sourceLandmarksItk_Lps = ThinPlateSplineTransformDoubleType::PointSetType::New();
1310 vtkPoints* sourceLandmarksVtk_Ras = transformVtk_RAS->GetSourceLandmarks();
1311 if (sourceLandmarksVtk_Ras !=
nullptr)
1313 for (
int i = 0; i < sourceLandmarksVtk_Ras->GetNumberOfPoints(); i++)
1315 double posVtk_Ras[3] = { 0 };
1316 sourceLandmarksVtk_Ras->GetPoint(i, posVtk_Ras);
1317 ThinPlateSplineTransformDoubleType::InputPointType posItk_Lps;
1318 posItk_Lps[0] = -posVtk_Ras[0];
1319 posItk_Lps[1] = -posVtk_Ras[1];
1320 posItk_Lps[2] = posVtk_Ras[2];
1321 sourceLandmarksItk_Lps->GetPoints()->InsertElement(i, posItk_Lps);
1324 ThinPlateSplineTransformDoubleType::PointSetType::Pointer targetLandmarksItk_Lps = ThinPlateSplineTransformDoubleType::PointSetType::New();
1325 vtkPoints* targetLandmarksVtk_Ras = transformVtk_RAS->GetTargetLandmarks();
1326 if (targetLandmarksVtk_Ras !=
nullptr)
1328 for (
int i = 0; i < targetLandmarksVtk_Ras->GetNumberOfPoints(); i++)
1330 double posVtk_Ras[3] = { 0 };
1331 targetLandmarksVtk_Ras->GetPoint(i, posVtk_Ras);
1332 ThinPlateSplineTransformDoubleType::InputPointType posItk_Lps;
1333 posItk_Lps[0] = -posVtk_Ras[0];
1334 posItk_Lps[1] = -posVtk_Ras[1];
1335 posItk_Lps[2] = posVtk_Ras[2];
1336 targetLandmarksItk_Lps->GetPoints()->InsertElement(i, posItk_Lps);
1340 if (transformVtk_RAS->GetInverseFlag())
1343 tpsTransformItk->SetSourceLandmarks(sourceLandmarksItk_Lps);
1344 tpsTransformItk->SetTargetLandmarks(targetLandmarksItk_Lps);
1347 tpsTransformItk->ComputeWMatrix();
1349 transformItk_LPS = tpsTransformItk;
1353 ThinPlateSplineTransformDoubleType::Pointer tpsTransformItk = ThinPlateSplineTransformDoubleType::New();
1354 tpsTransformItk->SetSourceLandmarks(sourceLandmarksItk_Lps);
1355 tpsTransformItk->SetTargetLandmarks(targetLandmarksItk_Lps);
1358 tpsTransformItk->ComputeWMatrix();
1360 transformItk_LPS = tpsTransformItk;
1368 typename itk::TransformBaseTemplate<T>::Pointer transformItk,
1369 double center_LocalRAS[3] )
1371 bool conversionSuccess =
false;
1374 vtkNew<vtkMatrix4x4> transformMatrixVtk;
1376 if (conversionSuccess)
1378 vtkNew<vtkTransform> linearTransformVtk;
1379 linearTransformVtk->SetMatrix(transformMatrixVtk.GetPointer());
1380 linearTransformVtk->Register(
nullptr);
1381 return linearTransformVtk.GetPointer();
1384 vtkNew<vtkOrientedGridTransform> gridTransformVtk;
1386 if (conversionSuccess)
1388 gridTransformVtk->Register(
nullptr);
1389 return gridTransformVtk.GetPointer();
1392 vtkNew<vtkOrientedBSplineTransform> bsplineTransformVtk;
1394 if (conversionSuccess)
1396 bsplineTransformVtk->Register(
nullptr);
1397 return bsplineTransformVtk.GetPointer();
1400 vtkNew<vtkThinPlateSplineTransform> tpsTransformVtk;
1402 if (conversionSuccess)
1404 tpsTransformVtk->Register(
nullptr);
1405 return tpsTransformVtk.GetPointer();
1413 vtkAbstractTransform* transformVtk,
1414 itk::Object::Pointer& secondaryTransformItk,
1415 int preferITKv3CompatibleTransforms,
1417 double center_LocalRAS[3] )
1419 typedef itk::CompositeTransform<double> CompositeTransformType;
1421 if (transformVtk ==
nullptr)
1423 vtkErrorWithObjectMacro(loggerObject,
"CreateITKTransformFromVTK failed: invalid VTK transform");
1426 vtkNew<vtkCollection> transformList;
1428 if (transformList->GetNumberOfItems() == 0)
1431 vtkNew<vtkTransform> identity;
1432 transformList->AddItem(identity.GetPointer());
1435 itk::Object::Pointer primaryTransformItk;
1436 if (transformList->GetNumberOfItems() == 1)
1439 vtkObject* singleTransformVtk = transformList->GetItemAsObject(0);
1441 if (vtkHomogeneousTransform::SafeDownCast(singleTransformVtk))
1443 vtkHomogeneousTransform* linearTransformVtk = vtkHomogeneousTransform::SafeDownCast(singleTransformVtk);
1444 vtkMatrix4x4* transformMatrix = linearTransformVtk->GetMatrix();
1450 return primaryTransformItk;
1453 else if (vtkOrientedBSplineTransform::SafeDownCast(singleTransformVtk))
1455 vtkOrientedBSplineTransform* bsplineTransformVtk = vtkOrientedBSplineTransform::SafeDownCast(singleTransformVtk);
1456 vtkMatrix4x4* bulkMatrix = bsplineTransformVtk->GetBulkTransformMatrix();
1457 if (preferITKv3CompatibleTransforms || (bulkMatrix !=
nullptr && !
IsIdentityMatrix(bulkMatrix)))
1459 if (!
SetITKv3BSplineFromVTK(loggerObject, primaryTransformItk, secondaryTransformItk, bsplineTransformVtk, preferITKv3CompatibleTransforms))
1464 return primaryTransformItk;
1473 return primaryTransformItk;
1477 else if (vtkOrientedGridTransform::SafeDownCast(singleTransformVtk))
1479 vtkOrientedGridTransform* gridTransformVtk = vtkOrientedGridTransform::SafeDownCast(singleTransformVtk);
1485 return primaryTransformItk;
1488 else if (vtkThinPlateSplineTransform::SafeDownCast(singleTransformVtk))
1490 vtkThinPlateSplineTransform* tpsTransformVtk = vtkThinPlateSplineTransform::SafeDownCast(singleTransformVtk);
1496 return primaryTransformItk;
1500 if (singleTransformVtk ==
nullptr)
1502 vtkErrorWithObjectMacro(loggerObject,
"vtkITKTransformConverter::CreateITKTransformFromVTK failed: invalid input transform");
1505 vtkErrorWithObjectMacro(
1506 loggerObject,
"vtkITKTransformConverter::CreateITKTransformFromVTK failed: conversion of transform type " << singleTransformVtk->GetClassName() <<
" is not supported");
1514 CompositeTransformType::Pointer compositeTransformItk = CompositeTransformType::New();
1515 primaryTransformItk = compositeTransformItk;
1517 for (
int transformIndex = transformList->GetNumberOfItems() - 1; transformIndex >= 0; --transformIndex)
1519 vtkAbstractTransform* singleTransformVtk = vtkAbstractTransform::SafeDownCast(transformList->GetItemAsObject(transformIndex));
1520 itk::Object::Pointer secondaryTransformItkTmp;
1524 itk::Object::Pointer singleTransformItk =
CreateITKTransformFromVTK(loggerObject, singleTransformVtk, secondaryTransformItkTmp,
false);
1525 if (secondaryTransformItkTmp.IsNotNull())
1527 vtkErrorWithObjectMacro(loggerObject,
1528 "vtkITKTransformConverter::CreateITKTransformFromVTK failed:"
1529 " composite transforms cannot contain legacy transforms (that contains secondary transforms)."
1530 " Do not harden transforms on legacy ITK transforms to avoid this error.");
1534 if (singleTransformItk.IsNull()
1535 || std::string(singleTransformItk->GetNameOfClass()).find(
"Transform") == std::string::npos)
1537 vtkErrorWithObjectMacro(loggerObject,
1538 "vtkITKTransformConverter::CreateITKTransformFromVTK failed:"
1539 " invalid element found while trying to create a composite transform");
1542 CompositeTransformType::TransformType::Pointer singleTransformItkTypeChecked =
static_cast<CompositeTransformType::TransformType*
>(singleTransformItk.GetPointer());
1543 compositeTransformItk->AddTransform(singleTransformItkTypeChecked.GetPointer());
1545 return primaryTransformItk;