《VTK笔记——轴对齐包围盒(AABB)》提到了有向包围盒(OBB/Oriented bounding box)。
有向包围盒,是较为常用的包围盒类型。简单的说,它就是包围模型的最小盒子,是根据模型的几何形状来决定包围盒的大小和方向,无需和坐标轴垂直,方向是任意的,这是它的特点,但也导致了生成的复杂性。
在VTK中,有一个算法类vtkOBBTree可以得到有向包围盒。它是一个Tree,为什么需要Tree?这是一种为了得到复杂模型的包围盒常用的一种方法,以一种更加专业的包围盒层次对模型进行分解。基本思路就是将模型组织成一个树状结构,根节点是整个模型,每个叶子节点包括一个简单的局部。
Description
generate oriented bounding box (OBB) tree
vtkOBBTree is an object to generate oriented bounding box (OBB) trees. An oriented bounding box is a bounding box that does not necessarily line up along coordinate axes. The OBB tree is a hierarchical tree structure of such boxes, where deeper levels of OBB confine smaller regions of space.
To build the OBB, a recursive, top-down process is used. First, the root OBB is constructed by finding the mean and covariance matrix of the cells (and their points) that define the dataset. The eigenvectors of the covariance matrix are extracted, giving a set of three orthogonal vectors that define the tightest-fitting OBB. To create the two children OBB’s, a split plane is found that (approximately) divides the number cells in half. These are then assigned to the children OBB’s. This process then continues until the MaxLevel ivar limits the recursion, or no split plane can be found.
A good reference for OBB-trees is Gottschalk & Manocha in Proceedings of Siggraph `96.
int maxLevel = 10;
vtkSmartPointer<vtkOBBTree> obbTree =
vtkSmartPointer<vtkOBBTree>::New();
obbTree->SetDataSet(polydata);
obbTree->SetMaxLevel(maxLevel);
obbTree->BuildLocator();
double corner[3] = { 0.0, 0.0, 0.0 };
double max[3] = { 0.0, 0.0, 0.0 };
double mid[3] = { 0.0, 0.0, 0.0 };
double min[3] = { 0.0, 0.0, 0.0 };
double size[3] = { 0.0, 0.0, 0.0 };
obbTree->ComputeOBB(polydata, corner, max, mid, min, size);
vtkSmartPointer<vtkPolyData> obbPolydata =
vtkSmartPointer<vtkPolyData>::New();
obbTree->GenerateRepresentation(0, obbPolydata);
SetMaxLevel设置Tree的最大层级,默认是8.
GenerateRepresentation用于获取指定层级的polydata.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
if (argc > 1)
{
vtkSmartPointer<vtkXMLPolyDataReader> reader =
vtkSmartPointer<vtkXMLPolyDataReader>::New();
reader->SetFileName(argv[1]);
reader->Update();
polydata = reader->GetOutput();
}
else
{
vtkSmartPointer<vtkSphereSource> modelSource =
vtkSmartPointer<vtkSphereSource>::New();
modelSource->Update();
polydata = modelSource->GetOutput();
}
int maxLevel = 10;
vtkSmartPointer<vtkOBBTree> obbTree =
vtkSmartPointer<vtkOBBTree>::New();
obbTree->SetDataSet(polydata);
obbTree->SetMaxLevel(maxLevel);
obbTree->BuildLocator();
double corner[3] = { 0.0, 0.0, 0.0 };
double max[3] = { 0.0, 0.0, 0.0 };
double mid[3] = { 0.0, 0.0, 0.0 };
double min[3] = { 0.0, 0.0, 0.0 };
double size[3] = { 0.0, 0.0, 0.0 };
obbTree->ComputeOBB(polydata, corner, max, mid, min, size);
std::cout << "Corner:\t" << corner[0] << ", " << corner[1] << ", "
<< corner[2] << std::endl
<< "Max:\t" << max[0] << ", " << max[1] << ", " << max[2]
<< std::endl
<< "Mid:\t" << mid[0] << ", " << mid[1] << ", " << mid[2]
<< std::endl
<< "Min:\t" << min[0] << ", " << min[1] << ", " << min[2]
<< std::endl
<< "Size:\t" << size[0] << ", " << size[1] << ", " << size[2]
<< std::endl;
vtkSmartPointer<vtkPolyData> obbPolydata =
vtkSmartPointer<vtkPolyData>::New();
obbTree->GenerateRepresentation(0, obbPolydata);
vtkSmartPointer<vtkPolyDataMapper> modelMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
modelMapper->SetInputData(polydata);
vtkSmartPointer<vtkActor> modelActor =
vtkSmartPointer<vtkActor>::New();
modelActor->SetMapper(modelMapper);
vtkSmartPointer<vtkPolyDataMapper> obbTreeMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
obbTreeMapper->SetInputData(obbPolydata);
vtkSmartPointer<vtkActor> obbTreeActor =
vtkSmartPointer<vtkActor>::New();
obbTreeActor->SetMapper(obbTreeMapper);
obbTreeActor->GetProperty()->SetInterpolationToFlat();
obbTreeActor->GetProperty()->SetOpacity(.5);
obbTreeActor->GetProperty()->SetColor(
colors->GetColor4d("SpringGreen").GetData());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(400, 400);
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(modelActor);
renderer->AddActor(obbTreeActor);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
vtkOBBTree Class Reference
VisualizeOBBTree
[算法][包围盒]球,AABB,OBB