5.VTK 可视化管线

第三阶段 VTK可视化管线实战:Source、Filter、材质渲染模式

前面已经懂管线整体流程、vtkPolyData数据结构。本阶段重点:Source、Filter怎么串联,常用过滤器,修改物体外观(颜色、线框、透明度)。

回顾管线核心链条: Source → Filter(可0个或多个) → Mapper → Actor → Renderer

3.1 Source 数据源

Source的作用:生成/读取原始vtkDataSet数据,输出数据集,不需要输入。 分为两类:

  1. 几何生成Source(程序造几何体) vtkSphereSource球体、vtkCubeSource立方体、vtkCylinderSource圆柱体、vtkConeSource圆锥
  2. 文件读取Source(读磁盘文件) vtkSTLReader读取stl、vtkOBJReader读取obj

示例:立方体Source,只看关键片段

vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();
cubeSource->SetXLength(4); //X方向长度
cubeSource->SetYLength(4);
cubeSource->SetZLength(4);
cubeSource->Update(); //触发生成网格

Source统一行为:

  • 一堆SetXXX设置参数
  • 调用Update()真正计算生成数据
  • GetOutput()拿到输出数据集(vtkPolyData)

3.2 Filter 过滤器(管线最重要的数据处理环节)

Filter:接收一份输入数据集,处理之后输出一份新的数据集。 可以多个Filter首尾串联:source → filterA → filterB → mapper

核心接口

filter->SetInputData(输入数据集); //设置输入
filter->Update();                 //执行处理算法
filter->GetOutput();              //拿到处理后的结果

注意:SetInputData() 接收的是数据集(vtkPolyData等)。 你可以直接拿source/上一个filter的GetOutput()传进去。

示例1:vtkCleanPolyData 清理冗余点过滤器

场景:模型有大量重复重合点,占用内存、渲染异常,用这个过滤器清理合并重合点。

// sphereSource是球体数据源
vtkSmartPointer<vtkCleanPolyData> cleanFilter = vtkSmartPointer<vtkCleanPolyData>::New();
cleanFilter->SetInputData(sphereSource->GetOutput()); //接入球体输出
cleanFilter->SetTolerance(0.001); //距离小于这个阈值就判定为重合点,进行合并
cleanFilter->Update();

// 把filter输出交给mapper,而不是直接用sphereSource输出
mapper->SetInputData(cleanFilter->GetOutput());

管线链路:sphereSource → cleanFilter → mapper

示例2:串联多个Filter

球体 → 清理点 → 坐标变换

sphereSource → cleanFilter → transformFilter → mapper
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->Translate(2,0,0); //整体沿X轴平移2个单位

vtkSmartPointer<vtkTransformFilter> transformFilter = vtkSmartPointer<vtkTransformFilter>::New();
transformFilter->SetInputData(cleanFilter->GetOutput());
transformFilter->SetTransform(transform);
transformFilter->Update();

mapper->SetInputData(transformFilter->GetOutput());

✨小白铁律:

  1. 每一个Filter都要Update()才会执行算法;
  2. 串联的时候,后一个Filter的输入 = 前一个Filter的GetOutput();
  3. Filter不会修改原始输入数据,输出是新生成一份数据。原始数据不受破坏。

几个高频入门Filter清单(记住名字,后面会反复用)

Filter类名 功能
vtkCleanPolyData 合并重复点,清理无效面片
vtkTransformFilter 平移、旋转、缩放模型
vtkClipPolyData 按平面裁剪模型,切掉一部分
vtkSmoothPolyDataFilter 网格平滑
vtkAppendPolyData 把多个PolyData合并成一个
vtkPolyDataNormals 计算面片、点法向量,解决模型发黑

3.3 Actor Property:修改物体外观(材质、线框、透明度)

actor->GetProperty() 返回 vtkProperty 对象,控制物体显示模样,不改动底层网格数据,只改渲染表现。

常用接口示例:

vtkProperty* prop = actor->GetProperty();

prop->SetColor(1,0.3,0.3);      // RGB颜色 0~1
prop->SetOpacity(0.5);          // 透明度,0完全透明,1不透明
prop->SetRepresentationToSurface(); // 实体面渲染(默认)
prop->SetRepresentationToWireframe();// 只渲染线框,看不到面片填充
prop->SetRepresentationToPoints();  // 只渲染顶点点云

prop->SetEdgeVisibility(true);  // 实体模式下,把面片边线显示出来
prop->SetEdgeColor(1,1,1);      // 边线颜色白色

prop->SetPointSize(3);          // 点模式下点的大小
prop->SetLineWidth(2);          // 线框模式线宽

关键点:Representation 三种模式,只是渲染模式切换,不会修改vtkPolyData内部数据。比如切到线框模式,Points、Polys数据还完整保存在内存里。

完整可阅读Demo:球体经过Clean+平移Filter,线框显示

整合Source+两级Filter+修改渲染属性,完整代码,只看逻辑。

#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkCleanPolyData.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

int main()
{
    //1.Source 球体
    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetRadius(3);
    sphereSource->SetThetaResolution(20);
    sphereSource->SetPhiResolution(20);
    sphereSource->Update();

    //2.Filter1:清理重复点
    vtkSmartPointer<vtkCleanPolyData> cleanFilter = vtkSmartPointer<vtkCleanPolyData>::New();
    cleanFilter->SetInputData(sphereSource->GetOutput());
    cleanFilter->SetTolerance(0.001);
    cleanFilter->Update();

    //3.Filter2:X轴平移
    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
    trans->Translate(1.5,0,0);

    vtkSmartPointer<vtkTransformFilter> transFilter = vtkSmartPointer<vtkTransformFilter>::New();
    transFilter->SetInputData(cleanFilter->GetOutput());
    transFilter->SetTransform(trans);
    transFilter->Update();

    //4.Mapper 接收最后一个filter输出
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData(transFilter->GetOutput());

    //5.Actor 设置外观:线框模式,红色
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper.Get());
    actor->GetProperty()->SetColor(1,0.2,0.2);
    actor->GetProperty()->SetRepresentationToWireframe(); //线框渲染

    //渲染交互部分不变
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground(0,0,0);

    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800,600);

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    interactor->Initialize();
    interactor->Start();
    return 0;
}

管线链路: sphereSource → cleanFilter → transFilter → mapper → actor

运行效果:窗口显示一个向右偏移的红色线框球体。

本阶段重点小结

  1. Source只输出数据,无输入;Filter有输入有输出,可以串联;
  2. SetInputData() 连接管线,Update()触发计算,GetOutput()拿结果;
  3. Filter处理会输出新数据集,原始输入数据不会被修改;
  4. vtkProperty控制外观:颜色、透明度、实体/线框/点模式,只改渲染,不改网格数据。

新手高频坑

  1. Filter串联,Mapper错误的拿最开头source的输出,Filter完全没生效;
  2. 忘记Filter的Update(),拿到空数据;
  3. 混淆:SetRepresentationToWireframe只是渲染模式,不是把模型变成线几何。

posted @ 2026-08-24 16:11  Drunker•L  阅读(10)  评论(0)    收藏  举报