最近收到需求,要实现多视图显示同一个STL模型,并且控制主窗口要其他试图窗口也跟着交互,花了点时间去尝试一下,把这个效果给实现出来了,而且实现也挺简单。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
class vtkUpdateCamera : public vtkCommand
{
public:
static vtkUpdateCamera* New()
{
return new vtkUpdateCamera;
}
void Execute(vtkObject* caller, unsigned long vtkNotUsed(event), void* callData)
{
//获取主camera
vtkRenderer* renderer = dynamic_cast<vtkRenderer*>(caller);
auto camera = renderer->GetActiveCamera();
//更新两个辅助camera的参数
camera1->SetPosition(camera->GetPosition());
camera1->SetFocalPoint(camera->GetFocalPoint());
camera1->SetViewUp(camera->GetViewUp());
camera1->Azimuth(90);
camera1->Modified();
//通过调整摄像头的viewup的旋转角度,为辅助摄像头实现上试图,左视图的朝向
camera2->SetPosition(camera->GetPosition());
camera2->SetFocalPoint(camera->GetFocalPoint());
double* viewUp = camera->GetViewUp();
double* direction = camera->GetDirectionOfProjection();
double view[3];
vtkMath::Cross(direction, viewUp, view);
camera2->SetViewUp(view);
camera2->Azimuth(-90);
camera2->Modified();
}
void SetCamera1(vtkCamera* c)
{
camera1 = c;
}
void SetCamera2(vtkCamera* c)
{
camera2 = c;
}
private:
vtkCamera* camera1;
vtkCamera* camera2;
};
int main()
{
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName("D://Bunny.stl");
reader->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
double* bounds = reader->GetOutput()->GetBounds();
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0, bounds[2]- 200, 0);
camera->SetFocalPoint(reader->GetOutput()->GetCenter());
camera->SetViewUp(0, 0, 1);
vtkSmartPointer<vtkCamera> camera1 = vtkSmartPointer<vtkCamera>::New();
vtkSmartPointer<vtkCamera> camera2 = vtkSmartPointer<vtkCamera>::New();
//为主渲染器准备更新摄像头的回调函数
vtkSmartPointer<vtkUpdateCamera> callback = vtkSmartPointer<vtkUpdateCamera>::New();
callback->SetCamera1(camera1);
callback->SetCamera2(camera2);
//---------设置主渲染器----------
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetActiveCamera(camera);
renderer->SetBackground(1, 1, 1);
renderer->SetViewport(0, 0, 0.33, 1);
//为主渲染器绑定回调函数,使用AnyEvent为了使任何交互都影响两个辅助摄像头
renderer->AddObserver(vtkCommand::AnyEvent, callback);
//---------设置第一个辅助渲染器----------
vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
auto actors = renderer->GetActors();
actors->InitTraversal();
for (int i = 0; i < actors->GetNumberOfItems(); i++)
{
renderer1->AddActor(actors->GetNextActor());
}
renderer1->SetActiveCamera(camera1);
renderer1->SetViewport(0.33, 0, 0.66, 1);
renderer1->SetBackground(1, 1, 1);
//---------设置第二个辅助渲染器----------
vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
renderer2->SetActiveCamera(camera2);
renderer2->SetViewport(0.66, 0, 1, 1);
renderer2->SetBackground(1, 1, 1);
actors->InitTraversal();
for (int i = 0; i < actors->GetNumberOfItems(); i++)
{
renderer2->AddActor(actors->GetNextActor());
}
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->AddRenderer(renderer1);
renderWindow->AddRenderer(renderer2);
renderWindow->SetSize(1200, 400);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(renderWindow);
rwi->SetInteractorStyle(style);
rwi->Start();
}