转载:VTK笔记-裁剪分割-不规则闭合圈选裁剪-vtkSelectPolyData类(黑山老妖)

17 篇文章 0 订阅

原文链接:https://blog.csdn.net/liushao1031177/article/details/1182543

vtkClipClosedSurface
  vtkClipClosedSurface类使用平面集合剪裁闭合曲面。
  vtkClipClosedSurface将使用一组剪裁平面剪裁闭合的多边形曲面。它将通过在剪切输入数据的地方创建新的多边形面来生成新的闭合曲面。
  非流体表面不应用作vtkClipClosedSurface的输入。输入曲面不应具有开放边,并且不能具有由两个以上面共享的任何边。  vtkFeatureEdges过滤器可用于验证数据集是否满足这些条件。此外,输入曲面不应自相交,这意味着曲面的面应仅在其边缘处接触。
  如果GenerateOutline处于启用状态,则此过滤器将在剪裁平面与数据相交的任何位置生成轮廓。ScalarMode选项将向输出中添加单元格标量,以便生成的面可以以与原始曲面不同的颜色显示。
  注意:对于简单的凸输入,新面的三角剖分是在O(n)时间内完成的,但是对于非凸输入,最坏情况的时间是O(n2*m2),其中n是点的数量,m是三维腔的数量。相比之下,最好的三角剖分算法是O(nlogn)。但也有少数情况下,三角测量将无法产生严密输出。打开TriangulationErrorDisplay可以通知这些故障。
  之前对vtkPolyData数据进行裁剪后,就会破坏闭合多边形的闭合性,生成开放性的多边形。对于需要剪切后生成闭合多边形就需要使用vtkClipClosedSurface类;

接口
多面隐函数
  设置用于裁剪的隐函数,是vtkPlaneCollection类型指针;

virtual void SetClippingPlanes(vtkPlaneCollection* planes);
vtkGetObjectMacro(ClippingPlanes, vtkPlaneCollection);
1
2
单元标量
  支持设置是否添加单元标量,以便可以将新面和轮廓与原始面和线区分开来。
  选项有以下:

宏    意义
VTK_CCS_SCALAR_MODE_NONE    无
VTK_CCS_SCALAR_MODE_COLORS    颜色
VTK_CCS_SCALAR_MODE_LABELS    标签
  对于“Labels”选项,标量值“0”表示原始单元格,“1”表示剖切面上的新单元格,“2”表示由SetActivePlane()方法设置的ActivePlane上的新单元格。默认标量模式为“无”(VTK_CCS_SCALAR_MODE_NONE)。

vtkSetClampMacro(ScalarMode, int, VTK_CCS_SCALAR_MODE_NONE, VTK_CCS_SCALAR_MODE_LABELS);
void SetScalarModeToNone() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_NONE); }
void SetScalarModeToColors() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_COLORS); }
void SetScalarModeToLabels() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_LABELS); }
vtkGetMacro(ScalarMode, int);
const char* GetScalarModeAsString();
是否生成轮廓
  使用GenerateOutline控制是否在输入面被平面切割的位置生成轮廓。

vtkSetMacro(GenerateOutline, vtkTypeBool);
vtkBooleanMacro(GenerateOutline, vtkTypeBool);
vtkGetMacro(GenerateOutline, vtkTypeBool);

是否生成面
  GenerateFaces用来设置是否为输出生成多边形面。
  默认情况下,此选项处于启用状态。如果关闭,则输出将没有poly。

vtkSetMacro(GenerateFaces, vtkTypeBool);
vtkBooleanMacro(GenerateFaces, vtkTypeBool);
vtkGetMacro(GenerateFaces, vtkTypeBool);  

颜色
  BaseColor设置所有单元格的颜色是原始几何图形的一部分。
  如果输入数据已经有颜色单元格标量,那么这些值将被使用,参数将被忽略。默认颜色为红色。需要设置为颜色类型:SetScalarModeColors。
  ClipColor设置由于剪裁而创建的任何新几何图形(面或轮廓)的颜色。
  默认颜色为橙色。需要设置为颜色类型:SetScalarModeColors。
  如果设置了ActivePlaneId,则为通过使用ActivePlane剪裁生成的任何新几何体设置颜色。
  默认值为黄色。需要设置为颜色类型:SetScalarModeColors。

vtkSetVector3Macro(BaseColor, double);
vtkGetVector3Macro(BaseColor, double);
vtkSetVector3Macro(ClipColor, double);
vtkGetVector3Macro(ClipColor, double);
vtkSetMacro(ActivePlaneId, int);
vtkGetMacro(ActivePlaneId, int);
vtkSetVector3Macro(ActivePlaneColor, double);
vtkGetVector3Macro(ActivePlaneColor, double);

  TriangulationErrorDisplay用来开启三角剖分失败时生成错误。
  通常三角测量误差太小而看不见,但它们会导致曲面不闭合。TriangulationErrorDisplay选项对性能没有影响。

vtkSetMacro(TriangulationErrorDisplay, vtkTypeBool);
vtkBooleanMacro(TriangulationErrorDisplay, vtkTypeBool);
vtkGetMacro(TriangulationErrorDisplay, vtkTypeBool);
从示例中拿到一个vtkClipClosedSurface使用的片段:

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("SandyBrown").GetData());

1.使用SetInputData设定被裁剪的闭合多边形vtkPolyData:polyData;
2.使用SetClippingPlanes设定一组用来裁剪的隐函数平面集合vtkPlaneCollection指针:planes;
3.使用SetActivePlaneId设定当前活动平面ID为2;
4.设定单元标量为颜色,SetScalarModeToColors;
5.SetClipColor设定新生成的平面颜色为香蕉黄;
6.SetBaseColor设定之前多边形表面颜色为西红柿红;
7.设定当前平面颜色为SandyBrown颜色(#f4a460);

 

代码:

#include <vtkProperty.h>
#include <vtkSelectPolyData.h>
#include <vtkSphereSource.h>
#include <vtkClipPolyData.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkLODActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkNamedColors.h>

/*
* vtkSelectPolyData
  vtkSelectPolyData是一个Filter,它基于定义“循环”并指示循环内的区域来选择多边形数据。Loop循环中的网格由完整的单元组成(单元未被切割)。vtkSelectPolyData可以用来生成标量。这些标量值是到Loop循环的距离度量,可用于剪裁、绘制轮廓。或者提取数据(即隐式函数可以做的任何事情)。
  Loop循环由x-y-z点坐标数组定义(坐标应与输入的多边形数据位于同一坐标空间。)回路可以是凹面和非平面的,但不能是自交的。
  Filter输入是:多边形网格(仅曲面基本体,如三角形条带和多边形);
  Filter输出是:
    a)原始网格的一部分在选择循环中(GenerateSelectionScalarsOff)。
    b)添加标量值的相同多边形网格(GenerateSelectionScalarsOn)。
算法的工作原理如下:
  对于循环中的每个点坐标,将找到网格中最近的点。结果是网格中最近点ids的循环。然后,在网格中找到连接最近点(并沿形成回路的线排列)的边。贪婪的边缘跟踪过程如下所示。在当前点,将选择朝向的方向且其终点最接近直线的网格边。沿着边到达新的端点,然后重复该过程。此过程将继续,直到创建了整个循环。
  要确定网格的哪个部分在循环的内部和外部,可以使用三个选项:1) 最小连通区域,2)最大连通区域,3)最接近用户指定点的连通区域(设置ivar选择模式SelectionMode)。
  循环按上述方式计算后,GenerateSelectionScalars将控制过滤器的输出。如果启用,则基于到环线的距离生成标量值。否则,将输出位于选择循环内的单元格。默认情况下,输出在循环中铺设的网格;但是,如果“InsideOut”处于启用状态,则输出位于循环外部的网格部分。
  通过设置GenerateUnselectedOutput,可以将过滤器配置为生成网格的未选定部分作为输出。使用GetUnselectedOutput()方法访问此输出(注意:仅当GenerateSelectionScalars处于禁用状态时,此标志才相关)。
  注意:要确保拾取的点位于连接的曲面上。否则,Filter将生成一个空的或部分的结果。此外,自交Loop将产生不可预测的结果,所以输入闭合点集不要自相交;在数据处理过程中,如果禁用GenerateSelectionScalars,则非三角形单元将转换为三角形。
  注意:vtkImplicitSelectionLoop类是隐函数,用来做裁剪的,vtkSelectPolyDatas是数据集,使用SetLoop设置隐函数用来裁剪多边形数据,vtkSelectPolyDatas是选择多边形表面区域,vtkClipPolyData类使用SetClipFunction设置隐函数裁剪多边形,不同的是vtkClipPolyData裁剪的是贯穿了多边形的区域;

*被选择部分模式
  要确定网格的哪个部分在循环的内部和外部,可以使用三个选项:1) 最小连通区域,2)最大连通区域,3)最接近用户指定点的连通区域(设置ivar选择模式SelectionMode)

#define VTK_INSIDE_SMALLEST_REGION   		0 
#define VTK_INSIDE_LARGEST_REGION   		1 
#define VTK_INSIDE_CLOSEST_POINT_REGION   	2

  void SetSelectionModeToSmallestRegion() { this->SetSelectionMode(VTK_INSIDE_SMALLEST_REGION); }
  void SetSelectionModeToLargestRegion() { this->SetSelectionMode(VTK_INSIDE_LARGEST_REGION); }
  void SetSelectionModeToClosestPointRegion()  {this->SetSelectionMode(VTK_INSIDE_CLOSEST_POINT_REGION);
  }

————————————————
版权声明:本文为CSDN博主「黑山老妖的博客」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liushao1031177/article/details/118151714
*/

class Test_vtkSelectPolyData 
{
public:
	static void Test()
	{
		vtkNew<vtkNamedColors> colors;
		vtkNew<vtkSphereSource> sphereSource;
		sphereSource->SetPhiResolution(50);
		sphereSource->SetThetaResolution(100);
		sphereSource->Update();

		vtkNew<vtkPoints> loopPoints;
		loopPoints->InsertNextPoint(-0.16553, 0.135971, 0.451972);
		loopPoints->InsertNextPoint(-0.0880123, -0.134952, 0.4747);
		loopPoints->InsertNextPoint(0.00292618, -0.134604, 0.482459);
		loopPoints->InsertNextPoint(0.0641941, 0.067112, 0.490947);
		loopPoints->InsertNextPoint(0.15577, 0.0734765, 0.469245);
		loopPoints->InsertNextPoint(0.166667, -0.129217, 0.454622);
		loopPoints->InsertNextPoint(0.241259, -0.123363, 0.420581);
		loopPoints->InsertNextPoint(0.240334, 0.0727106, 0.432555);
		loopPoints->InsertNextPoint(0.308529, 0.0844311, 0.384357);
		loopPoints->InsertNextPoint(0.32672, -0.121674, 0.359187);
		loopPoints->InsertNextPoint(0.380721, -0.117342, 0.302527);
		loopPoints->InsertNextPoint(0.387804, 0.0455074, 0.312375);
		loopPoints->InsertNextPoint(0.43943, -0.111673, 0.211707);
		loopPoints->InsertNextPoint(0.470984, -0.0801913, 0.147919);
		loopPoints->InsertNextPoint(0.436777, 0.0688872, 0.233021);
		loopPoints->InsertNextPoint(0.44874, 0.188852, 0.109882);
		loopPoints->InsertNextPoint(0.391352, 0.254285, 0.176943);
		loopPoints->InsertNextPoint(0.373274, 0.154162, 0.294296);
		loopPoints->InsertNextPoint(0.274659, 0.311654, 0.276609);
		loopPoints->InsertNextPoint(0.206068, 0.31396, 0.329702);
		loopPoints->InsertNextPoint(0.263789, 0.174982, 0.387308);
		loopPoints->InsertNextPoint(0.213034, 0.175485, 0.417142);
		loopPoints->InsertNextPoint(0.169113, 0.261974, 0.390286);
		loopPoints->InsertNextPoint(0.102552, 0.25997, 0.414814);
		loopPoints->InsertNextPoint(0.131512, 0.161254, 0.454705);
		loopPoints->InsertNextPoint(0.000192443, 0.156264, 0.475307);
		loopPoints->InsertNextPoint(-0.0392091, 0.000251724, 0.499943);
		loopPoints->InsertNextPoint(-0.096161, 0.159646, 0.46438);

		vtkNew<vtkSelectPolyData> selectPolyData;
		selectPolyData->SetInputConnection(sphereSource->GetOutputPort());
		selectPolyData->SetLoop(loopPoints);
		selectPolyData->GenerateUnselectedOutputOn();
		selectPolyData->SetSelectionModeToSmallestRegion();
		selectPolyData->Update();

		vtkNew<vtkProperty> backProp;
		backProp->SetColor(colors->GetColor3d("tomato").GetData());

		vtkNew<vtkPolyDataMapper> selectMapper;
		selectMapper->SetInputData(selectPolyData->GetUnselectedOutput());
		
		vtkNew<vtkLODActor> selectActor;
		selectActor->SetMapper(selectMapper);
		selectActor->SetBackfaceProperty(backProp);
		selectActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());

		vtkNew<vtkPolyDataMapper> unselectMapper;
		unselectMapper->SetInputConnection(selectPolyData->GetOutputPort());
		
		vtkNew<vtkLODActor> unselectActor;
		unselectActor->SetMapper(unselectMapper);
		unselectActor->SetBackfaceProperty(backProp);
		unselectActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());

		vtkNew<vtkRenderer> renderer1;
		vtkNew<vtkRenderer> renderer2;

		vtkNew<vtkRenderWindow> renderWindow;
		renderWindow->AddRenderer(renderer1);
		renderWindow->AddRenderer(renderer2);

		vtkNew<vtkRenderWindowInteractor> interactor;
		interactor->SetRenderWindow(renderWindow);

		renderer1->AddActor(selectActor);
		renderer1->SetBackground(colors->GetColor3d("slate_grey").GetData());
		renderer1->SetViewport(0, 0, 0.5, 1);

		renderer2->AddActor(unselectActor);
		renderer2->SetBackground(colors->GetColor3d("slate_blue").GetData());
		renderer2->SetViewport(0.5, 0, 1, 1);

		renderWindow->SetSize(800, 400);
		renderWindow->Render();
		interactor->Start();
	}
};

int main(int, char* [])
{
	Test_vtkSelectPolyData::Test();
	return 0;
}

————————————————
版权声明:本文为CSDN博主「黑山老妖的博客」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liushao1031177/article/details/118254310

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值