文章目录
- 1. 概述
- 2. CMake链接VTK
- 3. main.cpp文件
- 4. 演示效果
| 更多精彩内容 |
|---|
| 👉内容导航 👈 |
| 👉VTK开发 👈 |
1. 概述
本示例用于读取并可视化PDB格式的分子结构文件,显示分子中的原子和化学键的3D模型;
PDB(Protein Data Bank)是一种用于存储生物大分子三维结构数据的标准文件格式。它最初是为了存储蛋白质结构而设计的,现在也广泛用于存储DNA、RNA、病毒和其他生物大分子的结构信息。
核心组件和流程
- 数据读取
使用 vtkPDBReader 读取PDB文件
设置氢键和B因子的缩放比例
- 原子可视化
根据原子数量动态计算适当的分辨率
使用 vtkSphereSource创建球体表示原子
通过 vtkGlyph3D将原子数据映射到球体上
使用 vtkPolyDataMapper 和 vtkLODActor进行渲染
- 化学键可视化
使用 vtkTubeFilter 创建管状结构表示化学键
使用 vtkPolyDataMapper 和 vtkLODActor进行渲染
使用PDB文件下载地址
VTK环境使用vcpkg安装,使用vcpkg安装的VTK编译后会自动打包依赖的dll到可执行程序路径下,方便程序运行;
手动编译和引入VTK看这里
| 环境 | 说明 |
|---|---|
| 系统 | ubuntu22.04、windows11 |
| cmake | 3.22、3.25 |
| Qt | 5.14.2 |
| 编译器 | g++11.4、msvc2017 |
| VTK | 9.4.1 |
2. CMake链接VTK
cmake_minimum_required(VERSION3.20FATAL_ERROR)# 设置CMake最低版本include("D:/vcpkg/scripts/buildsystems/vcpkg.cmake")# 引入vcpkg 《《《《《《project(vtk_vcpkg)# 设置工程名# 设置C++标准set(CMAKE_CXX_STANDARD14)# 设置MSVC编译器使用UTF-8编码if(MSVC)set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}/utf-8")endif()# 查找VTKfind_package(VTK COMPONENTS CommonColor FiltersCore FiltersSources IOChemistry InteractionStyle RenderingContextOpenGL2 RenderingCore RenderingFreeType RenderingGL2PSOpenGL2 RenderingLOD RenderingOpenGL2)if(NOT VTK_FOUND)# 如果VTK没有找到message(FATAL_ERROR"VTK 没找到")# 报错return()endif()add_executable(${PROJECT_NAME}main.cpp)# 添加可执行文件target_link_libraries(${PROJECT_NAME}PRIVATE${VTK_LIBRARIES})# 链接VTK库# 设置VTK模块自动初始化vtk_module_autoinit(TARGETS${PROJECT_NAME}MODULES${VTK_LIBRARIES})3. main.cpp文件
// 包含VTK库中的各种头文件,用于3D可视化#include<vtkGlyph3D.h>#include<vtkLODActor.h>#include<vtkNamedColors.h>#include<vtkPDBReader.h>#include<vtkPolyDataMapper.h>#include<vtkProperty.h>#include<vtkRenderWindow.h>#include<vtkRenderWindowInteractor.h>#include<vtkRenderer.h>#include<vtkSphereSource.h>#include<vtkTubeFilter.h>// 包含标准库头文件#include<cmath>#include<iostream>#include<algorithm>usingnamespacestd;intmain(intargc,char*argv[]){// 定义要读取的PDB文件路径string filename="E:/VTK/vtk-data/Data/caffeine.pdb";vtkNew<vtkPDBReader>pdb;// 创建PDB文件读取器对象pdb->SetFileName(filename.c_str());pdb->SetHBScale(1.0);// 设置氢键缩放因子pdb->SetBScale(1.0);// 设置B因子缩放pdb->Update();// 更新读取器,执行读取操作vtkNew<vtkNamedColors>colors;// 创建颜色管理对象vtkNew<vtkRenderer>renderer;// 创建渲染器对象,用于显示数据// 设置渲染器背景色为石板灰(SlateGray)renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());vtkNew<vtkRenderWindow>renderWindow;// 创建渲染窗口对象renderWindow->AddRenderer(renderer);renderWindow->SetSize(600,600);vtkNew<vtkRenderWindowInteractor>interactor;// 创建交互器对象interactor->SetRenderWindow(renderWindow);// 将渲染窗口设置给交互器// 计算合适的分辨率值,基于原子数量调整球体精细度doubleresolution=sqrt(300000.0/pdb->GetNumberOfAtoms());cout<<"Resolution: "<<resolution<<endl;// 限制分辨率在4到20之间resolution=max(1.0,min(resolution,20.0));// 创建球体源,用于表示原子vtkNew<vtkSphereSource>sphere;sphere->SetCenter(0,0,0);// 设置球心坐标sphere->SetRadius(1);// 设置球半径// 根据计算出的分辨率设置球体的经线和纬线数sphere->SetThetaResolution(static_cast<int>(resolution));// 经线数sphere->SetPhiResolution(static_cast<int>(resolution));// 纬线数// 创建字形过滤器,用于将原子数据映射到球体上,将输入数据集中的每个点替换为一个几何图形vtkNew<vtkGlyph3D>glyph;glyph->SetInputConnection(pdb->GetOutputPort());// 设置输入数据源glyph->SetOrient(1);// 启用方向设置(0/1)glyph->SetColorMode(VTK_COLOR_BY_SCALAR);// 设置颜色模式,根据输入数据的标量值来为每个glyph分配颜色// glyph->ScalingOn(); // 启用缩放glyph->SetScaleMode(VTK_SCALE_BY_VECTORCOMPONENTS);// 设置缩放模式glyph->SetScaleFactor(0.25);// 设置缩放因子,控制最终显示大小glyph->SetSourceConnection(sphere->GetOutputPort());// 设置球体作为源数据// 创建多边形数据映射器,用于原子显示,为 vtkActor 提供渲染所需的所有信息vtkNew<vtkPolyDataMapper>atomMapper;atomMapper->SetInputConnection(glyph->GetOutputPort());// 设置输入连接,接收来自上游过滤器的数据atomMapper->UseLookupTableScalarRangeOff();// 控制是否使用查找表定义的标量范围来映射颜色atomMapper->ScalarVisibilityOn();// 启用或禁用标量数据的可见性,即是否根据标量数据对几何体进行着色atomMapper->SetScalarModeToDefault();// 使用默认的标量映射模式,使用标量数据进行颜色映射// 创建LOD Actor,支持多层细节的演员,专门用于处理大规模数据集的高效渲染vtkNew<vtkLODActor>atom;atom->SetMapper(atomMapper);// 设置映射器// atom->GetProperty()->SetRepresentationToPoints(); // 只渲染几何体的顶点// atom->GetProperty()->SetRepresentationToWireframe(); // 渲染几何体的边框线条atom->GetProperty()->SetRepresentationToSurface();// 渲染完整的表面// atom->GetProperty()->SetInterpolationToFlat(); // 平面着色,渲染速度快但效果粗糙atom->GetProperty()->SetInterpolationToGouraud();// 高洛德着色,基于顶点颜色进行线性插值,在多边形内部进行颜色平滑过渡,平衡了质量和性能// atom->GetProperty()->SetInterpolationToPhong(); // 冯氏着色,最真实的光照表现,计算量最大atom->GetProperty()->SetAmbient(0.1);// 设置环境光系数[0, 1]atom->GetProperty()->SetDiffuse(0.7);// 设置漫反射系数atom->GetProperty()->SetSpecular(0.5);// 设置镜面反射系数atom->GetProperty()->SetSpecularPower(80);// 设置镜面反射强度atom->GetProperty()->SetSpecularColor(colors->GetColor3d("White").GetData());// 设置镜面反射颜色atom->SetNumberOfCloudPoints(pdb->GetNumberOfAtoms());// 使用 PDB 文件中包含的原子总数设置点云数量renderer->AddActor(atom);// 将原子Actor添加到渲染器// 创建管状过滤器,用于绘制化学键vtkNew<vtkTubeFilter>tube;tube->SetInputConnection(pdb->GetOutputPort());// 设置输入数据源tube->SetNumberOfSides(static_cast<int>(resolution));// 设置管状体侧面数tube->CappingOff();// 关闭封顶tube->SetRadius(0.2);// 设置管半径tube->SetVaryRadius(0);// 设置半径变化模式tube->SetRadiusFactor(10);// 设置半径因子// 创建多边形数据映射器,用于化学键显示vtkNew<vtkPolyDataMapper>bondMapper;bondMapper->SetInputConnection(tube->GetOutputPort());// 设置输入连接bondMapper->UseLookupTableScalarRangeOff();// 不使用查找表标量范围bondMapper->ScalarVisibilityOff();// 关闭标量可见性bondMapper->SetScalarModeToDefault();// 设置默认标量模式// 创建LOD Actor,用于高效渲染化学键vtkNew<vtkLODActor>bond;bond->SetMapper(bondMapper);// 设置映射器bond->GetProperty()->SetRepresentationToSurface();// 设置表面表示bond->GetProperty()->SetInterpolationToGouraud();// 设置高洛德着色插值bond->GetProperty()->SetAmbient(0.1);// 设置环境光系数bond->GetProperty()->SetDiffuse(0.7);// 设置漫反射系数bond->GetProperty()->SetSpecular(0.5);// 设置镜面反射系数bond->GetProperty()->SetSpecularPower(80);// 设置镜面反射强度bond->GetProperty()->SetSpecularColor(colors->GetColor3d("White").GetData());// 设置镜面反射颜色renderer->AddActor(bond);// 将化学键Actor添加到渲染器// 设置窗口名称并启动渲染和交互循环renderWindow->SetWindowName("PDBReader");// 设置窗口标题renderWindow->Render();// 渲染场景interactor->Initialize();// 初始化交互器interactor->Start();// 开始事件循环returnEXIT_SUCCESS;// 正常退出程序}