diff --git a/GUI/Qt/View/QtVTKRenderWindowBox.cxx b/GUI/Qt/View/QtVTKRenderWindowBox.cxx index 64510a55..8dfd2ea4 100644 --- a/GUI/Qt/View/QtVTKRenderWindowBox.cxx +++ b/GUI/Qt/View/QtVTKRenderWindowBox.cxx @@ -175,37 +175,25 @@ class QtVTKOffscreenMesaWidget : public QWidget QtVTKRenderWindowBox::QtVTKRenderWindowBox(QWidget *parent) : QWidget(parent) { - // Create a sphere - sphereSource = vtkSmartPointer::New(); - sphereSource->SetCenter(0.0, 0.0, 0.0); - sphereSource->SetRadius(5.0); - sphereSource->SetPhiResolution(100); - sphereSource->SetThetaResolution(100); - - mapper = vtkSmartPointer::New(); - mapper->SetInputConnection(sphereSource->GetOutputPort()); - - actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - actor->GetProperty()->SetColor(1.0, 0.0, 0.0); - + /* renderer = vtkSmartPointer::New(); renderer->AddActor(actor); renderer->ResetCamera(); renderer->SetBackground(0.2,0.2,0.0); + */ // Create an internal GL rendering widget #ifndef VTK_OPENGL_HAS_OSMESA auto *iw = new QVTKOpenGLNativeWidgetWithScreenshot(this); iw->setRenderWindow(vtkNew()); - iw->renderWindow()->AddRenderer(renderer); + // iw->renderWindow()->AddRenderer(renderer); iw->setObjectName("internalWidget"); m_InternalWidget = iw; #else auto *iw = new QtVTKOffscreenMesaWidget(this); vtkNew rwin; - rwin->AddRenderer(renderer); + // rwin->AddRenderer(renderer); vtkNew inter; inter->SetRenderWindow(rwin); diff --git a/GUI/Qt/View/QtVTKRenderWindowBox.h b/GUI/Qt/View/QtVTKRenderWindowBox.h index 091bb792..8afcf506 100644 --- a/GUI/Qt/View/QtVTKRenderWindowBox.h +++ b/GUI/Qt/View/QtVTKRenderWindowBox.h @@ -71,11 +71,5 @@ public slots: // Enter and leave events virtual void enterEvent(QEnterEvent *) override; virtual void leaveEvent(QEvent *) override; - - // TODO delete this stuff - vtkSmartPointer sphereSource; - vtkSmartPointer mapper; - vtkSmartPointer actor; - vtkSmartPointer renderer; }; #endif // QTVTKRENDERWINDOWBOX_H diff --git a/Logic/Framework/GenericImageData.cxx b/Logic/Framework/GenericImageData.cxx index af9411fc..59ddefc9 100644 --- a/Logic/Framework/GenericImageData.cxx +++ b/Logic/Framework/GenericImageData.cxx @@ -274,6 +274,21 @@ ::UnloadMainImage() m_TimePointProperties->Reset(); } +void GenericImageData::UpdateReferenceImageInAllLayers() +{ + for(LayerIterator lit(this); !lit.IsAtEnd(); ++lit) + { + auto *wrapper = lit.GetLayer(); + if(wrapper && wrapper->IsInitialized()) + { + if(wrapper->GetReferenceSpace() && wrapper->GetReferenceSpace() != wrapper->GetImageBase()) + { + wrapper->SetReferenceSpace(this->GetMain()->GetImageBase()); + } + } + } +} + void diff --git a/Logic/Framework/GenericImageData.h b/Logic/Framework/GenericImageData.h index 3d03045e..09f18148 100644 --- a/Logic/Framework/GenericImageData.h +++ b/Logic/Framework/GenericImageData.h @@ -225,6 +225,9 @@ class GenericImageData : public itk::Object /** Unload the main image (and everything else) */ virtual void UnloadMainImage(); + /** Update the reference space after the reload of the main image */ + virtual void UpdateReferenceImageInAllLayers(); + /** * Get the first segmentation image. */ diff --git a/Logic/Framework/ImageIODelegates.cxx b/Logic/Framework/ImageIODelegates.cxx index bf73420f..a3f27078 100644 --- a/Logic/Framework/ImageIODelegates.cxx +++ b/Logic/Framework/ImageIODelegates.cxx @@ -453,9 +453,9 @@ ::UpdateWrapperWithTraits() RescaleNativeImageToIntegralType rescaler; typename Image4DType::Pointer image4d = rescaler(m_IO); - auto anatomicWrapper = dynamic_cast(m_Wrapper.GetPointer()); + auto *aw = dynamic_cast(m_Wrapper.GetPointer()); - if (!anatomicWrapper) + if (!aw) { std::ostringstream oss; oss << "Cannot cast wrapper to: \"" @@ -463,7 +463,19 @@ ::UpdateWrapperWithTraits() throw IRISException("Error reloading image from file: %s", oss.str().c_str()); } - anatomicWrapper->SetImage4D(image4d); + // Maintain the reference space and transform when reloading an image + auto *old_tform = aw->GetITKTransform(); + auto *old_refspace = aw->GetReferenceSpace(); + if(old_refspace == aw->GetImageBase()) + old_refspace = nullptr; + aw->SetImage4D(image4d, + old_refspace, + const_cast(old_tform)); + + // This line takes care of stale pointers to reference_space in image wrappers + if(m_Wrapper == m_Driver->GetCurrentImageData()->GetMain()) + m_Driver->GetCurrentImageData()->UpdateReferenceImageInAllLayers(); + m_Driver->SetCursorPosition(m_Driver->GetCursorPosition(), true); m_Driver->InvokeEvent(LayerChangeEvent()); // important, to trigger renderer rebuild assemblies } diff --git a/Logic/ImageWrapper/ImageWrapper.cxx b/Logic/ImageWrapper/ImageWrapper.cxx index 58c65f24..df806f1c 100644 --- a/Logic/ImageWrapper/ImageWrapper.cxx +++ b/Logic/ImageWrapper/ImageWrapper.cxx @@ -1648,6 +1648,14 @@ ::SetITKTransform(ImageBaseType *refSpace, ITKTransformType *transform) this->InvokeEvent(WrapperDisplayMappingChangeEvent()); } +template +void +ImageWrapper +::SetReferenceSpace(ImageBaseType *referenceSpace) +{ + this->SetITKTransform(referenceSpace, m_AffineTransform); +} + template const typename ImageWrapper::ITKTransformType * ImageWrapper diff --git a/Logic/ImageWrapper/ImageWrapper.h b/Logic/ImageWrapper/ImageWrapper.h index 426075f7..87689ab6 100644 --- a/Logic/ImageWrapper/ImageWrapper.h +++ b/Logic/ImageWrapper/ImageWrapper.h @@ -524,6 +524,11 @@ class ImageWrapper : public TTraits::WrapperBaseType */ virtual void SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) ITK_OVERRIDE; + /** + * Set the reference image without changing the transform + */ + virtual void SetReferenceSpace(ImageBaseType *referenceSpace) ITK_OVERRIDE; + /** * Get the ITK transform between this layer and its reference space */ diff --git a/Logic/ImageWrapper/ImageWrapperBase.h b/Logic/ImageWrapper/ImageWrapperBase.h index a306ca86..b190f962 100644 --- a/Logic/ImageWrapper/ImageWrapperBase.h +++ b/Logic/ImageWrapper/ImageWrapperBase.h @@ -477,6 +477,11 @@ class ImageWrapperBase : public WrapperBase */ virtual void SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) = 0; + /** + * Set the reference image without changing the transform + */ + virtual void SetReferenceSpace(ImageBaseType *referenceSpace) = 0; + /** * Get the ITK transform between this image and the reference space */ diff --git a/Logic/ImageWrapper/VectorImageWrapper.cxx b/Logic/ImageWrapper/VectorImageWrapper.cxx index f0631df7..008c9d3f 100644 --- a/Logic/ImageWrapper/VectorImageWrapper.cxx +++ b/Logic/ImageWrapper/VectorImageWrapper.cxx @@ -360,10 +360,18 @@ VectorImageWrapper ::SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) { Superclass::SetITKTransform(referenceSpace, transform); - for(ScalarRepIterator it = m_ScalarReps.begin(); it != m_ScalarReps.end(); ++it) - { - it->second->SetITKTransform(referenceSpace, transform); - } + for(auto &it : m_ScalarReps) + it.second->SetITKTransform(referenceSpace, transform); +} + +template +void +VectorImageWrapper +::SetReferenceSpace(ImageBaseType *referenceSpace) +{ + Superclass::SetReferenceSpace(referenceSpace); + for(auto &it : m_ScalarReps) + it.second->SetReferenceSpace(referenceSpace); } diff --git a/Logic/ImageWrapper/VectorImageWrapper.h b/Logic/ImageWrapper/VectorImageWrapper.h index f61be954..dee0ae8e 100644 --- a/Logic/ImageWrapper/VectorImageWrapper.h +++ b/Logic/ImageWrapper/VectorImageWrapper.h @@ -183,6 +183,11 @@ class VectorImageWrapper : public ImageWrapper virtual void CopyImageCoordinateTransform(const ImageWrapperBase *source) ITK_OVERRIDE; virtual void SetSticky(bool value) ITK_OVERRIDE; + + virtual void SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) ITK_OVERRIDE; + + virtual void SetReferenceSpace(ImageBaseType *referenceSpace) ITK_OVERRIDE; + protected: /** @@ -200,8 +205,6 @@ class VectorImageWrapper : public ImageWrapper ImageBaseType *refSpace = NULL, ITKTransformType *tran = NULL) ITK_OVERRIDE; - virtual void SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) ITK_OVERRIDE; - /** Destructor */ virtual ~VectorImageWrapper();