From 2723d45e7fa0580164d62a596d6e477df967f104 Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Tue, 9 Apr 2024 17:06:26 -0700 Subject: [PATCH] Add code to enable reslicing. --- .../QtWidgets/sv4gui_ResliceSlider.cxx | 397 ++++++++++-------- .../Modules/QtWidgets/sv4gui_ResliceSlider.h | 8 +- .../Segmentation/sv4gui_SegmentationUtils.cxx | 85 +++- .../Segmentation/sv4gui_SegmentationUtils.h | 3 +- .../sv4gui_Seg2DEdit.cxx | 33 +- 5 files changed, 316 insertions(+), 210 deletions(-) diff --git a/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.cxx b/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.cxx index 692cce438..c3cff0cdb 100644 --- a/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.cxx +++ b/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.cxx @@ -58,13 +58,19 @@ sv4guiResliceSlider::sv4guiResliceSlider(QWidget *parent) { } +//----------------- +// SetRenderWindow +//----------------- +// This replaces the SetDisplayWidget() method. +// void sv4guiResliceSlider::SetRenderWindow(mitk::IRenderWindowPart* renderWindow) { - m_renderWindow = renderWindow; - - currentSlicedGeometry=nullptr; + std::string msg = "[sv4guiResliceSlider::SetRenderWindow] "; + std::cout << msg << "========== sv4guiResliceSlider::SetRenderWindow ========== " << std::endl; - stepperSynchronized=false; + m_renderWindow = renderWindow; + currentSlicedGeometry = nullptr; + stepperSynchronized = false; QVBoxLayout* vlayout = new QVBoxLayout(this); vlayout->setContentsMargins(0,0,0,0); @@ -77,39 +83,51 @@ void sv4guiResliceSlider::SetRenderWindow(mitk::IRenderWindowPart* renderWindow) setLayout(vlayout); - resliceCheckBox=new QCheckBox("Turn on Reslicing"); - // resliceCheckBox->setFixedWidth(80); + resliceCheckBox = new QCheckBox("Turn on Reslicing"); resliceCheckBox->setChecked(false); resliceCheckBox->setToolTip("Show image reslice perpendicular to the path."); - intensityWindow=m_renderWindow->GetQmitkRenderWindow("axial"); - QmitkSliderNavigatorWidget* intensitySlider=new QmitkSliderNavigatorWidget; - // intensitySlider->hide(); + // Setup axial slice window? + intensityWindow = m_renderWindow->GetQmitkRenderWindow("axial"); + QmitkSliderNavigatorWidget* intensitySlider = new QmitkSliderNavigatorWidget; intensityStepper = new QmitkStepperAdapter(intensitySlider, intensityWindow->GetSliceNavigationController()->GetSlice(), "IntensityStepper"); - potentialWindow=m_renderWindow->GetQmitkRenderWindow("sagittal"); - QmitkSliderNavigatorWidget* potentialSlider=new QmitkSliderNavigatorWidget; + // Setup sagittal slice window? + potentialWindow = m_renderWindow->GetQmitkRenderWindow("sagittal"); + QmitkSliderNavigatorWidget* potentialSlider = new QmitkSliderNavigatorWidget; potentialSlider->hide(); potentialStepper = new QmitkStepperAdapter(potentialSlider, potentialWindow->GetSliceNavigationController()->GetSlice(), "PotentialStepper"); - btnResliceSize=new QPushButton("Size"); + btnResliceSize = new QPushButton("Size"); btnResliceSize->setToolTip("Change reslice size"); hlayout->addWidget(new QLabel("Reslice:")); hlayout->addWidget(intensitySlider); hlayout->addWidget(btnResliceSize); - // hlayout->addWidget(potentialSlider); sliderContainer->hide(); vlayout->addWidget(resliceCheckBox); vlayout->addWidget(sliderContainer); - // vlayout->addStretch(); - coronalWindow=m_renderWindow->GetQmitkRenderWindow("coronal"); + QHashIterator renderIter(m_renderWindow->GetQmitkRenderWindows()); + while (renderIter.hasNext()) { + renderIter.next(); + std::cout << msg << "renderIter.key(): " << renderIter.key() << std::endl; + //m_Controls->renderWindowComboBox->addItem(renderIter.key()); + } + + // These seem to be the renderers used with the different slice planes. + // + //threeDWindow = m_renderWindow->GetQmitkRenderWindow("3d"); + //QmitkSliderNavigatorWidget* threeDSlider = new QmitkSliderNavigatorWidget; + //ThreeDStepper = new QmitkStepperAdapter(threeDSlider, + //threeDWindow->GetSliceNavigationController()->GetSlice(), "ThreeDStepper"); + + coronalWindow = m_renderWindow->GetQmitkRenderWindow("coronal"); connect(resliceCheckBox, SIGNAL(toggled(bool)), this, SLOT(changeDisplayWidget(bool))); connect(btnResliceSize, SIGNAL(clicked()), this, SLOT(updateResliceSize()) ); @@ -165,169 +183,207 @@ double sv4guiResliceSlider::getResliceSize() return resliceSize; } +//--------------- +// updateReslice +//--------------- +// void sv4guiResliceSlider::updateReslice() { - if(!isResliceOn()) return; - - if(m_PathPoints.size()==0) return; + std::string msg("[sv4guiResliceSlider::updateReslice] "); + std::cout << msg << "========== updateReslice ==========" << std::endl; + std::cout << msg << "isResliceOn(): " << isResliceOn() << std::endl; + std::cout << msg << "m_PathPoints.size(): " << m_PathPoints.size() << std::endl; -// if(!currentDataNode) return; - mitk::Image* image=nullptr; - mitk::BaseData* baseData=nullptr; - if(currentDataNode.IsNotNull()) - { - image= dynamic_cast(currentDataNode->GetData()); - baseData=currentDataNode->GetData(); + if (!isResliceOn()) { + std::cout << msg << "return " << std::endl; + return; } -// if(!image) return; - // if(currentSlicedGeometry) - // { - // currentSlicedGeometry->Delete(); - // currentSlicedGeometry=nullptr; - // } + if (m_PathPoints.size() == 0) { + return; + } - currentSlicedGeometry=sv4guiSegmentationUtils::CreateSlicedGeometry(m_PathPoints, baseData, resliceSize); + mitk::Image* image = nullptr; + mitk::BaseData* baseData = nullptr; + std::cout << msg << "currentDataNode.IsNotNull(): " << currentDataNode.IsNotNull() << std::endl; - if (!currentSlicedGeometry){ - std::cout << "sliced geometry is nullptr" << std::endl << std::flush; + if (currentDataNode.IsNotNull()) { + image = dynamic_cast(currentDataNode->GetData()); + baseData = currentDataNode->GetData(); } + // Create a ProportionalTimeGeometry object that will contain + // all of the 2D image slices for the current time (always 1 for SV). + // + std::cout << msg << "resliceSize: " << resliceSize << std::endl; + currentSlicedGeometry = sv4guiSegmentationUtils::CreateSlicedGeometry(m_PathPoints, baseData, resliceSize); + + // Change graphics window layout. + // QmitkStdMultiWidgetEditor *multiWidgetEditor = dynamic_cast(m_renderWindow); - if (multiWidgetEditor) - { - QmitkMultiWidgetLayoutManager layoutManager(multiWidgetEditor->GetMultiWidget()); - // layoutManager.SetAll2DLeft3DRightLayout(); + if (multiWidgetEditor) { + QmitkMultiWidgetLayoutManager layoutManager(multiWidgetEditor->GetMultiWidget()); layoutManager.SetLayoutDesign(QmitkRenderWindowMenu::LayoutDesign::ALL_2D_LEFT_3D_RIGHT); - - // auto coronalWindow = m_renderWindow->GetQmitkRenderWindow("coronal"); - // coronalWindow->close(); - // mitk::RenderingManager::GetInstance()->RemoveRenderWindow(coronalWindow->GetVtkRenderWindow()); - } - else - { + } else { MITK_ERROR << "No MultiWidgetEditor!" << std::endl; return; } - // QmitkAbstractMultiWidget* multiWidget = GetMultiWidget(); - // QmitkMultiWidgetLayoutManager layoutManager(nullptr); - - // m_renderWindow->GetActiveQmitkRenderWindow()->UpdateLayoutDesignList(QmitkRenderWindowMenu::LayoutDesign::ALL_2D_LEFT_3D_RIGHT); - - // // m_renderWindow->GetMultiWidgetLayoutManager(); - // // m_renderWindow->GetQmitkRenderWindow()->SetProperty(mitk::IRenderWindowPartLayoutProperty::New(4, mitk::IRenderWindowPartLayout::LAYOUT_2x2D_AND_3D)); - - // // m_renderWindow->GetQmitkRenderWindow()->GetRenderWindow()->Render(); - - // exit(1); - // // displayWidget->changeLayoutTo2x2Dand3DWidget(); - - mitk::SliceNavigationController::Pointer intensityController=intensityWindow->GetSliceNavigationController(); - - // std::cout << "SetInputWorldGeometry3D This method doesn't exist anymore" << std::endl << std::flush; - // exit(1); - - // std::cout << ".1" << std::endl << std::flush; - // auto createdTimeGeometry = mitk::ArbitraryTimeGeometry::New(); - // createdTimeGeometry->Initialize(currentSlicedGeometry, 1); - // createdTimeGeometry->ReserveSpaceForGeometries(1); - // std::cout << ".1.5" << std::endl << std::flush; - // if (!currentSlicedGeometry->IsValidSlice()) - // { - // std::cout << "not a valid slice" << std::endl << std::flush; - // } - // std::cout << ".2" << std::endl << std::flush; - // createdTimeGeometry->AppendNewTimeStep(currentSlicedGeometry,0,0); - // std::cout << ".3" << std::endl << std::flush; - // createdTimeGeometry->Update(); - // std::cout << ".4" << std::endl << std::flush; - // intensityController->SetInputWorldTimeGeometry(createdTimeGeometry); - // std::cout << ".5" << std::endl << std::flush; - // intensityController->SetViewDirection(mitk::SliceNavigationController::Original); - // std::cout << ".6" << std::endl << std::flush; - - // try { - // intensityController->Update(); - // } - // catch (const std::exception& e) - // { - // std::cout << "intensityController->Update() failed" << std::endl << std::flush; - // std::cout << e.what() << std::endl << std::flush; - // } - // std::cout << ".7" << std::endl << std::flush; - // mitk::SliceNavigationController::Pointer potentialController=potentialWindow->GetSliceNavigationController(); - // std::cout << "SetInputWorldGeometry3D This method doesn't exist anymore" << std::endl << std::flush; - // exit(1); - // // potentialController->SetInputWorldGeometry3D(currentSlicedGeometry); - // potentialController->SetViewDirection(mitk::SliceNavigationController::Original); - // potentialController->Update(); - // if(image) - // { - // mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); - // mitkLut->SetType(mitk::LookupTable::GRAYSCALE); - // mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); - // mitkLutProp->SetLookupTable(mitkLut); - // currentDataNode->SetProperty("LookupTable", mitkLutProp,potentialWindow->GetRenderer()); - - // currentDataNode->SetBoolProperty("show gradient", true, potentialWindow->GetRenderer()); - // if(m_UseGeometrySpacing) - // { - // currentDataNode->SetBoolProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( true ),intensityWindow->GetRenderer()); - // currentDataNode->SetBoolProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( true ),potentialWindow->GetRenderer()); - // } - - // if(m_UseGeometrySize) - // { - // currentDataNode->SetBoolProperty( "in plane resample size by geometry", mitk::BoolProperty::New( true ),intensityWindow->GetRenderer()); - // currentDataNode->SetBoolProperty( "in plane resample size by geometry", mitk::BoolProperty::New( true ),potentialWindow->GetRenderer()); - // } - - // if(m_UseMinimumSpacing) - // { - // currentDataNode->SetBoolProperty( "in plane resample extent by minimum spacing", mitk::BoolProperty::New( true ),intensityWindow->GetRenderer()); - // currentDataNode->SetBoolProperty( "in plane resample extent by minimum spacing", mitk::BoolProperty::New( true ),potentialWindow->GetRenderer()); - // } - - // mitk::VtkResliceInterpolationProperty::Pointer interProp=mitk::VtkResliceInterpolationProperty::New(); - // switch(m_ResliceMode) - // { - // case mitk::ExtractSliceFilter::RESLICE_NEAREST: - // interProp->SetInterpolationToNearest(); - // break; - // case mitk::ExtractSliceFilter::RESLICE_LINEAR: - // interProp->SetInterpolationToLinear(); - // break; - // case mitk::ExtractSliceFilter::RESLICE_CUBIC: - // interProp->SetInterpolationToCubic(); - // break; - // default: - // break; - // } - // currentDataNode->SetProperty("reslice interpolation", interProp,intensityWindow->GetRenderer()); - // currentDataNode->SetProperty("reslice interpolation", interProp,potentialWindow->GetRenderer()); - - // } - - // intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(true); - // std::cout << "not sure about 3D" << std::endl << std::flush; - // intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetBoolProperty( "in plane resample size by geometry", mitk::BoolProperty::New( true ),m_renderWindow->GetQmitkRenderWindow("3D")->GetRenderer()); - // potentialWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); - // coronalWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); - - // intensityWindow->GetRenderer()->GetCameraController()->Fit(); - // potentialWindow->GetRenderer()->GetCameraController()->Fit(); - // if(!stepperSynchronized){ - // connect(intensityStepper, SIGNAL(Refetch()), this, SLOT(intensityOnRefetch())); - // connect(potentialStepper, SIGNAL(Refetch()), this, SLOT(potentialOnRefetch())); - // stepperSynchronized=true; - // } - - // mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); - // sliderContainer->show(); - // setSlicePos(m_StartingSlicePos); + + // This is displayed in the 3D window. + //auto threeDController = threeDWindow->GetSliceNavigationController(); + //threeDController->SetInputWorldTimeGeometry(currentSlicedGeometry); + //threeDController->SetViewDirection(mitk::SliceNavigationController::Original); + //threeDController->Update(); + + // This is displayed in the axial window. + auto intensityController = intensityWindow->GetSliceNavigationController(); + intensityController->SetInputWorldTimeGeometry(currentSlicedGeometry); + //intensityController->SetInputWorldGeometry3D(currentSlicedGeometry); + intensityController->SetViewDirection(mitk::SliceNavigationController::Original); + intensityController->Update(); + + // This is displayed in the sagittal window. + auto potentialController = potentialWindow->GetSliceNavigationController(); + potentialController->SetInputWorldTimeGeometry(currentSlicedGeometry); + //potentialController->SetInputWorldGeometry3D(currentSlicedGeometry); + potentialController->SetViewDirection(mitk::SliceNavigationController::Original); + potentialController->Update(); + + + + if (image) { + std::cout << msg << "Have image " << std::endl; + + // create vtk lookup table + //vtkLookupTable* vtkLut = vtkLookupTable::New(); + //vtkLut->SetTableRange(0.0,10.0); + //vtkLut->Build(); + + mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); + //mitkLut->SetVtkLookupTable(vtkLut); + mitkLut->SetType(mitk::LookupTable::GRAYSCALE); + mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); + mitkLutProp->SetLookupTable(mitkLut); + + currentDataNode->SetProperty("LookupTable", mitkLutProp, potentialWindow->GetRenderer()); + currentDataNode->SetBoolProperty("show gradient", true, potentialWindow->GetRenderer()); + //currentDataNode->SetBoolProperty("texture interpolation", true, potentialWindow->GetRenderer()); + //currentDataNode->SetBoolProperty("visible", false, potentialWindow->GetRenderer()); + //float rgb[3]={1.0f, 0.0f, 0.0f}; + //currentDataNode->SetColor(rgb, potentialWindow->GetRenderer()); + + auto prop = currentDataNode->GetProperty("in plane resample extent by geometry"); + std::cout << msg << "prop: " << prop << std::endl; + + std::cout << msg << "m_UseGeometrySpacing: " << m_UseGeometrySpacing << std::endl; + std::cout << msg << "m_UseGeometrySize: " << m_UseGeometrySize << std::endl; + std::cout << msg << "m_UseMinimumSpacing: " << m_UseMinimumSpacing << std::endl; + std::cout << msg << "m_ResliceMode: " << m_ResliceMode << std::endl; + auto bool_prop = mitk::BoolProperty::New(true); + + if (m_UseGeometrySpacing) { + currentDataNode->SetBoolProperty("in plane resample extent by geometry", mitk::BoolProperty::New(true),intensityWindow->GetRenderer()); + currentDataNode->SetBoolProperty("in plane resample extent by geometry", mitk::BoolProperty::New(true),potentialWindow->GetRenderer()); + } + + if (m_UseGeometrySize) { + //currentDataNode->SetBoolProperty("in plane resample size by geometry", mitk::BoolProperty::New(true), threeDWindow->GetRenderer()); + currentDataNode->SetBoolProperty("in plane resample size by geometry", mitk::BoolProperty::New(true), intensityWindow->GetRenderer()); + currentDataNode->SetBoolProperty("in plane resample size by geometry", mitk::BoolProperty::New(true), potentialWindow->GetRenderer()); + } + + if (m_UseMinimumSpacing) { + currentDataNode->SetBoolProperty("in plane resample extent by minimum spacing", mitk::BoolProperty::New(true), + intensityWindow->GetRenderer()); + currentDataNode->SetBoolProperty("in plane resample extent by minimum spacing", mitk::BoolProperty::New(true), + potentialWindow->GetRenderer()); + } + + mitk::VtkResliceInterpolationProperty::Pointer interProp = mitk::VtkResliceInterpolationProperty::New(); + + switch(m_ResliceMode) { + case mitk::ExtractSliceFilter::RESLICE_NEAREST: + interProp->SetInterpolationToNearest(); + std::cout << msg << "m_ResliceMode: RESLICE_NEAREST " << std::endl; + break; + + case mitk::ExtractSliceFilter::RESLICE_LINEAR: + interProp->SetInterpolationToLinear(); + std::cout << msg << "m_ResliceMode: RESLICE_LINEAR" << std::endl; + break; + + case mitk::ExtractSliceFilter::RESLICE_CUBIC: + interProp->SetInterpolationToCubic(); + std::cout << msg << "m_ResliceMode: RESLICE_CUBIC" << std::endl; + break; + + default: + break; + } + + //currentDataNode->SetProperty("reslice interpolation", interProp, threeDWindow->GetRenderer()); + currentDataNode->SetProperty("reslice interpolation", interProp, intensityWindow->GetRenderer()); + currentDataNode->SetProperty("reslice interpolation", interProp, potentialWindow->GetRenderer()); + currentDataNode->Update(); + } + + std::cout << msg << "PropertyListKeyNames: " << std::endl; + mitk::DataNode::PropertyListKeyNames refListNames = currentDataNode->GetPropertyListNames(); + for (const auto &name : refListNames) { + std::cout << msg << " property name: " << name << std::endl; + } + + // These seem to be the renderers used with the different slice planes. + // +/* + threeDWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(true); + threeDWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetBoolProperty("in plane resample size by geometry", + mitk::BoolProperty::New(true), m_renderWindow->GetQmitkRenderWindow("3d")->GetRenderer()); +*/ + ////threeDWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); + //threeDWindow->GetRenderer()->GetCameraController()->Fit(); + + // Controls display of slice planes in 3D view? + // + // from QtWidgets/src/QmitkStdMultiWidget.cpp + // "axial" = RenderWindow1 + // "sagittal" = RenderWindow2 + // "coronal" = RenderWindow3 + // "3d" = RenderWindow4 + // + // axial + //intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); + intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(true); + /* this does not seem to do anything. + */ + intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetBoolProperty( + "in plane resample size by geometry", + mitk::BoolProperty::New(true), + m_renderWindow->GetQmitkRenderWindow("3d")->GetRenderer()); + intensityWindow->GetRenderer()->GetCameraController()->Fit(); + + // sagittal + potentialWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); + potentialWindow->GetRenderer()->GetCameraController()->Fit(); + + coronalWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(false); + + if (!stepperSynchronized) { + connect(intensityStepper, SIGNAL(Refetch()), this, SLOT(intensityOnRefetch())); + connect(potentialStepper, SIGNAL(Refetch()), this, SLOT(potentialOnRefetch())); + stepperSynchronized = true; + } + + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + sliderContainer->show(); + setSlicePos(m_StartingSlicePos); } +//---------------------- +// getCurrentSliceIndex +//---------------------- +// int sv4guiResliceSlider::getCurrentSliceIndex(){ return intensityWindow->GetSliceNavigationController()->GetSlice()->GetPos(); } @@ -369,11 +425,18 @@ void sv4guiResliceSlider::potentialOnRefetch() } } +//----------------------- +// restoreDisplayWidget +//----------------------- +// [Note] This is not used. +// void sv4guiResliceSlider::restoreDisplayWidget() { // if(currentDataNode.IsNull()) // return; +#if 0 + if(stepperSynchronized){ disconnect(intensityStepper, SIGNAL(Refetch()), this, SLOT(intensityOnRefetch())); disconnect(potentialStepper, SIGNAL(Refetch()), this, SLOT(potentialOnRefetch())); @@ -404,7 +467,6 @@ void sv4guiResliceSlider::restoreDisplayWidget() currentDataNode->GetPropertyList(intensityWindow->GetRenderer())->DeleteProperty("reslice interpolation"); } - std::cout << "not sure about 3D here" << std::endl << std::flush; intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->GetPropertyList(m_renderWindow->GetQmitkRenderWindow("3D")->GetRenderer())->DeleteProperty("in plane resample size by geometry"); intensityWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(true); potentialWindow->GetRenderer()->GetCurrentWorldPlaneGeometryNode()->SetVisibility(true); @@ -429,6 +491,7 @@ void sv4guiResliceSlider::restoreDisplayWidget() sliderContainer->hide(); +#endif } void sv4guiResliceSlider::changeDisplayWidget(bool checked) @@ -454,6 +517,7 @@ void sv4guiResliceSlider::setCheckBoxVisible(bool visible) void sv4guiResliceSlider::setSlicePos(int pos) { + //threeDWindow->GetSliceNavigationController()->GetSlice()->SetPos(pos); intensityWindow->GetSliceNavigationController()->GetSlice()->SetPos(pos); potentialWindow->GetSliceNavigationController()->GetSlice()->SetPos(pos); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); @@ -461,10 +525,13 @@ void sv4guiResliceSlider::setSlicePos(int pos) int sv4guiResliceSlider::GetSliceNumber() { - if(currentSlicedGeometry.IsNull()) + if (currentSlicedGeometry.IsNull()) { return 0; - else - return currentSlicedGeometry->GetSlices(); + } else { + // [davep] change method name. + return currentSlicedGeometry->CountTimeSteps(); + //return currentSlicedGeometry->GetSlices(); + } } void sv4guiResliceSlider::moveToPathPosPoint(mitk::Point3D posPoint){ diff --git a/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.h b/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.h index f050ee193..2675b383f 100644 --- a/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.h +++ b/Code/Source/sv4gui/Modules/QtWidgets/sv4gui_ResliceSlider.h @@ -130,17 +130,23 @@ public slots: double resliceSize; - mitk::SlicedGeometry3D::Pointer currentSlicedGeometry; + // [davep] change type. + mitk::ProportionalTimeGeometry::Pointer currentSlicedGeometry; + //mitk::SlicedGeometry3D::Pointer currentSlicedGeometry; QCheckBox* resliceCheckBox; + + QmitkRenderWindow* threeDWindow; QmitkRenderWindow* intensityWindow; QmitkRenderWindow* potentialWindow; QmitkRenderWindow* coronalWindow; + QWidget* sliderContainer; // QmitkSliderNavigatorWidget* intensitySlider; // QmitkSliderNavigatorWidget* potentialSlider; QmitkStepperAdapter* intensityStepper; QmitkStepperAdapter* potentialStepper; + QmitkStepperAdapter* threeDStepper; QPushButton* btnResliceSize; diff --git a/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.cxx b/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.cxx index 7c456ef46..f3addc231 100644 --- a/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.cxx +++ b/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.cxx @@ -243,6 +243,8 @@ mitk::PlaneGeometry::Pointer sv4guiSegmentationUtils::CreatePlaneGeometryFromSpacing(sv4guiPathElement::sv4guiPathPoint pathPoint, mitk::Vector3D spacing, double size) { + //std::cout << "[CreatePlaneGeometryFromSpacing] ========== CreatePlaneGeometryFromSpacing ========== " << std::endl; + auto tr=GetvtkTransform(pathPoint); mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->SetIndexToWorldTransformByVtkMatrix(tr->GetMatrix()); @@ -261,6 +263,8 @@ sv4guiSegmentationUtils::CreatePlaneGeometryFromSpacing(sv4guiPathElement::sv4gu double width=size/spacing[0]; double height=size/spacing[1]; + //std::cout << "[CreatePlaneGeometryFromSpacing] width: " << width << std::endl; + //std::cout << "[CreatePlaneGeometryFromSpacing] height: " << height << std::endl; mitk::ScalarType bounds[6] = { 0, width, 0, height, 0, 1 }; planegeometry->SetBounds( bounds ); @@ -282,11 +286,15 @@ mitk::PlaneGeometry::Pointer sv4guiSegmentationUtils::CreatePlaneGeometry(sv4guiPathElement::sv4guiPathPoint pathPoint, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing) { + //std::cout << "[CreatePlaneGeometry] ========== CreatePlaneGeometry ==========" << std::endl; + //std::cout << "[CreatePlaneGeometry] useOnlyMinimumSpacing: " << useOnlyMinimumSpacing << std::endl; + mitk::Vector3D newSpacing; mitk::Image* image = dynamic_cast(baseData); if (image) { mitk::Vector3D imageSpacing = image->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetSpacing(); + if (useOnlyMinimumSpacing) { double minSpacing = std::min(imageSpacing[0],std::min(imageSpacing[1],imageSpacing[2])); newSpacing.Fill(minSpacing); @@ -311,6 +319,7 @@ sv4guiSegmentationUtils::CreatePlaneGeometry(sv4guiPathElement::sv4guiPathPoint image->GetTimeGeometry()->GetGeometryForTimeStep(0)->WorldToIndex( right, rightInIndex ); image->GetTimeGeometry()->GetGeometryForTimeStep(0)->WorldToIndex( bottom, bottomInIndex ); image->GetTimeGeometry()->GetGeometryForTimeStep(0)->WorldToIndex( normal, normalInIndex ); + newSpacing[0] = size/rightInIndex.GetNorm(); newSpacing[1] = size/bottomInIndex.GetNorm(); newSpacing[2] = 1.0/normalInIndex.GetNorm(); @@ -322,6 +331,8 @@ sv4guiSegmentationUtils::CreatePlaneGeometry(sv4guiPathElement::sv4guiPathPoint newSpacing[2] = 0.1; } + //std::cout << "[CreatePlaneGeometry] newSpacing: " << newSpacing[0] << " " << newSpacing[1] << " " << newSpacing[2] << std::endl; + mitk::PlaneGeometry::Pointer planeGeometry = CreatePlaneGeometryFromSpacing(pathPoint, newSpacing, size); if (baseData) { @@ -335,37 +346,71 @@ sv4guiSegmentationUtils::CreatePlaneGeometry(sv4guiPathElement::sv4guiPathPoint // CreateSlicedGeometry //---------------------- // -mitk::SlicedGeometry3D::Pointer sv4guiSegmentationUtils::CreateSlicedGeometry(std::vector pathPoints, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing) +// [davep] modify to return a ProportionalTimeGeometry object. +// +mitk::ProportionalTimeGeometry::Pointer +//mitk::SlicedGeometry3D::Pointer +sv4guiSegmentationUtils::CreateSlicedGeometry(std::vector pathPoints, + mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing) { - mitk::SlicedGeometry3D::Pointer slicedGeo3D=mitk::SlicedGeometry3D::New(); + //std::string msg = "[CreateSlicedGeometry] "; + //std::cout << msg << "========== CreateSlicedGeometry ========== " << std::endl; + //std::cout << msg << "pathPoints.size(): " << pathPoints.size() << std::endl; + //std::cout << msg << "size: " << size << std::endl; + + // Create a ProportionalTimeGeometry object to store a slicedGeo3D object. + //std::cout << msg << "Create prop_time_geom ... " << std::endl; + auto prop_time_geom = mitk::ProportionalTimeGeometry::New(); + + //std::cout << msg << "Create slicedGeo3D ... " << std::endl; + mitk::SlicedGeometry3D::Pointer slicedGeo3D = mitk::SlicedGeometry3D::New(); slicedGeo3D->SetEvenlySpaced(false); slicedGeo3D->InitializeSlicedGeometry(pathPoints.size()); - mitk::Image* image=dynamic_cast(baseData); + mitk::Image* image = dynamic_cast(baseData); + + //std::cout << msg << "Add planegeometry ... " << std::endl; for (int i = 0; i < pathPoints.size(); i++) { - mitk::PlaneGeometry::Pointer planegeometry = CreatePlaneGeometry(pathPoints[i], baseData, + //std::cout << msg << "----- i " << i << " -----" << std::endl; + mitk::PlaneGeometry::Pointer plane_geometry = CreatePlaneGeometry(pathPoints[i], baseData, size, useOnlyMinimumSpacing); if (image) { - planegeometry->SetImageGeometry(true); + plane_geometry->SetImageGeometry(true); } - slicedGeo3D->SetPlaneGeometry(planegeometry,i); + slicedGeo3D->SetPlaneGeometry(plane_geometry,i); } if (baseData) { + //std::cout << msg << "Have baseData " << baseData << std::endl; + //std::cout << msg << "Set reference geometry ... " << std::endl; auto geometry = baseData->GetTimeGeometry()->GetGeometryForTimeStep(0); slicedGeo3D->SetReferenceGeometry(geometry); slicedGeo3D->SetBounds(geometry->GetBounds()); slicedGeo3D->SetOrigin(geometry->GetOrigin()); slicedGeo3D->SetIndexToWorldTransform(geometry->GetIndexToWorldTransform()); + auto origin = geometry->GetOrigin(); + //std::cout << msg << "reference geometry origin: " << origin[0] << " " << origin[1] << " " << origin[2] << std::endl; } - return slicedGeo3D; + + //std::cout << msg << "prop_time_geom->Initialize ... " << std::endl; + prop_time_geom->Initialize(slicedGeo3D, 1); + + // This causes a segfault using the new extrnals. + //std::cout << msg << "########### clone ... " << std::endl; + //auto cgeom = slicedGeo3D->Clone(); + //mitk::BaseGeometry::Pointer cgeom = slicedGeo3D->Clone(); + + //std::cout << msg << "return ... " << std::endl; + return prop_time_geom; + //return slicedGeo3D; } //--------------- // GetSliceImage //--------------- +// this is not used. // mitk::Image::Pointer sv4guiSegmentationUtils::GetSliceImage(const mitk::PlaneGeometry* planeGeometry, const mitk::Image* image, unsigned int timeStep) { @@ -380,6 +425,10 @@ mitk::Image::Pointer sv4guiSegmentationUtils::GetSliceImage(const mitk::PlaneGeo //use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting // mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); +#if 0 + std::cout << "========== GetSliceImage ===========" << std::endl; + exit(0); + mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(); extractor->SetInput( image ); extractor->SetTimeStep( timeStep ); @@ -393,6 +442,7 @@ mitk::Image::Pointer sv4guiSegmentationUtils::GetSliceImage(const mitk::PlaneGeo mitk::Image::Pointer slice = extractor->GetOutput(); return slice; +#endif } //------------------ @@ -404,7 +454,7 @@ mitk::Image::Pointer sv4guiSegmentationUtils::GetSliceImage(const mitk::PlaneGeo vtkImageData * sv4guiSegmentationUtils::GetSlicevtkImage(const mitk::PlaneGeometry* planeGeometry, const mitk::Image* image, unsigned int timeStep) { - if ( !image || !planeGeometry ) return nullptr; + if ( !image || !planeGeometry ) return NULL; // //Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer // vtkSmartPointer reslice = vtkSmartPointer::New(); @@ -506,6 +556,7 @@ sv4guiSegmentationUtils::GetImageTransformation(mitk::Image* image) cvStrPts * sv4guiSegmentationUtils::GetSlicevtkImage_old(sv4guiPathElement::sv4guiPathPoint pathPoint, vtkImageData* volumeImage, double size) { +#if 0 // Compute a slice transformation from the 'pathPoint' path point, normal and tangent. // auto sliceTransform = GetvtkTransform(pathPoint); @@ -538,12 +589,14 @@ sv4guiSegmentationUtils::GetSlicevtkImage_old(sv4guiPathElement::sv4guiPathPoint imageReslice->Update(); return vtkImageData2cvStrPts(imageReslice->GetOutput()); +#endif } //------------------ // GetSlicevtkImage //------------------ // Extract a 2D slice from a 3D volume using a path point. +// This is called when segmenting a 2D slice. // // An image slice is extracted using 'vtkImageReslice' from a 'vtkImageData' image volume. // However, 'vtkImageData' does not store a rotation matrix and so supports only axis-parallel @@ -556,6 +609,8 @@ cvStrPts * sv4guiSegmentationUtils::GetSlicevtkImage(sv4guiPathElement::sv4guiPathPoint pathPoint, vtkImageData* volumeImage, double size, vtkTransform* imageTransform) { + std::cout << "========== GetSlicevtkImage ===========" << std::endl; + // Compute the transformation to define a slice plane aligned with // the 'pathPoint' point, normal and tangent. // @@ -689,7 +744,7 @@ sv4guiSegmentationUtils::CreateLSContour(sv4guiPathElement::sv4guiPathPoint path } // Create seed curve. - cvPolyData *seedPd = nullptr; + cvPolyData *seedPd = NULL; double center[3]; center[0] = param->ctrx; center[1] = param->ctry; @@ -915,24 +970,20 @@ sv4guiContour* sv4guiSegmentationUtils::CreateThresholdContour(sv4guiPathElement std::deque sv4guiSegmentationUtils::GetOrderedPtIDs(vtkCellArray* lines, bool& ifClosed) { - const vtkIdType *ptIds; vtkIdType npts; lines->InitTraversal(); - std::vector> lineList; - std::deque linkedPtList; - while ( lines->GetNextCell( npts, ptIds ) ) { - - if(npts!=2) break; - + while (lines->GetNextCell(npts, ptIds)) { + if (npts != 2) { + break; + } std::vector ids; ids.push_back(ptIds[0]); ids.push_back(ptIds[1]); - lineList.push_back(ids); } diff --git a/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.h b/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.h index 78ec023c9..f7cdcb3e4 100644 --- a/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.h +++ b/Code/Source/sv4gui/Modules/Segmentation/sv4gui_SegmentationUtils.h @@ -113,7 +113,8 @@ class SV4GUIMODULESEGMENTATION_EXPORT sv4guiSegmentationUtils static mitk::PlaneGeometry::Pointer CreatePlaneGeometry(sv4guiPathElement::sv4guiPathPoint pathPoint, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing = false); - static mitk::SlicedGeometry3D::Pointer CreateSlicedGeometry(std::vector pathPoints, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing = false); + static mitk::ProportionalTimeGeometry::Pointer CreateSlicedGeometry(std::vector pathPoints, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing = false); + //static mitk::SlicedGeometry3D::Pointer CreateSlicedGeometry(std::vector pathPoints, mitk::BaseData* baseData, double size, bool useOnlyMinimumSpacing = false); static mitk::Image::Pointer GetSliceImage(const mitk::PlaneGeometry* planeGeometry, const mitk::Image* image, unsigned int timeStep = 0); 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 b55b2b497..654ab1559 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 @@ -154,8 +154,6 @@ void sv4guiSeg2DEdit::CreateQtPartControl( QWidget *parent ) ui->resliceSlider->SetRenderWindow(m_renderWindow); ui->resliceSlider->setCheckBoxVisible(false); -// ui->resliceSlider->SetResliceMode(mitk::ExtractSliceFilter::RESLICE_NEAREST); -// ui->resliceSlider->SetResliceMode(mitk::ExtractSliceFilter::RESLICE_LINEAR); ui->resliceSlider->SetResliceMode(mitk::ExtractSliceFilter::RESLICE_CUBIC); m_CurrentParamWidget=nullptr; @@ -176,7 +174,6 @@ void sv4guiSeg2DEdit::CreateQtPartControl( QWidget *parent ) ui->batchWidget->hide(); parent->setMinimumWidth(400); -// parent->setFixedWidth(400); connect(ui->checkBoxShowPath, SIGNAL(clicked(bool)), this, SLOT(ShowPath(bool)) ); @@ -236,6 +233,7 @@ void sv4guiSeg2DEdit::CreateQtPartControl( QWidget *parent ) } else { ui->SinglePathTab->setEnabled(true); } + } void sv4guiSeg2DEdit::Activated() @@ -249,7 +247,6 @@ void sv4guiSeg2DEdit::Deactivated() void sv4guiSeg2DEdit::Visible() { m_isVisible = true; -// ui->resliceSlider->turnOnReslice(true); OnSelectionChanged(berry::IWorkbenchPart::Pointer(), GetDataManagerSelection()); } @@ -261,14 +258,10 @@ void sv4guiSeg2DEdit::Hidden() ClearAll(); } -//bool sv4guiSeg2DEdit::IsExclusiveFunctionality() const -//{ -// return true; -//} - int sv4guiSeg2DEdit::GetTimeStep() { mitk::SliceNavigationController* timeNavigationController = nullptr; + if(m_renderWindow) { timeNavigationController=m_renderWindow->GetTimeNavigationController(); @@ -326,11 +319,8 @@ void sv4guiSeg2DEdit::OnSelectionChanged(berry::IWorkbenchPart::Pointer part, m_Parent->setEnabled(true); ui->SinglePathTab->setEnabled(true); - ////remove_toolbox ui->segToolbox->setCurrentIndex(1); -// std::string groupPathName=m_ContourGroup->GetPathName(); - int groupPathID=m_ContourGroup->GetPathID(); + int groupPathID = m_ContourGroup->GetPathID(); -// mitk::DataNode::Pointer pathNode=nullptr; mitk::DataNode::Pointer imageNode=nullptr; m_Image=nullptr; mitk::NodePredicateDataType::Pointer isProjFolder = mitk::NodePredicateDataType::New("sv4guiProjectFolder"); @@ -376,11 +366,6 @@ void sv4guiSeg2DEdit::OnSelectionChanged(berry::IWorkbenchPart::Pointer part, } -// if(!m_Image){ -// QMessageBox::warning(nullptr,"No image found for this project","Make sure the image is loaded!"); -//// return; -// } - if(!m_Path){ QMessageBox::warning(nullptr,"No path found for this contour group","Make sure the path for the contour group exits!"); return; @@ -468,13 +453,11 @@ void sv4guiSeg2DEdit::OnSelectionChanged(berry::IWorkbenchPart::Pointer part, //set resice slider ui->resliceSlider->setPathPoints(pathPoints); - if(imageNode.IsNotNull()) + if(imageNode.IsNotNull()) { ui->resliceSlider->setDataNode(imageNode); - else + } else { ui->resliceSlider->setDataNode(m_PathNode); - - //ui->resliceSlider->setDataNode(m_ContourGroupNode); - + } double resliceSize=m_ContourGroup->GetResliceSize(); if(resliceSize==0) @@ -831,8 +814,6 @@ void sv4guiSeg2DEdit::CreateContours(SegmentationMethod method) mitk::ProgressBar::GetInstance()->Progress(1); } - - //LoftContourGroup(); } void sv4guiSeg2DEdit::SetSecondaryWidgetsVisible(bool visible) @@ -1787,7 +1768,7 @@ void sv4guiSeg2DEdit::ShowPath(bool checked) // void sv4guiSeg2DEdit::PreparePreviewInteraction(QString method) { - //std::cout << "========== sv4guiSeg2DEdit::PreparePreviewInteraction ========== " << std::endl; + std::cout << "========== sv4guiSeg2DEdit::PreparePreviewInteraction ========== " << std::endl; // Create Data Node to show threshold contour. m_PreviewContourModel = sv4guiContourModel::New();