Получение фасетов и точек из файла VTK в python - PullRequest
0 голосов
/ 06 июля 2018

У меня есть файл vtk, содержащий 3d модель,

Я хотел бы извлечь координаты точки и грани.

Вот минимальный рабочий пример:

import vtk
import numpy
from vtk.util.numpy_support import vtk_to_numpy

reader = vtk.vtkPolyDataReader()
reader.SetFileName('test.vtk')
reader.Update()

polydata = reader.GetOutput()

points = polydata.GetPoints()
array = points.GetData()
numpy_nodes = vtk_to_numpy(array)

Это работает, так как numpy_nodes содержит координаты x, y, z всех точек, но я не могу найти список, который связывает аспекты этой модели с соответствующими точками.

Я пытался:

facets= polydata.GetPolys()
array = facets.GetData()
numpy_nodes = vtk_to_numpy(array)

Но тогда numpy_nodes - это просто одномерный массив, в котором я бы ожидал двумерный массив (размер 3 * количество граней), где первое измерение содержит количество соответствующих точек фасету (как в файле .ply). .

Любые советы о том, как действовать, будут приветствоваться

1 Ответ

0 голосов
/ 17 июля 2018

Вы были почти там. Чтобы разрешить ячейки разных типов (треугольники, квадраты и т. Д.), Массив NumPy кодирует информацию по следующей схеме:

numpyArray = [ n_0, id_0(0), id_0(1), ..., id_0(n0-1), 
               n_1, id_1(0), id_1(1), ..., id_1(n1-1), 
               ... 
               n_i, id_i(0), id_i(1), ..., id_1(n1-1), 
               ...
              ]

Если все polys имеют одинаковый вид, то есть n_i==n для всех i, просто измените массив 1D, чтобы получить что-то интерпретируемое:

cells = polydata.GetPolys()
nCells = cells.GetNumberOfCells()
array = cells.GetData()
# This holds true if all polys are of the same kind, e.g. triangles.
assert(array.GetNumberOfValues()%nCells==0)
nCols = array.GetNumberOfValues()//nCells
numpy_cells = vtk_to_numpy(array)
numpy_cells = numpy_cells.reshape((-1,nCols))

Первый столбец numpy_cells можно отбросить, поскольку он содержит только количество точек на ячейку. Но остальные столбцы содержат информацию, которую вы искали.

Чтобы быть уверенным в результате, сравните вывод с «традиционным» способом получения идентификаторов точек:

def getCellIds(polydata):
    cells = polydata.GetPolys()
    ids = []
    idList = vtk.vtkIdList()
    cells.InitTraversal()
    while cells.GetNextCell(idList):
        for i in range(0, idList.GetNumberOfIds()):
            pId = idList.GetId(i)
            ids.append(pId)
    ids = np.array(ids)
    return ids

numpy_cells2 = getCellIds(polydata).reshape((-1,3))

print(numpy_cells[:10,1:])
print(numpy_cells2[:10])
assert(np.array_equal(numpy_cells[:,1:], numpy_cells2))
...