绘制线段、立方体、多条线段、管线:
import vtk.vtkActor; import vtk.vtkCamera; import vtk.vtkCellArray; import vtk.vtkExtractEdges; import vtk.vtkFloatArray; import vtk.vtkInteractorStyleTrackballActor; import vtk.vtkPoints; import vtk.vtkPolyData; import vtk.vtkPolyDataMapper; import vtk.vtkRenderWindow; import vtk.vtkRenderWindowInteractor; import vtk.vtkRenderer; import vtk.* ; //Then we define our class. public class Lifangti { static { if (!vtkNativeLibrary.LoadAllNativeLibraries()) { for (vtkNativeLibrary lib : vtkNativeLibrary.values()) { if (!lib.IsLoaded()) { System.out.println(lib.GetLibraryName() + " not loaded"); } } } vtkNativeLibrary.DisableOutputWindow(null); } public static void makeYangtiaoquxian(){ vtkPoints points=new vtkPoints(); points.InsertPoint(0, 0.0 ,0.0 ,0.0); points.InsertPoint(1 ,1.0 ,1.0 ,1.0); points.InsertPoint(2 ,1.0, 0.0 ,0.0); points.InsertPoint(3, 1.0 ,0.0, 1.0); //插值为样条曲线 vtkParametricSpline spline =new vtkParametricSpline(); spline.SetPoints(points); spline.ClosedOff(); vtkParametricFunctionSource splineSource =new vtkParametricFunctionSource(); splineSource.SetParametricFunction(spline); vtkPolyDataMapper splineMapper =new vtkPolyDataMapper(); splineMapper.SetInputConnection(splineSource.GetOutputPort()); vtkActor splineActor =new vtkActor(); splineActor.SetMapper(splineMapper); splineActor.GetProperty().SetColor(0.3800 ,0.7000 ,0.1600); vtkTubeFilter tube= new vtkTubeFilter(); tube.SetInputData(splineSource.GetOutput()); tube.SetNumberOfSides(20); tube.SetRadius(50); vtkPolyDataMapper tubeMapper=new vtkPolyDataMapper(); tubeMapper.SetInputData(tube.GetOutput()); vtkActor tubeActor=new vtkActor(); tubeActor.SetMapper(tubeMapper); vtkRenderer ren1=new vtkRenderer(); vtkRenderWindow renWin=new vtkRenderWindow(); renWin.AddRenderer(ren1); vtkRenderWindowInteractor iren=new vtkRenderWindowInteractor(); iren.SetRenderWindow(renWin); ren1.AddActor(splineActor); ren1.AddActor(tubeActor); ren1.SetBackground(1, 1, 1); renWin.SetSize(250 ,250); renWin.Render(); iren.Start(); } public static void makeYuanzhuti(){ double[][] x={{10,10,0},{20.33,20,0},{20.3,10.3,0},{10,20.3,0}, {10,10,20.3},{10.3,10,20.3},{30.3,40.3,20.3},{10,20.3,20.3}}; vtkLineSource line =new vtkLineSource(); line.SetPoint1(x[0]); line.SetPoint2(x[1]); vtkPolyDataMapper splineMapper =new vtkPolyDataMapper(); splineMapper.SetInputConnection(line.GetOutputPort()); vtkActor splineActor =new vtkActor(); splineActor.SetMapper(splineMapper); splineActor.GetProperty().SetColor(0.3800 ,0.7000 ,0.1600); vtkTubeFilter tubeFilter = new vtkTubeFilter(); tubeFilter.SetInputConnection(line.GetOutputPort()); tubeFilter.SetRadius(9.0); tubeFilter.SetNumberOfSides(100); tubeFilter.CappingOn(); vtkPolyData cube =new vtkPolyData(); //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。 vtkCellArray polys =new vtkCellArray(); //这个是关于颜色的属性值,在这里不做重点介绍。 vtkFloatArray scalars =new vtkFloatArray(); //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里 vtkPoints points =new vtkPoints(); //把我们定义好的点,放到points里,这里的i 才是真正的索引,如果我们的循环从i=8开始 //真正的点的索引,以及cell中引用的,将会跟这个索引一致 for (int i=0;i<8;i++) points.InsertPoint(i, x[i]); cube.SetPoints(points); cube.SetPolys(polys); vtkPolyDataMapper cubeMapper =new vtkPolyDataMapper(); cubeMapper.SetInputData(tubeFilter.GetOutput()); vtkActor tempactor =new vtkActor (); tempactor.SetMapper(cubeMapper); vtkRenderer renderer =new vtkRenderer(); renderer.AddActor(tempactor); renderer.AddActor(splineActor); vtkCamera camera =new vtkCamera(); camera.SetPosition(1,1,1); camera.SetFocalPoint(0,0,0); vtkRenderWindow reWin = new vtkRenderWindow(); reWin.AddRenderer(renderer); vtkRenderWindowInteractor iren =new vtkRenderWindowInteractor(); iren.SetRenderWindow(reWin); //如果去掉这个style那么,交互的时候,整个立方体会一起转动 //如果加上,则是每个立方体单独转动 // vtkInteractorStyleTrackballActor style =new vtkInteractorStyleTrackballActor(); // iren.SetInteractorStyle(style); renderer.SetActiveCamera(camera); renderer.ResetCamera(); renderer.SetBackground(0,0,0); reWin.SetSize(300,300); reWin.Render(); iren.Initialize(); iren.Start(); } public static void makeManyLines(){ double[][] x={{10,10,0},{15.33,10,0},{20.3,10.3,0},{10,20.3,0}, {10,10,20.3},{10.3,10,20.3},{30.3,40.3,20.3},{10,20.3,20.3}}; int numb=5; //concrete dataset represents vertices, lines, polygons, and triangle strips, 这是文档里的描述,已经比较清楚了。 vtkPolyData polyData =new vtkPolyData(); //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。 //这个是关于颜色的属性值,在这里不做重点介绍。 vtkFloatArray scalars =new vtkFloatArray(); //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里 vtkPoints points =new vtkPoints(); vtkLine line2 = new vtkLine(); vtkCellArray lines2 = new vtkCellArray(); //这个CellArray比较重要,缺了这个运行不了 for(int ID2=0;ID2<numb;ID2=ID2+2) { line2.GetPointIds().SetId(0,ID2); line2.GetPointIds().SetId(1,ID2+1); lines2.InsertNextCell(line2); } //这个循环结束后,就会把points_2clip里面所有需要的线段画出来了。如果是三个点确定的折线段,//就是下面的代码 vtkPolyLine line3 =new vtkPolyLine(); vtkCellArray lines3 = new vtkCellArray(); for(int ID3=0;ID3<numb;ID3=ID3+3) { line3.GetPointIds().SetNumberOfIds(3); line3.GetPointIds().SetId(0,ID3); line3.GetPointIds().SetId(1,ID3+1); line3.GetPointIds().SetId(2,ID3+2); lines3.InsertNextCell(line3); } /* 紧接着就是vtkPolyData.vtkPolyDataMapper.vtkActor.vtkRenderer.vtkRenderWindow.vtkRenderWindowInteractor, 为了更好地显示点和线的关系,我还用了vtkVertexGlyphFilter, 用来显示所有的用到的点,还添加了vtkAxesActor用来显示坐标轴,相对来说更直观了一些。*/ for (int i=0;i<x.length;i++) points.InsertPoint(i, x[i]); for (int i=0;i<x.length;i++) scalars.InsertTuple1(i,i); //接下来就开始了VTK的pipeline流程。 polyData.SetPoints(points); polyData.SetLines(lines2); //lines3 polyData.GetPointData().SetScalars(scalars); vtkPolyDataMapper cubeMapper =new vtkPolyDataMapper(); cubeMapper.SetInputData(polyData); cubeMapper.SetScalarRange(0,7); vtkActor tempactor =new vtkActor (); tempactor.SetMapper(cubeMapper); tempactor.GetProperty().SetColor(1, 1, 1); tempactor.SetPosition(5,5,5); tempactor.GetProperty().SetLineWidth(30); vtkPolyDataMapper polyDataMapper =new vtkPolyDataMapper(); vtkLookupTable lut= new vtkLookupTable(); lut.SetNumberOfTableValues(10); for(int i=0;i<10;++i) lut.SetTableValue(i, Math.random(), Math.random(), Math.random(),1); polyDataMapper.SetInputData(polyData); polyDataMapper.SetLookupTable(lut); polyDataMapper.SetScalarRange(0,10); polyDataMapper.SetScalarModeToDefault(); vtkActor actor =new vtkActor (); actor.SetMapper(polyDataMapper); actor.PickableOff(); actor.GetProperty().SetLineWidth(3); vtkRenderer renderer =new vtkRenderer(); renderer.AddActor(tempactor); renderer.AddActor(actor); vtkCamera camera =new vtkCamera(); camera.SetPosition(1,1,1); camera.SetFocalPoint(0,0,0); vtkRenderWindow reWin = new vtkRenderWindow(); reWin.AddRenderer(renderer); vtkRenderWindowInteractor iren =new vtkRenderWindowInteractor(); iren.SetRenderWindow(reWin); //如果去掉这个style那么,交互的时候,整个立方体会一起转动 //如果加上,则是每个立方体单独转动 // vtkInteractorStyleTrackballActor style =new vtkInteractorStyleTrackballActor(); // iren.SetInteractorStyle(style); renderer.SetActiveCamera(camera); renderer.ResetCamera(); renderer.SetBackground(0,0,0); reWin.SetSize(300,300); reWin.Render(); iren.Initialize(); iren.Start(); } public static void makeLifangti(){ int i ; //可以看到图中有27个小正方体组成了一个大的正方体 //x[8][3],就是每一个小正方体的 8个点的x,y,z值 //java float类型后面需加上f 表示float类型数据 //float[][] x= {{0,0,0},{0.3f,0,0},{0.3f,0.3f,0},{0,0.3f,0}, {0,0,0.3f},{0.3f,0,0.3f},{0.3f,0.3f,0.3f},{0,0.3f,0.3f}}; double[][] x={{0,0,0},{0.3,0,0},{0.3,0.3,0},{0,0.3,0}, {0,0,0.3},{0.3,0,0.3},{0.3,0.3,0.3},{0,0.3,0.3}}; //这个查阅VTK文档发现解释的跟我理解的不一样。。。很有可能是我看不懂。。。 //我的理解是 这样的, 一个正方体 是由 6个面组成,我们程序也正是打算以面位最小的CELL 来组成我们要的正方体 //当然,我们也可以用线来画,那样只能画出正方体的边框,就不能用下面用到的PolyData,而要用vtkLine这个对象作为CELL //既然选定了 由面来组成,那就产生了六个面,第一个面 是由上面定义的8个点的 0,1,2,3四个点组成,以下以此类推。 //特别注意的是,这里的0,1,2,3 这几个点,并不是对应的 x[8][3],这里的第0,1,2,3具体为什么下面会说。 //每个数代表点数据的索引下标 int[][] pts= {{0,1,2,3},{4,5,6,7},{0,1,5,4}, {1,2,6,5},{2,3,7,6},{3,0,4,7}}; //concrete dataset represents vertices, lines, polygons, and triangle strips, 这是文档里的描述,已经比较清楚了。 vtkPolyData cube =new vtkPolyData(); //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。 vtkCellArray polys =new vtkCellArray(); //这个是关于颜色的属性值,在这里不做重点介绍。 vtkFloatArray scalars =new vtkFloatArray(); //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里 vtkPoints points =new vtkPoints(); //把我们定义好的点,放到points里,这里的i 才是真正的索引,如果我们的循环从i=8开始 //真正的点的索引,以及cell中引用的,将会跟这个索引一致 for (i=0;i<8;i++) points.InsertPoint(i, x[i]); //插入点的拓扑结构, //2011年11月10日 - god_sun - 随枫¤心慧 //第一个参数 虽然是vtkIdType类型的,但事实上也是一个int型的,文档里的解释第一个参数是 点的个数,第二个是点的内容。 //设置单元由几个点组成,每个单元指定对应的点 for (i=0;i<6;i++) { polys.InsertNextCell(4); for(int j=0;j<4;j++){ polys.InsertCellPoint(pts[i][j]); } } for (i=0;i<8;i++) scalars.InsertTuple1(i,i); //接下来就开始了VTK的pipeline流程。 cube.SetPoints(points); cube.SetPolys(polys); cube.GetPointData().SetScalars(scalars); ////这段代码是为了显示立方体周围的边框。。。但是设置visibilityOn 或者visibilityOff看起来不是非常明显。 //以前photoshop的时候画一个立方体,会在周围再画上边框,这样会感觉更饱满一些。。。 //vtk5之后使用SetInputData(cube);之前格式为SetInput(cube) vtkExtractEdges extract=new vtkExtractEdges(); extract.SetInputData(cube); vtkPolyDataMapper mapEdges=new vtkPolyDataMapper(); mapEdges.SetInputConnection(extract.GetOutputPort()); mapEdges.SetScalarVisibility(0); vtkActor edgeActor=new vtkActor(); edgeActor.SetMapper(mapEdges); edgeActor.VisibilityOn(); vtkPolyDataMapper cubeMapper =new vtkPolyDataMapper(); cubeMapper.SetInputData(cube); cubeMapper.SetScalarRange(0,7); int No=0; //p,j,k是为了设置立方体的不同位置。 float p=0.0f,j=0.0f,k=0.0f; vtkRenderer renderer =new vtkRenderer(); for (p=0.0f;p<0.9;p=p+0.3f) { for (j=0.0f;j<0.9;j=j+0.3f) { for(k=0.0f;k<0.9;k=k+0.3f) { vtkActor cubeActor =new vtkActor(); //设置ACTOR的不同位置,来显示最终的图形。 cubeActor.SetPosition(p,j,k); cubeActor.SetMapper(cubeMapper); renderer.AddActor(cubeActor); } } } vtkCamera camera =new vtkCamera(); camera.SetPosition(1,1,1); camera.SetFocalPoint(0,0,0); vtkRenderWindow reWin = new vtkRenderWindow(); reWin.AddRenderer(renderer); vtkRenderWindowInteractor iren =new vtkRenderWindowInteractor(); iren.SetRenderWindow(reWin); //如果去掉这个style那么,交互的时候,整个立方体会一起转动 //如果加上,则是每个立方体单独转动 vtkInteractorStyleTrackballActor style =new vtkInteractorStyleTrackballActor(); iren.SetInteractorStyle(style); renderer.SetActiveCamera(camera); renderer.ResetCamera(); renderer.SetBackground(0,1,1); reWin.SetSize(300,300); reWin.Render(); iren.Initialize(); iren.Start(); } public static void main(String[] args) { // TODO Auto-generated method stub makeYangtiaoquxian(); makeYuanzhuti(); makeManyLines(); makeLifangti(); } }
结果图: