VTK中的裁剪功能

最近在开发vtk的相关功能,项目中用到了数据裁剪,vtk中提供了多种数据裁剪算法,常用的有:vtkClipClosedSurface、vtkClipPolyData,还有其他的裁剪算法,如vtkClipDataSet、vtkClipVolume、vtkClipConvexPolyData 。本文主要介绍vtkClipClosedSurface和vtkClipPolyData。
两者差异:vtkClipPolvData切割带有锯齿形状日不是封闭的模型;vtkClipClosedSurace通过插值确保切割面为光滑目封闭的。

  1. vtkClipPolyData
    使用用户指定的隐式函数(user-specified implicit function)或输入标量数据(input scalar data)剪裁多边形数据;vtkClipPolyData是一种Filter,接受vtkImplicitFunction派生出的任何子类或者标量数据集,vtkClipPolyData实现的剪切功能实际上“剪切”数据集的单元格,返回指定隐式函数(或大于标量值)内的所有内容,包括单元格的“片段”(将此与vtkExtractGeometry进行比较,该几何图形将拉出整个未切割单元格。)此筛选器的输出为多边形数据(vtkPolyData)。
    要使用此Filter,必须决定是否使用隐式函数剪裁,还是使用输入标量数据。
    1)定义隐式函数
    2)使用SetClipFunction方法设置它
    3)如果未指定ClipFunction,则使用方法GenerateClipScalarsOn开启,或者是GenerateClipScalars关闭(默认值),则将使用输入的标量数据来剪裁多数据。
  2. vtkClipClosedSurface
    用途:通过一组切割平面实现对闭合曲面的切割。将输入数据切割未由多边形面组成的闭合由。
    约束:输入的曲面不应该有开放的边缘,也不能有任何被两个以上的面共享的边缘。
    vtkFeatureEdges 过滤器器可以用来验证一个数据集是否满足这些条件。输入的面不应该是自相交的,即曲面的各面应该只与它们的边缘相接触。
    选项:
    a.如果"生成轮廓"(GenerateOutline)是打干的,这个过滤器将在剪裁平面与数据相交处生戒一个轮廓;
    b. PassPointData;若打开表示将点数据传递给输出,若新点产生时,点数据将会进行插值。此变量默认关闭。
    c. ScalarMode选项将在输出中添加单元格标量,这样生成的面就可以用与原始面不同的颜色显示。可以用与原始表面不同的颜色来显示。
    注意:
    (1)一组切割平面应该是一组凸平面,否则成的结果可能为空;
    (2) 生成的结果为多个平面围成的部分。
    (3)若ScalarMode设置为On时,则是标量来映射Mapper的颜色;此时通过actor->GetProperty()->SetColor(color);
    设置颜色时不生效;解决方案:关闭Mapper的ScalarVisibility,颜色设置才能生效。
    代码:
#include <vtkActor.h>
#include <vtkAreaPicker.h>
#include <vtkDataSetMapper.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkExtractPolyDataGeometry.h>
#include <vtkIdFilter.h>
#include <vtkIdTypeArray.h>
#include <vtkInteractorStyleRubberBandPick.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkPlanes.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkUnstructuredGrid.h>
#include <vtkVersion.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include "vtkClipClosedSurface.h"
#include "vtkPlaneCollection.h"
#include "vtkAxesActor.h"
#define VTKISRBP_ORIENT 0
#define VTKISRBP_SELECT 1
  
namespace {
	// Define interaction style
	class HighlightInteractorStyle : public vtkInteractorStyleRubberBandPick
	{
	public:
		static HighlightInteractorStyle* New();
		vtkTypeMacro(HighlightInteractorStyle, vtkInteractorStyleRubberBandPick);
 
		HighlightInteractorStyle() : vtkInteractorStyleRubberBandPick()
		{
			this->SelectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();
			this->SelectedActor = vtkSmartPointer<vtkActor>::New();
			this->SelectedActor->SetMapper(SelectedMapper);
		}
 
		virtual void OnLeftButtonUp() override
		{
			// Forward events
			vtkInteractorStyleRubberBandPick::OnLeftButtonUp();
 
			if (this->CurrentMode == VTKISRBP_SELECT)
			{
				vtkNew<vtkNamedColors> colors;
 
				vtkPlanes* frustum = static_cast<vtkAreaPicker*>(this->GetInteractor()->GetPicker())->GetFrustum();
 
				vtkNew<vtkPlaneCollection> planeCollection;
				int pCount = frustum->GetNumberOfPlanes() - 2;
				for (int i = 0; i < pCount; i++)
				{
					double normal[3];
					frustum->GetPlane(i)->GetNormal(normal);
					double origin[3];
					frustum->GetPlane(i)->GetOrigin(origin);
 
					vtkNew<vtkPlane> plane;
					plane->SetOrigin(origin[0], origin[1], origin[2]);
					plane->SetNormal(-normal[0], -normal[1], -normal[2]);
					planeCollection->AddItem(plane);
				}
				
				vtkNew<vtkClipClosedSurface> clipper;
				clipper->SetInputData(this->PolyData);
				clipper->SetClippingPlanes(planeCollection);
				clipper->Update();
 
				if (m_SrcActor != nullptr)
					m_SrcActor->VisibilityOff();
 
				this->SelectedMapper->SetInputData(clipper->GetOutput());
 
				this->SelectedActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
				this->GetInteractor()->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(SelectedActor);
				this->GetInteractor()->GetRenderWindow()->Render();
				this->HighlightProp(NULL);
			}
		}
 
		void SetPolyData(vtkSmartPointer<vtkPolyData> polyData)
		{
			this->PolyData = polyData;
		}
		vtkActor* m_SrcActor = nullptr;
	private:
		vtkSmartPointer<vtkPolyData> PolyData;
		vtkSmartPointer<vtkActor> SelectedActor;
		vtkSmartPointer<vtkDataSetMapper> SelectedMapper;
	};
	vtkStandardNewMacro(HighlightInteractorStyle);
 
} // namespace
 
int main(int argc, char* argv[])
{
 
	vtkNew<vtkSphereSource> source;
	source->SetPhiResolution(49);
	source->SetThetaResolution(200);
	source->Update();
	auto polyData = source->GetOutput();
 
 
	// Create a mapper and actor
	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputData(polyData);
	mapper->ScalarVisibilityOff();
 
	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);
	actor->GetProperty()->SetPointSize(5);
 
	vtkNew<vtkAxesActor> axes;
	// Visualize
	vtkNew<vtkRenderer> renderer;
	renderer->UseHiddenLineRemovalOn();
 
	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(640, 480);
	renderWindow->SetWindowName("HighlightSelection");
 
	vtkNew<vtkAreaPicker> areaPicker;
	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetPicker(areaPicker);
	renderWindowInteractor->SetRenderWindow(renderWindow);
 
	renderer->AddActor(actor);
	renderer->AddActor(axes);
 
	renderWindow->Render();
 
	vtkNew<HighlightInteractorStyle> style;
	style->m_SrcActor = actor;
	style->SetPolyData(polyData);
	style->SetCurrentRenderer(renderer);
	renderWindowInteractor->SetInteractorStyle(style);
 
	renderWindowInteractor->Start();
 
	return EXIT_SUCCESS;
}
 

vtkClipClosedSurface

vtkClipPolydata的代码参考:VTK笔记——多边形剪切(vtkClipPolyData)
VTK折线裁剪封闭曲面 三角剖分 Delaunay2D参考博客:VTK 三角剖分 Delaunay2D(五)—— 折线裁剪封闭曲面

其他的参考博客还有:

  1. vk裁剪的平面裁剪Vtk裁剪功能之平面裁剪vtkClipClosedSurface(vtk小记)
  2. VTK裁剪【1】-VTK中Clip/Trim总结 VTK裁剪【1】-VTK中Clip/Trim总结
    3.VTK笔记-裁剪分割-几何裁剪-vtkClipPolyDat VTK笔记-裁剪分割-几何裁剪-vtkClipPolyData
  3. VTK多个多边形数据的合并 - vtkAppendPolyData VTK多个多边形数据的合并 - vtkAppendPolyData
  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值