From b0f9ef265dbfc67374eaa989e606d2b00d634f76 Mon Sep 17 00:00:00 2001 From: tbaudier Date: Thu, 7 Jan 2016 16:24:49 +0100 Subject: [PATCH] Add funtions to Profile tool Display the two selected points Save the coordinates in mm Compute the profile automaticaly Allow the user to choose the name of the saving file Prepare for the display of a line between the 2 selected points --- tools/clitkProfileImageGenericFilter.cxx | 18 ++ vv/qt_ui/vvToolProfile.ui | 28 +- vv/vvLandmarks.cxx | 35 +++ vv/vvLandmarks.h | 2 + vv/vvLandmarksPanel.cxx | 27 +- vv/vvSlicerManager.cxx | 40 ++- vv/vvSlicerManager.h | 7 +- vv/vvSlicerManagerCommand.cxx | 2 +- vv/vvToolProfile.cxx | 310 +++++++++++++++++++---- vv/vvToolProfile.h | 9 +- 10 files changed, 403 insertions(+), 75 deletions(-) diff --git a/tools/clitkProfileImageGenericFilter.cxx b/tools/clitkProfileImageGenericFilter.cxx index 1eb58c2..89edb0b 100644 --- a/tools/clitkProfileImageGenericFilter.cxx +++ b/tools/clitkProfileImageGenericFilter.cxx @@ -120,6 +120,13 @@ ProfileImageGenericFilter::UpdateWithInputImageType() mCoord = vtkSmartPointer::New(); mCoord->SetNumberOfComponents(InputImageType::ImageDimension); + /*typename InputImageType::Pointer outputImage; + outputImage = InputImageType::New(); + + outputImage->SetRegions(input->GetLargestPossibleRegion()); + outputImage->Allocate(); + outputImage->FillBuffer(0); */ + //Iterator IndexType pointBegin, pointEnd; @@ -149,6 +156,17 @@ ProfileImageGenericFilter::UpdateWithInputImageType() ++itProfile; } + /* + itk::LineIterator otProfile(outputImage, pointBegin, pointEnd); + otProfile.GoToBegin(); + while (!otProfile.IsAtEnd()) + { + otProfile.Set(1.0); + ++otProfile; + } + + this->template SetNextOutput(outputImage): */ + delete [] tuple; } //-------------------------------------------------------------------- diff --git a/vv/qt_ui/vvToolProfile.ui b/vv/qt_ui/vvToolProfile.ui index f9edb6d..2cbddab 100644 --- a/vv/qt_ui/vvToolProfile.ui +++ b/vv/qt_ui/vvToolProfile.ui @@ -43,6 +43,18 @@ + + + 0 + 0 + + + + + 200 + 0 + + @@ -60,7 +72,7 @@ - + 0 @@ -68,7 +80,7 @@ - Compute Profile + Save Profile @@ -96,6 +108,18 @@ + + + 0 + 0 + + + + + 200 + 0 + + diff --git a/vv/vvLandmarks.cxx b/vv/vvLandmarks.cxx index d0f2c91..dc38cd2 100644 --- a/vv/vvLandmarks.cxx +++ b/vv/vvLandmarks.cxx @@ -118,6 +118,41 @@ void vvLandmarks::RemoveLastLandmark() //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +void vvLandmarks::RemoveLandmarkWithLabel(vtkStdString label, int time) +{ + if (label != "P1" && label != "P2") + return; + // erase a vtkPoint by shifiting the array . + // not a problem here because there are no + // pologyons linking the points + int t = time;//mLandmarks[index].coordinates[3]; + int npoints = mPoints[t]->GetNumberOfPoints(); + + //search of the index corresponding to the label + int index(0); + while (mLabels[t]->GetValue(index) != label) + ++index; + + for (int i = index; i < npoints - 1; i++) { + mPoints[t]->InsertPoint(i, mPoints[t]->GetPoint(i+1)); + std::string str_i; // string which will contain the result + std::ostringstream convert; // stream used for the conversion + convert << i; // insert the textual representation of 'i' in the characters in the stream + str_i = convert.str(); // set 'str_i' to the contents of the stream + mLabels[t]->SetValue(i,mLabels[t]->GetValue(i+1)); + } + mPoints[t]->SetNumberOfPoints(npoints-1); + mLabels[t]->SetNumberOfValues(npoints-1); + mLabels[t]->Modified(); + mPolyData->Modified(); + + mLandmarks[t].erase(mLandmarks[t].begin() + index); + mIds[t]->RemoveLastTuple(); +} +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- void vvLandmarks::RemoveLandmark(int index) { diff --git a/vv/vvLandmarks.h b/vv/vvLandmarks.h index 7920d6f..6f7e91f 100644 --- a/vv/vvLandmarks.h +++ b/vv/vvLandmarks.h @@ -44,6 +44,7 @@ public : void AddLandmark(float x,float y,float z,float t,double value); void RemoveLastLandmark(); + void RemoveLandmarkWithLabel(vtkStdString, int); void RemoveLandmark(int index); void RemoveAll(); @@ -51,6 +52,7 @@ public : float* GetCoordinates(int index); double GetPixelValue(int index); std::string GetComments(int index); + vtkStringArray* GetLabels() { return mLabels[mTime]; } unsigned int GetNumberOfPoints() { return (unsigned int) mLandmarks[mTime].size(); } //int GetNumberOfSources(){return mText.size();} diff --git a/vv/vvLandmarksPanel.cxx b/vv/vvLandmarksPanel.cxx index 1c6d84a..f23631c 100644 --- a/vv/vvLandmarksPanel.cxx +++ b/vv/vvLandmarksPanel.cxx @@ -30,7 +30,7 @@ //==================================================================== vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent) -{ //out << __func__ << endl; +{ setupUi(this); tableWidget->verticalHeader()->hide(); @@ -48,7 +48,7 @@ vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent) } void vvLandmarksPanel::Load() -{ //out << __func__ << endl; +{ QString file = QFileDialog::getOpenFileName(this,tr("Load Landmarks"), mCurrentPath.c_str(),tr("Landmarks ( *.txt *.pts)")); if (!file.isEmpty()) { @@ -58,7 +58,7 @@ void vvLandmarksPanel::Load() } bool vvLandmarksPanel::LoadFromFile(std::vector files) -{ //out << __func__ << endl; +{ if (!mCurrentLandmarks->LoadFile(files)) return false; @@ -68,7 +68,7 @@ bool vvLandmarksPanel::LoadFromFile(std::vector files) } void vvLandmarksPanel::Save() -{ //out << __func__ << endl; +{ QString file = QFileDialog::getSaveFileName(this, tr("Save Landmarks"), mCurrentPath.c_str(),tr("Landmarks ( *.txt)")); @@ -81,7 +81,7 @@ void vvLandmarksPanel::Save() } void vvLandmarksPanel::SelectPoint() -{ //out << __func__ << endl; +{ if (tableWidget->rowCount() > 0) { QList items = tableWidget->selectedItems(); if (!items.empty()) { @@ -100,7 +100,7 @@ void vvLandmarksPanel::SelectPoint() void vvLandmarksPanel::RemoveSelectedPoints() -{ //out << __func__ << endl; +{ if (tableWidget->rowCount() > 0) { QList items = tableWidget->selectedItems(); if (items.empty()) { @@ -124,7 +124,7 @@ void vvLandmarksPanel::RemoveSelectedPoints() } void vvLandmarksPanel::RemoveAllPoints() -{ //out << __func__ << endl; +{ mCurrentLandmarks->RemoveAll(); tableWidget->clearContents(); tableWidget->setRowCount(0); @@ -132,12 +132,12 @@ void vvLandmarksPanel::RemoveAllPoints() } void vvLandmarksPanel::AddPoint() -{ //out << __func__ << endl; +{ AddPoint(mCurrentLandmarks->GetNumberOfPoints()-1); } void vvLandmarksPanel::AddPoint(int landmarksIndex) -{ //out << __func__ << endl; +{ int rowIndex = tableWidget->rowCount(); // DD(rowIndex); tableWidget->setRowCount(rowIndex+1); @@ -176,7 +176,7 @@ void vvLandmarksPanel::AddPoint(int landmarksIndex) } void vvLandmarksPanel::SetCurrentLandmarks(vvLandmarks* lm,int time) -{ //out << __func__ << endl; +{ if (time != lm->GetTime()) return; loadButton->setEnabled(1); @@ -186,7 +186,8 @@ void vvLandmarksPanel::SetCurrentLandmarks(vvLandmarks* lm,int time) tableWidget->clearContents(); tableWidget->setRowCount(0); for (unsigned int i = 0; i < mCurrentLandmarks->GetNumberOfPoints(); i++) { - AddPoint(i); + if ((mCurrentLandmarks->GetLabels()->GetValue(i) != "P1") && (mCurrentLandmarks->GetLabels()->GetValue(i) != "P2")) + AddPoint(i); } //if (time > 1) //tableWidget->setColumnHidden(4,1); @@ -196,14 +197,14 @@ void vvLandmarksPanel::SetCurrentLandmarks(vvLandmarks* lm,int time) } void vvLandmarksPanel::SetCurrentImage(std::string filename) -{ //out << __func__ << endl; +{ QString image = "CurrentImage : "; image += vtksys::SystemTools::GetFilenameWithoutLastExtension(filename).c_str(); nameLabel->setText(image); } void vvLandmarksPanel::CommentsChanged(int row, int column) -{ //out << __func__ << endl; +{ if (column == 6) { mCurrentLandmarks->ChangeComments(row,std::string(tableWidget->item(row,column)->text().toStdString())); tableWidget->resizeColumnsToContents(); diff --git a/vv/vvSlicerManager.cxx b/vv/vvSlicerManager.cxx index 17995ac..b2855d1 100644 --- a/vv/vvSlicerManager.cxx +++ b/vv/vvSlicerManager.cxx @@ -47,6 +47,9 @@ //---------------------------------------------------------------------------- vvSlicerManager::vvSlicerManager(int numberOfSlicers) { + + connect(this, SIGNAL(callAddLandmark(float,float,float,float)), this, SLOT(AddLandmark(float,float,float,float))); + mFileName = ""; mId = ""; mVFName = ""; @@ -1676,7 +1679,10 @@ vvLandmarks* vvSlicerManager::GetLandmarks() return mLandmarks; } //---------------------------------------------------------------------------- - +void vvSlicerManager::AddNewLandmark(float x,float y,float z,float t) +{ + emit callAddLandmark(x,y,z,t); +} //---------------------------------------------------------------------------- void vvSlicerManager::AddLandmark(float x,float y,float z,float t) @@ -1712,6 +1718,38 @@ void vvSlicerManager::AddLandmark(float x,float y,float z,float t) } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +void vvSlicerManager::AddLandmarkProfile(float x,float y,float z,float t) +{ + double x_index = (x - mSlicers[0]->GetInput()->GetOrigin()[0])/mSlicers[0]->GetInput()->GetSpacing()[0]; + double y_index = (y - mSlicers[0]->GetInput()->GetOrigin()[1])/mSlicers[0]->GetInput()->GetSpacing()[1]; + double z_index = (z - mSlicers[0]->GetInput()->GetOrigin()[2])/mSlicers[0]->GetInput()->GetSpacing()[2]; +#if VTK_MAJOR_VERSION <= 5 + if (x_index >= mSlicers[0]->GetInput()->GetWholeExtent()[0]-0.5 && + x_index <= mSlicers[0]->GetInput()->GetWholeExtent()[1]+0.5 && + y_index >= mSlicers[0]->GetInput()->GetWholeExtent()[2]-0.5 && + y_index <= mSlicers[0]->GetInput()->GetWholeExtent()[3]+0.5 && + z_index >= mSlicers[0]->GetInput()->GetWholeExtent()[4]-0.5 && + z_index <= mSlicers[0]->GetInput()->GetWholeExtent()[5]+0.5) { + double value = this->GetScalarComponentAsDouble(mSlicers[0]->GetInput(), x_index, y_index, z_index); + this->GetLandmarks()->AddLandmark(x,y,z,t,value); + } +#else + int extentImageReslice[6]; + mSlicers[0]->GetRegisterExtent(extentImageReslice); + if (x_index >= extentImageReslice[0]-0.5 && + x_index <= extentImageReslice[1]+0.5 && + y_index >= extentImageReslice[2]-0.5 && + y_index <= extentImageReslice[3]+0.5 && + z_index >= extentImageReslice[4]-0.5 && + z_index <= extentImageReslice[5]+0.5) { + double value = this->GetScalarComponentAsDouble(mImage->GetVTKImages()[mSlicers[0]->GetTSlice()], x_index, y_index, z_index); + this->GetLandmarks()->AddLandmark(x,y,z,t,value); + } +#endif +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- void vvSlicerManager::PrevImage(int slicer) { diff --git a/vv/vvSlicerManager.h b/vv/vvSlicerManager.h index bbdd2a4..e80ef48 100644 --- a/vv/vvSlicerManager.h +++ b/vv/vvSlicerManager.h @@ -274,7 +274,8 @@ class vvSlicerManager : public QObject { void SetSlicingPreset(SlicingPresetType preset); vvLandmarks *GetLandmarks(); - void AddLandmark(float x,float y,float z,float t); + void AddNewLandmark(float x,float y,float z,float t); + void AddLandmarkProfile(float x,float y,float z,float t); void NextImage(int slicer); void PrevImage(int slicer); @@ -282,7 +283,11 @@ class vvSlicerManager : public QObject { void VerticalSliderHasChanged(int slicer, int slice); double GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int component=0); +public slots: + void AddLandmark(float x,float y,float z,float t); + signals : + void callAddLandmark(float x,float y,float z,float t); void currentImageChanged(std::string id); void currentPickedImageChanged(std::string id); void UpdatePosition(int visibility,double x, double y, double z, double X, double Y, double Z, double value); diff --git a/vv/vvSlicerManagerCommand.cxx b/vv/vvSlicerManagerCommand.cxx index c737eda..cb56455 100644 --- a/vv/vvSlicerManagerCommand.cxx +++ b/vv/vvSlicerManagerCommand.cxx @@ -381,7 +381,7 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller, //>>>>>>> 921642d767beba2442dacc8fdb40dc36396e1b7d if (newLandmark) { - this->SM->AddLandmark(xWorld,yWorld,zWorld, + this->SM->AddNewLandmark(xWorld,yWorld,zWorld, this->SM->GetSlicer(VisibleInWindow)->GetTSlice()); this->SM->GetSlicer(VisibleInWindow)->UpdateLandmarks(); this->SM->Render(); diff --git a/vv/vvToolProfile.cxx b/vv/vvToolProfile.cxx index 2e07d61..f0fbf8c 100644 --- a/vv/vvToolProfile.cxx +++ b/vv/vvToolProfile.cxx @@ -16,8 +16,11 @@ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ +#include + // vv #include "vvToolProfile.h" +#include "vvProgressDialog.h" #include "vvSlicerManager.h" #include "vvSlicer.h" #include "vvToolInputSelectorWidget.h" @@ -32,7 +35,6 @@ #include #include - //------------------------------------------------------------------------------ // Create the tool and automagically (I like this word) insert it in // the main window menu. @@ -65,7 +67,7 @@ vvToolProfile::vvToolProfile(vvMainWindowBase * parent, Qt::WindowFlags f) connect(mSelectPoint1Button, SIGNAL(clicked()), this, SLOT(selectPoint1())); connect(mSelectPoint2Button, SIGNAL(clicked()), this, SLOT(selectPoint2())); connect(mCancelPointsButton, SIGNAL(clicked()), this, SLOT(cancelPoints())); - connect(mComputeProfileButton, SIGNAL(clicked()), this, SLOT(computeProfile())); + connect(mSaveProfileButton, SIGNAL(clicked()), this, SLOT(SaveAs())); // Initialize some widget ProfileWidget->hide(); @@ -96,6 +98,7 @@ vvToolProfile::vvToolProfile(vvMainWindowBase * parent, Qt::WindowFlags f) //------------------------------------------------------------------------------ vvToolProfile::~vvToolProfile() { + connect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float))); } //------------------------------------------------------------------------------ @@ -115,6 +118,7 @@ void vvToolProfile::selectPoint1() this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems(); this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer()); ProfileWidget->show(); + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]); } mPoint1Selected = false; @@ -122,21 +126,34 @@ void vvToolProfile::selectPoint1() if(mCurrentSlicerManager->GetSelectedSlicer() != -1) { double *pos; int *index; - pos = new double [mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; + pos = new double [4]; + pos[0] = pos[1] = pos[2] = pos[3] = 0; index = new int [mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; - for (int i=0; iGetImage()->GetNumberOfDimensions(); ++i) { + int i(0); + while (iGetImage()->GetNumberOfDimensions() && i<3) { pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i]; index[i] = (int) (pos[i] - mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[i])/mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[i]; - position += QString::number(pos[i],'f',1) + " "; mPoint1[i] = index[i]; + ++i; + } + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) { + pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice(); + index[3] = (int)pos[3]; + position += QString::number(pos[3],'f',1) + " "; + mPoint1[3] = index[3]; } mPoint1Selected = true; + mCurrentSlicerManager->AddLandmarkProfile(pos[0], pos[1], pos[2], pos[3]); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->SetNumberOfValues(mCurrentSlicerManager->GetLandmarks()->GetLabels()->GetNumberOfValues()-1); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->Modified(); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->InsertNextValue("P1"); } } mPosPoint1Label->setText(position); isPointsSelected(); + mCurrentSlicerManager->Render(); } //------------------------------------------------------------------------------ @@ -156,6 +173,7 @@ void vvToolProfile::selectPoint2() this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems(); this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer()); ProfileWidget->show(); + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]); } mPoint2Selected = false; @@ -163,31 +181,47 @@ void vvToolProfile::selectPoint2() if(mCurrentSlicerManager->GetSelectedSlicer() != -1) { double *pos; int *index; - pos = new double [mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; + pos = new double [4]; + pos[0] = pos[1] = pos[2] = pos[3] = 0;; index = new int [mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; - for (int i=0; iGetImage()->GetNumberOfDimensions(); ++i) { + int i(0); + while (iGetImage()->GetNumberOfDimensions() &&i<3) { pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i]; index[i] = (int) (pos[i] - mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[i])/mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[i]; - position += QString::number(pos[i],'f',1) + " "; mPoint2[i] = index[i]; + ++i; + } + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) { + pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice(); + index[3] = (int)pos[3]; + position += QString::number(pos[3],'f',1) + " "; + mPoint2[3] = index[3]; } mPoint2Selected = true; + mCurrentSlicerManager->AddLandmarkProfile(pos[0], pos[1], pos[2], pos[3]); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->SetNumberOfValues(mCurrentSlicerManager->GetLandmarks()->GetLabels()->GetNumberOfValues()-1); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->Modified(); + mCurrentSlicerManager->GetLandmarks()->GetLabels()->InsertNextValue("P2"); } } mPosPoint2Label->setText(position); isPointsSelected(); + mCurrentSlicerManager->Render(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool vvToolProfile::isPointsSelected() { - if (mPoint1Selected && mPoint2Selected) - mComputeProfileButton->setEnabled(true); + if (mPoint1Selected && mPoint2Selected) { + mSaveProfileButton->setEnabled(true); + computeProfile(); + //DisplayLine(); + } else - mComputeProfileButton->setEnabled(false); + mSaveProfileButton->setEnabled(false); return (mPoint1Selected && mPoint2Selected); } @@ -207,6 +241,7 @@ void vvToolProfile::computeProfile() mFilter->SetInputVVImage(mCurrentImage); mFilter->SetArgsInfo(mArgsInfo); mFilter->Update(); + //mImageLine = mFilter->GetOutputVVImage(); vtkSmartPointer table = vtkSmartPointer::New(); vtkSmartPointer arrX = vtkSmartPointer::New(); @@ -245,6 +280,10 @@ void vvToolProfile::computeProfile() //------------------------------------------------------------------------------ void vvToolProfile::cancelPoints() { + if (mPoint1Selected) + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]); + if (mPoint2Selected) + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]); ProfileWidget->hide(); vtkSmartPointer chart = vtkSmartPointer::New(); chart->SetAutoSize(false); @@ -260,8 +299,9 @@ void vvToolProfile::cancelPoints() mPosPoint2Label->setText(position); mPoint1Selected = false; mPoint2Selected = false; - mComputeProfileButton->setEnabled(false); + mSaveProfileButton->setEnabled(false); isPointsSelected(); + mCurrentSlicerManager->Render(); } //------------------------------------------------------------------------------ @@ -269,8 +309,17 @@ void vvToolProfile::cancelPoints() //------------------------------------------------------------------------------ void vvToolProfile::RemoveVTKObjects() { + if (mPoint1Selected) + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]); + if (mPoint2Selected) + mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]); + + if (mCurrentSlicerManager) mCurrentSlicerManager->Render(); + + delete [] mPoint1; + delete [] mPoint2; } //------------------------------------------------------------------------------ @@ -278,7 +327,7 @@ void vvToolProfile::RemoveVTKObjects() //------------------------------------------------------------------------------ bool vvToolProfile::close() { - // RemoveVTKObjects(); + //RemoveVTKObjects(); return vvToolWidgetBase::close(); } //------------------------------------------------------------------------------ @@ -298,8 +347,6 @@ void vvToolProfile::reject() { // DD("vvToolProfile::reject"); RemoveVTKObjects(); - delete [] mPoint1; - delete [] mPoint2; return vvToolWidgetBase::reject(); } //------------------------------------------------------------------------------ @@ -310,10 +357,16 @@ void vvToolProfile::InputIsSelected(vvSlicerManager * m) { mCurrentSlicerManager = m; - mPoint1 = new int[mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; - mPoint2 = new int[mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; + mPoint1 = new int[4]; + mPoint1[0] = mPoint1[1] = mPoint1[2] = mPoint1[3] = 0; + mPoint2 = new int[4]; + mPoint2[0] = mPoint2[1] = mPoint2[2] = mPoint2[3] = 0; - mComputeProfileButton->setEnabled(false); + mSaveProfileButton->setEnabled(false); + mTextFileName = "Profile.txt"; + mImageLine = vvImage::New(); + + disconnect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float))); } //------------------------------------------------------------------------------ @@ -354,52 +407,197 @@ void vvToolProfile::GetArgsInfoFromGUI() //------------------------------------------------------------------------------ void vvToolProfile::apply() { - if (!mCurrentSlicerManager || !isPointsSelected()) { - close(); - return; - } - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + reject(); +} +//------------------------------------------------------------------------------ - // Output - std::string fileName = "Profiled_" + mCurrentSlicerManager->GetSlicer(0)->GetFileName() + ".txt"; - ofstream fileOpen(fileName.c_str(), std::ofstream::trunc); + +//------------------------------------------------------------------------------ +void vvToolProfile::SaveAs() +{ + QStringList OutputListeFormat; + OutputListeFormat.clear(); + OutputListeFormat.push_back(".txt"); - if(!fileOpen) { - cerr << "Error during saving" << endl; - QApplication::restoreOverrideCursor(); - close(); - - return; + QString Extensions = "AllFiles(*.*)"; + for (int i = 0; i < OutputListeFormat.count(); i++) { + Extensions += ";;Text File ( *"; + Extensions += OutputListeFormat[i]; + Extensions += ")"; } - vtkSmartPointer arrX = vtkSmartPointer::New(); - vtkSmartPointer arrY = vtkSmartPointer::New(); - vtkSmartPointer coords = vtkSmartPointer::New(); - arrX = mFilter->GetArrayX(); - arrY = mFilter->GetArrayY(); - coords = mFilter->GetCoord(); - double *tuple; - tuple = new double[mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; - int i(0); + QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), mTextFileName.c_str(), Extensions); + if (!fileName.isEmpty()) { + std::string fileformat = itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString()); + QString fileQFormat = fileformat.c_str(); + if (OutputListeFormat.contains(fileformat.c_str()) || fileQFormat.isEmpty()) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + std::string action = "Saving"; + vvProgressDialog progress("Saving "+fileName.toStdString()); + qApp->processEvents(); + + if (!mCurrentSlicerManager || !isPointsSelected()) { + close(); + return; + } + + // Output + mTextFileName = fileName.toStdString(); + if (fileQFormat.isEmpty()) + mTextFileName += ".txt"; + ofstream fileOpen(mTextFileName.c_str(), std::ofstream::trunc); + + if(!fileOpen) { + cerr << "Error during saving" << endl; + QApplication::restoreOverrideCursor(); + close(); + return; + } + + vtkSmartPointer arrX = vtkSmartPointer::New(); + vtkSmartPointer arrY = vtkSmartPointer::New(); + vtkSmartPointer coords = vtkSmartPointer::New(); + arrX = mFilter->GetArrayX(); + arrY = mFilter->GetArrayY(); + coords = mFilter->GetCoord(); + double *tuple; + tuple = new double[mCurrentSlicerManager->GetImage()->GetNumberOfDimensions()]; + int i(0); + + fileOpen << "Id" << "\t" << "Value" << "\t" ; + fileOpen << "x(vox)" << "\t" << "y(vox)" << "\t"; + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() >=3) + fileOpen << "z(vox)" << "\t"; + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() >=4) + fileOpen << "t" << "\t"; + fileOpen << "x(mm)" << "\t" << "y(mm)" << "\t"; + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() >=3) + fileOpen << "z(mm)" << "\t"; + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() >=4) + fileOpen << "t" << "\t"; + fileOpen << endl; - while (iGetNumberOfTuples()) { - fileOpen << arrX->GetTuple(i)[0] << "\t" << arrY->GetTuple(i)[0] << "\t" ; + while (iGetNumberOfTuples()) { + fileOpen << arrX->GetTuple(i)[0] << "\t" << arrY->GetTuple(i)[0] << "\t" ; - coords->GetTuple(i, tuple); - for (int j=0; jGetImage()->GetNumberOfDimensions() ; ++j) { - fileOpen << tuple[j] << "\t" ; - } - fileOpen << endl; - ++i; - } + coords->GetTuple(i, tuple); + for (int j=0; jGetImage()->GetNumberOfDimensions() ; ++j) { + fileOpen << tuple[j] << "\t" ; + } + int j(0); + while (jGetImage()->GetNumberOfDimensions() && j<3) { + fileOpen << tuple[j]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[j]+mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[j] << "\t" ; + ++j; + } + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) { + fileOpen << tuple[3] << "\t" ; + } + fileOpen << endl; + ++i; + } - delete [] tuple; + delete [] tuple; + + fileOpen.close(); + QApplication::restoreOverrideCursor(); + } else { + QString error = fileformat.c_str(); + error += " format unknown !!!\n"; + QMessageBox::information(this,tr("Saving Problem"),error); + SaveAs(); + } + } +} +//------------------------------------------------------------------------------ - fileOpen.close(); - QApplication::restoreOverrideCursor(); - close(); +//------------------------------------------------------------------------------ +void vvToolProfile::DisplayLine() +{ + if (!mPoint1Selected && !mPoint2Selected) + return; + + if(mCurrentSlicerManager) { + if(mCurrentSlicerManager->GetSelectedSlicer() != -1) { + double *pos; + pos = new double [4]; + pos[0] = pos[1] = pos[2] = pos[3] = 0; + + int i(0); + while (i<3) { + pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i]; + ++i; + } + if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) { + pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice(); + } + + /*double p0[4]; + if (mPoint1Selected) { + p0[0] = mPoint1[0]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[0] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[0]; + p0[1] = mPoint1[1]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[1] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[1]; + p0[2] = mPoint1[2]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[2] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[2]; + p0[3] = mPoint1[3]; + } + else { + p0[0] = mPoint2[0]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[0] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[0]; + p0[1] = mPoint2[1]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[1] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[1]; + p0[2] = mPoint2[2]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[2] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[2]; + p0[3] = mPoint2[3]; + } + vtkSmartPointer pts = vtkSmartPointer::New(); + pts->InsertNextPoint(p0); + pts->InsertNextPoint(pos); + + vtkSmartPointer linesPolyData = vtkSmartPointer::New(); + linesPolyData->SetPoints(pts); + + vtkSmartPointer line = vtkSmartPointer::New(); + line->GetPointIds()->SetId(0, 0); // the second 0 is the index of the Origin in linesPolyData's points + line->GetPointIds()->SetId(1, 1); // the second 1 is the index of P0 in linesPolyData's points + + vtkSmartPointer lines = vtkSmartPointer::New(); + lines->InsertNextCell(line); + + linesPolyData->SetLines(lines); + + unsigned char red[3] = { 255, 0, 0 }; + + vtkSmartPointer colors = vtkSmartPointer::New(); + colors->SetNumberOfComponents(3); + colors->InsertNextTupleValue(red); + + linesPolyData->GetCellData()->SetScalars(colors); + + + vtkSmartPointer lineMapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 + lineMapper->SetInput(linesPolyData); +#else + lineMapper->SetInputData(linesPolyData); +#endif + vtkSmartPointer lineActor = vtkSmartPointer::New(); + lineActor->SetMapper(lineMapper); + lineActor->GetProperty()->SetOpacity(0.995); + + for(int i=0;iGetNumberOfSlicers(); i++) { + mCurrentSlicerManager->GetSlicer(i)->GetRenderer()->AddActor(lineActor); + }*/ + + mOverlayActors.clear(); + for(int i=0;iGetNumberOfSlicers(); i++) { + mOverlayActors.push_back(vvBinaryImageOverlayActor::New()); + mOverlayActors[i]->SetImage(mImageLine, 0); + mOverlayActors[i]->SetColor(1,0,0); + mOverlayActors[i]->SetOpacity(0.995); + mOverlayActors[i]->SetSlicer(mCurrentSlicerManager->GetSlicer(i)); + mOverlayActors[i]->Initialize(true); + mOverlayActors[i]->SetDepth(1); + mOverlayActors[i]->ShowActors(); + mOverlayActors[i]->UpdateSlice(i, mCurrentSlicerManager->GetSlicer(i)->GetSlice(), false); + } + } + } + mCurrentSlicerManager->Render(); } //------------------------------------------------------------------------------ - diff --git a/vv/vvToolProfile.h b/vv/vvToolProfile.h index 072dc3a..1f5d6c9 100644 --- a/vv/vvToolProfile.h +++ b/vv/vvToolProfile.h @@ -23,7 +23,9 @@ #include "vvToolBase.h" #include "vvToolWidgetBase.h" #include "vvImageContour.h" +#include "vvLandmarks.h" #include "ui_vvToolProfile.h" +#include "vvBinaryImageOverlayActor.h" #include "clitkProfileImage_ggo.h" #include "clitkProfileImageGenericFilter.h" @@ -48,6 +50,7 @@ class vvToolProfile: virtual void InputIsSelected(vvSlicerManager * m); bool isPointsSelected(); + void computeProfile(); //----------------------------------------------------- public slots: @@ -58,7 +61,8 @@ class vvToolProfile: void selectPoint1(); void selectPoint2(); void cancelPoints(); - void computeProfile(); + void SaveAs(); + void DisplayLine(); protected: void RemoveVTKObjects(); @@ -72,6 +76,9 @@ class vvToolProfile: bool mPoint2Selected; vtkSmartPointer mView; clitk::ProfileImageGenericFilter::Pointer mFilter; + std::string mTextFileName; + vvImage::Pointer mImageLine; + std::vector< vvBinaryImageOverlayActor::Pointer > mOverlayActors; }; // end class vvToolProfile -- 2.45.1