使用vtkClipPolyData进行裁剪
效果:
#include "stdafx.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkCylinder.h" #include "vtkPlane.h" #include "vtkImplicitBoolean.h" #include "vtkPolyDataMapper.h" #include "vtkSphereSource.h" #include "vtkProperty.h" #include "vtkClipPolyData.h" #include "vtkTransformPolyDataFilter.h" #include "vtkTransform.h" #include "vtkInteractorStyleTrackballCamera.h" int main() { vtkSphereSource *sphere=vtkSphereSource::New(); sphere->SetCenter(0,0,0); sphere->SetRadius(10); sphere->SetThetaResolution(40); sphere->SetPhiResolution(40); vtkCylinder *cylinder = vtkCylinder::New();//圆柱 cylinder->SetCenter(0,0,0); cylinder->SetRadius(3); vtkPlane *vPlane = vtkPlane::New();//横截面 vPlane->SetOrigin(0, 0, 0); vPlane->SetNormal(0, -1, 0); vtkImplicitBoolean *cuted_cylinder = vtkImplicitBoolean::New(); cuted_cylinder->SetOperationTypeToIntersection(); cuted_cylinder->AddFunction(cylinder); cuted_cylinder->AddFunction(vPlane); vtkClipPolyData *clipper=vtkClipPolyData::New(); clipper->SetInputConnection(sphere->GetOutputPort()); clipper->SetClipFunction(cylinder); clipper->GenerateClipScalarsOn(); clipper->GenerateClippedOutputOn(); clipper->SetValue(0.5); vtkTransform *transform=vtkTransform::New(); transform->Translate(7,0,0); vtkTransformPolyDataFilter *filter=vtkTransformPolyDataFilter::New(); filter->SetInputConnection(clipper->GetOutputPort()); filter->SetTransform(transform); vtkClipPolyData *clipper2=vtkClipPolyData::New(); clipper2->SetInputConnection(filter->GetOutputPort()); clipper2->SetClipFunction(cuted_cylinder); clipper2->GenerateClipScalarsOn(); clipper2->GenerateClippedOutputOn(); clipper2->SetValue(0.5); vtkPolyDataMapper *map = vtkPolyDataMapper::New(); map->SetInputConnection(clipper2->GetOutputPort()); map->ScalarVisibilityOff(); vtkActor *actor = vtkActor::New(); actor->SetMapper(map); actor->GetProperty()->SetColor(0,1,1); //actor->GetProperty()->SetAmbientColor(0.4,0.5,0.6); //actor->GetProperty()->SetDiffuseColor(0.8,0.6,0.2); actor->RotateX(40); vtkRenderer *ren = vtkRenderer::New(); vtkRenderWindow *renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); ren->AddActor(actor); ren->SetBackground(1, 1, 1); renWin->SetSize(450, 450); vtkInteractorStyleTrackballCamera *style=vtkInteractorStyleTrackballCamera::New(); iren->SetInteractorStyle(style); iren->Initialize(); renWin->Render(); iren->Start(); }
其中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