例如:我们的初衷是想要显示一个图像,然后在图像上画一条直线,得到直线与图像重合的点的坐标。
问题:在主函数中,显示一个图像,并写上交互类Style,那么如何使图像数据与直线数据进行交互处理呢?
主函数中的交互函数一般是写成下面这样的:
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->SetPicker(pointPicker);
renderWindow->Render(); //绘制请求
// vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
vtkSmartPointer<customMouseInteractorStyle> style =vtkSmartPointer<customMouseInteractorStyle>::New(); ///这个是画线的
renderWindowInteractor->SetInteractorStyle(style);
在这个主程序中我们实现的是显示一个图像,然后在交互中画一条直线,最后显示我们想要的结果。
下面是我重写的Style函数:实现鼠标左键点两个点,连成一条线:
double point1[3]{ 0 };double point2[3]{ 0 };double point3[3]{ 0 };double p[3]{ 0 };
double WorldPointbegin[3]{ 0 };double WorldPointend[3]{ 0 };
int *clickPosbegin;int *clickPosend;int *click;
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
protected:
;
public:
vtkPolyDataMapper *lineMapper = vtkPolyDataMapper::New();
vtkSmartPointer<vtkActor> lineActor=vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkLineSource> lineSource= vtkSmartPointer<vtkLineSource>::New();
virtual void OnLeftButtonDown(){
if(i==0){
//打印鼠标左键像素位置
clickPosbegin = this->Interactor->GetEventPosition();
point1[0]=clickPosbegin[0];
point1[1]=clickPosbegin[1];
std::cout << "clickPosbegin: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointbegin);
std::cout << "WorldPointbegin :" << WorldPointbegin[0] << "," << WorldPointbegin[1] << "," << WorldPointbegin[2] << std::endl;
//对拾取点进行标记
sphereSourcebegin->Update();
mapperbegin->SetInputConnection(sphereSourcebegin->GetOutputPort());
actorbegin->SetMapper(mapperbegin);
actorbegin->SetPosition(WorldPointbegin);
actorbegin->SetScale(4);
actorbegin->GetProperty()->SetColor(1.0, 0.0, 1.0);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorbegin);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
i=1;
}
else if(i==1)
{
//打印鼠标左键像素位置
clickPosend = this->Interactor->GetEventPosition();
point2[0]=clickPosend[0];
point2[1]=clickPosend[1];
std::cout << "clickPosend: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
//打印拾取点空间位置
this->Interactor->GetPicker()->GetPickPosition(WorldPointend);
std::cout << "WorldPointend : " << WorldPointend[0] << " " << WorldPointend[1] << " " << WorldPointend[2] << std::endl;
//对拾取点进行标记
sphereSourcend->Update();
mapperend->SetInputConnection(sphereSourcend->GetOutputPort());
actorend->SetMapper(mapperend);
actorend->SetPosition(WorldPointend);
actorend->SetScale(4);
actorend->GetProperty()->SetColor(0.0, 1.0, 1.0);
Point_in_Tube_function(pointsPolydata);
lineSource->SetPoint1(WorldPointbegin);
lineSource->SetPoint2(WorldPointend);//两点确定一条直线
lineSource->Update();
lineMapper->SetInputConnection(lineSource->GetOutputPort());
lineMapper->ScalarVisibilityOff();
lineActor->SetMapper(lineMapper);
lineActor->GetProperty()->SetColor(0, 0, 0);//线的颜色设置
lineActor->GetProperty()->SetOpacity(1);//0是透明
/*
*
*这里可以添加图像与直线的交互过程
*
*/
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actorend);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(lineActor);
i=0;
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
}
}
{ vtkInteractorStyleTrackballCamera::OnLeftButtonUp();}
};
vtkStandardNewMacro(customMouseInteractorStyle);
线画好了,这时候就要将图像的数据传进来:
备注:我的style函数中的protected是空的:这个地方就可以放传进来的图像数据:具体写法是;
protected:
vtkImageData image;
同时定义函数
public:
void Setimage(vtkImageData _image ) {
image = _image ;
}
主函数中的Style也要有传数据的通道:
vtkSmartPointer<customMouseInteractorStyle> style =vtkSmartPointer<customMouseInteractorStyle>::New(); ///这个是画线的
style->Setimage(reader->GetOutput()) ;