VTK中在同一窗口或空间显示多个渲染模型的三种方法
刚开始学习vtk,记录一下学习过程。
在使用vtk进行可视化处理时,想将多个模型放在同一空间显示。但是网上大多都是使用视口方法,在同一窗口
分区域单独显示多个模型,不是我想要的效果,搜索良久,终于找到另外两种方法,在这里和视口法一起记录一下。
- 使用vtkAppendPolyData数据合并显示;
- 在render中渲染多个actor后在renderwin中显示;
- 多视口显示;
1.使用vtkAppendPolyData数据合并显示
VTKPolyData主要由几何结构数据、拓扑结构数据、属性数据组成,可以用来表示很多常用的数据结构,如点云数据、面片模型等。使用vtkAppendPolyData()函数可以将两个或多个模型数据合并在一起,示例代码是将平面和点云数据合并显示
vtkSmartPointer<vtkPlaneSource>planeSource = vtkSmartPointer<vtkPlaneSource>::New();//下面是根据点法式创建的平面
planeSource->SetCenter(0, 0, -1);//平面中心
//三点确定平面
planeSource->SetOrigin(-10, -10, -1);//平面起点
planeSource->SetPoint1(10 , -10, -1);//第一象限
planeSource->SetPoint2(-10 ,10, -1);//第二象限
planeSource->SetNormal(0, 0, 1);//平面法向量
planeSource->Update();
//planeSource会根据上面输入数据,创建PolyData对象,并通过GetOutput输出对象指针
vtkSmartPointer<vtkPolyData> polydataPlane = vtkSmartPointer<vtkPolyData>::New();
polydataPlane = planeSource->GetOutput();
//输入自己点云数据
vtkPoints* points = vtkPoints::New();
vtkCellArray* cells = vtkCellArray::New();
ifstream fs("chuli.txt");
vtkIdType idtype;
double x, y, z;
while (fs >> x >> y >> z)
{
//插入点坐标,此处可改为其它的xyz
idtype = points->InsertNextPoint(x, y, z);
cells->InsertNextCell(1, &idtype);
}
// 渲染机制未知,需要同时设置点坐标与点坐标对应的verts
// verts中的id必须与点坐标对应
vtkPolyData* polyData = vtkPolyData::New();
polyData->SetPoints(points);
polyData->SetVerts(cells);
//合并平面和点云
vtkSmartPointer<vtkAppendPolyData> append =
vtkSmartPointer<vtkAppendPolyData>::New();
append->AddInputData(polyData);
append->AddInputData(planeSource->GetOutput());
append->Update();
// 创建映射
vtkSmartPointer<vtkPolyDataMapper> appendmapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
appendmapper->SetInputConnection(append->GetOutputPort());
//演员
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(appendmapper);
//渲染
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetActiveCamera(camera);
//显示
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(600, 600);
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow)
renderWindowInteractor->Start();
2. 在render中渲染多个actor后在renderwin中显示
之前一直纠结两个物体如何渲染后在一个窗口显示,运行代码一直只显示最后一个被渲染的物体,苦恼半天,后来看了大佬们的博客才想到,可以先设置好多个actor的属性然后在同一个渲染器里渲染就可以了啊。
//创建平面
vtkSmartPointer<vtkPlaneSource>planeSource = vtkSmartPointer<vtkPlaneSource>::New();
planeSource->SetCenter(0, 0, -1);
planeSource->SetOrigin(-10, -10, -1);
planeSource->SetPoint1(10 , -10, -1);
planeSource->SetPoint2(-10 ,10, -1);
planeSource->SetNormal(0, 0, 1);
planeSource->Update();
vtkSmartPointer<vtkPolyData> polydataPlane = vtkSmartPointer<vtkPolyData>::New();
polydataPlane = planeSource->GetOutput();
//设置平面属性
vtkSmartPointer<vtkPolyDataMapper> planemapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
planemapper->SetInputConnection(planeSource->GetOutputPort());
vtkSmartPointer<vtkActor>planeactor =
vtkSmartPointer<vtkActor>::New();
planeactor->SetMapper(planemapper);
//planeactor->SetTexture(texture);//纹理映射
//设置点云属性
vtkSmartPointer<vtkSimplePointsReader> reader = vtkSmartPointer<vtkSimplePointsReader>::New();
reader->SetFileName("chuli.txt");
reader->Update();
vtkSmartPointer<vtkPolyDataMapper> cloudmapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
cloudmapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor>cloudactor =
vtkSmartPointer<vtkActor>::New();
cloudactor->SetMapper(cloudmapper);
cloudactor->GetProperty()->SetColor(0.75,1, 0.75);//绿色
//渲染器渲染两个actor
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cloudactor);
renderer->AddActor(planeactor);
renderer->SetActiveCamera(camera);
//显示
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(600, 600);
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Start();
3. 多视口显示
多视口显示网上代码很多,不多赘述了,其实就是在绘制器类里调用SetViewport()函数。
vtkSmartPointer<vtkRenderer> renderer1 =
vtkSmartPointer<vtkRenderer>::New();
renderer1->AddActor(actor1);
renderer1->SetViewport(0.0, 0.0, 0.5, 1.0);
vtkSmartPointer<vtkRenderer> renderer2 =
vtkSmartPointer<vtkRenderer>::New();
renderer2->AddActor(actor2);
renderer2->SetViewport(0.5, 0.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(600, 600);
renderWindow->AddRenderer(renderer1);
renderWindow->AddRenderer(renderer2);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Start();