Проверьте, находится ли точка внутри и объект с помощью VTK - PullRequest
0 голосов
/ 08 октября 2018

Я следую этому примеру , чтобы проверить, находится ли данная точка внутри объекта.Следующий код является сводкой примера использования куба.

vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();
cubeSource->Update();
vtkPolyData* cube = cubeSource->GetOutput();

vtkSmartPointer<vtkSelectEnclosedPoints> selectEnclosedPoints = vtkSmartPointer<vtkSelectEnclosedPoints>::New();
double test[3] = {0.0, 0.0, 0.0};

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(test);
vtkSmartPointer<vtkPolyData> pointsPolydata = vtkSmartPointer<vtkPolyData>::New();
pointsPolydata->SetPoints(points);

selectEnclosedPoints->SetInputData(pointsPolydata);
selectEnclosedPoints->SetSurfaceData(cube);
selectEnclosedPoints->Update();

std::cout << "Point: " << selectEnclosedPoints->IsInside(0) << std::endl;

При проверке точки в настроенном объекте polyData функция не возвращает то, что я ожидал:

vtkSmartPointer<vtkPoints> pointsVTK = vtkSmartPointer<vtkPoints>::New();
pointsVTK->SetNumberOfPoints(hashMapPoints.size());
////
//insert the points in pointsVTK and vertex, and set labels and sizes
////
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();

polyData->SetPoints(pointsVTK);
polyData->SetVerts(vertsVTK);
point_poly->GetPointData()->AddArray(labels);
point_poly->GetPointData()->AddArray(sizes);

vtkSmartPointer<vtkSelectEnclosedPoints> selectEnclosedPoints = vtkSmartPointer<vtkSelectEnclosedPoints>::New();
double test[3] = {1, 1, 0};

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(test);
vtkSmartPointer<vtkPolyData> pointsPolydata = vtkSmartPointer<vtkPolyData>::New();
pointsPolydata->SetPoints(points);

selectEnclosedPoints->SetInputData(pointsPolydata);
selectEnclosedPoints->SetSurfaceData(polyData);
selectEnclosedPoints->Update();

std::cout << "Point: " << selectEnclosedPoints->IsInside(0) << std::endl;

MyПредполагается, что структура куба имеет другую информацию, используемую функцией selectEnclosedPoints-> IsInside , но я не вижу, чего ей не хватает.

1 Ответ

0 голосов
/ 09 октября 2018

vtkSelectEnclosedPoints - это правильный способ проверить, находится ли точка внутри объекта.Однако алгоритм требует (идеально замкнутой) поверхности, состоящей из ячеек с трехмерным экстентом .Ваш объект полиданных состоит из вершин (которые являются ячейками с 0D-экстентом).Разница объясняется в этом SO ответе .

С помощью следующего фиктивного кода (на python) я демонстрирую, как можно создать объект полиданных, который можно использовать с vtkSelectEnclosedPoints:

# Create poly data object
surfacePoly = vtk.vtkPolyData()
surfacePoly.SetPoints(points)
surfacePoly.SetPolys(cells)   # 2D cells, not verts!

# ...

# Use surfacePoly as input
selectEnclosed = vtk.vtkSelectEnclosedPoints()
selectEnclosed.SetInputData(pointsPoly)
selectEnclosed.SetSurfaceData(surfacePoly)
selectEnclosed.Update()

См. Пример vtkколлекция (раздел «Ячейки»), где приведены дополнительные примеры создания объектов данных poly.Если вы работаете с облаком точек, вам сначала нужно вычислить выпуклую оболочку или определить поверхность вокруг ваших точек. См. Здесь для примера.

Надеюсь, это поможет!


Обновление: Добавлен пример извлечения выпуклой оболочки с помощью vtkDelaunay3D.Обязательно прочтите также примечания в документации.Вычисление триангуляции Делоне имеет тенденцию быть более устойчивым, если точки не образуют регулярные структуры.

polyPoints = vtk.vtkPolyData()
polyPoints.SetPoints(points)
triangulation = vtk.vtkDelaunay3D()
triangulation.SetInputData(polyPoints)
# Tuning parameter.
# triangulation.SetOffset(100.0)
triangulation.Update()
# Extract the surface
convexHull = vtk.vtkDataSetSurfaceFilter()
convexHull.SetInputConnection(triangulation.GetOutputPort())
convexHull.Update()
# And retrieve the corresponding polydata object.
surfacePoly = convexHull.GetOutput()
...