VTK平面切割


本文的主要内容:简单介绍VTK中通过平面切割模型的相关功能。
哪些人适合阅读本文:有一定VTK基础的人。

一、vtkClipPolyData

VTK官网描述:
vtkClipPolyData使用用户指定的隐函数剪切多边形数据,如果使用vtkPlane作为隐函数就是平面切割。
vtkClipPolyData是一个过滤器,它使用vtkImplicitFunction的任何子类或输入标量数据来剪辑多边形数据。剪切意味着它实际上“剪切”了数据集的单元格,返回指定隐式函数(或大于标量值)内的所有内容,包括单元格的“片段”。(将其与vtkExtractGeometry进行比较,后者提取整个未切割的单元格。)此过滤器的输出是多边形数据。
要使用此过滤器,必须决定是使用隐式函数进行剪裁,还是使用输入标量数据。如果你想使用隐式函数进行剪裁,你必须:1)定义一个隐式函数2)用SetClipFunction方法设置它3)应用GenerateClipScalarsOn方法如果未指定ClipFunction,或者GenerateClipScalar处于关闭状态(默认设置),则输入的标量数据将用于剪裁polydata。
还可以指定一个标量值,用于决定隐式函数内部和外部的内容。还可以通过设置InsideOut实例变量来颠倒内部/外部的含义。(切割算法通过计算隐式函数值或使用数据集中每个点的输入标量数据来进行。将其与标量值进行比较以确定内部/外部。)
该滤波器可以被配置为计算第二输出。第二个输出是剪切掉的多边形数据。如果要访问此输出数据,请启用GenerateClippedData布尔值。

vtkClipPolyData的使用很简单:

vtkNew<vtkSphereSource> source;
source->SetThetaResolution(20);
source->SetPhiResolution(20);
source->Update();

vtkNew<vtkPlane> plane;
plane->SetOrigin(polyData->GetCenter());
plane->SetNormal(1.0, -1.0, -1.0);

vtkNew<vtkClipPolyData> clipper;
clipper->SetInputData(source->GetOutput());
clipper->SetClipFunction(plane);
clipper->Update();

在这里插入图片描述
这种方法切完之后是个空壳子,切口不封闭。要想让切割之后的切口封闭,继续往下看。

二、CapClip

此示例显示了如何在剪切的vtkPolyData上生成“上限”。在使用vtkClipPolyData进行裁剪后,它使用了一种巧妙的“技巧”将折线转换为多边形。
就是通过vtkFeatureEdges和vtkStripper将切割之后的边缘进行封闭。

// Extract feature edges
vtkNew<vtkFeatureEdges> boundaryEdges;
boundaryEdges->SetInputData(clipper->GetOutput());
boundaryEdges->BoundaryEdgesOn();
boundaryEdges->FeatureEdgesOff();
boundaryEdges->NonManifoldEdgesOff();
boundaryEdges->ManifoldEdgesOff();

vtkNew<vtkStripper> boundaryStrips;
boundaryStrips->SetInputConnection(boundaryEdges->GetOutputPort());
boundaryStrips->Update();

// Change the polylines into polygons
vtkNew<vtkPolyData> boundaryPoly;
boundaryPoly->SetPoints(boundaryStrips->GetOutput()->GetPoints());
boundaryPoly->SetPolys(boundaryStrips->GetOutput()->GetLines());

vtkNew<vtkPolyDataMapper> boundaryMapper;
boundaryMapper->SetInputData(boundaryPoly);

vtkNew<vtkActor> boundaryActor;
boundaryActor->SetMapper(boundaryMapper);
boundaryActor->GetProperty()->SetDiffuseColor(boundaryColor.GetData());

在这里插入图片描述

三、SolidClip

此示例剪裁网格并将背面特性应用于该网格,使其看起来具有实心内部。
还显示了被剪掉的部分的“幽灵”。

其实还是用vtkClipPolyData来切割,然后通过将模型内表面的漫反射和镜面反射光关闭,只保留环境光,造成一种视觉上模型是实心的效果。

// Create a mapper and actor
vtkNew<vtkPolyDataMapper> superquadricMapper;
superquadricMapper->SetInputConnection(clipper->GetOutputPort());

vtkNew<vtkActor> superquadricActor;
superquadricActor->SetMapper(superquadricMapper);

// Create a property to be used for the back faces. Turn off all
// shading by specifying 0 weights for specular and diffuse. Max the
// ambient.
vtkNew<vtkProperty> backFaces;
backFaces->SetSpecular(0.0);
backFaces->SetDiffuse(0.0);
backFaces->SetAmbient(1.0);
backFaces->SetAmbientColor(colors->GetColor3d("Tomato").GetData());

superquadricActor->SetBackfaceProperty(backFaces);

在这里插入图片描述

四、vtkClipClosedSurface

VTK官网描述:
使用平面集合剪裁闭合曲面。
vtkClipClosedSurface将使用一组剪裁平面剪裁一个闭合的polydata曲面。它将通过创建剪切输入数据的新多边形面来生成新的闭合曲面。
形成曲面的多边形的方向很重要。多边形有一个正面和一个背面,背面定义了闭合曲面的内部或“实体”区域。当剪切平面剪切穿过“实体”区域时,会生成一个新的剪切面,但当剪切平面切割穿过孔或“空”区域时则不会。在处理复杂曲面时,这种区别至关重要。请注意,如果一个简单曲面的背面朝外,则该曲面在潜在的无限实体中定义了一个孔。
非歧管表面不应用作此过滤器的输入。输入曲面不应有开放边,并且不得有任何由两个以上面共享的边。vtkFeatureEdges过滤器可用于验证数据集是否满足这些条件。此外,输入曲面不应自相交,这意味着曲面的面只应接触其边缘。
如果启用了GenerateOutline,则此过滤器将在剪裁平面与数据相交的任何位置生成轮廓。ScalarMode选项将向输出中添加单元格标量,以便生成的面可以以与原始曲面不同的颜色显示。
InsideOut标志可用于反转剪辑区域内外的含义。这将更改剪裁平面的哪一侧被剪裁掉。
该滤波器可以被配置为计算第二输出。第二个输出是具有新三角面的多边形数据。如果要访问此输出数据,请启用GenerateClipFaceOutput布尔值。

vtkClipClosedSurface需要输入一个polyData和一组vtkPlaneCollection面集合,有两种输出一种是剪切之后的模型,一种是剪切的面的模型。

vtkNew<vtkNamedColors> colors;

// PolyData to process
vtkSmartPointer<vtkPolyData> polyData;

// Create a sphere
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetThetaResolution(20);
sphereSource->SetPhiResolution(11);
sphereSource->Update();

polyData = sphereSource->GetOutput();

auto center = polyData->GetCenter();
vtkNew<vtkPlane> plane1;
plane1->SetOrigin(center[0], center[1], center[2]);
plane1->SetNormal(0.0, -1.0, 0.0);
vtkNew<vtkPlane> plane2;
plane2->SetOrigin(center[0], center[1], center[2]);
plane2->SetNormal(0.0, 0.0, 1.0);
vtkNew<vtkPlane> plane3;
plane3->SetOrigin(center[0], center[1], center[2]);
plane3->SetNormal(-1.0, 0.0, 0.0);

vtkNew<vtkPlaneCollection> planes;
planes->AddItem(plane1);
planes->AddItem(plane2);
planes->AddItem(plane3);

vtkNew<vtkClipClosedSurface> clipper;
clipper->SetInputData(polyData);
clipper->SetClippingPlanes(planes);
clipper->SetActivePlaneId(2);
clipper->SetScalarModeToColors();
clipper->SetClipColor(colors->GetColor3d("Banana").GetData());
clipper->SetBaseColor(colors->GetColor3d("Tomato").GetData());
clipper->SetActivePlaneColor(colors->GetColor3d("Green").GetData());
clipper->GenerateClipFaceOutputOn();
clipper->Update();

vtkNew<vtkDataSetMapper> clipMapper;
clipMapper->SetInputConnection(clipper->GetOutputPort());
//clipMapper->SetInputData(clipper->GetClipFaceOutput());

vtkNew<vtkActor> clipActor;
clipActor->SetMapper(clipMapper);
clipActor->GetProperty()->SetColor(colors->GetColor3d("tomato").GetData());
clipActor->GetProperty()->SetInterpolationToFlat();

在这里插入图片描述
在这里插入图片描述
vtkClipClosedSurface和SolidClip这两种方法都有一个小问题,就是模型被一刀切完。如果只想切一半的话就没办法实现。

如果只想切一部分的话,在vtkClipClosedSurface里面SetClippingPlanes设置一个面的集合就可以,但是这个面集必须是闭合的,得到的效果如下图所示。
在这里插入图片描述
可以看出这种方法切出来的必然是一个凸集,要想切一个凹面如下图所示的效果,这种方法就做不了。
为什么会这样?是因为vtkClipClosedSurface的原理是把每个切割面法相对应的模型全部切掉,如下图所示。最后只剩下闭合平面包络中心的模型被保留。
在这里插入图片描述
可以想想看,无论怎么设计闭合平面以及平面法线如何指向,都无法得到下图所示的切割模型。
那么要如何实现切割凹面模型?可以尝试vtk的纹理切割,主要用到的是vtkImplicitTextureCoords,具体可以看官方例子,切出的效果是这样的。
在这里插入图片描述
可以看出也没有封口,要封口也不难,改变一下纹理就可以。

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
vtk是一种用于可视化和图形处理的开源软件包。点云是由一系列的点组成的三维空间数据集,常用于激光扫描、三维建模等领域。点云平面切割是指将点云数据集中的点按照它们所在的平面进行分组。 在vtk中,点云平面切割可以通过以下步骤实现: 1. 加载点云数据集:首先需要从文件中加载点云数据集,vtk支持多种点云数据格式,如PLY、XYZ等。通过vtk的读取器类,可以将点云数据集读取到内存中。 2. 点云数据预处理:为了提高切割的准确性和效率,可以对点云数据进行一些预处理操作。例如,可以对点云进行滤波处理,去除离群点,平滑数据,或者进行降采样等操作。 3. 平面提取:通过点云的法向量计算,可以估计每个点的法向量信息。然后,可以使用RANSAC或最小二乘法等算法,进行平面的拟合。根据拟合结果可以确定平面的参数,如法向量和距离等。 4. 点云分割:根据拟合的平面参数,可以将点云数据分成多个点集,每个点集代表一个平面。可以使用vtk的点集类,将每个平面的点保存在不同的点集中。 5. 可视化展示:最后,可以使用vtk提供的可视化类和方法,将分割后的点云数据进行可视化展示。可以使用不同的颜色或者形状来区分不同的平面。 通过以上步骤,可以在vtk中实现点云平面切割,实现对点云数据的分割和可视化展示。这样的平面切割技术在计算机视觉、机器人、虚拟现实等领域有着广泛的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巴普蒂斯塔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值