Hi:
I want to get an oblique slice by picking a point on the CT image and rotating with mouse move. Please see codes below. So far everything works fine except that the resliced image will be repositioned to the center of my window. Anyone can shed some lights on this issue? The ideal behavior is :No matter what the reslice origin is,the image should remain on the original position.
class myResliceImageViewerCallback : public vtkCommand
{
public:
static myResliceImageViewerCallback *New() { return new myResliceImageViewerCallback1; }
void Execute(vtkObject *caller,
unsigned long event,
void *vtkNotUsed(callData)) override
{
if (this->IV->GetInput() == nullptr)
{
return;
}
if (event == vtkCommand::StartReslice3DEvent)
{
int* intPt = style->GetInteractor()->GetEventPosition();
int x = intPt[0];
int y = intPt[1];
this->render->SetDisplayPoint(x, y, 0);
this->render->DisplayToWorld();
auto worldPoint = this->render->GetWorldPoint();
vtkMatrix4x4 *mat = this->IV->GetResliceAxes();
std::cout << "x:" << worldPoint[0] << " Y:" << worldPoint[1] << " z:" << worldPoint[2] << endl;
double *w = new double[4]{ worldPoint[0], worldPoint[1], 0, 1 };
double * p = mat->MultiplyDoublePoint(w);
std::cout << "x1:" << p[0] << " Y1:" << p[1] << " z1:" << p[2] << endl;
this->IV->SetResliceAxesOrigin(p);
return;
}
if (event == vtkCommand::Reslice3DEvent)
{
auto curPos = style->GetResliceCurrentPosition();
auto startPos = style->GetResliceStartPosition();
if (startPos[0] == curPos[0] &&
startPos[1] == curPos[1])
{
return;
}
bool verticalRotate = false;
double delta = sqrt((curPos[0] - startPos[0])*(curPos[0] - startPos[0]) +
(curPos[1] - startPos[1])*(curPos[1] - startPos[1]));
if (abs(curPos[0] - startPos[0]) > abs(curPos[1] - startPos[1]))
{
verticalRotate = true;
if (curPos[0] < startPos[0])
{
delta = -delta;
}
}
else
{
if (curPos[1] < startPos[1])
{
delta = -delta;
}
}
vtkMatrix4x4* resliceAxes = this->IV->GetResliceAxes();
vtkVector3d horAxis(resliceAxes->GetElement(0, 0), resliceAxes->GetElement(1, 0), resliceAxes->GetElement(2, 0));
vtkVector3d verAxis(resliceAxes->GetElement(0, 1), resliceAxes->GetElement(1, 1), resliceAxes->GetElement(2, 1));
vtkVector3d normal(resliceAxes->GetElement(0, 2), resliceAxes->GetElement(1, 2), resliceAxes->GetElement(2, 2));
double *newNormal;
vtkVector3d axisN;
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
if (verticalRotate)
{
transform->RotateWXYZ(delta, verAxis.GetData());
newNormal = transform->TransformDoublePoint(normal.GetData());
vtkMath::Cross(verAxis.GetData(), newNormal, axisN.GetData());
this->IV->SetResliceAxesDirectionCosines(axisN.GetData(), verAxis.GetData(), newNormal);
}
else
{
transform->RotateWXYZ(delta, horAxis.GetData());
newNormal = transform->TransformDoublePoint(normal.GetData());
vtkMath::Cross(newNormal, horAxis.GetData(), axisN.GetData());
this->IV->SetResliceAxesDirectionCosines(horAxis.GetData(), axisN.GetData(), newNormal);
}
win->Render();
return;
}
}
vtkImageReslice *IV;
vtkRenderWindow *win;
vtkRenderer * render;
double InitialWindow;
double InitialLevel;
};
vtkSmartPointer<vtkDICOMImageReader> dicomReader = vtkSmartPointer<vtkDICOMImageReader>::New();
dicomReader->SetDirectoryName("d:\\shared\\CTs\\myTest);
dicomReader->Update();
vtkSmartPointer<vtkImageReslice> imgReslice = vtkSmartPointer<vtkImageReslice>::New();
imgReslice->SetInputConnection(dicomReader->GetOutputPort());
imgReslice->SetInterpolationModeToLinear();
imgReslice->SetOutputDimensionality(2);
double *centerr = dicomReader->GetOutput()->GetCenter();
double xAxis[3] = { 1.0, 0.0, 0.0 };
double yAxis[3] = { 0.0, 1.0, 0.0 };
double zAxis[3] = { 0.0, 0.0, 1.0 };
yAxis[0] = 0.0;
yAxis[1] = 0.0;
yAxis[2] = -1.0;
zAxis[0] = 0.0;
zAxis[1] = 1.0;
zAxis[2] = 0.0;
imgReslice->SetResliceAxesOrigin(centerr);
imgReslice->SetResliceAxesDirectionCosines(xAxis, yAxis, zAxis);
vtkSmartPointer<vtkImageMapToWindowLevelColors> wl = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
wl->SetWindow(1500);
wl->SetLevel(-600);
wl->SetInputConnection(imgReslice->GetOutputPort());
vtkSmartPointer<vtkImageActor> imgActor = vtkSmartPointer<vtkImageActor>::New();
imgActor->GetMapper()->SetInputConnection(wl->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<myCustomizedStyleImage>style = vtkSmartPointer<vtkLHInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
vtkSmartPointer<vtkRenderWindow> renderWin = vtkSmartPointer<vtkRenderWindow>::New();
renderWin->SetInteractor(renderWindowInteractor);
vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
renderWindowInteractor->GetRenderWindow()->AddRenderer(render);
myResliceImageViewerCallback *cbk = myResliceImageViewerCallback::New();
cbk->IV = imgReslice;
cbk->win = renderWin;
cbk->render = render;
style->AddObserver(vtkCommand::Reslice3DEvent, cbk);
style->AddObserver(vtkCommand::StartReslice3DEvent, cbk);
render->AddActor(imgActor);
renderWindowInteractor->Start();