最近在学习vtk,想尝试绘制等值线,后来在网上找到一份教程:vtk培训教程,里面有讲到这个内容,在这里非常感谢这位作者的讲解与示例,可惜这份文档没有署名!
使用vtk来绘制等值线,需要使用到vtkContourFilter,它所处理的数据需要是规则网格数据,如规则的正方形网格等。
通过使用vtkContourFilter::SetValue(i,value)方法来指定绘制第几条等值线,其中等值线的值由value指定。意思就是提取网格数据中标量值为value的点,然后将其连接起来,对于一些边,vtkContourFilter会进行插值运算,计算出对应的点。也可以使用vtkContourFilter::GenerateValues(count, start, end);来生成一些列的等值线,其中count参数指定等值线的条数,而start指定第一条等值线的值,end指定最后一条等值线的值,中间等值线的值则通过计算得到。
在下面的例子中,我们首先生成网格数据的点集,其次指定网格的拓扑结构即cells,然后设置每个点的标量值,,最后通过vtlContourFile来生成等值线并最终显示出来。
在vtk中保存点集使用vtkPoints,可以使用它的InsertNextPoint(x,y,z)来插入一个点的坐标,这些点在vtkPoints内部都有对应的id,其值可以理解为这些点对应的索引值。在后面设置cell值和标量值的时候,都需要使用到这些id。
拓扑结构使用vtkCellArray来保存,其中cell信息,下面示例中使用的是多边形vtkPolygon,在创建vtkPolygon对象时,首先需要通过SetNumberOfIds(num)来指定多边形点的个数,然后通过GetPointIds().SetId(0,0);来设置这个多边形每个点对应在点集中的id。最后通过vtkCellArray.InsertNextCell将创建的多边形添加到vtkCellArray中。
标量值保存在vtkFloatArray中,通过InsertTuple1(id,value)来设置点集中对应点的标量值。
程序最终运行效果图:
其中关键代码如下:
public void build(){ //创建对象 vtkPolyData pGrid= new vtkPolyData(); //创建多边形数据 pGrid.SetPoints(buildPoints()); //设定单元类型为多边形 pGrid.SetPolys(buildPolygonCell()); //设定每个顶点的标量值 pGrid.GetPointData().SetScalars(buildScalars()); //数据映射,使用默认颜色映射表 vtkPolyDataMapper cubeMapper =new vtkPolyDataMapper(); cubeMapper.SetInput(pGrid); //设置标量值范围 cubeMapper.SetScalarRange(0,9); vtkActor cubeActor =new vtkActor(); cubeActor.SetMapper(cubeMapper); //提取轮廓线 vtkContourFilter pContourFilter=new vtkContourFilter(); //设置提取的标量值 pContourFilter.SetValue(0,5.0); pContourFilter.SetInput(pGrid); vtkPolyDataMapper pContouMapper=new vtkPolyDataMapper(); pContouMapper.SetInput((vtkPolyData)pContourFilter.GetOutput()); //禁用属性数据绘制颜色 pContouMapper.ScalarVisibilityOff(); vtkActor pContoActor = new vtkActor(); pContoActor.SetMapper(pContouMapper); pContoActor.GetProperty().SetColor(1.0,1.0,0.0); pContoActor.GetProperty().SetLineWidth(2.0); //设置图形以线框的方式显示 cubeActor.GetProperty().SetRepresentationToWireframe(); pContoActor.GetProperty().SetRepresentationToWireframe(); vtkRenderer renderer = new vtkRenderer(); renderWindow.AddRenderer(renderer); renderer.AddActor(cubeActor); renderer.AddActor(pContoActor); renderer.ResetCamera(); renderer.SetBackground(1,1,1); start(); }
源码见附件