VTK地自定义8个点绘制立方体

点击打开链接http://blog.163.com/god_sun/blog/static/56399926201110108481537/


java代码:

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 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);
		     vtkActor  tempactor =new vtkActor ();
		     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
		  makeLifangti();
		}
 
 
}  


c++代码如下:

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCellArray.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkExtractEdges.h>
typedef vtkActorCollection* vtkActorCollection_Array;
int main()
{
 int i ;
 //可以看到图中有27个小正方体组成了一个大的正方体
       //x[8][3],就是每一个小正方体的 8个点的x,y,z值
 float x[8][3]={{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具体为什么下面会说。
 vtkIdType pts[6][4]={{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 = vtkPolyData::New();
 //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。
 vtkCellArray *polys = vtkCellArray::New();
 //这个是关于颜色的属性值,在这里不做重点介绍。
 vtkFloatArray *scalars = vtkFloatArray::New();
 //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里
 vtkPoints *points = vtkPoints::New();
 //把我们定义好的点,放到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,pts[i]);
 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的时候画一个立方体,会在周围再画上边框,这样会感觉更饱满一些。。。
 vtkExtractEdges *extract=vtkExtractEdges::New();
        extract->SetInput(cube);
 vtkPolyDataMapper *mapEdges=vtkPolyDataMapper::New();
        mapEdges->SetInputConnection(extract->GetOutputPort());
  mapEdges->SetScalarVisibility(0);
 vtkActor *edgeActor=vtkActor::New();
        edgeActor->SetMapper(mapEdges);
  edgeActor->VisibilityOn();
 

 vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
 cubeMapper->SetInput(cube);
 cubeMapper->SetScalarRange(0,7);
 int No=0;
 //p,j,k是为了设置立方体的不同位置。
 float p=0.0,j=0.0,k=0.0;
 vtkRenderer *renderer = vtkRenderer::New();
 for (p=0.0;p<0.9;p=p+0.3)
 {
  for (j=0.0;j<0.9;j=j+0.3)
  {
   for(k=0.0;k<0.9;k=k+0.3)
   {
    vtkActor *cubeActor = vtkActor::New();
    //设置ACTOR的不同位置,来显示最终的图形。
    cubeActor->SetPosition(p,j,k);
    vtkActor *tempactor = vtkActor ::New();
    cubeActor->SetMapper(cubeMapper);
    renderer->AddActor(cubeActor);
   }
  }
 }
 
 vtkCamera *camera =vtkCamera::New();
 camera->SetPosition(1,1,1);
 camera->SetFocalPoint(0,0,0);
 
 
 vtkRenderWindow *reWin = vtkRenderWindow::New();
 reWin->AddRenderer(renderer);

 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
 iren->SetRenderWindow(reWin);
 //如果去掉这个style那么,交互的时候,整个立方体会一起转动
 //如果加上,则是每个立方体单独转动
 vtkInteractorStyleTrackballActor *style = vtkInteractorStyleTrackballActor::New();
 iren->SetInteractorStyle(style); 
  
 renderer->SetActiveCamera(camera);
  renderer->ResetCamera();
  renderer->SetBackground(0,1,1);

 reWin->SetSize(300,300);

 reWin->Render();
 iren->Initialize();
 iren->Start();

 points->Delete();
 cube->Delete();
 cubeMapper->Delete();
 renderer->Delete();
 reWin->Delete();
 iren->Delete();
 polys->Delete();
  scalars->Delete();
 return 0;
}

如何使用 自己定义好的点,来画图 
自己定义的点插入到 vtkpoints中
定义好的拓扑结构插入到 vtkcellarray中 无非就是这种方式。

 
 

绘制上图的思路:

8个点定义一个立方体的8个顶点;

每4个点组成一个面,总共6个面;

8个点插入到VTKpoints中;

6个面插入到拓扑结构中VTKcellarray中;

组装好一个立方体,然后平移这个立方体9次,即可形成最终的一个大立方体;

每个小立方体可单独旋转;




猜你喜欢

转载自blog.csdn.net/sinat_23619409/article/details/80007353