vtkOpenGLGPUVolumeRayCastMapper crashes when its actor is removed/re-added
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
When the actor of a vtkOpenGLGPUVolumeRayCastMapper is removed from a renderer, vtkOpenGLGPUVolumeRayCastMapper releases its graphics resources. If it is then re-added very quickly, vtkOpenGLGPUVolumeRayCastMapper doesn't recreate the resources before trying to use them and crashes.
This is a small sample program that reproduces the issue (using a vtkSmartVolumeMapper that internally used a vtkOpenGLGPUVolumeRayCastMapper):
#include "vtkColorTransferFunction.h" #include "vtkCommand.h" #include "vtkPiecewiseFunction.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkSmartPointer.h" #include "vtkSmartVolumeMapper.h" #include "vtkStructuredPoints.h" #include "vtkStructuredPointsReader.h" #include "vtkVolume.h" #include "vtkVolumeProperty.h"
class MyCallBack: public vtkCommand { public:
static MyCallBack *New()
{
return new MyCallBack;
}
virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData)
{
if (eventId != vtkCommand::KeyPressEvent) return;
vtkRenderWindowInteractor* interactor = static_cast<vtkRenderWindowInteractor*>(caller);
if (interactor == NULL) return;
char* pressedKey = interactor->GetKeySym();
if (strcmp(pressedKey, "9") == 0)
{
renderer->RemoveActor(volume);
renderer->AddActor(volume);
renderWindow->Render();
}
}
vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkVolume> volume;
vtkSmartPointer<vtkRenderWindow> renderWindow;
};
int main() { vtkSmartPointer pointsReader = vtkSmartPointer::New(); pointsReader->SetFileName("ironProt.vtk"); pointsReader->Update();
vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
colorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0);
colorTransferFunction->AddRGBPoint( 64.0, 1.0, 0.0, 0.0);
colorTransferFunction->AddRGBPoint(128.0, 0.0, 0.0, 1.0);
colorTransferFunction->AddRGBPoint(192.0, 0.0, 1.0, 0.0);
colorTransferFunction->AddRGBPoint(255.0, 0.0, 0.2, 0.0);
vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
opacityTransferFunction->AddPoint(0, 0.0);
opacityTransferFunction->AddPoint(255, 1.0);
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(colorTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
vtkSmartPointer<vtkSmartVolumeMapper> smartMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
smartMapper->SetInputConnection(pointsReader->GetOutputPort());
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(smartMapper);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor= vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindow->SetParentId(0);
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(500, 300);
renderWindow->SetPosition(100, 100);
interactor->SetRenderWindow(renderWindow);
renderer->AddActor(volume);
renderer->SetBackground(1.0, 1.0, 1.0);
// Create callback so we can trigger the problem
vtkSmartPointer<MyCallBack> callback = vtkSmartPointer<MyCallBack>::New();
callback->renderer = renderer;
callback->renderWindow = renderWindow;
callback->volume = volume;
interactor->AddObserver("KeyPressEvent", callback);
// Let's go
renderWindow->Render();
interactor->Start();
}
Running the program and pressing '9' crashes the program in line 990 of vtkOpenGLGPUVolumeRayCastMapper:
this->OpacityTables->GetTable(component)->Update( scalarOpacity,this->Parent->BlendMode, this->ActualSampleDistance, this->ScalarsRange, volumeProperty->GetScalarOpacityUnitDistance(component), filterVal, vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow()));
OpacityTables is NULL and so causes a NULL pointer dereference.
I'm using VTK 6.2.0 on windows using the OpenGL2 backend.