66 auto createFramesAndTransformation(QString frame1, QString frame2) {
71 return std::make_tuple(fr1, fr2, tr);
77 bool isEqual(vtkSmartPointer<vtkMatrix4x4> m1, vtkSmartPointer<vtkMatrix4x4> m2) {
78 if (m1 ==
nullptr || m2 ==
nullptr) {
81 for (
int i = 0; i < 16; ++i) {
82 if (m1->GetElement(i / 4, i % 4) != m2->GetElement(i / 4, i % 4)) {
93 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
94 sphereSource->SetRadius(radius);
95 vtkSmartPointer<vtkPointSet> sphere(sphereSource->GetOutput());
96 return new MeshComponent(sphere, QString(
"Sphere %1").arg(radius));
100 vtkNew<vtkImageData> imageData;
101 imageData->SetDimensions(5, 5, 5);
102 imageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
103 unsigned char* scalars =
static_cast<unsigned char*
>(imageData->GetScalarPointer());
104 memset(scalars, 255, 5 * 5 * 5);
108 int countDefaultIdentityToWorldTransformations() {
121 void initTestCase() {
131 void cleanupTestCase() {
139 for (
auto* comp : components) {
141 comp->setModified(
false);
174 QVERIFY(fr !=
nullptr);
175 QVERIFY(fr->getName() ==
"myFrame");
176 QVERIFY(fr->getDescription() ==
"Test frame");
178 QVERIFY(fr->getIndex() == 1);
181 QVERIFY(fr->getIndex() == 1);
185 QVariantMap{ {
"frames", QVariantList{
186 QVariantMap{ {
"anatomicalOrientation", QVariant()},
187 {
"description",
"Data frame for component 'Mesh'"},
189 {
"name",
"Mesh (Data Frame)"},
191 "units", QVariantList({
198 {
"uuid", QUuid(
"04ef78c0-8a8d-4d52-b888-b7ac2ef79c36")}}
204 QCOMPARE(fr->getName(),
"Mesh (Data Frame)");
205 QCOMPARE(fr->getDescription(),
"Data frame for component 'Mesh'");
206 QCOMPARE(fr->getUuid(), QUuid(
"04ef78c0-8a8d-4d52-b888-b7ac2ef79c36"));
207 QCOMPARE(fr->getNumberOfDimensions(), 3);
212 QVERIFY(fr->getIndex() == 2);
216 QVERIFY(fr3 !=
nullptr);
218 QVERIFY(fr3->getUuid() != fr->getUuid());
219 QVERIFY(fr3->getIndex() > fr->getIndex());
220 QVERIFY(fr3->getIndex() == 3);
221 QVERIFY(fr3->getColor().isValid());
222 QVERIFY(fr3->getColor() != fr->getColor());
225 QVERIFY(fr->getNumberOfDimensions() == 3);
226 fr->setNumberOfDimensions(4);
227 QVERIFY(fr->getNumberOfDimensions() == 4);
230 fr->setUnit(0,
"mm");
232 QVERIFY(fr->getUnit(0) ==
"mm");
233 QVERIFY(fr->getUnit(3) ==
"s");
234 QVERIFY(fr->getUnit(1) ==
"");
237 QVERIFY(!fr->setUuid(QUuid::createUuid()));
240 QVariantMap frameBackup = fr->toVariant().toMap();
241 frameBackup[
"uuid"] = QUuid();
242 fr->fromVariant(frameBackup);
243 QVERIFY(fr->getUuid().isNull());
244 QVERIFY(fr->setUuid(QUuid::createUuid()));
245 QVERIFY(!fr->getUuid().isNull());
248 fr->setAnatomicalOrientation(
"LPS");
249 QVERIFY(fr->getAnatomicalOrientationLabel(0,
true) ==
"L");
250 QVERIFY(fr->getAnatomicalOrientationLabel(1,
true) ==
"P");
251 QVERIFY(fr->getAnatomicalOrientationLabel(2,
true) ==
"S");
254 QVariant frameVariant = fr->toVariant();
257 fr->setAnatomicalOrientation(
"RAI");
258 QVERIFY(fr->getAnatomicalOrientationLabel(0,
false) ==
"L");
259 QVERIFY(fr->getAnatomicalOrientationLabel(1,
false) ==
"P");
260 QVERIFY(fr->getAnatomicalOrientationLabel(2,
false) ==
"S");
263 fr->getAnatomicalOrientation().setMinLabel(0,
"Xmin");
264 QVERIFY(fr->getAnatomicalOrientation().getMinLabel(0) ==
"Xmin");
265 QVERIFY(fr->getAnatomicalOrientationLabel(0,
true) ==
"Xmin");
268 fr->fromVariant(frameVariant);
269 QVERIFY(fr->getAnatomicalOrientationLabel(0,
true) ==
"L");
272 fr->setAnatomicalOrientation(
"RAI+");
273 QVERIFY(fr->getAnatomicalOrientationLabel(0,
false) ==
"R");
278 void createIdentityTransformation() {
279 auto [frame1, frame2, tr] = createFramesAndTransformation(
"Frame1",
"Frame2");
280 QVERIFY(frame1 !=
nullptr && frame2 !=
nullptr);
282 QVERIFY(tr !=
nullptr);
283 QVERIFY(tr->getFrom() == frame1.get());
284 QVERIFY(tr->getTo() == frame2.get());
287 vtkMatrix4x4* matrix = tr->getMatrix();
288 QVERIFY(matrix !=
nullptr);
289 QVERIFY(matrix->IsIdentity());
293 QVERIFY(invalidTr ==
nullptr);
300 void createSpecificTransformation() {
301 auto [frame1, frame2, tr] = createFramesAndTransformation(
"Frame3",
"Frame4");
302 auto m = vtkSmartPointer<vtkMatrix4x4>::New();
303 m->SetElement(1, 1, 2.0);
304 m->SetElement(1, 3, 12.0);
305 m->SetElement(3, 3, -5.0);
307 vtkMatrix4x4* m2 = tr->getTransform()->GetMatrix();
309 QVERIFY(m2->GetElement(2, 2) == 1 && m2->GetElement(3, 1) == 0);
311 QCOMPARE(m2->GetElement(1, 1), 2.0);
312 QCOMPARE(m2->GetElement(1, 3), 12.0);
313 QCOMPARE(m2->GetElement(3, 3), -5.0);
316 tr->setName(
"New name");
317 QCOMPARE(tr->getName(),
"New name");
318 tr->setDescription(
"New description");
319 QCOMPARE(tr->getDescription(),
"New description");
327 void invertTransformation() {
331 auto [frame1, frame2, tr] = createFramesAndTransformation(
"Frame5",
"Frame6");
332 QVERIFY(tr !=
nullptr);
337 QVERIFY(nbTrBefore + 2 == nbTrAfter);
340 QVERIFY(tr->getMatrix()->IsIdentity());
347 QVERIFY(tr2 !=
nullptr);
362 tr->getTransform()->Scale(1, 1, 4);
365 QCOMPARE(tr2->
getMatrix()->GetElement(2, 2), 0.25);
368 auto vtkTr = vtkSmartPointer<vtkTransform>::New();
370 vtkTr->Translate(10.0, 0, 0);
372 QCOMPARE(tr2->
getMatrix()->GetElement(0, 3), -10.0);
376 auto vtkMat = vtkSmartPointer<vtkMatrix4x4>::New();
378 vtkMat->SetElement(1, 3, 123.0);
380 QCOMPARE(tr2->
getMatrix()->GetElement(1, 3), -123.0);
384 void combineTransformations() {
386 auto [frame1, frame2, tr1] = createFramesAndTransformation(
"Frame7",
"Frame8");
387 QVERIFY(tr1 !=
nullptr);
388 tr1->getTransform()->Translate(1, 2, 3);
389 auto [frame3, frame4, tr3] = createFramesAndTransformation(
"Frame9",
"Frame10");
390 tr3->getTransform()->Translate(1, -5, 30);
397 QVERIFY(tr4 !=
nullptr);
398 QCOMPARE(tr4->
getTransform()->GetNumberOfConcatenatedTransforms(), 3);
399 QCOMPARE(tr4->
getMatrix()->GetElement(0, 3), 10.0);
400 QCOMPARE(tr4->
getMatrix()->GetElement(1, 3), 0.0);
401 QCOMPARE(tr4->
getMatrix()->GetElement(2, 3), 20.0);
406 QCOMPARE(tr4->
getMatrix()->GetElement(0, 3), 2.0);
409 auto vtkMat = vtkSmartPointer<vtkMatrix4x4>::New();
411 vtkMat->SetElement(0, 3, 98.0);
413 QCOMPARE(tr4->
getMatrix()->GetElement(0, 3), 100.0);
417 void findTransformationsPath() {
419 auto [frame1, frame2, tr1_2] = createFramesAndTransformation(
"Frame11",
"Frame12");
420 auto [frame4, frame3, tr4_3] = createFramesAndTransformation(
"Frame14",
"Frame13");
421 auto [frame5, frame6, tr5_6] = createFramesAndTransformation(
"Frame15",
"Frame16");
422 auto [frame7, frame8, tr7_8] = createFramesAndTransformation(
"Frame17",
"Frame18");
443 QVERIFY(wantedTransform !=
nullptr);
445 QVERIFY(wantedTransform !=
nullptr);
449 QVERIFY(tr5_4 !=
nullptr);
453 QVERIFY(tr1_8 ==
nullptr);
457 QVERIFY(tr5_1 ==
nullptr);
465 QVERIFY(nbTrBefore == 0);
467 QVERIFY(nbFrBefore == 0);
477 auto component = std::make_unique<MeshComponent>(vtkSmartPointer<vtkPolyData>::New(),
"EmptyMeshComponent");
478 QVERIFY(component->getFrame() !=
nullptr);
481 auto component2 = std::make_unique<MeshComponent>(vtkSmartPointer<vtkPolyData>::New(),
"EmptyMeshComponent2");
482 QVERIFY(component2->getFrame() !=
nullptr);
486 QCOMPARE(nbFrBefore + 2, nbFrAfter);
493 QCOMPARE(nbTrBefore + 4, nbTrAfter);
497 QVERIFY(trWorldFrame !=
nullptr);
498 QVERIFY(trWorldFrame->
getMatrix()->IsIdentity());
501 vtkSmartPointer<vtkTransform> vtkTr2_1 = vtkSmartPointer<vtkTransform>::New();
502 vtkTr2_1->Translate(1, 2, 3);
505 QVERIFY(tr2_1 !=
nullptr);
512 auto component = std::make_unique<MeshComponent>(vtkSmartPointer<vtkPolyData>::New(),
"EmptyMeshComponent");
513 QVERIFY(component->getFrame() !=
nullptr);
517 QVERIFY(viewerFr !=
nullptr);
528 QVERIFY(viewer2world->
getMatrix()->IsIdentity());
538 auto comp2viewerTransform = vtkSmartPointer<vtkTransform>::New();
539 comp2viewerTransform->Translate(1, 2, 3);
541 QVERIFY(comp2viewerAdded !=
nullptr);
545 QCOMPARE(viewer2comp->
getMatrix()->GetElement(0, 3), 1);
546 QCOMPARE(viewer2comp->
getMatrix()->GetElement(1, 3), 2);
547 QCOMPARE(viewer2comp->
getMatrix()->GetElement(2, 3), 3);
550 QCOMPARE(comp2viewer->
getMatrix()->GetElement(0, 3), -1);
551 QCOMPARE(comp2viewer->
getMatrix()->GetElement(1, 3), -2);
552 QCOMPARE(comp2viewer->
getMatrix()->GetElement(2, 3), -3);
564 QVERIFY(viewer2world !=
nullptr);
565 QCOMPARE(viewer2world->
getMatrix()->GetElement(0, 3), 1);
566 QCOMPARE(viewer2world->
getMatrix()->GetElement(1, 3), 2);
567 QCOMPARE(viewer2world->
getMatrix()->GetElement(2, 3), 3);
572 void checkTransformationToWorld() {
576 QVERIFY(worldFrame !=
nullptr);
583 QVERIFY(sphereFrame !=
nullptr);
593 QVERIFY(sphere2world !=
nullptr);
601 auto vtkSphere2worldTranslation = vtkSmartPointer<vtkTransform>::New();
602 vtkSphere2worldTranslation->Translate(1, 2, 3);
606 QVERIFY(sphere2worldTranslation !=
nullptr);
609 QCOMPARE(sphere2worldTranslation->getMatrix()->GetElement(0, 3), 1);
624 void checkRemoveTransformation() {
625 auto [frameA, frameB, trA_B] = createFramesAndTransformation(
"FrameA",
"FrameB");
626 auto [frameD, frameC, trD_C] = createFramesAndTransformation(
"FrameD",
"FrameC");
627 auto [frameF, frameE, trF_E] = createFramesAndTransformation(
"FrameF",
"FrameE");
637 auto matrixTransl10 = vtkMatrix4x4::New();
638 matrixTransl10->SetElement(0, 3, 10.0);
673 void checkUpdateTransformation() {
678 auto [frameA, frameB, trA_B] = createFramesAndTransformation(
"FrameA",
"FrameB");
679 auto [frameD, frameC, trD_C] = createFramesAndTransformation(
"FrameD",
"FrameC");
680 auto [frameF, frameE, trF_E] = createFramesAndTransformation(
"FrameF",
"FrameE");
683 QUuid trB_World_Uuid = trB_World->
getUuid();
699 vtkMatrix4x4* matrixTransl10 = vtkMatrix4x4::New();
700 matrixTransl10->SetElement(0, 3, 10.0);
710 QVERIFY(trB_World_Uuid != nonDefault_trB_World->
getUuid());
715 QVERIFY(trWorld_B !=
nullptr);
717 QCOMPARE(trWorld_B->
getMatrix()->GetElement(0, 3), -10.0);
734 QVERIFY(trWorld_C !=
nullptr);
750 QVERIFY(trA_F !=
nullptr);
758 vtkMatrix4x4* matrixTransl15 = vtkMatrix4x4::New();
759 matrixTransl15->SetElement(0, 3, 15.0);
771 QVERIFY(trA_F !=
nullptr);
780 QVERIFY(trE_World !=
nullptr);
786 QVERIFY(trE_D !=
nullptr);
796 QCOMPARE(trE_World->
getMatrix()->GetElement(0, 3), -5.0);
802 QCOMPARE(trE_World->
getMatrix()->GetElement(0, 3), 0.0);
806 QVERIFY(trA_D !=
nullptr);
808 QVERIFY(trD_A !=
nullptr);
813 auto [frameG, frameH, trG_H] = createFramesAndTransformation(
"FrameG",
"FrameH");
818 void checkViewerFrame() {
824 QVERIFY(viewer !=
nullptr);
837 QVERIFY(comp !=
nullptr);
854 QVERIFY(viewerFrame !=
nullptr);
865 vtkSmartPointer<vtkTransform> invertAxes = vtkSmartPointer<vtkTransform>::New();
866 invertAxes->Scale(1, -1, 1);
867 invertAxes->Translate(1, 2, 3);
869 QVERIFY(trMain2Vtk !=
nullptr);
872 viewerFrame->setAnatomicalOrientation(
"RAI");
878 QVERIFY(actor !=
nullptr);
881 vtkLinearTransform* userTransform = actor->GetUserTransform();
882 QVERIFY(userTransform !=
nullptr);
886 QVERIFY(isEqual(userTransform->GetMatrix(), invertAxes->GetMatrix()));
893 userTransform = actor->GetUserTransform();
894 QVERIFY(userTransform ==
nullptr || userTransform->GetMatrix()->IsIdentity());
898 void checkResetFrame() {
904 std::shared_ptr<FrameOfReference> frM, frIMain, frIData, frIArbitrary;
905 std::shared_ptr<Transformation> trIData_IMain, trIArbitrary_IData;
913 QVERIFY(frM !=
nullptr && frIMain !=
nullptr && frIData !=
nullptr && frIArbitrary !=
nullptr && trIData_IMain !=
nullptr && trIArbitrary_IData !=
nullptr);
917 QVERIFY(m->
getFrame() != frM.get());
920 QVERIFY(i->
getFrame() != frIMain.get());
924 QVERIFY(new_trIData_IMain !=
nullptr);
925 QVERIFY(new_trIData_IMain != trIData_IMain);
927 QVERIFY(new_trIArbitrary_IData !=
nullptr);
928 QVERIFY(new_trIArbitrary_IData != trIArbitrary_IData);
929 QVERIFY(isEqual(new_trIArbitrary_IData->getMatrix(), trIArbitrary_IData->getMatrix()));
933 void checkSetFrame() {
941 std::shared_ptr<FrameOfReference> frM1, frI1Main, frI1Data, frI1Arbitrary;
942 std::shared_ptr<Transformation> trI1Data_I1Main, trI1Arbitrary_I1Data;
954 QVERIFY(m1->
getFrame() != frM1.get());
959 QVERIFY(m1->
getFrame() != frM1.get());
961 QVERIFY(m1->
getFrame() == frI1Main.get());
965 QVERIFY(i1->
getFrame() != frI1Main.get());
970 QVERIFY(new_trI1Data_I1Main != trI1Data_I1Main);
982 QVERIFY(i1->
getFrame() != frI1Main.get());
988 QVERIFY(new2_trI1Data_I1Main !=
nullptr);
989 QVERIFY(new2_trI1Data_I1Main != trI1Data_I1Main);
990 QVERIFY(new2_trI1Data_I1Main != new_trI1Data_I1Main);
999 void checkSetFrameFrom() {
1007 std::shared_ptr<FrameOfReference> frM1, frI1Main, frI1Data, frI1Arbitrary;
1008 std::shared_ptr<Transformation> trI1Data_I1Main, trI1Arbitrary_I1Data;
1020 QVERIFY(m1->
getFrame() != frM1.get());
1025 QVERIFY(m1->
getFrame() != frM1.get());
1027 QVERIFY(m1->
getFrame() == frI1Main.get());
1032 QVERIFY(i1->
getFrame() != frI1Main.get());
1046 QVERIFY(new_trI1Data_I1Main != trI1Data_I1Main);
1052 QVERIFY(i1->
getFrame() != frI1Main.get());
1060 QVERIFY(new2_trI1Data_I1Main !=
nullptr);
1061 QVERIFY(new2_trI1Data_I1Main != trI1Data_I1Main);
1062 QVERIFY(new2_trI1Data_I1Main != new_trI1Data_I1Main);
1078 void checkPreferredDefaultIdentityToWorldLink() {
1079 auto [frameA, frameB, trA2B] = createFramesAndTransformation(
"FrameA",
"FrameB");
1080 auto [frameC, frameD, trC2D] = createFramesAndTransformation(
"FrameC",
"FrameD");
1083 QCOMPARE(countDefaultIdentityToWorldTransformations(), 4);
1088 QCOMPARE(countDefaultIdentityToWorldTransformations(), 0);
1091 QCOMPARE(countDefaultIdentityToWorldTransformations(), 2);
1095 QCOMPARE(countDefaultIdentityToWorldTransformations(), 2);
1100 QCOMPARE(countDefaultIdentityToWorldTransformations(), 2);
1106 void checkGetAllFrames() {
1111 QCOMPARE(mySphere->
getAllFrames().uniqueKeys().size(), 1);
1114 QCOMPARE(myImage->
getAllFrames(
false).uniqueKeys().size(), 2);
1116 QCOMPARE(myImage->
getAllFrames(
true).uniqueKeys().size(), 3);
1118 QCOMPARE(myImage->
getAllFrames().uniqueKeys().size(), 3);
1140 QCOMPARE(mySphere->
getAllFrames(
true).uniqueKeys().size(), 4);