Skip to content

Commit

Permalink
Fixed crashes when reloading images due to stale reference_pointer; a…
Browse files Browse the repository at this point in the history
…lso weird 3d sphere rendering
  • Loading branch information
pyushkevich committed Oct 15, 2024
1 parent 0843662 commit da47b26
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 31 deletions.
20 changes: 4 additions & 16 deletions GUI/Qt/View/QtVTKRenderWindowBox.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -175,37 +175,25 @@ class QtVTKOffscreenMesaWidget : public QWidget
QtVTKRenderWindowBox::QtVTKRenderWindowBox(QWidget *parent) :
QWidget(parent)
{
// Create a sphere
sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(5.0);
sphereSource->SetPhiResolution(100);
sphereSource->SetThetaResolution(100);

mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());

actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);

/*
renderer = vtkSmartPointer<vtkRenderer>::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<vtkGenericOpenGLRenderWindow>());
iw->renderWindow()->AddRenderer(renderer);
// iw->renderWindow()->AddRenderer(renderer);
iw->setObjectName("internalWidget");
m_InternalWidget = iw;

#else
auto *iw = new QtVTKOffscreenMesaWidget(this);
vtkNew<vtkRenderWindow> rwin;
rwin->AddRenderer(renderer);
// rwin->AddRenderer(renderer);

vtkNew<QVTKInteractor> inter;
inter->SetRenderWindow(rwin);
Expand Down
6 changes: 0 additions & 6 deletions GUI/Qt/View/QtVTKRenderWindowBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<vtkSphereSource> sphereSource;
vtkSmartPointer<vtkPolyDataMapper> mapper;
vtkSmartPointer<vtkActor> actor;
vtkSmartPointer<vtkRenderer> renderer;
};
#endif // QTVTKRENDERWINDOWBOX_H
15 changes: 15 additions & 0 deletions Logic/Framework/GenericImageData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions Logic/Framework/GenericImageData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
18 changes: 15 additions & 3 deletions Logic/Framework/ImageIODelegates.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -453,17 +453,29 @@ ::UpdateWrapperWithTraits()
RescaleNativeImageToIntegralType<Image4DType> rescaler;
typename Image4DType::Pointer image4d = rescaler(m_IO);

auto anatomicWrapper = dynamic_cast<WrapperType*>(m_Wrapper.GetPointer());
auto *aw = dynamic_cast<WrapperType*>(m_Wrapper.GetPointer());

if (!anatomicWrapper)
if (!aw)
{
std::ostringstream oss;
oss << "Cannot cast wrapper to: \""
<< typeid(WrapperType).name() << "\"";
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<typename WrapperType::ITKTransformType *>(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
}
Expand Down
8 changes: 8 additions & 0 deletions Logic/ImageWrapper/ImageWrapper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,14 @@ ::SetITKTransform(ImageBaseType *refSpace, ITKTransformType *transform)
this->InvokeEvent(WrapperDisplayMappingChangeEvent());
}

template<class TTraits>
void
ImageWrapper<TTraits>
::SetReferenceSpace(ImageBaseType *referenceSpace)
{
this->SetITKTransform(referenceSpace, m_AffineTransform);
}

template<class TTraits>
const typename ImageWrapper<TTraits>::ITKTransformType *
ImageWrapper<TTraits>
Expand Down
5 changes: 5 additions & 0 deletions Logic/ImageWrapper/ImageWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
5 changes: 5 additions & 0 deletions Logic/ImageWrapper/ImageWrapperBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
16 changes: 12 additions & 4 deletions Logic/ImageWrapper/VectorImageWrapper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,18 @@ VectorImageWrapper<TTraits>
::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<class TTraits>
void
VectorImageWrapper<TTraits>
::SetReferenceSpace(ImageBaseType *referenceSpace)
{
Superclass::SetReferenceSpace(referenceSpace);
for(auto &it : m_ScalarReps)
it.second->SetReferenceSpace(referenceSpace);
}


Expand Down
7 changes: 5 additions & 2 deletions Logic/ImageWrapper/VectorImageWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ class VectorImageWrapper : public ImageWrapper<TTraits>
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:

/**
Expand All @@ -200,8 +205,6 @@ class VectorImageWrapper : public ImageWrapper<TTraits>
ImageBaseType *refSpace = NULL,
ITKTransformType *tran = NULL) ITK_OVERRIDE;

virtual void SetITKTransform(ImageBaseType *referenceSpace, ITKTransformType *transform) ITK_OVERRIDE;

/** Destructor */
virtual ~VectorImageWrapper();

Expand Down

0 comments on commit da47b26

Please sign in to comment.