vtk中实现裁剪

tt posted @ 2007年10月13日 04:38 in  vtk , 2002 阅读

    在VTK中,我们通常需要的并不是严格标准的几何体,我们需要对这些几何体进行加工,修改其内容,得到我们想要的效果,下面结合例子介绍如何在VTK中实现对几何体的裁剪。

    要对几何体进行裁剪,需要建立好几何体模型,然后定义一个隐函数,利用vtkClipPolyData,通过隐函数vtkImplicitFunction实现对模型的裁剪,在vtk中,类似vtkPlane,vtkSphere,vtkCylinder这些后面没有Source的类,都是隐函数类。

    看下面这个例子(cut_sphere.cxx): 

  1. #include "vtkActor.h"
  2. #include "vtkRenderer.h"
  3. #include "vtkRenderWindow.h"
  4. #include "vtkRenderWindowInteractor.h"
  5. #include "vtkCylinder.h"
  6. #include "vtkPlane.h"
  7. #include "vtkImplicitBoolean.h"
  8. #include "vtkPolyDataMapper.h"
  9. #include "vtkSphereSource.h"
  10. #include "vtkProperty.h"
  11. #include "vtkClipPolyData.h"
  12. #include "vtkTransformPolyDataFilter.h"
  13. #include "vtkTransform.h"
  14. #include "vtkInteractorStyleTrackballCamera.h"
  15.  
  16. int main ( )
  17. {
  18.     vtkSphereSource *sphere=vtkSphereSource:: New ( );
  19.     sphere->SetCenter ( 0, 0, 0 );
  20.     sphere->SetRadius ( 10 );
  21.     sphere->SetThetaResolution ( 40 );
  22.     sphere->SetPhiResolution ( 40 );
  23.  
  24.     vtkCylinder *cylinder = vtkCylinder:: New ( ); //圆柱
  25.     cylinder->SetCenter ( 0, 0, 0 );
  26.     cylinder->SetRadius ( 3 );
  27.  
  28.     vtkPlane *vPlane = vtkPlane:: New ( ); //横截面
  29.     vPlane->SetOrigin ( 000 );
  30.     vPlane->SetNormal ( 0-10 );
  31.  
  32.     vtkImplicitBoolean *cuted_cylinder = vtkImplicitBoolean:: New ( );
  33.     cuted_cylinder->SetOperationTypeToIntersection ( );
  34.     cuted_cylinder->AddFunction (cylinder );
  35.     cuted_cylinder->AddFunction (vPlane );
  36.  
  37.     vtkClipPolyData *clipper=vtkClipPolyData:: New ( );
  38.     clipper->SetInputConnection (sphere->GetOutputPort ( ) );
  39.     clipper->SetClipFunction (cylinder );
  40.     clipper->GenerateClipScalarsOn ( );
  41.     clipper->GenerateClippedOutputOn ( );
  42.     clipper->SetValue ( 0.5 );
  43.  
  44.     vtkTransform *transform=vtkTransform:: New ( );
  45.     transform->Translate ( 7, 0, 0 );
  46.     vtkTransformPolyDataFilter *filter=vtkTransformPolyDataFilter:: New ( );
  47.     filter->SetInputConnection (clipper->GetOutputPort ( ) );
  48.     filter->SetTransform (transform );
  49.     vtkClipPolyData *clipper2=vtkClipPolyData:: New ( );
  50.     clipper2->SetInputConnection (filter->GetOutputPort ( ) );
  51.     clipper2->SetClipFunction (cuted_cylinder );
  52.     clipper2->GenerateClipScalarsOn ( );
  53.     clipper2->GenerateClippedOutputOn ( );
  54.     clipper2->SetValue ( 0.5 );
  55.  
  56.     vtkPolyDataMapper *map = vtkPolyDataMapper:: New ( );
  57.     map->SetInputConnection (clipper2->GetOutputPort ( ) );
  58.     map->ScalarVisibilityOff ( );
  59.  
  60.     vtkActor *actor = vtkActor:: New ( );
  61.     actor->SetMapper (map );
  62.     actor->GetProperty ( )->SetColor ( 0, 1, 1 );
  63.      //actor->GetProperty()->SetAmbientColor(0.4,0.5,0.6);
  64.      //actor->GetProperty()->SetDiffuseColor(0.8,0.6,0.2);
  65.     actor->RotateX ( 40 );
  66.  
  67.     vtkRenderer *ren = vtkRenderer:: New ( );
  68.     vtkRenderWindow *renWin = vtkRenderWindow:: New ( );
  69.     renWin->AddRenderer (ren );
  70.  
  71.     vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor:: New ( );
  72.     iren->SetRenderWindow (renWin );
  73.  
  74.     ren->AddActor (actor );
  75.     ren->SetBackground ( 111 );
  76.     renWin->SetSize ( 450450 );
  77.  
  78.     vtkInteractorStyleTrackballCamera *style=vtkInteractorStyleTrackballCamera:: New ( );
  79.     iren->SetInteractorStyle (style );
  80.  
  81.     iren->Initialize ( );
  82.     renWin->Render ( );
  83.    
  84.     iren->Start ( );
  85. }

 其中1~14行包含相应头文件

18~22行定义一个球,其圆心在原点,半径为10,设置经纬方向的三角片数均为40;

24~26行定义圆柱的隐函数,设定半径为3,中心在原点,在vtk中的圆柱隐函数是没有设定长度的,其方向为沿y轴方向,此处的圆柱用于对刚才定义的球进行裁剪,裁剪效果就是把球给打通了,两面都进行的裁剪,如果要只裁剪球的一面,则用半个圆柱。接下来的28~30行定义了一个平面,用平面与圆柱求交可得出半个圆柱。

32~35行将平面和圆柱进行Bool求交运算(SetOperationTypeToIntersection())得出半个圆柱的隐函数表示cuted_cylinder,如果是求和运算则用SetOperationTypeToUnion()。

37~42行定义了一个vtkClipPolyData对象clipper,将其输入设定为18~24行建立的球,裁剪函数设置为圆柱cylinder,接下来的三行40~42行似乎没有什么用处。

上面得到的只是用一个圆柱裁剪球的效果,但是为了同时显示用半个圆柱裁剪的效果,将刚才的裁剪体演x轴移动一定位置,然后用刚才Bool运算获得的半个圆柱进行裁剪,以便于比较。对几何对象的移动需要指定一个变换transform,然后定义一个vtkTransformPolyDataFilter对象filter,然后将filter的输入设定为要移动的几何对象,变换设定为transform。44~48行实现了将裁剪球的移动,其移动结果在filter中。

49~54行将移动后得到的filter作为新一次裁剪的输入,以半个圆柱cuted_cylinder为裁剪函数进行裁剪,得到裁剪结果clipper2

接下来的就是设定map,actor等常规对象了,在vtk不必细说了吧,

写好了程序代码, 接下来就是写CMakeLists.txt: 

  1. PROJECT  (Main )
  2.  
  3. FIND_PACKAGE (VTK REQUIRED )
  4. IF (NOT VTK_USE_RENDERING )
  5.   MESSAGE (FATAL_ERROR  "Example ${PROJECT_NAME} requires VTK_USE_RENDERING." )
  6. ENDIF (NOT VTK_USE_RENDERING )
  7. INCLUDE ($ {VTK_USE_FILE } )
  8.  
  9. ADD_EXECUTABLE (main cut_cube. cxx )
  10. TARGET_LINK_LIBRARIES (main vtkRendering )

用cmake编译程序 

  1. $> cmake .
  2. $> make
  3.  

运行效果如下: 

         

旋转一下看其效果

本文来源:http://tzc.is-programmer.com/posts/477.html