#include <vtkPlaneSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNamedColors.h>
#include <array>
#include <vtkProperty.h>
#include "vtkSmartPointer.h"
#include "vtkLineSource.h"
#include "vtkRendererCollection.h"
#include "vtkRenderer.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include <vtkSmartPointer.h>
#include <vtkRectilinearWipeWidget.h>
#include <vtkRectilinearWipeRepresentation.h>
#include <vtkJPEGReader.h>
#include <vtkImageRectilinearWipe.h>
#include <vtkImageActor.h>
#include <vtkImageMapper3D.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty2D.h>
#include <vtkCommand.h>
#include <vtkObjectFactory.h>
#include <vtkInteractorStyleImage.h>
#include <vtkResliceImageViewer.h>
#include <vtkBMPReader.h>
class MyRubberBand : public vtkInteractorStyleRubberBand2D
{
public:
static MyRubberBand* New();
vtkTypeMacro(MyRubberBand, vtkInteractorStyleRubberBand2D);
virtual void OnLeftButtonDown()
{
vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); //必须有这一句
//if (mExistActor)
//{
// return;
//}
startPosition[0] = this->GetInteractor()->GetEventPosition()[0];
startPosition[1] = this->GetInteractor()->GetEventPosition()[1];
startPosition[2] = 0;
std::cout << "startPosition: " << startPosition[0] << " " << startPosition[1] << std::endl;
}
virtual void OnLeftButtonUp()
{
vtkInteractorStyleRubberBand2D::OnLeftButtonUp(); //必须有这一句
//if (mExistActor)
//{
//return;
//}
endPosition[0] = this->GetInteractor()->GetEventPosition()[0];
endPosition[1] = this->GetInteractor()->GetEventPosition()[1];
endPosition[2] = 0;
std::cout << "endPosition: " << endPosition[0] << " " << endPosition[1] << std::endl;
this->viewer->GetRenderer()->SetDisplayPoint(startPosition);
this->viewer->GetRenderer()->DisplayToView();
this->viewer->GetRenderer()->ViewToWorld();
double start[4];
this->viewer->GetRenderer()->GetWorldPoint(start);
this->viewer->GetRenderer()->SetDisplayPoint(endPosition);
this->viewer->GetRenderer()->DisplayToView();
this->viewer->GetRenderer()->ViewToWorld();
double end[4];
this->viewer->GetRenderer()->GetWorldPoint(end);
double point1[3];
double point2[3];
double point3[3];
double point4[3];
double left[2];
double right[2];
left[0] = start[0] <= end[0] ? start[0] : end[0];
left[1] = start[1] <= end[1] ? start[1] : end[1];
right[0] = start[0]>end[0] ? start[0] : end[0];
right[1] = start[1]>end[1] ? start[1] : end[1];
point1[0] = left[0]; point1[1] = left[1]; point1[2] = 0;
point2[0] = left[0]; point2[1] = right[1]; point2[2] = 0;
point3[0] = right[0]; point3[1] = right[1]; point3[2] = 0;
point4[0] = right[0]; point4[1] = left[1]; point4[2] = 0;
this->SetLine(point1, point2);
this->SetLine(point2, point3);
this->SetLine(point3, point4);
this->SetLine(point4, point1);
}
void SetLine(double point1[], double point2[])
{
vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(point1);
lineSource->SetPoint2(point2);
lineSource->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetLineWidth(2);
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
this->viewer->GetRenderer()->AddActor(actor);
this->viewer->Render();
mExistActor = true;
}
vtkSmartPointer<vtkImageViewer2> viewer;
//vtkSmartPointer<vtkResliceImageViewer> viewer;
void SetRender(vtkImageViewer2 * render)
{
viewer = render;
}
protected:
MyRubberBand()
{
//viewer = vtkSmartPointer<vtkImageViewer2>::New();
//viewer->SetupInteractor(this->GetInteractor());
mExistActor = false;
}
//
private:
double startPosition[3];
double endPosition[3];
//bool mExistActor;
//vtkImageViewer2 * mRender;
};
vtkStandardNewMacro(MyRubberBand);
int main(int, char *[])
{
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
// Set the background color.
std::array<unsigned char, 4> bkg{ { 26, 51, 77, 255 } };
colors->SetColor("BkgColor", bkg.data());
// Create a renderer, render window and interactor
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
//renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer<vtkBMPReader> reader1 =
vtkSmartPointer<vtkBMPReader>::New();
reader1->SetFileName("./32.bmp");
reader1->Update();
// Add the actors to the scene
renderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();
viewer->SetInputConnection(reader1->GetOutputPort());
viewer->SetRenderer(renderer);
viewer->SetSize(640, 480);
viewer->SetColorLevel(500);
viewer->SetColorWindow(2000);
viewer->SetSlice(40);
viewer->SetSliceOrientationToXY();
viewer->Render();
viewer->GetRenderer()->SetBackground(1, 1, 1);
viewer->GetRenderWindow()->SetWindowName("ImageViewer2D");
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
viewer->SetupInteractor(rwi);
vtkSmartPointer<MyRubberBand> g_style = vtkSmartPointer<MyRubberBand>::New();
g_style->SetInteractor(rwi);
rwi->SetInteractorStyle(g_style);
g_style->SetRender(viewer);
//设置交互属性
rwi->Start();
return EXIT_SUCCESS;
}
要点:
1.在重新实现的onLeftButtonDown()函数中,必须调用 vtkInteractorStyleRubberBand2D::OnLeftButtonDown(); 否则无法交互;onLeftButtonUp()函数同理;
2.通过 this->GetInteractor()->GetEventPosition()得到的是屏幕坐标,必须先将其转换成世界坐标,否则矩形位置并不正确;
3.viewer->SetupInteractor(iren)必须置于iren->SetInteractorStyle(style)之前,否者viewer还使用原来的InteractorStyle。