From 52fa5dd65a30d4a2b748975af58d66a1e5fdabc0 Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Thu, 27 Jul 2023 16:56:11 -0700 Subject: [PATCH 1/3] Add code to disable gui controls if there is not image data. --- .../sv4gui_Seg2DEdit.cxx | 76 +++++++++++++++---- .../sv4gui_Seg2DEdit.h | 5 ++ .../org.sv.pythondatanodes/Dmg_PyModule.cxx | 9 --- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx index fe5158d29..f410b186f 100644 --- a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx +++ b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx @@ -238,10 +238,51 @@ void sv4guiSeg2DEdit::CreateQtPartControl( QWidget *parent ) } } +//------------------ +// EnableGuiControls +//------------------ +// Enable/disable GUI controls. +// +// This was added to disable GUI controls if image data +// is not defined. +// +void sv4guiSeg2DEdit::EnableGuiControls(bool enable) +{ + ui->btnLevelSet->setEnabled(enable); + ui->btnThreshold->setEnabled(enable); + ui->btnCircle->setEnabled(enable); + ui->btnEllipse->setEnabled(enable); + ui->btnSplinePoly->setEnabled(enable); + ui->btnPolygon->setEnabled(enable); + ui->btnSmooth->setEnabled(enable); + ui->btnCopy->setEnabled(enable); + ui->btnPaste->setEnabled(enable); + ui->btnML->setEnabled(enable); + ui->multiSegButton->setEnabled(enable); +} + +//------------------------ +// ShowNoImageDataWarning +//------------------------ +// Display a popup warning that no image data is defined and the +// tool is mostly disabled. +// +void sv4guiSeg2DEdit::ShowNoImageDataWarning() +{ + if (m_NoImageDataWarningShown) { + return; + } + + QMessageBox::warning(NULL, "The Segmentation Tool is disabled.", + "No image data has been loaded so the Segmentation Tool is disabled.\n\nLoad an image to enable full functionality."); + m_NoImageDataWarningShown = true; +} + void sv4guiSeg2DEdit::Visible() { // ui->resliceSlider->turnOnReslice(true); OnSelectionChanged(GetDataManagerSelection()); + } void sv4guiSeg2DEdit::Hidden() @@ -281,8 +322,6 @@ int sv4guiSeg2DEdit::GetTimeStep() // void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) { - std::cout << "OnSelectionChanged\n"; - if(!IsVisible()) { return; @@ -298,7 +337,7 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) mitk::DataNode::Pointer groupNode=nodes.front(); - if(m_ContourGroupNode==groupNode) + if(m_ContourGroupNode==groupNode && m_HasImageData) { ui->resliceSlider->turnOnReslice(true); return; @@ -310,7 +349,7 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) m_ContourGroup=dynamic_cast(groupNode->GetData()); if(!m_ContourGroup) { - std::cout << "no contour group selected\n"; + std::cout << "No contour group selected\n"; ui->resliceSlider->turnOnReslice(false); ClearAll(); ui->SinglePathTab->setEnabled(false); @@ -338,13 +377,21 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) if(rs->size()>0) { mitk::DataNode::Pointer imageFolderNode=rs->GetElement(0); rs=GetDataStorage()->GetDerivations(imageFolderNode); + if(rs->size()>0) { imageNode=rs->GetElement(0); if(imageNode.IsNotNull()) { m_Image= dynamic_cast(imageNode->GetData()); } - } + // If there is no image data then disable the reslice slider + // and most GUI controls to prevent SV from crashing. + // + } else { + ui->resliceSlider->turnOnReslice(false); + m_HasImageData = false; + EnableControls(false); + } } rs=GetDataStorage()->GetDerivations(projFolderNode,mitk::NodePredicateDataType::New("sv4guiPathFolder")); @@ -517,7 +564,12 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) m_ContourGroupNode->GetBoolProperty("lofting",lofting); ui->checkBoxLoftingPreview->setChecked(lofting); - ui->resliceSlider->turnOnReslice(true); + if (m_HasImageData) { + ui->resliceSlider->turnOnReslice(true); + } else { + ui->resliceSlider->turnOnReslice(false); + EnableControls(false); + } m_DataInteractor->SetPathPoints(m_PathPoints); m_DataInteractor->SetPathPoint(ui->resliceSlider->getCurrentPathPoint()); @@ -525,6 +577,9 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) connect(ui->resliceSlider,SIGNAL(reslicePositionChanged(int)), this, SLOT(UpdatePathPoint(int)) ); + if (!m_HasImageData) { + ShowNoImageDataWarning(); + } } double sv4guiSeg2DEdit::GetVolumeImageSpacing() @@ -1779,8 +1834,6 @@ void sv4guiSeg2DEdit::ShowPath(bool checked) // void sv4guiSeg2DEdit::PreparePreviewInteraction(QString method) { - //std::cout << "========== sv4guiSeg2DEdit::PreparePreviewInteraction ========== " << std::endl; - // Create Data Node to show threshold contour. m_PreviewContourModel = sv4guiContourModel::New(); m_PreviewDataNode = mitk::DataNode::New(); @@ -1956,7 +2009,6 @@ void sv4guiSeg2DEdit::segTabSelected(){ */ void sv4guiSeg2DEdit::initialize() { - std::cout << "========== sv4guiSeg2DEdit::initialize ==========" << std::endl; bool ml_init; GetDataStorage()->GetNamedNode("Segmentations")->GetBoolProperty("ml_init",ml_init); @@ -1974,7 +2026,6 @@ void sv4guiSeg2DEdit::initialize() std::string projPath; projFolderNode->GetStringProperty("project path", projPath); - std::cout << "[initialize] projPath: " << projPath << std::endl; mitk::DataNode::Pointer imageNode; auto rs = GetDataStorage()->GetDerivations(projFolderNode,mitk::NodePredicateDataType::New("sv4guiImageFolder")); @@ -1987,12 +2038,10 @@ void sv4guiSeg2DEdit::initialize() } if (imageNode.IsNull()) { - std::cout << "[initialize] imageNode is nullptr " << std::endl; return; } if (imageNode->GetStringProperty("image_absolute_file_name", m_imageFilePath)) { - std::cout << "[initialize] image_absolute_file_name: " << m_imageFilePath << std::endl; } ml_utils = sv4gui_MachineLearningUtils::getInstance("googlenet_c30_train300k_aug10_clean"); @@ -2032,7 +2081,7 @@ void sv4guiSeg2DEdit::updatePaths(){ return ; } - auto rs = dss->GetDerivations(path_folder_node); + auto rs = dss->GetDerivations(path_folder_node); if (rs->size() == 0){ std::cout << "No paths found\n"; @@ -2104,7 +2153,6 @@ void sv4guiSeg2DEdit::segmentPaths(){ } m_selected_paths.push_back(name); - std::cout << "selected " << name << "\n"; } } diff --git a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.h b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.h index 8d38d858f..0e4703aa9 100644 --- a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.h +++ b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.h @@ -216,6 +216,9 @@ public slots: virtual void Hidden() override; + void EnableGuiControls(bool enable); + void ShowNoImageDataWarning(); + // bool IsExclusiveFunctionality() const override; void PreparePreviewInteraction(QString method); @@ -317,6 +320,8 @@ public slots: bool m_MachineLearninginitialized = false; + bool m_HasImageData = true; + bool m_NoImageDataWarningShown = false; }; #endif // SV4GUI_SEG2DEDIT_H diff --git a/Code/Source/sv4gui/Plugins/org.sv.pythondatanodes/Dmg_PyModule.cxx b/Code/Source/sv4gui/Plugins/org.sv.pythondatanodes/Dmg_PyModule.cxx index 6d44c8594..e27a5a18a 100644 --- a/Code/Source/sv4gui/Plugins/org.sv.pythondatanodes/Dmg_PyModule.cxx +++ b/Code/Source/sv4gui/Plugins/org.sv.pythondatanodes/Dmg_PyModule.cxx @@ -735,7 +735,6 @@ Dmg_get_path(PyObject* self, PyObject* args) if (!PyArg_ParseTuple(args, api.format, &pathName)) { return api.argsError(); } - std::cout << "[Dmg_get_path] Path name: " << pathName << std::endl; // Get the Data Storage node. auto dataStorage = GetDataStorage(api); @@ -759,13 +758,11 @@ Dmg_get_path(PyObject* self, PyObject* args) return nullptr; } - std::cout << "[Dmg_get_path] Get path from node ... " << std::endl; auto path = dynamic_cast(node->GetData()); if (path == nullptr) { api.error("The Path node '" + std::string(pathName) + "' does not have data."); return nullptr; } - std::cout << "[Dmg_get_path] Path: "<< path << std::endl; // Create a copy of the path. auto pathElem = path->GetPathElement(); @@ -903,11 +900,9 @@ Dmg_add_segmentation(PyObject* self, PyObject* args, PyObject* kwargs) } // Get the Segmentation node. - std::cout << "##### GetToolNode" << std::endl; auto segNode = GetToolNode(dataStorage, projFolderNode, SvDataManagerNodes::Segmentation); // Get a list of segmentation objects. - std::cout << "##### Get a list of segmentation objects" << std::endl; int numSegmentations = PyList_Size(segList); std::vector segmentations; for (int i = 0; i < numSegmentations; i++) { @@ -916,7 +911,6 @@ Dmg_add_segmentation(PyObject* self, PyObject* args, PyObject* kwargs) } // Add the segmentation data node. - std::cout << "##### AddSegmentationDataNode " << std::endl; if (AddSegmentationDataNode(dataStorage, segmentations, segNode, segName, pathName, path) == SV_ERROR) { api.error("Error adding the segmentation data node '" + std::string(segName) + "' to the parent node '" + segNode->GetName() + "'."); @@ -1119,14 +1113,11 @@ Dmg_add_model(PyObject* self, PyObject* args, PyObject* kwargs) int time = 0; auto solidModelElement = model->GetModelElement(time); int numFaces = solidModelElement->GetFaceNumber(); - std::cout << "[add_model] numFaces: " << numFaces << std::endl; auto mepd = dynamic_cast(solidModelElement); double angle = 30.0; bool success = mepd->ExtractFaces(angle); numFaces = solidModelElement->GetFaceNumber(); - std::cout << "[add_model] numFaces: " << numFaces << std::endl; - return SV_PYTHON_OK; } From fb69e919976ebf646e30a2efd79a89059ff7cd81 Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Thu, 27 Jul 2023 19:23:06 -0700 Subject: [PATCH 2/3] Remove some print statements. --- Code/Source/sv3/Segmentation/sv3_CircleContour.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Code/Source/sv3/Segmentation/sv3_CircleContour.cxx b/Code/Source/sv3/Segmentation/sv3_CircleContour.cxx index eb90ec398..e69f3caff 100644 --- a/Code/Source/sv3/Segmentation/sv3_CircleContour.cxx +++ b/Code/Source/sv3/Segmentation/sv3_CircleContour.cxx @@ -161,9 +161,7 @@ void circleContour::SetRadius(double radius) void circleContour::SetControlPointByRadius(double radius, double* point) { double centerPt[3]; - std::cout <<"Point coords: "<ProjectPoint(point, centerPt); - std::cout <<"centerPt coords: "< dirVec; if(m_ControlPoints.size()==0) m_ControlPoints.push_back(std::array{centerPt[0],centerPt[1],centerPt[2]}); From 2640559eef747fe7f481ec2790bea3d92a97424b Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Wed, 2 Aug 2023 11:48:57 -0700 Subject: [PATCH 3/3] Fix method name. --- .../org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx index f410b186f..a1fe67fb0 100644 --- a/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx +++ b/Code/Source/sv4gui/Plugins/org.sv.gui.qt.segmentation/sv4gui_Seg2DEdit.cxx @@ -390,7 +390,7 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) } else { ui->resliceSlider->turnOnReslice(false); m_HasImageData = false; - EnableControls(false); + EnableGuiControls(false); } } @@ -566,9 +566,13 @@ void sv4guiSeg2DEdit::OnSelectionChanged(std::vector nodes ) if (m_HasImageData) { ui->resliceSlider->turnOnReslice(true); + + // If there is no image data then disable the reslice slider + // and most GUI controls to prevent SV from crashing. + // } else { ui->resliceSlider->turnOnReslice(false); - EnableControls(false); + EnableGuiControls(false); } m_DataInteractor->SetPathPoints(m_PathPoints);