vtkOBBTree directed bounding box
vtkOBBTree is a tree of bounding boxes, which divides each cell of the body into each small bounding box. SetNumberOfBuckets determines how many Cells are placed in each box. To create a vtkOBBTree, you must first set DataSet and SetDataSet. Then call BuildLocator. The fineness of the bounding box is determined by the recursion depth (MaxLevel) and the preset NumberOfBuckets.
Usage scenario:
You can use vtkOBBTree to perform intersection detection, calculation, and collision detection with a straight line, triangle, or even another vtkOBBTree;
It can be used to obtain the intersection point of straight line and polygon data; used to find the closest point; etc.;
1. Intersection of two vtkOBBTree:
vtkOBBTree * targetTree = vtkOBBTree::New(); targetTree->SetDataSet(targetPoly); targetTree->BuildLocator(); vtkOBBTree * clipTree = vtkOBBTree::New(); clipTree->SetDataSet(clipPoly); clipTree->BuildLocator(); //Use the bounding box to intersect, and the intersection part is in OBBNodeIntersected. NULL means no conversion is performed clipTree->IntersectWithOBBTree(targetTree,NULL,OBBNodeIntersected,this); //Definition of OBBNodeIntersected function: static int OBBNodeIntersected(vtkOBBNode *, vtkOBBNode *, vtkMatrix4x4 *,void *);
2. Official sample: OBBTreeExtractCells.cxx
Use vtkOBBTree
IntersectWithLine
Get the intersection point of the line and the bounding box and the Cell where the intersection point is located;
vtkOBBTree returns all intersection points of a line and a data set. If you want the closest intersection, you have to find it manually. In this example, we create a sphere and intersect it with a straight line.
In fact, it can also be used here to find the point reached by clicking the mouse; the 2D point of the mouse is converted into world coordinates, plus the point of the camera, and then extended; it is also a line, and the nearest point is found; that is, the point reached by the mouse Pick point;
CODE
#include <vtkExtractCells.h> #include <vtkIdList.h> #include <vtkLine.h> #include <vtkLineSource.h> #include <vtkNamedColors.h> #include <vtkNew.h> #include <vtkOBBTree.h> #include <vtkPointData.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkSphereSource.h> #include <vtkActor.h> #include <vtkDataSetMapper.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> int main(int, char*[]) { vtkNew<vtkNamedColors> colors; vtkNew<vtkSphereSource> sphereSource; sphereSource->SetPhiResolution(7); sphereSource->SetThetaResolution(15); sphereSource->Update(); //Create the locator vtkNew<vtkOBBTree> tree; tree->SetDataSet(sphereSource->GetOutput()); tree->BuildLocator(); // Intersect the locator with the line double lineP0[3] = {-0.6, -0.6, -0.6}; double lineP1[3] = {.6, .6, .6}; vtkNew<vtkPoints> intersectPoints; vtkNew<vtkIdList> intersectCells; double tol = 1.e-8; tree->SetTolerance(tol); tree->IntersectWithLine(lineP0, lineP1, intersectPoints, intersectCells); std::cout << "NumPoints: " << intersectPoints->GetNumberOfPoints() << std::endl; // Display list of intersections double intersection[3]; for (int i = 0; i < intersectPoints->GetNumberOfPoints(); i + + ) { intersectPoints->GetPoint(i, intersection); std::cout << "\tPoint Intersection " << i << ": " << intersection[0] << ", " << intersection[1] << ", " << intersection[2] << std::endl; } std::cout << "NumCells: " << intersectCells->GetNumberOfIds() << std::endl; vtkIdType cellId; for (int i = 0; i < intersectCells->GetNumberOfIds(); i + + ) { cellId = intersectCells->GetId(i); std::cout << "\tCellId " << i << ": " << cellId << std::endl; } // Render the line, sphere and intersected cells vtkNew<vtkLineSource> lineSource; lineSource->SetPoint1(lineP0); lineSource->SetPoint2(lineP1); vtkNew<vtkPolyDataMapper> lineMapper; lineMapper->SetInputConnection(lineSource->GetOutputPort()); vtkNew<vtkActor> lineActor; lineActor->SetMapper(lineMapper); vtkNew<vtkPolyDataMapper> sphereMapper; sphereMapper->SetInputConnection(sphereSource->GetOutputPort()); vtkNew<vtkActor> sphereActor; sphereActor->SetMapper(sphereMapper); sphereActor->GetProperty()->SetRepresentationToWireframe(); sphereActor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData()); vtkNew<vtkExtractCells> cellSource; cellSource->SetInputConnection(sphereSource->GetOutputPort()); cellSource->SetCellList(intersectCells); vtkNew<vtkDataSetMapper> cellMapper; cellMapper->SetInputConnection(cellSource->GetOutputPort()); vtkNew<vtkActor> cellActor; cellActor->SetMapper(cellMapper); cellActor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData()); vtkNew<vtkRenderer> renderer; vtkNew<vtkRenderWindow> renderWindow; renderWindow->AddRenderer(renderer); vtkNew<vtkRenderWindowInteractor> renderWindowInteractor; renderWindowInteractor->SetRenderWindow(renderWindow); renderer->AddActor(lineActor); renderer->AddActor(sphereActor); renderer->AddActor(cellActor); renderer->SetBackground(colors->GetColor3d("CornflowerBlue").GetData()); renderWindow->SetWindowName("OBBTreeExtractCells"); renderWindow->Render(); renderWindowInteractor->Start(); return EXIT_SUCCESS; }
3.Official sample bounding box visualization
int maxLevel = 5; //Create the tree vtkNew<vtkOBBTree> obbTree; 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); //Initialize the representation vtkNew<vtkPolyData> polydata; obbTree->GenerateRepresentation(0, polydata); vtkNew<vtkPolyDataMapper> obbtreeMapper; obbtreeMapper->SetInputData(polydata); vtkNew<vtkActor> obbtreeActor; obbtreeActor->SetMapper(obbtreeMapper); obbtreeActor->GetProperty()->SetInterpolationToFlat(); obbtreeActor->GetProperty()->SetOpacity(.5); obbtreeActor->GetProperty()->EdgeVisibilityOn(); obbtreeActor->GetProperty()->SetColor( colors->GetColor4d("SpringGreen").GetData());