[vtkusers] Slider Widget pick on multiple viewports/renderers
Timothee Evain
tevain at telecom-paristech.fr
Thu Nov 24 10:59:33 EST 2016
Hello everyone,
Some context: I'm trying to set up a light view for manually correcting 3D image segmentation with a paint-brush effect.
I have a window split in four viewports associated with a renderer for each. One part is the volume view of segmentation while the three other are image actors representing axial/sagittal/coronal slices overlayed with segmentation.
Following the idea of a paint brush, I wish to put a slider somewhere to control the radius of correction but I'm stuck on a strange behavior with the slider widget. If I associate it with the bottom-left renderer (the "first" viewport in term of coordinates), everything is fine, but if I associate the widget on any other renderer/viewport, it is well rendered, but cannot be picked anymore even if it should (pickable "on", higher priority).
Has anyone an idea on what could be tricking me ?
(Code provided at the end)
Tim
void GUI_EditSegmentation(vtkImageData *InputImage, vtkImageData *InputSegmentation)
{
/*
/!\ It is the user responsibility to ensure that image and segmentation are in same space i.e. same origin, same spacing /!\
Typical usage is to have the segmentation as RGBA image, with color on segmented parts, whereas background pixels are translucents (A=0)
*/
double ImSpacing[3];
int ImSize[3];
vtkSmartPointer<vtkImageData> ImVtk=InputImage;
ImVtk->GetSpacing(ImSpacing);
ImVtk->GetDimensions(ImSize);
double ImOri[3];
double SegmOri[3];
double SegmSpacing[3];
int ImExtent[6];
int SegmExtent[6];
ImVtk->GetOrigin(ImOri);
InputSegmentation->GetOrigin(SegmOri);
InputSegmentation->GetSpacing(SegmSpacing);
ImVtk->GetExtent(ImExtent);
InputSegmentation->GetExtent(SegmExtent);
vtkSmartPointer<vtkImageHistogramStatistics> ImStats=
vtkSmartPointer<vtkImageHistogramStatistics>::New();
ImStats->SetInputData(ImVtk);
ImStats->SetAutomaticBinning(true);
ImStats->Update();
double BestRangeVisu[2];
ImStats->GetAutoRange(BestRangeVisu);
float BestLevelVisu=(BestRangeVisu[0]+BestRangeVisu[1])/2;
float BestWindowVisu=BestRangeVisu[1]-BestRangeVisu[0];
vtkSmartPointer<vtkRenderWindow> RenderWin=vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> Interactor=vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> InterStyle=vtkSmartPointer<vtkInteractorStyleImage>::New();
/* AXIAL PART */
vtkSmartPointer<vtkRenderer> Renderer_1=vtkSmartPointer<vtkRenderer>::New();
Renderer_1->SetBackground(0.7,0.7,0.7);
Renderer_1->SetRenderWindow(RenderWin);
vtkSmartPointer<vtkImageReslice> AxialReslicer=vtkSmartPointer<vtkImageReslice>::New();
vtkSmartPointer<vtkImageActor> AxialImAct=vtkSmartPointer<vtkImageActor>::New();
AxialReslicer->SetInputData(ImVtk);
// ( 1 0 0 )
// ( 0 1 0 )
// ( 0 0 1 )
//Axial reslice
AxialReslicer->SetResliceAxesDirectionCosines(1,0,0,0,1,0,0,0,1);
AxialReslicer->SetOutputDimensionality(2);
AxialReslicer->SetResliceAxesOrigin(0,0,ImOri[2]+(float(ImExtent[4])*ImSpacing[2])+(float(ImSize[2])*ImSpacing[2]/2));
AxialReslicer->Update();
AxialImAct->SetInputData(AxialReslicer->GetOutput());
AxialImAct->GetProperty()->SetColorLevel(BestLevelVisu);
AxialImAct->GetProperty()->SetColorWindow(BestWindowVisu);
vtkSmartPointer<vtkImageReslice> AxialSegmReslicer=vtkSmartPointer<vtkImageReslice>::New();
vtkSmartPointer<vtkImageActor> AxialSegmAct=vtkSmartPointer<vtkImageActor>::New();
AxialSegmReslicer->SetInputData(InputSegmentation);
AxialSegmReslicer->SetResliceAxesDirectionCosines(1,0,0,0,1,0,0,0,1);
AxialSegmReslicer->SetOutputDimensionality(2);
AxialSegmReslicer->SetResliceAxesOrigin(0,0,ImOri[2]+(float(ImExtent[4])*ImSpacing[2])+(float(ImSize[2])*ImSpacing[2]/2));
AxialSegmReslicer->Update();
AxialSegmAct->SetInputData(AxialSegmReslicer->GetOutput());
Renderer_1->AddActor(AxialImAct);
Renderer_1->AddActor(AxialSegmAct);
Renderer_1->SetViewport(0, 0, 0.5, 0.5);
/* SAGITTAL PART */
vtkSmartPointer<vtkRenderer> Renderer_2=vtkSmartPointer<vtkRenderer>::New();
Renderer_2->SetBackground(0.7,0.7,0.7);
Renderer_2->SetRenderWindow(RenderWin);
vtkSmartPointer<vtkImageReslice> SagittalReslicer=vtkSmartPointer<vtkImageReslice>::New();
SagittalReslicer->SetInputData(ImVtk);
// ( 0 1 0 )
// ( 0 0 1 )
// ( 1 0 0 )
//Sagittal reslice
SagittalReslicer->SetResliceAxesDirectionCosines(0,1,0,0,0,1,1,0,0);
SagittalReslicer->SetOutputDimensionality(2);
SagittalReslicer->SetResliceAxesOrigin(ImOri[0]+(float(ImExtent[0])*ImSpacing[0])+(float(ImSize[0])*ImSpacing[0]/2),0,0);
SagittalReslicer->Update();
vtkSmartPointer<vtkImageActor> SagittalImAct=vtkSmartPointer<vtkImageActor>::New();
SagittalImAct->SetInputData(SagittalReslicer->GetOutput());
SagittalImAct->GetProperty()->SetColorLevel(BestLevelVisu);
SagittalImAct->GetProperty()->SetColorWindow(BestWindowVisu);
vtkSmartPointer<vtkImageReslice> SagittalSegmReslicer=vtkSmartPointer<vtkImageReslice>::New();
vtkSmartPointer<vtkImageActor> SagittalSegmAct=vtkSmartPointer<vtkImageActor>::New();
SagittalSegmReslicer->SetInputData(InputSegmentation);
SagittalSegmReslicer->SetResliceAxesDirectionCosines(0,1,0,0,0,1,1,0,0);
SagittalSegmReslicer->SetOutputDimensionality(2);
SagittalSegmReslicer->SetResliceAxesOrigin(ImOri[0]+(float(ImExtent[0])*ImSpacing[0])+(float(ImSize[0])*ImSpacing[0]/2),0,0);
SagittalSegmReslicer->Update();
SagittalSegmAct->SetInputData(SagittalSegmReslicer->GetOutput());
Renderer_2->AddActor(SagittalImAct);
Renderer_2->AddActor(SagittalSegmAct);
Renderer_2->SetViewport(0.5,0,1,0.5);
/* CORONAL PART */
vtkSmartPointer<vtkRenderer> Renderer_3=vtkSmartPointer<vtkRenderer>::New();
Renderer_3->SetBackground(0.7,0.7,0.7);
Renderer_3->SetRenderWindow(RenderWin);
vtkSmartPointer<vtkImageReslice> CoronalReslicer=vtkSmartPointer<vtkImageReslice>::New();
CoronalReslicer->SetInputData(ImVtk);
// ( 1 0 0 )
// ( 0 0 1 )
// ( 0 1 0 )
//Coronal reslice
CoronalReslicer->SetResliceAxesDirectionCosines(1,0,0,0,0,1,0,1,0);
CoronalReslicer->SetOutputDimensionality(2);
CoronalReslicer->SetResliceAxesOrigin(0,ImOri[1]+(float(ImExtent[2])*ImSpacing[1])+(float(ImSize[1])*ImSpacing[1]/2),0);
CoronalReslicer->Update();
vtkSmartPointer<vtkImageActor> CoronalImAct=vtkSmartPointer<vtkImageActor>::New();
CoronalImAct->SetInputData(CoronalReslicer->GetOutput());
CoronalImAct->GetProperty()->SetColorLevel(BestLevelVisu);
CoronalImAct->GetProperty()->SetColorWindow(BestWindowVisu);
vtkSmartPointer<vtkImageReslice> CoronalSegmReslicer=vtkSmartPointer<vtkImageReslice>::New();
vtkSmartPointer<vtkImageActor> CoronalSegmAct=vtkSmartPointer<vtkImageActor>::New();
CoronalSegmReslicer->SetInputData(InputSegmentation);
CoronalSegmReslicer->SetResliceAxesDirectionCosines(1,0,0,0,0,1,0,1,0);
CoronalSegmReslicer->SetOutputDimensionality(2);
CoronalSegmReslicer->SetResliceAxesOrigin(0,ImOri[1]+(float(ImExtent[2])*ImSpacing[1])+(float(ImSize[1])*ImSpacing[1]/2),0);
CoronalSegmReslicer->Update();
CoronalSegmAct->SetInputData(CoronalSegmReslicer->GetOutput());
Renderer_3->AddActor(CoronalImAct);
Renderer_3->AddActor(CoronalSegmAct);
Renderer_3->SetViewport(0,0.5,0.5,1);
/* VOLUME PART */
vtkSmartPointer<vtkSmartVolumeMapper> mapper =
vtkSmartPointer<vtkSmartVolumeMapper>::New();
mapper->SetInputData(InputSegmentation);
vtkSmartPointer<vtkVolumeProperty> volumeProperty =
vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(0.0,0.0);
compositeOpacity->AddPoint(120,0.3);
compositeOpacity->AddPoint(255,0.5);
volumeProperty->SetScalarOpacity(0,compositeOpacity);
volumeProperty->SetScalarOpacity(1,compositeOpacity);
volumeProperty->SetScalarOpacity(2,compositeOpacity);
volumeProperty->SetScalarOpacity(3,compositeOpacity);
vtkSmartPointer<vtkVolume> volume =
vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(mapper);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> Renderer_4=vtkSmartPointer<vtkRenderer>::New();
Renderer_4->SetBackground(0.7,0.7,0.7);
Renderer_4->SetRenderWindow(RenderWin);
Renderer_4->AddVolume(volume);
Renderer_4->SetViewport(0.5, 0.5, 1, 1);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> VolStyle=vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
/* ASSEMBLY PART*/
vtkSmartPointer<vtkSliderRepresentation2D> SliderRep = vtkSmartPointer<vtkSliderRepresentation2D>::New();
SliderRep->SetMinimumValue(1);
SliderRep->SetMaximumValue(100);
SliderRep->SetValue(5);
SliderRep->SetTitleText("Brush Radius");
SliderRep->GetSliderProperty()->SetColor(1, 1, 1);
SliderRep->GetTitleProperty()->SetColor(1, 1, 1);
SliderRep->GetLabelProperty()->SetColor(1, 1, 1);
SliderRep->GetSelectedProperty()->SetColor(0, 1, 0);
SliderRep->GetTubeProperty()->SetColor(0.8, 0.8, 0.8);
SliderRep->GetCapProperty()->SetColor(0.8, 0.8, 0.8);
SliderRep->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
SliderRep->GetPoint1Coordinate()->SetValue(0.3, 0.45, 0);
SliderRep->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
SliderRep->GetPoint2Coordinate()->SetValue(0.4, 0.45, 0);
vtkSmartPointer<vtkSliderWidget> Slider = vtkSmartPointer<vtkSliderWidget>::New();
Slider->SetPriority(1);
Slider->SetInteractor(Interactor);
Slider->SetRepresentation(SliderRep);
Slider->SetAnimationModeToJump();
Slider->SetCurrentRenderer(Renderer_1); // ONLY PICKABLE ON RENDERER_1, NOT ON OTHER
Interactor->SetInteractorStyle(InterStyle);
RenderWin->SetInteractor(Interactor);
RenderWin->AddRenderer(Renderer_1);
RenderWin->AddRenderer(Renderer_2);
RenderWin->AddRenderer(Renderer_3);
RenderWin->AddRenderer(Renderer_4);
RenderWin->SetSize(1600,900);
RenderWin->SetDesiredUpdateRate(Interactor->GetDesiredUpdateRate());
RenderWin->Render();
Slider->EnabledOn();
Interactor->Start();
}
More information about the vtkusers
mailing list