VTK笔记——多边形网格与直线的相交(vtkOBBTree)

在多边形网格中,求某一直线与多边形网格的交点,或者是判断它们是否有相交是极为常见的问题。这篇笔记就是使用OBB Tree来完成这样的需求。

vtkOBBTree

vtkOBBTree是用于生成有向包围盒(OBB)树的对象。一个有向的包围盒不一定是沿着坐标轴对齐的包围盒。OBB树是这种包围盒层次的树形结构,更深层次的OBB划分了更小的空间区域。
关于OBB Tree可以参考Gottschalk和Manocha在Siggraph `96的文章“OBBTree: A Hierarchical Structure for Rapid Interference Detection”,它是一个很好的参考资料。

用法

线段与多边形网格的交点
准确的说,这里的直线是线段,由一个起点和一个终点决定的。
设置多边形网格和线段的两个端点,结果返回交点和cell的id list.

	auto intersectionPoints = vsp<vtkPoints>::New();
	auto intersectioncells = vsp<vtkIdList>::New();
	double tol = 1e-8;
	auto obbTree = vsp<vtkOBBTree>::New();
	obbTree->SetTolerance(tol);
	obbTree->SetDataSet(sphereSource->GetOutput());
	obbTree->BuildLocator();
	obbTree->IntersectWithLine(lineP0, lineP1, intersectionPoints, intersectioncells);

提取cell
由于返回的是id list, 我们还需要用vtkExtractCells提取一下。

	auto cellSource = vsp<vtkExtractCells>::New();
	cellSource->SetInputConnection(sphereSource->GetOutputPort());
	cellSource->SetCellList(intersectioncells);

示例

我们创建一个球体,求它与一线段的相交。
在这里插入图片描述

IntersectWithLine.cxx

#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkLineSource.h>
#include <vtkPoints.h>
#include <vtkIdList.h>
#include <vtkPointData.h>
#include <vtkLine.h>
#include <vtkOBBTree.h>
#include <vtkExtractCells.h>
#include <vtkPolyDataMapper.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkNamedColors.h>
#include <vtkPolyData.h>
#include <vtkVertexGlyphFilter.h>

#define vsp	vtkSmartPointer

int main(int, char* [])
{
	auto colors = vsp<vtkNamedColors>::New();

	auto sphereSource = vsp<vtkSphereSource>::New();
	sphereSource->Update();

	double lineP0[3] = { -0.6, -0.6, -0.6 };
	double lineP1[3] = { .6, .6, .6 };
	auto lineSource = vsp<vtkLineSource>::New();
	lineSource->SetPoint1(lineP0);
	lineSource->SetPoint2(lineP1);
	lineSource->Update();

	auto intersectionPoints = vsp<vtkPoints>::New();
	auto intersectioncells = vsp<vtkIdList>::New();
	double tol = 1e-8;
	auto obbTree = vsp<vtkOBBTree>::New();
	obbTree->SetTolerance(tol);
	obbTree->SetDataSet(sphereSource->GetOutput());
	obbTree->BuildLocator();
	obbTree->IntersectWithLine(lineP0, lineP1, intersectionPoints, intersectioncells);

	auto pointsPolydata = vsp<vtkPolyData>::New();
	pointsPolydata->SetPoints(intersectionPoints);
	auto vertexFilter = vsp<vtkVertexGlyphFilter>::New();
	vertexFilter->SetInputData(pointsPolydata);
	vertexFilter->Update();
	auto polydata = vsp<vtkPolyData>::New();
	polydata->ShallowCopy(vertexFilter->GetOutput());

	auto cellSource = vsp<vtkExtractCells>::New();
	cellSource->SetInputConnection(sphereSource->GetOutputPort());
	cellSource->SetCellList(intersectioncells);

	auto sphereMapper = vsp<vtkPolyDataMapper>::New();
	sphereMapper->SetInputData(sphereSource->GetOutput());
	auto sphereActor = vsp<vtkActor>::New();
	sphereActor->SetMapper(sphereMapper);
	sphereActor->GetProperty()->SetRepresentationToWireframe();
	
	auto lineMapper = vsp<vtkPolyDataMapper>::New();
	lineMapper->SetInputData(lineSource->GetOutput());
	auto lineActor = vsp<vtkActor>::New();
	lineActor->SetMapper(lineMapper);
	lineActor->GetProperty()->SetColor(colors->GetColor3d("red").GetData());

	auto pointMapper = vsp<vtkPolyDataMapper>::New();
	pointMapper->SetInputData(polydata);
	auto pointActor = vsp<vtkActor>::New();
	pointActor->SetMapper(pointMapper);
	pointActor->GetProperty()->SetColor(colors->GetColor3d("blue").GetData());
	pointActor->GetProperty()->SetPointSize(8);

	auto cellMapper = vsp<vtkDataSetMapper>::New();
	cellMapper->SetInputConnection(cellSource->GetOutputPort());
	auto cellActor = vsp<vtkActor>::New();
	cellActor->SetMapper(cellMapper);
	cellActor->GetProperty()->SetColor(colors->GetColor3d("yellow").GetData());

	auto renderer = vsp<vtkRenderer>::New();
	auto renWinddow = vsp<vtkRenderWindow>::New();
	auto interactor = vsp<vtkRenderWindowInteractor>::New();
	renWinddow->SetSize(600, 600);
	renWinddow->AddRenderer(renderer);
	interactor->SetRenderWindow(renWinddow);
	renderer->SetBackground(colors->GetColor3d("DarkOliveGreen").GetData());
	renderer->AddActor(sphereActor);
	renderer->AddActor(lineActor);
	renderer->AddActor(pointActor);
	renderer->AddActor(cellActor);

	interactor->Initialize();
	interactor->Start();

	return EXIT_SUCCESS;
}

Ref

VTKExamples/Cxx/DataStructures/OBBTreeIntersectWithLine
VTKExamples/Cxx/DataStructures/OBBTreeExtractCells
在这里插入图片描述

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值