标签:
activiz本身自带的user guide 比较简单,所以我按着vtk的user guide来慢慢学。从简单例子入手去学习VTK。当然我之前已经看过很多VTK相关的东西了,但是没有自己去写去总结,导致我一段时间不用就忘记了。所以这次写博客就从简单的开始,一步一步写下来。记录自己的学习过程。
不过,(⊙﹏⊙)b 我英文不太好,所以是看中文版的来学习的。参考的是这一本:
有需要的小伙伴们可以自己下载。
《VTK用户手册》 P20
VTK 建立应用程序的基本过程如下:
1) 读取/生成数据
2)过滤数据
3) 绘制图形
4) 交互操作
VTK 提供了两种获取数据的方法,一种是读取已经存在的数据文件,另一种是通过算法或数学表达式生成数据。
在可视化流水线中起始节点对象被称为源对象,源对象又被分为程序源对象、读源对象,通过数学方法生成数据的对象称为程序源对象,从数据文件中读取数据的对象被称为读源对象。
首先,做一个程序源对象的读取:
(额,在写代码之前的如何添加引用和添加renderwindowcontrol到工具栏就不再重复了,直接进入代码阶段)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Kitware.VTK; namespace test1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void renderWindowControl1_Load(object sender, EventArgs e) { //vtkCylinderSource cylinder = new vtkCylinderSource(); vtkCylinderSource cylinder = vtkCylinderSource.New();//创建圆柱体 cylinder.SetResolution(8);//生成圆柱体多边形的数目 vtkPolyDataMapper mymapper = vtkPolyDataMapper.New();//创建映射器对象 mymapper.SetInput(cylinder.GetOutput());//圆柱体的输出作为映射器的输入 vtkLODActor myactor = vtkLODActor.New();//创建演员对象 myactor.SetMapper(mymapper);//为演员对象设置映射器 myactor.GetProperty().SetDiffuseColor(1.0,1.0,1.0);//设定颜色 vtkRenderer ren1 = renderWindowControl1.RenderWindow.GetRenderers().GetFirstRenderer();//获取renderwindowcontrol的绘制者 vtkRenderWindow renwin = renderWindowControl1.RenderWindow;//获取renderwindowcontrol的绘制窗口 ren1.AddActor(myactor);//为绘制者(我感觉可以翻译为渲染器)添加演员 renwin.SetSize(520,520);//设定窗口的大小 vtkRenderWindowInteractor iren = renderWindowControl1.RenderWindow.GetInteractor();//获取交互器 iren.Start();//开始交互 vtkCamera camera = ren1.GetActiveCamera();//获取活动的相机 camera.Zoom(1.5); } } }
运行效果:
 ̄へ ̄,上面的代码有点小问题,就是程序一运行的时候,柱体有点大,估计是我的相机没有设置好。
后面等看到了相机再说吧,也希望能有高手指点一下,我相机的一些操作还不是特别熟。
好了下面做一个 读源对象的例子:
这个书上给的例子好简单,我自己在vtk的例子网站上找了一个,读取dicom序列文件的。下面用activiz实现一下。
例子的网址:
http://www.vtk.org/Wiki/VTK/Examples/Cxx/IO/ReadDICOM
下面是自己的实现:
(同样前面的添加引用和添加renderwinowcontrol就不讲了,可以按照第一篇笔记添加上。)
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kitware.VTK;
namespace test2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_openfile_Click(object sender, EventArgs e)
{
OpenFileDialog openDicomImage = new OpenFileDialog();
openDicomImage.Filter = "DICOM文件|*.dcm";
if(openDicomImage.ShowDialog()==DialogResult.OK)
{
vtkDICOMImageReader reader = vtkDICOMImageReader.New();
reader.SetFileName(openDicomImage.FileName);
reader.Update();
vtkImageViewer2 view = vtkImageViewer2.New();
view.SetInputConnection(reader.GetOutputPort());
view.SetRenderWindow(renderWindowControl1.RenderWindow);
view.SetRenderer(renderWindowControl1.RenderWindow.GetRenderers().GetFirstRenderer());
view.Render();
view.GetRenderer().ResetCamera();
view.Render();
view.SetupInteractor(renderWindowControl1.RenderWindow.GetInteractor());
renderWindowControl1.RenderWindow.GetInteractor().Start();
}
}
}
}
实现效果:
(可以实现交互调节窗宽窗位)
上面两个数据源的读取例子写完了,得加上点理论知识才显得高大上啊!下面是我之前学VTK的时候做的笔记,贴在下面,尽量记得来源的就加上来源,不记得的如果有侵权,请告诉我一声我删掉。
VTK 流水线机制:
以上基本对应之前讲的VTK 建立应用程序的基本过程,也和我们之前做的两个小例子相对应,当然前面的两个小例子比较简单,没有涉及到filter。
可视化模型图形流水线的角色是将图形数据变换成图片,可视化流水线是将信息变换成图形数据。换句话说,可视化流水线负责几何表达,然后由图形流水线来绘制。VTK使用数据流方法将信息变换成图形数据,在这个方法中涉及两个基本对象类型。vtkDataObject 数据对象vtkProcessObject处理对象(过程对象?)数据对象表示各种类型的数据,
vtkDataObject可以看成是通用的“blob”数据(blob数据类型的列可以存储大型二进制对象,如图形、视频和声音等。具有正式结构的数据称为数据集(DataSet类)。
处理对象也常指滤波器,作用于数据对象,产生新的数据对象(注意这里与Mapper的不同,滤波器读取的是数据对象,产生的是新的数据对象。而mapper读取的是数据对象,产生的是图形对象(图形对象是什么呢?看下面总结的九种图形对象
http://blog.csdn.net/williamyk/article/details/6014276
)
vtkMapper指定了渲染数据和图形库中基本图元之间的联系)。处理对象表示系统的算法。处理对象和数据对象通过可视化流水线相连(数据流网)关于构建可视化流水线有一些重要的问题,简要在这里介绍一下。首先,流水线拓扑结构由方法变化而构成
A Filter->SetInput (anotherFilter->GetOutput());
这些方法将一个过滤器的输出作为另一个过滤器的输入(具有多输入和输出的过滤器类似)。其次,必须建立一个机制来控制流水线的执行,仅执行那些流水线的必要部分,产生输出的更新。可视化工具箱使用一个懒评估(惰性赋值这个翻译更贴切一些)方案(当数据被请求时才执行),依据每个对象内部修改时间。第三,流水线组装仅需要那些兼容的对象,使用SetInput() 和GetOutput()方法能与其它对象很好地结合在一起。在VTK中,C++编译时类型检查强迫做到这一点。最后,我们必须决定一旦流水线执行,数据对象是否需要缓存或保留。由于可视化数据集相当大,如何成功应用VTK工具相当重要。VTK提供了将数据缓存开或关的方法,使用计数参数来避免拷贝数据,以及当整个数据不能装入内存时将数据流分块的方法(建议参考第四章可视化工具箱内容获得更多的信息)。
标签:
原文地址:http://my.oschina.net/u/2009228/blog/502437