图形处理之封闭性检测

本文介绍VTK中封闭性检测。

基本概念

        介绍封闭性检测之前,介绍一些基本概念。如果一个网格模型中,一条边只被一个单元包含,那么这条边就是边界边,而边界上的点则为边界点。如果一个模型中含有边界边,则说明该模型不是封闭的,否则是封闭的。
        在VTK’中,vtkFeatureEdges是一个非常重要的类,该类能够提取多边形网格模型中四种类型的边。

  1. 边界边。
  2. 非流形边。被三个或者三个以上的多边形单元包含的边即为非流形边。
  3. 特征边。设置一个特征角的阈值,当包含同一条边的两个三角形的法向量的夹角大于该阈值时,即为一个特征边。
  4. 流行边。只被两个多边形单元包含的边即为流行边。

vtkFeatureEdges的输出是一个包含边信息的vtkPolyData数据。通过判断边界边的数目来确定网格是否封闭。

int numberofopenedges = featureedges->GetOutput()->GetNumberOfCells();

示例说明

        们演示用vtkFeatureEdges提取边,并显示出来。

/**********************************************************************

Copyright (c) Mr.Bin. All rights reserved.
For more information visit: http://blog.csdn.net/webzhuce

**********************************************************************/
#include <vtkSmartPointer.h>
#include <vtkInformation.h>
#include <vtkPolyData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSelection.h>
#include <vtkSelectionNode.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkIdTypeArray.h>
#include <vtkExtractSelection.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkFeatureEdges.h>
#include <vtkPolyDataMapper.h>

void GenerateData(vtkSmartPointer<vtkPolyData> input)
{
	vtkNew<vtkSphereSource> spheresource;
	spheresource->Update();

	vtkNew<vtkIdTypeArray> ids;
	ids->SetNumberOfComponents(1);
	ids->InsertNextValue(2);
	ids->InsertNextValue(10);

	vtkNew<vtkSelectionNode> selectionnode;
	selectionnode->SetFieldType(vtkSelectionNode::CELL);
	selectionnode->SetContentType(vtkSelectionNode::INDICES);
	selectionnode->SetSelectionList(ids);
	selectionnode->GetProperties()->Set(vtkSelectionNode::INVERSE(), 1);

	vtkNew<vtkSelection> selection;
	selection->AddNode(selectionnode);

	vtkNew<vtkExtractSelection> extractselection;
	extractselection->SetInputData(0, spheresource->GetOutput());
	extractselection->SetInputData(1, selection);
	extractselection->Update();

	vtkNew<vtkDataSetSurfaceFilter> surfacefilter;
	surfacefilter->SetInputConnection(extractselection->GetOutputPort());
	surfacefilter->Update();

	input->ShallowCopy(surfacefilter->GetOutput());
}

int main(int argc, char *argv[])
{
	vtkNew<vtkPolyData> input;
	GenerateData(input);

	vtkNew<vtkFeatureEdges> featureedges;
	featureedges->SetInputData(input);
	featureedges->BoundaryEdgesOn();
	featureedges->FeatureEdgesOff();
	featureedges->ManifoldEdgesOff();
	featureedges->NonManifoldEdgesOff();
	featureedges->Update();


	int numberofopenedges = featureedges->GetOutput()->GetNumberOfCells();
	if (numberofopenedges)
		std::cout << "该网格模型不是封闭的..." << std::endl;
	else {
		std::cout << "该网格模型是封闭的..." << std::endl;
		return EXIT_SUCCESS;
	}

	//
	double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
	double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };

	vtkNew<vtkPolyDataMapper> originalmapper;
	originalmapper->SetInputData(input);

	vtkNew<vtkProperty> backfaceprop;
	backfaceprop->SetDiffuseColor(0.89, 0.81, 0.34);

	vtkNew<vtkActor> originalactor;
	originalactor->SetMapper(originalmapper);
	originalactor->SetBackfaceProperty(backfaceprop);
	originalactor->GetProperty()->SetDiffuseColor(1.0, 0.3882, 0.2784);

	vtkNew<vtkPolyDataMapper> edgemapper;
	edgemapper->SetInputData(featureedges->GetOutput());
	vtkNew<vtkActor> edgeactor;
	edgeactor->SetMapper(edgemapper);
	edgeactor->GetProperty()->SetEdgeColor(0., 0., 1.0);
	edgeactor->GetProperty()->SetEdgeVisibility(1);
	edgeactor->GetProperty()->SetLineWidth(5);

	vtkNew<vtkRenderer> leftrenderer;
	leftrenderer->SetViewport(leftViewport);
	leftrenderer->AddActor(originalactor);
	leftrenderer->SetBackground(1.0, 1.0, 1.0);

	vtkNew<vtkRenderer> rightrenderer;
	rightrenderer->SetViewport(rightViewport);
	rightrenderer->AddActor(edgeactor);
	rightrenderer->SetBackground(1.0, 1.0, 1.0);

	vtkNew<vtkRenderWindow> renderwindow;
	renderwindow->AddRenderer(leftrenderer);
	renderwindow->AddRenderer(rightrenderer);
	renderwindow->SetSize(640, 320);
	renderwindow->Render();
	renderwindow->SetWindowName("FeatureEdges");

	vtkNew<vtkRenderWindowInteractor> renderwindowinteractor;
	renderwindowinteractor->SetRenderWindow(renderwindow);

	leftrenderer->GetActiveCamera()->SetPosition(0, -1, 0);
	leftrenderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
	leftrenderer->GetActiveCamera()->SetViewUp(0, 0, 1);
	leftrenderer->GetActiveCamera()->Azimuth(30);
	leftrenderer->GetActiveCamera()->Elevation(30);
	leftrenderer->ResetCamera();
	rightrenderer->SetActiveCamera(leftrenderer->GetActiveCamera());

	renderwindow->Render();
	renderwindowinteractor->Start();

	return EXIT_SUCCESS;
}

运行结果:

在这里插入图片描述

参考资料

  • VTK图形图像开发进阶[M]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值