SetClippingPlanes doesn't clip volume properly when performing a MIP with ParallelProjectionOn
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
I tried to clip a volume renderered with vtkVolumeRayCastMapper using the vtkVolumeRayCastMIPFunction. I introduced a vtkBoxWidget to clip it. It works very well in perspective projection. If, the parallel projection of the camera is ON, the clipping is not visible if the volume is othogonal to the camera... I put below a copy of the code which repoduces the bug...To run it you'll have to load your own data.
Thanks a lot Cedric
#include <VTK/include/vtkRenderer.h> #include <VTK/include/vtkRenderWindow.h> #include <VTK/include/vtkRenderWindowInteractor.h> #include <VTK/include/vtkImageData.h> #include <VTK/include/vtkPiecewiseFunction.h> #include <VTK/include/vtkVolumeProperty.h> #include <VTK/include/vtkRegressionTestImage.h> #include <VTK/include/vtkVolumeRayCastMapper.h> #include <VTK/include/vtkVolumeRayCastMIPFunction.h> #include <VTK/include/vtkWin32RenderWindowInteractor.h> #include <VTK/include/vtkRenderWindow.h> #include <VTK/include/vtkCamera.h> #include <VTK/include/vtkRenderer.h> #include <VTK/include/vtkCommand.h> #include <VTK/include/vtkBoxWidget.h> #include <VTK/include/vtkPlanes.h>
#define nSlice 400
vtkVolumeRayCastMapper *RCvolumeMapper = vtkVolumeRayCastMapper::New();
class vtkMyCallback : public vtkCommand { public: static vtkMyCallback *New() { return new vtkMyCallback; } void Delete() { delete this; } virtual void Execute(vtkObject caller, unsigned long, void) { vtkBoxWidget widget = reinterpret_cast<vtkBoxWidget>(caller); vtkPlanes *planes = vtkPlanes::New();
//Get the planes of the box widget and apply them to the ray cast mapper
widget->GetPlanes(planes);
RCvolumeMapper->SetClippingPlanes(planes);
}
};
void main() { unsigned short *buffer; unsigned long numread;
//First, we start loading the data
//We read them in a binary file
buffer = (unsigned short *)malloc(512*512*nSlice*sizeof(unsigned short));
//Create a vtkImageData
vtkImageData *img = vtkImageData::New();
img->SetDimensions(512,512,nSlice);
img->SetOrigin(0,0,0);
img->SetSpacing(0.7,0.7,1.0);
img->SetScalarTypeToUnsignedShort();
img->SetNumberOfScalarComponents(1);
img->AllocateScalars();
FILE *OutputFile;
char *string;
string = "volumeCT_Bx";
//Read the binary file
OutputFile = fopen(string, "r+b");
numread = fread(buffer, sizeof(unsigned short), 512*512*nSlice, OutputFile);
fclose(OutputFile);
unsigned short* imagePointer = (unsigned short*)img -> GetScalarPointer();
//Copy the scalar in the vtkImageData (img -> GetScalarPointer())
for (unsigned long i=0; i<numread; i++)
{
imagePointer[i] = buffer[i];
}
free(buffer);
img->Update();
///////////////////////////////////////////////////////////////////////////////////////
//Below: object creation to process a MIP on the data
vtkVolumeRayCastMIPFunction *MIPFunction = vtkVolumeRayCastMIPFunction::New();
MIPFunction->SetMaximizeMethodToOpacity();
RCvolumeMapper->SetInput(img);
RCvolumeMapper->SetVolumeRayCastFunction(MIPFunction);
vtkPiecewiseFunction *negOpacity = vtkPiecewiseFunction::New();
negOpacity->AddSegment(0, 0.0, 4095, 1.0);
vtkVolumeProperty *prop = vtkVolumeProperty::New();
prop->SetScalarOpacity(negOpacity);
vtkVolume *volume = vtkVolume::New();
volume->SetMapper(RCvolumeMapper);
volume->SetProperty(prop);
vtkRenderer *ren1 = vtkRenderer::New();
ren1->SetViewport(0.0, 0.0, 1.0, 1.0);
ren1->SetBackground(0.0, 0.5, 1.0);
ren1->AddProp(volume);
ren1->BackingStoreOn();
//Parallel projection is set to on -> the clipping on the MIP doesn't work properly
//if off, it works properly
//ren1->GetActiveCamera()->ParallelProjectionOn();
ren1->GetActiveCamera()->ParallelProjectionOff();
vtkRenderWindow *renWin;
renWin = vtkRenderWindow::New();
renWin->SetSize(600, 600);
renWin->AddRenderer(ren1);
vtkWin32RenderWindowInteractor *iren1 = vtkWin32RenderWindowInteractor::New();
iren1->SetRenderWindow(renWin);
//Boxwidget to clip the volume
vtkBoxWidget *boxWidget = vtkBoxWidget::New();
boxWidget->SetInteractor(iren1);
boxWidget->SetPlaceFactor(1.25);
boxWidget->InsideOutOn();
boxWidget->SetInput(img);
boxWidget->PlaceWidget();
vtkMyCallback *callback = vtkMyCallback::New();
boxWidget->AddObserver(vtkCommand::InteractionEvent, callback);
boxWidget->On();
renWin->Render();
iren1->Start();
boxWidget->Delete();
callback->Delete();
ren1->Delete();
renWin->Delete();
iren1->Delete();
volume->Delete();
prop->Delete();
negOpacity->Delete();
RCvolumeMapper->Delete();
MIPFunction->Delete();
img->Delete();
}