VTK笔记-裁剪分割-vtkClipVolume-vtkSelectPolyData类

vtkClipVolume

  vtkClipVolume类使用用户指定的隐式函数或输入标量数据剪裁体积数据。
  vtkClipVolume类是一个Filter类,它使用派生于vtkImplicitFunction的子类或输入标量数据来剪裁体数据(即vtkImageData)。剪切操作会剪切数据集的单元格–将三维图像数据转换为三维非结构化网格返回指定隐式函数内的所有内容(或大于标量值)。在剪切过程中,滤镜会产生一个单元的碎片(将其与vtkExtractGeometry或vtkGeometryFilter进行比较,后者生成完整的未剪切单元。)vtkClipVolume类的输出是三维非结构化网格(例如四面体或其他三维单元类型)。
  要使用此类,必须确定是使用隐式函数进行剪裁,还是使用输入标量数据。如果要使用隐式函数进行剪裁,必须首先定义隐式函数,然后使用SetClipFunction()方法设置隐式函数,否则,必须确保输入标量数据可用。还可以指定标量值,用于确定隐式函数的内部和外部。您还可以通过设置InsideOut实例变量来反转inside/outside的含义(切割算法通过计算隐式函数值或使用数据集中每个点的输入标量数据来进行。将其与标量值进行比较以确定inside/outside。)
  vtkClipVolume可配置为计算第二输出。第二个输出被剪裁掉的部分。如果要访问此输出数据,需要启用GenerateClippedData布尔值。
vtkClipVolume将生成完全四面体的非结构化网格,或四面体和其他三维单元类型(如楔形)的混合网格。通过设置Mixed3DCellGeneration来控制此行为。**默认情况下,Mixed3DCellGeneration处于启用状态,将生成单元类型的组合。**注意,生成混合单元类型比只生成四面体更快。
  同vtkClipPolyData类的用法类似,不同之处在于vtkClipPolyData类用于处理多边形数据(vtkPolyData),而vtkClipVolume类用于处理vtkImageData数据;这里不再列举vtkClipVolume类的主要接口,有需要的可以查看官方的vtkClipVolume说明;

示例

#pragma once
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCellData.h>
#include <vtkClipVolume.h>
#include <vtkColor.h>
#include <vtkDataSetMapper.h>
#include <vtkDoubleArray.h>
#include <vtkExecutive.h>
#include <vtkImageData.h>
#include <vtkImageMapToColors.h>
#include <vtkInteractorStyleSwitch.h>
#include <vtkLookupTable.h>
#include <vtkMapper.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlanes.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkProperty.h>
#include <vtkRenderStepsPass.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

#include "vtk_include.h"
namespace {
	constexpr auto IMAGESIZE{ 64 };  // number of checkerboard squares on a side
	constexpr auto CUBESIZE{ 20.0 }; // physical linear dimension of entire system

	// Color for the checkerboard image
	constexpr auto DIM{ 0.5 }; // amount to dim the dark squares by

	// Offsets for clipping planes with normals in the X and Y directions
	constexpr auto XOFFSET{ 8 };
	constexpr auto YOFFSET{ 8 };

	// Make the image data. A checkerboard pattern is used for
	// simplicity.
	vtkSmartPointer<vtkImageData> makeImage(int n, vtkColor3d fillColor, vtkColor3d checkerColor) {
		vtkNew<vtkImageData> image0;
		image0->SetDimensions(n, n, n);
		image0->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
		image0->SetSpacing(CUBESIZE / n, CUBESIZE / n, CUBESIZE / n);
		int checkerSize = n / 8;
		for (int z = 0; z < n; z++) {
			for (int y = 0; y < n; y++) {
				for (int x = 0; x < n; x++) {
					unsigned char* ptr = (unsigned char*)image0->GetScalarPointer(x, y, z);
					*ptr = (x / checkerSize + y / checkerSize + z / checkerSize) % 2; // checkerboard
				}
			}
		}

		vtkNew<vtkLookupTable> lut;
		lut->SetNumberOfTableValues(2);
		lut->SetTableRange(0, 1);
		lut->SetTableValue(0, fillColor.GetRed(), fillColor.GetGreen(), fillColor.GetBlue(), 1.0);
		lut->SetTableValue(1, checkerColor.GetRed(), checkerColor.GetGreen(), checkerColor.GetBlue(), 1.0);

		auto map = vtkSmartPointer<vtkImageMapToColors>::New();
		map->SetLookupTable(lut);
		map->SetOutputFormatToRGBA();
		map->SetInputData(image0);
		map->GetExecutive()->Update();

		return map->GetOutput();
	}

} // namespace
class Test_Clip_Volume {
public:
	static void Test() {
		vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();

		// Define colors
		vtkNew<vtkNamedColors> colors;
		vtkColor3d backgroundColor = colors->GetColor3d("Wheat");
		vtkColor3d checkerColor = colors->GetColor3d("Tomato");
		vtkColor3d fillColor = colors->GetColor3d("Banana");

		vtkNew<vtkRenderer> renderer;
		renderer->SetBackground(backgroundColor.GetData());

		vtkNew<vtkRenderWindow> renderWindow;
		renderWindow->AddRenderer(renderer);
		renderWindow->SetSize(640, 480);

		vtkNew<vtkRenderWindowInteractor> interactor;
		vtkNew<vtkInteractorStyleSwitch> style;
		interactor->SetInteractorStyle(style);
		interactor->SetRenderWindow(renderWindow);

		auto image = makeImage(IMAGESIZE, fillColor, checkerColor);

		// Clipping planes in the X and Y direction.
		vtkNew<vtkDoubleArray> normals;
		vtkNew<vtkPoints> clipPts;
		normals->SetNumberOfComponents(3);
		double xnorm[3] = { 0, 0., 1 };
		double ynorm[3] = { 1, 1., 0. };
		double znorm[3] = { 1, 1, 0 };
		double xpt[3] = { 0, 0., 19 };
		double ypt[3] = { 12, 8, 0. };
		double zpt[3] = { 12, 0, 0. };
		normals->InsertNextTuple(xnorm);
		normals->InsertNextTuple(ynorm);
		normals->InsertNextTuple(znorm);
		clipPts->InsertNextPoint(xpt);
		clipPts->InsertNextPoint(ypt);
		clipPts->InsertNextPoint(zpt);
		vtkNew<vtkPlanes> clipPlanes;
		clipPlanes->SetNormals(normals);
		clipPlanes->SetPoints(clipPts);

		vtkNew<vtkClipVolume> clipper;
		clipper->SetClipFunction(clipPlanes);
		clipper->SetInputData(image);

		vtkNew<vtkDataSetMapper> imageMapper;
		vtkNew<vtkActor> imageActor;
		imageActor->SetMapper(imageMapper);
		renderer->AddViewProp(imageActor);
		imageMapper->SetInputConnection(clipper->GetOutputPort());

		renderer->ResetCamera();
		renderer->GetActiveCamera()->Azimuth(120);
		renderer->GetActiveCamera()->Elevation(30);
		renderer->ResetCameraClippingRange();
		renderWindow->SetWindowName("ClipVolume");
		renderWindow->Render();

		interactor->Start();
	}
};

在这里插入图片描述
  当只使用一个方向上的平面进行裁剪时:
在这里插入图片描述
  将double xnorm[3] = { 0, 0, 1 };修改为double xnorm[3] = { 0, 0, -1 };
  相当时翻转之前的剪裁结果,将之前别裁剪的数据留下;
在这里插入图片描述

出现的问题-未解决

当constexpr auto IMAGESIZE{ 64 };设置为300以上时;
运行出现内存分配失败的情况,至于为什么出现这种情况,暂时没有定位到原因;
当constexpr auto IMAGESIZE{ 64 };IMAGESIZE设置为200以内时,没有出现这种问题;
在这里插入图片描述

参考资料

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑山老妖的笔记本

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

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

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

打赏作者

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

抵扣说明:

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

余额充值