diff --git a/Core/Code/Controllers/mitkPlanePositionManager.cpp b/Core/Code/Controllers/mitkPlanePositionManager.cpp index fcc6f3bae4..a734d2a456 100644 --- a/Core/Code/Controllers/mitkPlanePositionManager.cpp +++ b/Core/Code/Controllers/mitkPlanePositionManager.cpp @@ -1,136 +1,144 @@ #include "mitkPlanePositionManager.h" #include "mitkInteractionConst.h" mitk::PlanePositionManager::PlanePositionManager() -: m_ID (0) { } mitk::PlanePositionManager::~PlanePositionManager() { for (unsigned int i = 0; i < m_PositionList.size(); i++) { delete m_PositionList.at(i); } } mitk::PlanePositionManager* mitk::PlanePositionManager::GetInstance() { static mitk::PlanePositionManager* m_Instance; if ( m_Instance == 0) { m_Instance = new PlanePositionManager(); } return m_Instance; } unsigned int mitk::PlanePositionManager::AddNewPlanePosition ( const Geometry2D* plane, unsigned int sliceIndex ) { - AffineTransform3D::Pointer transform = AffineTransform3D::New(); - Matrix3D matrix; - matrix.GetVnlMatrix().set_column(0, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); - matrix.GetVnlMatrix().set_column(1, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); - matrix.GetVnlMatrix().set_column(2, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); - transform->SetMatrix(matrix); - transform->SetOffset(plane->GetIndexToWorldTransform()->GetOffset()); - - mitk::Vector3D direction; - direction[0] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[0]; - direction[1] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[1]; - direction[2] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[2]; - direction.Normalize(); - - for (unsigned int i = 0; i < m_PositionList.size(); i++) - { - if (m_PositionList.at(i) != 0) + for (unsigned int i = 0; i < m_PositionList.size(); i++) { - itk::Matrix diffM = plane->GetIndexToWorldTransform()->GetMatrix()-m_PositionList.at(i)->GetTransform()->GetMatrix(); - bool isSameMatrix(true); - for (unsigned int j = 0; j < 3; j++) - { - if (fabs(diffM[j][0]) > 0.00001 || fabs(diffM[j][1]) > 0.00001 || fabs(diffM[j][2]) > 0.00001) + if (m_PositionList.at(i) != 0) { - isSameMatrix = false; - break; + bool isSameMatrix(true); + bool isSameOffset(true); + isSameOffset = mitk::Equal(m_PositionList.at(i)->GetTransform()->GetOffset(), plane->GetIndexToWorldTransform()->GetOffset()); + if(!isSameOffset || sliceIndex != m_PositionList.at(i)->GetPos()) + continue; + isSameMatrix = mitk::MatrixEqualElementWise(m_PositionList.at(i)->GetTransform()->GetMatrix(), plane->GetIndexToWorldTransform()->GetMatrix()); + if(isSameMatrix) + return i; + // itk::Matrix diffM = plane->GetIndexToWorldTransform()->GetMatrix()-m_PositionList.at(i)->GetTransform()->GetMatrix(); + // bool isSameMatrix(true); + // for (unsigned int j = 0; j < 3; j++) + // { + // if (fabs(diffM[j][0]) > 0.00001 || fabs(diffM[j][1]) > 0.00001 || fabs(diffM[j][2]) > 0.00001) + // { + // isSameMatrix = false; + // break; + // } + // } + // itk::Vector diffV = m_PositionList.at(i)->GetTransform()->GetOffset()-transform->GetOffset(); + // if ( isSameMatrix && m_PositionList.at(i)->GetPos() == sliceIndex && (fabs(diffV[0]) < 0.00001 && fabs(diffV[1]) < 0.00001 && fabs(diffV[2]) < 0.00001) ) + // return i; } - } - itk::Vector diffV = m_PositionList.at(i)->GetTransform()->GetOffset()-transform->GetOffset(); - if ( isSameMatrix && m_PositionList.at(i)->GetPos() == sliceIndex && (fabs(diffV[0]) < 0.00001 && fabs(diffV[1]) < 0.00001 && fabs(diffV[2]) < 0.00001) ) - return i; - } - - } - mitk::RestorePlanePositionOperation* newOp = new mitk::RestorePlanePositionOperation (OpRESTOREPLANEPOSITION, plane->GetExtent(0), - plane->GetExtent(1), plane->GetSpacing(), sliceIndex, direction, transform); + } - m_PositionList.push_back( newOp ); - return GetNumberOfPlanePositions()-1; + AffineTransform3D::Pointer transform = AffineTransform3D::New(); + Matrix3D matrix; + matrix.GetVnlMatrix().set_column(0, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); + matrix.GetVnlMatrix().set_column(1, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); + matrix.GetVnlMatrix().set_column(2, plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); + transform->SetMatrix(matrix); + transform->SetOffset(plane->GetIndexToWorldTransform()->GetOffset()); + + mitk::Vector3D direction; + direction[0] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[0]; + direction[1] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[1]; + direction[2] = plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)[2]; + direction.Normalize(); + + mitk::RestorePlanePositionOperation* newOp = new mitk::RestorePlanePositionOperation (OpRESTOREPLANEPOSITION, plane->GetExtent(0), + plane->GetExtent(1), plane->GetSpacing(), sliceIndex, direction, transform); + + m_PositionList.push_back( newOp ); + return GetNumberOfPlanePositions()-1; } bool mitk::PlanePositionManager::RemovePlanePosition( unsigned int ID ) { - if (m_PositionList.size() > ID) + if (m_PositionList.size() > ID && ID >= 0) { - m_PositionList.at(ID) = 0; + m_PositionList.erase(m_PositionList.begin()+ID); + //m_PositionList.at(ID) = 0; return true; } else { return false; } } mitk::RestorePlanePositionOperation* mitk::PlanePositionManager::GetPlanePosition ( unsigned int ID ) { if ( ID < m_PositionList.size() ) { return m_PositionList.at(ID); } else { MITK_WARN<<"GetPlanePosition returned NULL!"; return 0; } } unsigned int mitk::PlanePositionManager::GetNumberOfPlanePositions() { return m_PositionList.size(); } void mitk::PlanePositionManager::RemoveAllPlanePositions() { m_PositionList.clear(); } -void mitk::PlanePositionManager::SetDataStorage( mitk::DataStorage* ds ) -{ - if (ds == NULL) - return; - - /* remove listeners of old DataStorage */ - if (m_DataStorage.IsNotNull()) - { - m_DataStorage->RemoveNodeEvent.RemoveListener(MessageDelegate1( this, &PlanePositionManager::DataStorageRemovedNode )); - } - /* register listener for new DataStorage */ - m_DataStorage = ds; // register - m_DataStorage->RemoveNodeEvent.AddListener(MessageDelegate1( this, &PlanePositionManager::DataStorageRemovedNode )); -} - -void mitk::PlanePositionManager::DataStorageRemovedNode(const mitk::DataNode* removedNode) -{ - bool isContourMarker (false); - if (removedNode->GetBoolProperty("isContourMarker", isContourMarker)) - { - unsigned int t = removedNode->GetName().find_last_of(" "); - unsigned int id = atof(removedNode->GetName().substr(t+1).c_str()); - this->RemovePlanePosition(id-1); - } -} +//void mitk::PlanePositionManager::SetDataStorage( mitk::DataStorage* ds ) +//{ +// if (ds == NULL) +// return; + +// /* remove listeners of old DataStorage */ +// if (m_DataStorage.IsNotNull()) +// { +// m_DataStorage->RemoveNodeEvent.RemoveListener(MessageDelegate1( this, &PlanePositionManager::DataStorageRemovedNode )); +// } +// /* register listener for new DataStorage */ +// m_DataStorage = ds; // register +// m_DataStorage->RemoveNodeEvent.AddListener(MessageDelegate1( this, &PlanePositionManager::DataStorageRemovedNode )); +//} + +//void mitk::PlanePositionManager::DataStorageRemovedNode(const mitk::DataNode* removedNode) +//{ +// bool isContourMarker (false); +// if (removedNode->GetBoolProperty("isContourMarker", isContourMarker)) +// { +// unsigned int t = removedNode->GetName().find_last_of(" "); +// unsigned int id = atof(removedNode->GetName().substr(t+1).c_str()); +// this->RemovePlanePosition(id-1); +// } +//} diff --git a/Core/Code/Controllers/mitkPlanePositionManager.h b/Core/Code/Controllers/mitkPlanePositionManager.h index efd689cdd7..c68b3e5c8a 100644 --- a/Core/Code/Controllers/mitkPlanePositionManager.h +++ b/Core/Code/Controllers/mitkPlanePositionManager.h @@ -1,70 +1,69 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef mitkPlanePositionManager_h_Included #define mitkPlanePositionManager_h_Included #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkRestorePlanePositionOperation.h" #include "mitkDataStorage.h" namespace mitk { class MITK_CORE_EXPORT PlanePositionManager : public itk::Object { public: mitkClassMacro(PlanePositionManager, itk::Object); itkNewMacro(Self); static PlanePositionManager* GetInstance(); unsigned int AddNewPlanePosition(const Geometry2D* plane, unsigned int sliceIndex = 0); bool RemovePlanePosition(unsigned int ID); void RemoveAllPlanePositions(); RestorePlanePositionOperation* GetPlanePosition( unsigned int ID); unsigned int GetNumberOfPlanePositions(); - void DataStorageRemovedNode(const mitk::DataNode* removedNode = NULL); +// void DataStorageRemovedNode(const mitk::DataNode* removedNode = NULL); - void SetDataStorage(mitk::DataStorage* ds); +// void SetDataStorage(mitk::DataStorage* ds); protected: PlanePositionManager(); ~PlanePositionManager(); private: static PlanePositionManager* m_Instance; std::vector m_PositionList; - unsigned int m_ID; - DataStorage::Pointer m_DataStorage; + //DataStorage::Pointer m_DataStorage; }; } #endif diff --git a/Core/Code/Testing/mitkPlanePositionManagerTest.cpp b/Core/Code/Testing/mitkPlanePositionManagerTest.cpp index 3049df4179..c122f1505b 100644 --- a/Core/Code/Testing/mitkPlanePositionManagerTest.cpp +++ b/Core/Code/Testing/mitkPlanePositionManagerTest.cpp @@ -1,316 +1,435 @@ #include "mitkRotationOperation.h" #include "mitkTestingMacros.h" #include "mitkPlanePositionManager.h" #include "mitkSliceNavigationController.h" #include "mitkGeometry3D.h" #include "mitkPlaneGeometry.h" #include "mitkImage.h" #include "mitkSurface.h" #include "mitkStandaloneDataStorage.h" #include "mitkDataNode.h" #include "mitkStringProperty.h" #include "mitkBaseProperty.h" #include "mitkInteractionConst.h" - -//#include "mitkExtractImageFilter.h" -//#include "mitkExtractDirectedPlaneImageFilterNew.h" - +#include "vnl/vnl_vector.h" +#include //TODO: Test GetInstance() / GetService -//SNCs of the image/surface -mitk::SliceNavigationController* sncTransversal; -mitk::SliceNavigationController* sncSagittal; -mitk::SliceNavigationController* sncCoronal; +std::vector m_Geometries; +std::vector m_SliceIndices; -mitk::Image* testImage; -mitk::Surface* testSurface; void SetUpBeforeTest() { - //Creating different + //Creating different Geometries + m_Geometries.reserve(100); + mitk::PlaneGeometry::PlaneOrientation views[] = {mitk::PlaneGeometry::Transversal, mitk::PlaneGeometry::Sagittal, mitk::PlaneGeometry::Frontal}; + for (unsigned int i = 0; i < 100; ++i) + { + mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); + + mitk::ScalarType width = 256+(0.01*i); + mitk::ScalarType height = 256+(0.002*i); + + mitk::Vector3D right; + mitk::Vector3D down; + right[0] = 1; + right[1] = i; + right[2] = 0.5; + down[0] = i*0.02; + down[1] = 1; + down[2] = i*0.03; + + mitk::Vector3D spacing; + mitk::FillVector3D(spacing, 1.0*0.02*i, 1.0*0.15*i, 1.0); + + mitk::Vector3D rightVector; + mitk::FillVector3D(rightVector, 0.02*(i+1), 0+(0.05*i), 1.0); + + mitk::Vector3D downVector; + mitk::FillVector3D(downVector, 1, 3-0.01*i, 0.0345*i); + + vnl_vector normal = vnl_cross_3d(rightVector.GetVnlVector(), downVector.GetVnlVector()); + normal.normalize(); + normal *= 1.5; + + mitk::Vector3D origin; + origin.Fill(1); + origin[0] = 12 + 0.03*i; +// itk::AffineTransform::Pointer transform; + +// mitk::Transform3D + + + mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New(); + mitk::Matrix3D matrix; + matrix.GetVnlMatrix().set_column(0, rightVector.GetVnlVector()); + matrix.GetVnlMatrix().set_column(1, downVector.GetVnlVector()); + matrix.GetVnlMatrix().set_column(2, normal); + transform->SetMatrix(matrix); + transform->SetOffset(origin); + + + plane->InitializeStandardPlane(width, height, transform, + views[i%3], i, + true, false); + + m_Geometries.push_back(plane); + } } void TearDownAfterTest() { } -void testAddPlanePosition() +int testAddPlanePosition() { MITK_TEST_OUTPUT(<<"Starting Test: ######### A d d P l a n e P o s i t i o n #########"); MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance() != NULL, "Testing GetInstance() of PlanePositionManager"); - //Initializing StandardPlanes - mitk::PlaneGeometry::Pointer pos1 = mitk::PlaneGeometry::New(); + mitk::PlaneGeometry::Pointer temp = m_Geometries.at(0); + MITK_INFO<<"DEBUG: "<GetIndexToWorldTransform()->GetMatrix(); - mitk::ScalarType width = 256; - mitk::ScalarType height = 256; + unsigned int currentID(mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(m_Geometries.at(0),0)); - mitk::Vector3D right; - mitk::Vector3D down; - right[0] = 1; - right[1] = 0; - right[2] = 0; - down[0] = 0; - down[1] = 1; - down[2] = 0; + bool error = ((mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() != 1)||(currentID != 0)); - mitk::Vector3D spacing; - mitk::FillVector3D(spacing, 1.0, 1.0, 1.0); + if(error) + { + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 1,"Checking for correct number of planepositions"); + MITK_TEST_CONDITION(currentID == 0, "Testing for correct ID"); + return EXIT_FAILURE; + } - pos1->InitializeStandardPlane(width, height, right.Get_vnl_vector(), down.Get_vnl_vector(), &spacing); + for(unsigned int i = 1; i < m_Geometries.size(); ++i) + { + unsigned int newID = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(m_Geometries.at(i),i); + error = ((mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() != i+1)||(newID != (currentID+1))); - mitk::PlaneGeometry::Pointer pos2 = mitk::PlaneGeometry::New(); - //width, height, vnl right/down, spacing - mitk::ScalarType width2 = 256; - mitk::ScalarType height2 = 256; - mitk::Vector3D right2; - mitk::Vector3D down2; + if (error) + { + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == i+1,"Checking for correct number of planepositions"); + MITK_TEST_CONDITION(newID == (currentID+1), "Testing for correct ID"); + MITK_TEST_OUTPUT(<<"New: "<GetNumberOfPlanePositions(); - down2[0] = 0.1; - down2[1] = 1.1; - down2[2] = 0.0; + for(unsigned int i = 0; i < (m_Geometries.size()-1)*0.5; ++i) + { + unsigned int newID = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(m_Geometries.at(i*2),i*2); + error = ((mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() != numberOfPlanePos)||(newID != i*2)); + if (error) + { + MITK_TEST_CONDITION( mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == numberOfPlanePos, "Checking for correct number of planepositions"); + MITK_TEST_CONDITION(newID == i*2, "Testing for correct ID"); + return EXIT_FAILURE; + } + } - mitk::Vector3D spacing2; - mitk::FillVector3D(spacing2, 1.0, 1.0, 1.0); + return EXIT_SUCCESS; - pos2->InitializeStandardPlane(width2, height2, right2.Get_vnl_vector(), down2.Get_vnl_vector(), &spacing2); +} - unsigned int id1 = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos1, 20); +int testGetPlanePosition() +{ + mitk::PlaneGeometry* plane; + mitk::RestorePlanePositionOperation* op; + bool error(true); - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 1,"Checking for correct number of planepositions"); - MITK_TEST_CONDITION(id1 == 0, "Testing for correct ID"); + MITK_TEST_OUTPUT(<<"Starting Test: ######### G e t P l a n e P o s i t i o n #########"); - //Adding the same Pos again->nothing should change - unsigned int id2 = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos1, 20); + //Testing for existing planepositions + for (unsigned int i = 0; i < m_Geometries.size(); ++i) + { + plane = m_Geometries.at(i); + mitk::PlaneGeometry* test = m_Geometries.at(i); + op = mitk::PlanePositionManager::GetInstance()->GetPlanePosition(i); + error = ( !mitk::Equal(op->GetHeight(),plane->GetExtent(1)) || + !mitk::Equal(op->GetWidth(),plane->GetExtent(0)) || + !mitk::Equal(op->GetSpacing(),plane->GetSpacing()) || + !mitk::Equal(op->GetTransform()->GetOffset(),plane->GetIndexToWorldTransform()->GetOffset()) || + !mitk::Equal(op->GetDirectionVector().Get_vnl_vector(),plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).normalize()) || + !mitk::MatrixEqualElementWise(op->GetTransform()->GetMatrix(), plane->GetIndexToWorldTransform()->GetMatrix()) ); + + if( error ) + { + MITK_TEST_OUTPUT(<<"Iteration: "<GetHeight(),plane->GetExtent(1)) && mitk::Equal(op->GetWidth(),plane->GetExtent(0)), "Checking for correct extent"); + MITK_TEST_CONDITION( mitk::Equal(op->GetSpacing(),plane->GetSpacing()), "Checking for correct spacing"); + MITK_TEST_CONDITION( mitk::Equal(op->GetTransform()->GetOffset(),plane->GetIndexToWorldTransform()->GetOffset()), "Checking for correct offset"); + MITK_INFO<<"Op: "<GetDirectionVector()<<" plane: "<GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)<<"\n"; + MITK_TEST_CONDITION( mitk::Equal(op->GetDirectionVector().Get_vnl_vector(),plane->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)), "Checking for correct direction"); + MITK_TEST_CONDITION( mitk::MatrixEqualElementWise(op->GetTransform()->GetMatrix(), plane->GetIndexToWorldTransform()->GetMatrix()), "Checking for correct matrix"); + return EXIT_FAILURE; + } + } - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 1,"Checking for correct number of planepositions"); - MITK_TEST_CONDITION(id2 == id1, "Testing for correct ID"); + //Testing for not existing planepositions + error = ( mitk::PlanePositionManager::GetInstance()->GetPlanePosition(100000000) != 0 || + mitk::PlanePositionManager::GetInstance()->GetPlanePosition(-1) != 0 ); - //Adding a new Pos -> NumberOfPos should increase - unsigned int id3 = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos2, 20); + if (error) + { + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(100000000) == 0, "Trying to get non existing pos"); + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(-1) == 0, "Trying to get non existing pos"); + return EXIT_FAILURE; + } - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 2,"Checking for correct number of planepositions"); - MITK_TEST_CONDITION(id3 == 1, "Testing for correct ID"); - MITK_TEST_OUTPUT(<GetNumberOfPlanePositions()); + return EXIT_SUCCESS; -} -void testGetPlanePosition() -{ - MITK_TEST_OUTPUT(<<"Starting Test: ######### G e t P l a n e P o s i t i o n #########"); - unsigned int numPos = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); - MITK_TEST_OUTPUT(<<"Current number of Positions: "<GetNumberOfPlanePositions(); +// MITK_TEST_OUTPUT(<<"Current number of Positions: "<InitializeStandardPlane(width, height, right.Get_vnl_vector(), down.Get_vnl_vector(), &spacing); +// pos->InitializeStandardPlane(width, height, right.Get_vnl_vector(), down.Get_vnl_vector(), &spacing); - unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos, 20); +// unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos, 20); - mitk::RestorePlanePositionOperation* op = mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id); +// mitk::RestorePlanePositionOperation* op = mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id); - MITK_TEST_CONDITION(op != 0,"Testing received Pos is not null"); +// MITK_TEST_CONDITION(op != 0,"Testing received Pos is not null"); - MITK_TEST_CONDITION(op->GetHeight() == height, "Testing for correct height"); - MITK_TEST_CONDITION(op->GetWidth() == width, "Testing for correct width"); +// MITK_TEST_CONDITION(op->GetHeight() == height, "Testing for correct height"); +// MITK_TEST_CONDITION(op->GetWidth() == width, "Testing for correct width"); - MITK_TEST_CONDITION(((op->GetSpacing()[0]-spacing[0]) < 0.00001 && (op->GetSpacing()[1]-spacing[1]) < 0.00001 && - (op->GetSpacing()[2]-spacing[2]) < 0.00001), "Testing for correct spacing"); +// MITK_TEST_CONDITION(((op->GetSpacing()[0]-spacing[0]) < 0.00001 && (op->GetSpacing()[1]-spacing[1]) < 0.00001 && +// (op->GetSpacing()[2]-spacing[2]) < 0.00001), "Testing for correct spacing"); - mitk::AffineTransform3D* tr1 = pos->GetIndexToWorldTransform(); - mitk::AffineTransform3D* tr2 = op->GetTransform(); - bool sameMatrix(true); +// mitk::AffineTransform3D* tr1 = pos->GetIndexToWorldTransform(); +// mitk::AffineTransform3D* tr2 = op->GetTransform(); +// bool sameMatrix(true); - for (unsigned int i = 0; i < 3; i++) +// for (unsigned int i = 0; i < 3; i++) +// { +// for (unsigned int j = 0; j < 3; j++) +// { +// if(tr1->GetMatrix()[i][j]-tr2->GetMatrix()[i][j] > 0.00001) +// { +// sameMatrix=false; +// break; +// } +// } +// } + +// mitk::Vector3D offsetDiff = tr1->GetOffset() - tr2->GetOffset(); +// bool sameOffset(offsetDiff[0] < 0.00001 && offsetDiff[1] < 0.00001 && offsetDiff[2] < 0.00001); + +// MITK_TEST_CONDITION((sameMatrix && sameOffset), "Testing for correct transform"); + +// MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(100000000) == 0, "Trying to get non existing pos"); + +} + +int testRemovePlanePosition() +{ + MITK_TEST_OUTPUT(<<"Starting Test: ######### R e m o v e P l a n e P o s i t i o n #########"); + unsigned int size = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); + + bool removed (true); + removed = mitk::PlanePositionManager::GetInstance()->RemovePlanePosition( -1 ); + removed = mitk::PlanePositionManager::GetInstance()->RemovePlanePosition( 1000000 ); + unsigned int size2 = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); + + if (removed) { - for (unsigned int j = 0; j < 3; j++) + MITK_TEST_CONDITION(removed == false, "Testing remove not existing planepositions"); + MITK_TEST_CONDITION(size == size2, "Testing remove not existing planepositions"); + return EXIT_FAILURE; + } + + for (unsigned int i = 0; i < m_Geometries.size()*0.5; i++) + { + removed = mitk::PlanePositionManager::GetInstance()->RemovePlanePosition( i ); + unsigned int size2 = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); + removed = (size2 == (size-(i+1))); + if (!removed) { - if(tr1->GetMatrix()[i][j]-tr2->GetMatrix()[i][j] > 0.00001) - { - sameMatrix=false; - break; - } + MITK_TEST_CONDITION(removed == true, "Testing remove existing planepositions"); + MITK_TEST_CONDITION(size == (size-i+1), "Testing remove existing planepositions"); + return EXIT_FAILURE; } } - mitk::Vector3D offsetDiff = tr1->GetOffset() - tr2->GetOffset(); - bool sameOffset(offsetDiff[0] < 0.00001 && offsetDiff[1] < 0.00001 && offsetDiff[2] < 0.00001); - - MITK_TEST_CONDITION((sameMatrix && sameOffset), "Testing for correct transform"); + return EXIT_SUCCESS; +// MITK_TEST_OUTPUT(<<"Testing RemovePlanePosition - Current number of Position: "<GetPlanePosition(100000000) == 0, "Trying to get non existing pos"); +// bool removed = mitk::PlanePositionManager::GetInstance()->RemovePlanePosition( 0 ); +// bool stillExists (mitk::PlanePositionManager::GetInstance()->GetPlanePosition(0)); +// MITK_TEST_CONDITION((removed && !stillExists), "Testing remove planepos"); } -void testRemovePlanePosition() +int testRemoveAll() { - MITK_TEST_OUTPUT(<<"Starting Test: ######### R e m o v e P l a n e P o s i t i o n #########"); + MITK_TEST_OUTPUT(<<"Starting Test: ######### R e m o v e A l l #########"); + unsigned int numPos = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); - MITK_TEST_OUTPUT(<<"Testing RemovePlanePosition - Current number of Position: "<RemoveAllPlanePositions(); - bool removed = mitk::PlanePositionManager::GetInstance()->RemovePlanePosition( 0 ); - bool stillExists (mitk::PlanePositionManager::GetInstance()->GetPlanePosition(0)); + bool error (true); - MITK_TEST_CONDITION((removed && !stillExists), "Testing remove planepos"); + error = (mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() != 0 || + mitk::PlanePositionManager::GetInstance()->GetPlanePosition(60) != 0); + + if (error) + { + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 0, "Testing remove all pos"); + MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(60) == 0, "Testing remove all pos"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } -void testRestorePlanePosition() +int mitkPlanePositionManagerTest(int argc, char* argv[]) { - //Set up a Geometry3D - mitk::Geometry3D::Pointer geometry3d = mitk::Geometry3D::New(); - float bounds[ ] = {-10.0, 17.0, -12.0, 188.0, 13.0, 211.0}; - geometry3d->Initialize(); - geometry3d->SetFloatBounds(bounds); - - mitk::AffineTransform3D::MatrixType matrix; - matrix.SetIdentity(); - matrix(1,1) = 2; - mitk::AffineTransform3D::Pointer transform; - transform = mitk::AffineTransform3D::New(); - transform->SetMatrix(matrix); - geometry3d->SetIndexToWorldTransform(transform); - - //CreateSNC - mitk::SliceNavigationController::Pointer sliceCtrl = mitk::SliceNavigationController::New(); - sliceCtrl->SetInputWorldGeometry(geometry3d); - sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Original); - - //Rotate Geometry3D - double angle = 35.0; - mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 1, 0, 0 ); - mitk::Point3D center = geometry3d->GetCenter(); - mitk::RotationOperation* op = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle ); - geometry3d->ExecuteOperation(op); - - sliceCtrl->Update(); - - //Save PlanePositon - const mitk::Geometry2D* plane = dynamic_cast (dynamic_cast< const mitk::SlicedGeometry3D*>( - sliceCtrl->GetCurrentGeometry3D())->GetGeometry2D(0)); + MITK_TEST_OUTPUT(<<"Starting Test PlanePositionManager"); + SetUpBeforeTest(); + int result; + MITK_TEST_CONDITION_REQUIRED( (result = testAddPlanePosition()) == EXIT_SUCCESS, ""); + MITK_TEST_CONDITION_REQUIRED( (result = testGetPlanePosition()) == EXIT_SUCCESS, ""); + MITK_TEST_CONDITION_REQUIRED( (result = testRemovePlanePosition()) == EXIT_SUCCESS, ""); + MITK_TEST_CONDITION_REQUIRED( (result = testRemoveAll()) == EXIT_SUCCESS, ""); + return EXIT_SUCCESS; +} - unsigned int size = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); - unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(plane, sliceCtrl->GetSlice()->GetPos()); - //Reinit Geometry3d - // Restore the initial plane pose by undoing the previous rotation - // operation @Swiveller - mitk::RotationOperation* opReset = new mitk::RotationOperation( mitk::OpROTATE, center, - rotationVector, -angle ); - geometry3d->ExecuteOperation(opReset); +//void testRestorePlanePosition() +//{ +// //Set up a Geometry3D +// mitk::Geometry3D::Pointer geometry3d = mitk::Geometry3D::New(); +// float bounds[ ] = {-10.0, 17.0, -12.0, 188.0, 13.0, 211.0}; +// geometry3d->Initialize(); +// geometry3d->SetFloatBounds(bounds); - sliceCtrl->Update(); +// mitk::AffineTransform3D::MatrixType matrix; +// matrix.SetIdentity(); +// matrix(1,1) = 2; +// mitk::AffineTransform3D::Pointer transform; +// transform = mitk::AffineTransform3D::New(); +// transform->SetMatrix(matrix); +// geometry3d->SetIndexToWorldTransform(transform); - //Restore PlanePosition - mitk::RestorePlanePositionOperation* restoreOp = mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id); - sliceCtrl->ExecuteOperation(restoreOp); - sliceCtrl->Update(); +// //CreateSNC +// mitk::SliceNavigationController::Pointer sliceCtrl = mitk::SliceNavigationController::New(); +// sliceCtrl->SetInputWorldGeometry(geometry3d); +// sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Original); - MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(sliceCtrl->GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetMatrix(), restoreOp->GetTransform()->GetMatrix()),"Testing for correct restoration of geometry"); - MITK_TEST_OUTPUT(<<"RestoredMatrix: "<GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetMatrix()<<" OriginalMatrix: "<GetTransform()->GetMatrix()); - MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetOffset(), restoreOp->GetTransform()->GetOffset()), "Testing for correct restoration of geometry"); - MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetSpacing(), restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); - //MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetEx, restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); - MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetSpacing(), restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); - MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetSlice()->GetPos(), restoreOp->GetPos()), "Testing for correct restoration of geometry"); +// //Rotate Geometry3D +// double angle = 35.0; +// mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 1, 0, 0 ); +// mitk::Point3D center = geometry3d->GetCenter(); +// mitk::RotationOperation* op = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle ); +// geometry3d->ExecuteOperation(op); +// sliceCtrl->Update(); -} +// //Save PlanePositon +// const mitk::Geometry2D* plane = dynamic_cast (dynamic_cast< const mitk::SlicedGeometry3D*>( +// sliceCtrl->GetCurrentGeometry3D())->GetGeometry2D(0)); -void testDataStorageNodeRemoved() -{ - MITK_TEST_OUTPUT(<<"Starting Test: ######### D a t a S t o r a g e N o d e R e m o v e d #########"); +// unsigned int size = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); +// unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(plane, sliceCtrl->GetSlice()->GetPos()); +// //Reinit Geometry3d - mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); +// // Restore the initial plane pose by undoing the previous rotation +// // operation @Swiveller +// mitk::RotationOperation* opReset = new mitk::RotationOperation( mitk::OpROTATE, center, +// rotationVector, -angle ); +// geometry3d->ExecuteOperation(opReset); - mitk::PlanePositionManager::GetInstance()->SetDataStorage(ds); +// sliceCtrl->Update(); - mitk::PlaneGeometry::Pointer pos = mitk::PlaneGeometry::New(); - //width, height, vnl right/down, spacing - mitk::ScalarType width = 1024; - mitk::ScalarType height = 1024; - mitk::Vector3D right; - mitk::Vector3D down; +// //Restore PlanePosition +// mitk::RestorePlanePositionOperation* restoreOp = mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id); +// sliceCtrl->ExecuteOperation(restoreOp); +// sliceCtrl->Update(); - right[0] = 0.3723; - right[1] = 0.938; - right[2] = 1.0; +// MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(sliceCtrl->GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetMatrix(), restoreOp->GetTransform()->GetMatrix()),"Testing for correct restoration of geometry"); +// MITK_TEST_OUTPUT(<<"RestoredMatrix: "<GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetMatrix()<<" OriginalMatrix: "<GetTransform()->GetMatrix()); +// MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetIndexToWorldTransform()->GetOffset(), restoreOp->GetTransform()->GetOffset()), "Testing for correct restoration of geometry"); +// MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetSpacing(), restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); +// //MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetEx, restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); +// MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetCreatedWorldGeometry()->GetSpacing(), restoreOp->GetSpacing()), "Testing for correct restoration of geometry"); +// MITK_TEST_CONDITION(mitk::Equal(sliceCtrl->GetSlice()->GetPos(), restoreOp->GetPos()), "Testing for correct restoration of geometry"); - down[0] = 1.0; - down[1] = 0.57; - down[2] = 1.0; - mitk::Vector3D spacing; - mitk::FillVector3D(spacing, 0.5674, 1.0, 1.0); +//} - pos->InitializeStandardPlane(width, height, right.Get_vnl_vector(), down.Get_vnl_vector(), &spacing); +//void testDataStorageNodeRemoved() +//{ +// MITK_TEST_OUTPUT(<<"Starting Test: ######### D a t a S t o r a g e N o d e R e m o v e d #########"); - unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos, 20); +// mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); - std::stringstream markerStream; - markerStream << "Position"; - markerStream << " "; - markerStream << id+1; +// mitk::PlanePositionManager::GetInstance()->SetDataStorage(ds); - mitk::DataNode::Pointer rotatedContourNode = mitk::DataNode::New(); +// mitk::PlaneGeometry::Pointer pos = mitk::PlaneGeometry::New(); +// //width, height, vnl right/down, spacing +// mitk::ScalarType width = 1024; +// mitk::ScalarType height = 1024; +// mitk::Vector3D right; +// mitk::Vector3D down; - //rotatedContourNode->SetData(contourMarker); - rotatedContourNode->SetProperty( "name", mitk::StringProperty::New(markerStream.str()) ); - rotatedContourNode->SetProperty( "isContourMarker", mitk::BoolProperty::New(true)); - ds->Add(rotatedContourNode); +// right[0] = 0.3723; +// right[1] = 0.938; +// right[2] = 1.0; - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id) != 0, "Testing DataStorage Node removed"); +// down[0] = 1.0; +// down[1] = 0.57; +// down[2] = 1.0; - ds->Remove(rotatedContourNode); +// mitk::Vector3D spacing; +// mitk::FillVector3D(spacing, 0.5674, 1.0, 1.0); - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id) == 0, "Testing DataStorage Node removed"); -} +// pos->InitializeStandardPlane(width, height, right.Get_vnl_vector(), down.Get_vnl_vector(), &spacing); -void testRemoveAll() -{ - MITK_TEST_OUTPUT(<<"Starting Test: ######### R e m o v e A l l #########"); +// unsigned int id = mitk::PlanePositionManager::GetInstance()->AddNewPlanePosition(pos, 20); - unsigned int numPos = mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions(); - MITK_TEST_OUTPUT(<<"Testing RemovePlanePosition - Current number of Position: "<RemoveAllPlanePositions(); +// mitk::DataNode::Pointer rotatedContourNode = mitk::DataNode::New(); - MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetNumberOfPlanePositions() == 0, "Testing remove all pos"); +// //rotatedContourNode->SetData(contourMarker); +// rotatedContourNode->SetProperty( "name", mitk::StringProperty::New(markerStream.str()) ); +// rotatedContourNode->SetProperty( "isContourMarker", mitk::BoolProperty::New(true)); +// ds->Add(rotatedContourNode); +// MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id) != 0, "Testing DataStorage Node removed"); -} +// ds->Remove(rotatedContourNode); -int mitkPlanePositionManagerTest(int argc, char* argv[]) -{ - MITK_TEST_OUTPUT(<<"Starting Test PlanePositionManager"); - testAddPlanePosition(); - testGetPlanePosition(); - testRemovePlanePosition(); - testRemoveAll(); - testDataStorageNodeRemoved(); - testRestorePlanePosition(); - return 0; -} +// MITK_TEST_CONDITION(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id) == 0, "Testing DataStorage Node removed"); +//} diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp index f71ffe7637..4ea1dfde68 100644 --- a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp @@ -1,938 +1,938 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDataNodeObject.h" #include "mitkProperties.h" #include "mitkSegTool2D.h" #include "mitkGlobalInteraction.h" #include "QmitkStdMultiWidget.h" #include "QmitkNewSegmentationDialog.h" #include #include #include "QmitkSegmentationView.h" #include "QmitkSegmentationPostProcessing.h" #include "QmitkSegmentationOrganNamesHandling.cpp" #include #include #include "mitkVtkResliceInterpolationProperty.h" const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation"; // public methods QmitkSegmentationView::QmitkSegmentationView() :m_Parent(NULL) ,m_Controls(NULL) ,m_MultiWidget(NULL) ,m_RenderingManagerObserverTag(0) { } QmitkSegmentationView::~QmitkSegmentationView() { // delete m_PostProcessing; delete m_Controls; } void QmitkSegmentationView::NewNodesGenerated() { // ForceDisplayPreferencesUponAllImages(); } void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes) { if (!nodes) return; mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); if (!toolManager) return; for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter) { this->FireNodeSelected( *iter ); // only last iteration meaningful, multiple generated objects are not taken into account here } } void QmitkSegmentationView::Activated() { // should be moved to ::BecomesVisible() or similar if( m_Controls ) { m_Controls->m_ManualToolSelectionBox->setEnabled( true ); m_Controls->m_OrganToolSelectionBox->setEnabled( true ); m_Controls->m_LesionToolSelectionBox->setEnabled( true ); m_Controls->m_SlicesInterpolator->EnableInterpolation( m_Controls->widgetStack->currentWidget() == m_Controls->pageManual ); itk::ReceptorMemberCommand::Pointer command1 = itk::ReceptorMemberCommand::New(); command1->SetCallbackFunction( this, &QmitkSegmentationView::RenderingManagerReinitialized ); m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver( mitk::RenderingManagerViewsInitializedEvent(), command1 ); - mitk::PlanePositionManager::GetInstance()->SetDataStorage(this->GetDataStorage()); + //mitk::PlanePositionManager::GetInstance()->SetDataStorage(this->GetDataStorage()); } } void QmitkSegmentationView::Deactivated() { if( m_Controls ) { mitk::RenderingManager::GetInstance()->RemoveObserver( m_RenderingManagerObserverTag ); m_Controls->m_ManualToolSelectionBox->setEnabled( false ); //deactivate all tools m_Controls->m_ManualToolSelectionBox->GetToolManager()->ActivateTool(-1); m_Controls->m_OrganToolSelectionBox->setEnabled( false ); m_Controls->m_LesionToolSelectionBox->setEnabled( false ); m_Controls->m_SlicesInterpolator->EnableInterpolation( false ); mitk::PlanePositionManager::GetInstance()->RemoveAllPlanePositions(); } } void QmitkSegmentationView::StdMultiWidgetAvailable( QmitkStdMultiWidget& stdMultiWidget ) { SetMultiWidget(&stdMultiWidget); } void QmitkSegmentationView::StdMultiWidgetNotAvailable() { SetMultiWidget(NULL); } void QmitkSegmentationView::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ ) { SetMultiWidget(NULL); } void QmitkSegmentationView::SetMultiWidget(QmitkStdMultiWidget* multiWidget) { if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { coordinator->RemoveObserver( m_SlicesRotationObserverTag1 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { coordinator->RemoveObserver( m_SlicesRotationObserverTag2 ); } } // save the current multiwidget as the working widget m_MultiWidget = multiWidget; if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkSegmentationView::SliceRotation ); m_SlicesRotationObserverTag1 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkSegmentationView::SliceRotation ); m_SlicesRotationObserverTag2 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } } if (m_Parent) { m_Parent->setEnabled(m_MultiWidget); } // tell the interpolation about toolmanager and multiwidget (and data storage) if (m_Controls && m_MultiWidget) { mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); m_Controls->m_SlicesInterpolator->SetDataStorage( *(this->GetDefaultDataStorage())); m_Controls->m_SlicesInterpolator->Initialize( toolManager, m_MultiWidget ); } } void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences*) { ForceDisplayPreferencesUponAllImages(); } void QmitkSegmentationView::RenderingManagerReinitialized(const itk::EventObject&) { CheckImageAlignment(); } void QmitkSegmentationView::SliceRotation(const itk::EventObject&) { CheckImageAlignment(); } // protected slots void QmitkSegmentationView::CreateNewSegmentation() { mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull()) { if (image->GetDimension()>2) { // ask about the name and organ type of the new segmentation QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog( m_Parent ); // needs a QWidget as parent, "this" is not QWidget QString storedList = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); QStringList organColors; if (storedList.isEmpty()) { organColors = GetDefaultOrganColorString(); } else { /* a couple of examples of how organ names are stored: a simple item is built up like 'name#AABBCC' where #AABBCC is the hexadecimal notation of a color as known from HTML items are stored separated by ';' this makes it necessary to escape occurrences of ';' in name. otherwise the string "hugo;ypsilon#AABBCC;eugen#AABBCC" could not be parsed as two organs but we would get "hugo" and "ypsilon#AABBCC" and "eugen#AABBCC" so the organ name "hugo;ypsilon" is stored as "hugo\;ypsilon" and must be unescaped after loading the following lines could be one split with Perl's negative lookbehind */ // recover string list from BlueBerry view's preferences QString storedString = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); MITK_DEBUG << "storedString: " << storedString.toStdString(); // match a string consisting of any number of repetitions of either "anything but ;" or "\;". This matches everything until the next unescaped ';' QRegExp onePart("(?:[^;]|\\\\;)*"); MITK_DEBUG << "matching " << onePart.pattern().toStdString(); int count = 0; int pos = 0; while( (pos = onePart.indexIn( storedString, pos )) != -1 ) { ++count; int length = onePart.matchedLength(); if (length == 0) break; QString matchedString = storedString.mid(pos, length); MITK_DEBUG << " Captured length " << length << ": " << matchedString.toStdString(); pos += length + 1; // skip separating ';' // unescape possible occurrences of '\;' in the string matchedString.replace("\\;", ";"); // add matched string part to output list organColors << matchedString; } MITK_DEBUG << "Captured " << count << " organ name/colors"; } dialog->SetSuggestionList( organColors ); int dialogReturnValue = dialog->exec(); if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar // ask the user about an organ type and name, add this information to the image's (!) propertylist // create a new image of the same dimensions and smallest possible pixel type mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); mitk::Tool* firstTool = toolManager->GetToolById(0); if (firstTool) { try { mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode( image, dialog->GetSegmentationName().toStdString(), dialog->GetColor() ); //Here we change the reslice interpolation mode for a segmentation, so that contours in rotated slice can be shown correctly emptySegmentation->SetProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_LINEAR) ); // initialize showVolume to false to prevent recalculating the volume while working on the segmentation emptySegmentation->SetProperty( "showVolume", mitk::BoolProperty::New( false ) ); if (!emptySegmentation) return; // could be aborted by user UpdateOrganList( organColors, dialog->GetSegmentationName(), dialog->GetColor() ); /* escape ';' here (replace by '\;'), see longer comment above */ std::string stringForStorage = organColors.replaceInStrings(";","\\;").join(";").toStdString(); MITK_DEBUG << "Will store: " << stringForStorage; this->GetPreferences()->PutByteArray("Organ-Color-List", stringForStorage ); this->GetPreferences()->Flush(); this->GetDefaultDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original this->FireNodeSelected( emptySegmentation ); this->OnSelectionChanged( emptySegmentation ); } catch (std::bad_alloc) { QMessageBox::warning(NULL,"Create new segmentation","Could not allocate memory for new segmentation"); } } } else { QMessageBox::information(NULL,"Segmentation","Segmentation is currently not supported for 2D images"); } } } else { MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected..."; } } void QmitkSegmentationView::CreateSegmentationFromSurface() { mitk::DataNode::Pointer surfaceNode = m_Controls->MaskSurfaces->GetSelectedNode(); mitk::Surface::Pointer surface(0); if(surfaceNode.IsNotNull()) surface = dynamic_cast ( surfaceNode->GetData() ); if(surface.IsNull()) { this->HandleException( "No surface selected.", m_Parent, true); return; } mitk::DataNode::Pointer imageNode = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); mitk::Image::Pointer image(0); if (imageNode.IsNotNull()) image = dynamic_cast( imageNode->GetData() ); if(image.IsNull()) { this->HandleException( "No image selected.", m_Parent, true); return; } mitk::SurfaceToImageFilter::Pointer s2iFilter = mitk::SurfaceToImageFilter::New(); s2iFilter->MakeOutputBinaryOn(); s2iFilter->SetInput(surface); s2iFilter->SetImage(image); s2iFilter->Update(); mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); std::string nameOfResultImage = imageNode->GetName(); nameOfResultImage.append(surfaceNode->GetName()); resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); resultNode->SetData( s2iFilter->GetOutput() ); this->GetDataStorage()->Add(resultNode, imageNode); } void QmitkSegmentationView::ManualToolSelected(int id) { // disable crosshair movement when a manual drawing tool is active (otherwise too much visual noise) if (m_MultiWidget) { if (id >= 0) { m_MultiWidget->DisableNavigationControllerEventListening(); m_MultiWidget->SetWidgetPlaneMode(0); } else { m_MultiWidget->EnableNavigationControllerEventListening(); } } } void QmitkSegmentationView::ToolboxStackPageChanged(int id) { // interpolation only with manual tools visible m_Controls->m_SlicesInterpolator->EnableInterpolation( id == 0 ); if( id == 0 ) { mitk::DataNode::Pointer workingData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0); if( workingData.IsNotNull() ) { m_Controls->lblSegmentation->setText( workingData->GetName().c_str() ); m_Controls->lblSegImage->show(); m_Controls->lblSegmentation->show(); } } else { m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } // this is just a workaround, should be removed when all tools support 3D+t if (id==2) // lesions { mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull()) { if (image->GetDimension()>3) { m_Controls->widgetStack->setCurrentIndex(0); QMessageBox::information(NULL,"Segmentation","Lesion segmentation is currently not supported for 4D images"); } } } } } // protected void QmitkSegmentationView::OnComboBoxSelectionChanged( const mitk::DataNode* node ) { mitk::DataNode* selectedNode = const_cast(node); if( selectedNode != NULL ) { m_Controls->refImageSelector->show(); m_Controls->lblReferenceImageSelectionWarning->hide(); this->OnSelectionChanged( const_cast(node) ); } else { m_Controls->refImageSelector->hide(); m_Controls->lblReferenceImageSelectionWarning->show(); } } //to remember the contour positions void QmitkSegmentationView::CheckboxRememberContourPositionsStateChanged (int state) { mitk::SegTool2D::Pointer manualSegmentationTool; unsigned int numberOfExistingTools = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetTools().size(); for(unsigned int i = 0; i < numberOfExistingTools; i++) { manualSegmentationTool = dynamic_cast(m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetToolById(i)); if (manualSegmentationTool) { if(state == Qt::Checked) { manualSegmentationTool->SetRememberContourPositions( true ); } else { manualSegmentationTool->SetRememberContourPositions( false ); } } } } void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node) { std::vector nodes; nodes.push_back( node ); this->OnSelectionChanged( nodes ); } void QmitkSegmentationView::OnSurfaceSelectionChanged() { // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull())) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); } void QmitkSegmentationView::OnSelectionChanged(std::vector nodes) { // if the selected node is a contourmarker if ( !nodes.empty() ) { std::string markerName = "Position"; unsigned int numberOfNodes = nodes.size(); std::string nodeName = nodes.at( 0 )->GetName(); if ( ( numberOfNodes == 1 ) && ( nodeName.find( markerName ) == 0) ) { this->OnContourMarkerSelected( nodes.at( 0 ) ); } } // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull())) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); if (!m_Parent || !m_Parent->isVisible()) return; // reaction to BlueBerry selection events // this method will try to figure out if a relevant segmentation and its corresponding original image were selected // a warning is issued if the selection is invalid // appropriate reactions are triggered otherwise mitk::DataNode::Pointer referenceData = FindFirstRegularImage( nodes ); //m_Controls->refImageSelector->GetSelectedNode(); //FindFirstRegularImage( nodes ); mitk::DataNode::Pointer workingData = FindFirstSegmentation( nodes ); bool invalidSelection( !nodes.empty() && ( nodes.size() > 2 || // maximum 2 selected nodes (nodes.size() == 2 && (workingData.IsNull() || referenceData.IsNull()) ) || // with two nodes, one must be the original image, one the segmentation ( workingData.GetPointer() == referenceData.GetPointer() ) //one node is selected as reference and working image // one item is always ok (might be working or reference or nothing ) ); if (invalidSelection) { // TODO visible warning when two images are selected MITK_ERROR << "WARNING: No image, too many (>2) or two equal images were selected."; workingData = NULL; if( m_Controls->refImageSelector->GetSelectedNode().IsNull() ) referenceData = NULL; } if ( workingData.IsNotNull() && referenceData.IsNull() ) { // find the DataStorage parent of workingData // try to find a "normal image" parent, select this as reference image mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary ); mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary ); mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( workingData, isNormalImage ); if (possibleParents->size() > 0) { if (possibleParents->size() > 1) { // TODO visible warning for this rare case MITK_ERROR << "Selected binary image has multiple parents. Using arbitrary first one for segmentation."; } referenceData = (*possibleParents)[0]; } } //set comboBox to reference image disconnect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->refImageSelector->setCurrentIndex( m_Controls->refImageSelector->Find(referenceData) ); connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull()) || (!referenceData)) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); SetToolManagerSelection(referenceData, workingData); ForceDisplayPreferencesUponAllImages(); } //New since rotated contour drawing is allowed. Effects a reorientation of the plane of the affected widget to the marker`s position void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node) { //TODO renderWindow anders bestimmen, siehe CheckAlignment QmitkRenderWindow* selectedRenderWindow = 0; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); bool PlanarFigureInitializedWindow = false; // find initialized renderwindow if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } // make node visible if (selectedRenderWindow) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t+1).c_str())-1; //selectedRenderWindow->GetSliceNavigationController()->RestorePlanePosition(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id)); selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(mitk::PlanePositionManager::GetInstance()->GetPlanePosition(id)); selectedRenderWindow->GetRenderer()->GetDisplayGeometry()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } mitk::DataNode::Pointer QmitkSegmentationView::FindFirstRegularImage( std::vector nodes ) { if (nodes.empty()) return NULL; for(unsigned int i = 0; i < nodes.size(); ++i) { //mitk::DataNode::Pointer node = i.value() bool isImage(false); if (nodes.at(i)->GetData()) { isImage = dynamic_cast(nodes.at(i)->GetData()) != NULL; } // make sure this is not a binary image bool isSegmentation(false); nodes.at(i)->GetBoolProperty("binary", isSegmentation); // return first proper mitk::Image if (isImage && !isSegmentation) return nodes.at(i); } return NULL; } mitk::DataNode::Pointer QmitkSegmentationView::FindFirstSegmentation( std::vector nodes ) { if (nodes.empty()) return NULL; for(unsigned int i = 0; i < nodes.size(); ++i) { bool isImage(false); if (nodes.at(i)->GetData()) { isImage = dynamic_cast(nodes.at(i)->GetData()) != NULL; } bool isSegmentation(false); nodes.at(i)->GetBoolProperty("binary", isSegmentation); // return first proper binary mitk::Image if (isImage && isSegmentation) { return nodes.at(i); } } return NULL; } void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData) { // called as a result of new BlueBerry selections // tells the ToolManager for manual segmentation about new selections // updates GUI information about what the user should select mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); toolManager->SetReferenceData(const_cast(referenceData)); toolManager->SetWorkingData( const_cast(workingData)); // check original image m_Controls->btnNewSegmentation->setEnabled(referenceData != NULL); if (referenceData) { m_Controls->lblReferenceImageSelectionWarning->hide(); } else { m_Controls->lblReferenceImageSelectionWarning->show(); m_Controls->lblWorkingImageSelectionWarning->hide(); m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } // check, wheter reference image is aligned like render windows. Otherwise display a visible warning (because 2D tools will probably not work) CheckImageAlignment(); // check segmentation if (referenceData) { if (!workingData) { m_Controls->lblWorkingImageSelectionWarning->show(); if( m_Controls->widgetStack->currentIndex() == 0 ) { m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } } else { m_Controls->lblWorkingImageSelectionWarning->hide(); if( m_Controls->widgetStack->currentIndex() == 0 ) { m_Controls->lblSegmentation->setText( workingData->GetName().c_str() ); m_Controls->lblSegmentation->show(); m_Controls->lblSegImage->show(); } } } } void QmitkSegmentationView::CheckImageAlignment() { bool wrongAlignment(true); mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull() && m_MultiWidget) { wrongAlignment = !( IsRenderWindowAligned(m_MultiWidget->GetRenderWindow1(), image ) && IsRenderWindowAligned(m_MultiWidget->GetRenderWindow2(), image ) && IsRenderWindowAligned(m_MultiWidget->GetRenderWindow3(), image ) ); } if (wrongAlignment) { m_Controls->lblAlignmentWarning->show(); } } } bool QmitkSegmentationView::IsRenderWindowAligned(QmitkRenderWindow* renderWindow, mitk::Image* image) { if (!renderWindow) return false; // for all 2D renderwindows of m_MultiWidget check alignment mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( renderWindow->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; int affectedDimension(-1); int affectedSlice(-1); return mitk::SegTool2D::DetermineAffectedImageSlice( image, displayPlane, affectedDimension, affectedSlice ); } void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages() { if (!m_Parent || !m_Parent->isVisible()) return; // check all images and segmentations in DataStorage: // (items in brackets are implicitly done by previous steps) // 1. // if a reference image is selected, // show the reference image // and hide all other images (orignal and segmentation), // (and hide all segmentations of the other original images) // and show all the reference's segmentations // if no reference image is selected, do do nothing // // 2. // if a segmentation is selected, // show it // (and hide all all its siblings (childs of the same parent, incl, NULL parent)) // if no segmentation is selected, do nothing if (!m_Controls) return; // might happen on initialization (preferences loaded) mitk::DataNode::Pointer referenceData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); mitk::DataNode::Pointer workingData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0); // 1. if (referenceData.IsNotNull()) { // iterate all images mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDefaultDataStorage()->GetSubset( isImage ); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { mitk::DataNode* node = *iter; // apply display preferences ApplyDisplayOptions(node); // set visibility node->SetVisibility(node == referenceData); } } // 2. if (workingData.IsNotNull()) { workingData->SetVisibility(true); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) { if (!node) return; bool isBinary(false); node->GetPropertyValue("binary", isBinary); if (isBinary) { node->SetProperty( "outline binary", mitk::BoolProperty::New( this->GetPreferences()->GetBool("draw outline", true)) ); node->SetProperty( "outline width", mitk::FloatProperty::New( 2.0 ) ); node->SetProperty( "opacity", mitk::FloatProperty::New( this->GetPreferences()->GetBool("draw outline", true) ? 1.0 : 0.3 ) ); node->SetProperty( "volumerendering", mitk::BoolProperty::New( this->GetPreferences()->GetBool("volume rendering", false) ) ); } } void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) { // setup the basic GUI of this view m_Parent = parent; m_Controls = new Ui::QmitkSegmentationControls; m_Controls->setupUi(parent); m_Controls->lblWorkingImageSelectionWarning->hide(); m_Controls->lblAlignmentWarning->hide(); m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); m_Controls->refImageSelector->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->refImageSelector->SetPredicate(mitk::NodePredicateDataType::New("Image")); if( m_Controls->refImageSelector->GetSelectedNode().IsNotNull() ) m_Controls->lblReferenceImageSelectionWarning->hide(); else m_Controls->refImageSelector->hide(); mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); toolManager->SetDataStorage( *(this->GetDefaultDataStorage()) ); assert ( toolManager ); // all part of open source MITK m_Controls->m_ManualToolSelectionBox->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer ); m_Controls->m_ManualToolSelectionBox->SetDisplayedToolGroups("Add Subtract Paint Wipe 'Region Growing' Correction Fill Erase"); m_Controls->m_ManualToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingData ); // available only in the 3M application if ( !m_Controls->m_OrganToolSelectionBox->children().count() ) { m_Controls->widgetStack->setItemEnabled( 1, false ); } m_Controls->m_OrganToolSelectionBox->SetToolManager( *toolManager ); m_Controls->m_OrganToolSelectionBox->SetToolGUIArea( m_Controls->m_OrganToolGUIContainer ); m_Controls->m_OrganToolSelectionBox->SetDisplayedToolGroups("'Hippocampus left' 'Hippocampus right' 'Lung left' 'Lung right' 'Liver' 'Heart LV' 'Endocard LV' 'Epicard LV' 'Prostate'"); m_Controls->m_OrganToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceData ); // available only in the 3M application if ( !m_Controls->m_LesionToolSelectionBox->children().count() ) { m_Controls->widgetStack->setItemEnabled( 2, false ); } m_Controls->m_LesionToolSelectionBox->SetToolManager( *toolManager ); m_Controls->m_LesionToolSelectionBox->SetToolGUIArea( m_Controls->m_LesionToolGUIContainer ); m_Controls->m_LesionToolSelectionBox->SetDisplayedToolGroups("'Lymph Node'"); m_Controls->m_LesionToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceData ); toolManager->NewNodesGenerated += mitk::MessageDelegate( this, &QmitkSegmentationView::NewNodesGenerated ); // update the list of segmentations toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1( this, &QmitkSegmentationView::NewNodeObjectsGenerated ); // update the list of segmentations // create signal/slot connections connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) ); connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) ); connect( m_Controls->m_ManualToolSelectionBox, SIGNAL(ToolSelected(int)), this, SLOT(ManualToolSelected(int)) ); connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) ); //To remember the position of each contour connect( m_Controls->cbRememberContourPositions, SIGNAL(stateChanged(int)), this, SLOT(CheckboxRememberContourPositionsStateChanged(int))); connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSurfaceSelectionChanged( ) ) ); m_Controls->MaskSurfaces->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface")); //// create helper class to provide context menus for segmentations in data manager // m_PostProcessing = new QmitkSegmentationPostProcessing(this->GetDefaultDataStorage(), this, m_Parent); } //void QmitkSegmentationView::OnPlaneModeChanged(int i) //{ // //if plane mode changes, disable all tools // if (m_MultiWidget) // { // mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); // // if (toolManager) // { // if (toolManager->GetActiveToolID() >= 0) // { // toolManager->ActivateTool(-1); // } // else // { // m_MultiWidget->EnableNavigationControllerEventListening(); // } // } // } //} // ATTENTION some methods for handling the known list of (organ names, colors) are defined in QmitkSegmentationOrganNamesHandling.cpp