vtk 提供了 vtkCylinder 可以进行圆柱裁剪,但是,这个东西没法控制圆柱体的长度(默认是无限长度),这时候可以结合vtkImplicitBoolean 和 vtkPlane,控制圆柱体的大小。 本文参考自:blog.csdn.net/xs1997/arti… 但是原帖中代码有问题,我这里做了优化化,并加了详细注释:
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);
cylinder->SetAxis(1,0,0); // 这里指定圆柱是X轴方向的,便于观察
vtkPlane* vPlane = vtkPlane::New(); //横截面1,控制圆柱的左侧边界
vPlane->SetOrigin(-12, 0, 0); // -12 表示 截面的位置,因为球半径是10,改变这个值,可以控制圆柱的大小
vPlane->SetNormal(-1, 0, 0); // 注意这里必须是<0的,表示,截面左侧部分被丢弃
vtkPlane* vPlane2 = vtkPlane::New();//横截面2,控制圆柱的右侧边界
vPlane2->SetOrigin(12, 0, 0);
vPlane2->SetNormal(1, 0, 0); // 注意这里必须是>1的,表示,截面右侧部分被丢弃
vtkImplicitBoolean* cuted_cylinder = vtkImplicitBoolean::New();
cuted_cylinder->SetOperationTypeToIntersection(); // 这里是下面三个function 取交集,还有其他几个OperationType,可以看类声明
cuted_cylinder->AddFunction(cylinder);
cuted_cylinder->AddFunction(vPlane);
cuted_cylinder->AddFunction(vPlane2);
// vtkClipPolyData* clipper = vtkClipPolyData::New();
// clipper->SetInputConnection(sphere->GetOutputPort());
// clipper->SetClipFunction(cylinder);
// clipper->GenerateClipScalarsOn();
// clipper->GenerateClippedOutputOn();
// clipper->SetValue(0.5);
vtkClipPolyData* clipper2 = vtkClipPolyData::New();
clipper2->SetInputConnection(sphere->GetOutputPort()); // 原帖中这里用filter->GetOutputPort() 导致不起作用
clipper2->SetClipFunction(cuted_cylinder);
clipper2->GenerateClipScalarsOn();
clipper2->GenerateClippedOutputOn();
clipper2->SetValue(0.5); // 这个值会导致实际尺寸和真实尺寸不一致,设置为0.0,是真实尺寸,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);
// 显示坐标轴,方便观察
vtkSmartPointer<vtkAxesActor> actor2 = vtkSmartPointer<vtkAxesActor>::New();
actor2->SetPosition(0, 0, 0);
actor2->SetTotalLength(15, 15, 15); // 坐标轴长度
actor2->SetShaftType(0);
actor2->SetAxisLabels(0);
actor2->SetCylinderRadius(0.02);
vtkRenderer* ren = vtkRenderer::New();
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
ren->AddActor(actor2);
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();
return 0;
}
横截面1 位置 为 -12 时效果,发现,x轴两侧都被圆柱裁剪了(两侧都有窟窿)
横截面1 位置 由 -12 改为-8 的效果,圆柱左侧在球内部,所以左侧球没有被裁剪