VTKDemo:绘制线段、立方体、多条线段、管线:
绘制线段、立方体、多条线段、管线:
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();
}
}
结果图: