How do I make reslice cursor orthogonal in MPR Scene???

OS : win10
vtk version : 8.0 with QT
IDE : VisualStudio 2019(msvc v142) with QT 5.6

I want to be orthogonal each reslice cursor in MPR when I control( e.g rotate, ) a one axis like this.

Why are there not maintain orthogonal each axis??

You can check my code below.

please tell me how to make orthogonal 2 axis in mpr scene…

if (m_bResliceCursor)
{
C_VTK(vtkCellPicker, picker);
picker->SetTolerance(0.005);

  C_VTK(vtkProperty, ipwProp);
  //vtkSP<vtkImagePlaneWidget> ipw[3];

  int dims[3];
  volumeData->GetImageData()->GetDimensions(dims);

  //vtkSP<vtkImagePlaneWidget> ipw[3];

  // Image Plane Widget set
  for (int i = VIEW_AXIAL; i <= VIEW_SAGITTAL; i++)
  {
  	m_ipw[i] = vtkSP<vtkImagePlaneWidget>::New();
  	m_ipw[i]->SetInteractor(GetMprInteractor(i)->GetInteractor());
  	m_ipw[i]->SetPicker(picker);
  	m_ipw[i]->RestrictPlaneToVolumeOn();

  	double color[3] = { 0,0,0 };
  	color[i] = 1;

  	m_ipw[i]->GetPlaneProperty()->SetColor(color);
  	m_ipw[i]->SetTexturePlaneProperty(ipwProp);
  	m_ipw[i]->TextureInterpolateOff();
  	m_ipw[i]->SetResliceInterpolateToLinear();
  	m_ipw[i]->SetInputData(volumeData->GetImageData());
  	m_ipw[i]->SetSliceIndex(dims[i] / 2);
  	m_ipw[i]->DisplayTextOn();
  	m_ipw[i]->SetDefaultRenderer(GetRenderer(VIEW_3D));
  	m_ipw[i]->SetWindowLevel(1358, -27);
  	m_ipw[i]->On();
  	m_ipw[i]->InteractionOn();
  }
  
  m_ipw[1]->SetLookupTable(m_ipw[0]->GetLookupTable());
  m_ipw[2]->SetLookupTable(m_ipw[0]->GetLookupTable());

  C_VTK(vtkResliceCursorCallback, cbk);
  cbk->m_pRen = GetRenderer(VIEW_3D);

  //C_VTK(vtkResliceCursor, resliceCursor);

  m_resliceCursor->SetCenter(volumeData->GetImageData()->GetCenter());
  m_resliceCursor->SetThickMode(0);
  m_resliceCursor->SetThickness(10, 10, 10);
  m_resliceCursor->SetImage(volumeData->GetImageData());
  
  /*vtkSP<vtkResliceCursorWidget> rcw[3];
  vtkSP<vtkResliceCursorLineRepresentation> rep[3];*/

  double viewUp[3][3] = { {0,0,-1},{0,0,1},{0,1,0} };
  for (int i = 0; i < 3; i++)
  {
  	//m_rcw[i] = vtkSP<vtkResliceCursorWidget>::New();
  	m_rcw[i]->SetInteractor(GetVtkWindow(i)->GetInteractor());
  	
  	//m_rep[i] = vtkSP<vtkResliceCursorLineRepresentation>::New();
  	m_rcw[i]->SetRepresentation(m_rep[i]);
  	m_rep[i]->GetResliceCursorActor()->GetCursorAlgorithm()->SetResliceCursor(m_resliceCursor);
  	m_rep[i]->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i);
  	
  	const double minVal = volumeData->GetImageData()->GetScalarRange()[0];

  	if (vtkImageReslice* reslice = vtkImageReslice::SafeDownCast(m_rep[i]->GetReslice()))
  	{
  		reslice->SetBackgroundColor(minVal, minVal, minVal, minVal);
  	}

  	m_rcw[i]->SetDefaultRenderer(GetRenderer(i));
  	m_rcw[i]->SetEnabled(true);
  	GetRenderer(i)->GetActiveCamera()->SetFocalPoint(0,0,0);
  	GetRenderer(i)->GetActiveCamera()->ParallelProjectionOn();
  	GetRenderer(i)->GetActiveCamera()->SetViewUp(viewUp[i][0], viewUp[i][1], viewUp[i][2]);
  	GetRenderer(i)->GetActiveCamera()->Zoom(1.5);
  	GetRenderer(i)->ResetCamera();

  	cbk->IPW[i] = m_ipw[i];
  	cbk->RCW[i] = m_rcw[i];

  	m_rcw[i]->AddObserver(vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk);
  	m_rcw[i]->AddObserver(
  		vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk);
  	m_rcw[i]->AddObserver(
  		vtkResliceCursorWidget::WindowLevelEvent, cbk);
  	m_rcw[i]->AddObserver(
  		vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk);
  	m_rcw[i]->AddObserver(
  		vtkResliceCursorWidget::ResetCursorEvent, cbk);
  	m_rcw[i]->AddObserver(
  		vtkCommand::WindowLevelEvent, cbk);
  	

  	double range[2];
  	volumeData->GetImageData()->GetScalarRange(range);
  	m_rep[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
  	m_ipw[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
  	m_rep[i]->SetLookupTable(m_rep[0]->GetLookupTable());
  	m_ipw[i]->GetColorMap()->SetLookupTable(m_rep[0]->GetLookupTable());
  	
  }

}

class vtkResliceCursorCallback : public vtkCommand
{
public:
static vtkResliceCursorCallback * New()
{

   return new vtkResliceCursorCallback;

}

void Execute(vtkObject * caller, unsigned long event, void* callData) override
{
if (vtkResliceCursorWidget::WindowLevelEvent == event ||
vtkCommand::WindowLevelEvent == event ||
vtkResliceCursorWidget::ResliceThicknessChangedEvent == event)
{
for (int i = 0; i < 3; i++)
{
this->RCW[i]->Render();
if(nullptr == m_pRen) m_pRen->Render();
}
this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
return;
}

      vtkImagePlaneWidget * ipw = dynamic_cast<vtkImagePlaneWidget*>(caller);
      if (ipw)
      {
          double* wl = static_cast<double*>(callData);

          if (ipw == this->IPW[0])
          {
              this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
              this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
          }
          else if (ipw == this->IPW[1])
          {
              this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
              this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
          }
          else if (ipw == this->IPW[2])
          {
              this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
              this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
          }
      }
      vtkResliceCursorWidget * rcw = dynamic_cast<vtkResliceCursorWidget*>(caller);
      if (rcw)
      {
          vtkResliceCursorLineRepresentation * rep = 
  			dynamic_cast<vtkResliceCursorLineRepresentation*>(rcw->GetRepresentation());

          //vtkResliceCursor* rc = rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
  		

  		rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
          for (int i = 0; i < 3; i++)
          {
  			vtkPlaneSource* ps = static_cast<vtkPlaneSource*>(this->IPW[i]->GetPolyDataAlgorithm());
  			ps->SetOrigin(
  				this->RCW[i]->GetResliceCursorRepresentation()->GetPlaneSource()->GetOrigin());
  			ps->SetPoint1(
  				this->RCW[i]->GetResliceCursorRepresentation()->GetPlaneSource()->GetPoint1());
  			ps->SetPoint2(
  				this->RCW[i]->GetResliceCursorRepresentation()->GetPlaneSource()->GetPoint2());
  			
  			/*vtkPlaneSource * ps = static_cast<vtkPlaneSource*>(this->IPW[i]->GetPolyDataAlgorithm());
              ps->SetNormal(rc->GetPlane(i)->GetNormal());
              ps->SetCenter(rc->GetPlane(i)->GetOrigin());*/
  			

              this->IPW[i]->UpdatePlacement();
          }
      }

  	for (int i = 0; i < 3; i++)
  	{
  		this->RCW[i]->Render();
  		if (nullptr == m_pRen) m_pRen->Render();
  	}
  	this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();        
  	if (nullptr == m_pRen) m_pRen->Render();
  	
   }

vtkResliceCursorCallback() {}
vtkImagePlaneWidget * IPW[3];
vtkResliceCursorWidget * RCW[3];

// 3d renderer
vtkRenderer* m_pRen;
};

I found that it is operating when I press mouse left button with ctrl key.
then I want to default set as pressing ctrl key even if I don’t press ctrl key.
the thing that i want is setting a defulat by orthogonal when I drag one axis in MPR , two axis is maintaining orthogonal.
How can I do?? Tell me know how can I set.

I checked option which can set a orthogonal here.

but I can’t find ResliceCursorWidgetState and set “keep orthogonal” like below photo.

Hi, did you solve it yet? I got the same problem