Чтение и построение структуры данных файла VTK с помощью Python - PullRequest
3 голосов
/ 31 мая 2019

У меня есть файл VTK (неструктурированная сетка) с points и cells.

Я могу импортировать файл и прочитать его, используя пакет meshio python.

Если я наберу команду mesh.cells, я вижу словарь под названием 'hexahedron' с массивом, состоящим из списков внутри, например:

{'hexahedron': array([[  0, 162, 185, ..., 163, 186,  23],
        [162, 329, 351, ..., 330, 352, 186],
        [329, 491, 514, ..., 492, 515, 352],
        ...,
        [483, 583, 600, ..., 584, 601, 490],
        [583, 650, 656, ..., 651, 657, 601],
        [650, 746, 762, ..., 747, 763, 657]])}

Я хотел бы представить это в matplotlib (я знаю, что ParaView - это альтернатива, которую я использовал, но я также хотел бы использовать для этого matplotlib). В любом случае, у меня проблемы с тем, чтобы обернуть голову вокруг конструкции.

В каждом списке 8 точек данных.

Если я запускаю команду mesh.points, я получаю массив списков x, y, z координат, что имеет смысл. Однако, с шестигранником, есть ли также x, y, z координаты в списке? Было бы более разумно, если бы были списки x, y, z координат, так как это составляло бы многоугольники.

Я видел эту ветку , но я все еще застрял в понимании этого.

Прилагается файл VTK , а также то, как он выглядит в ParaView. Спасибо! screenshot from paraview, bar with three bands of different colour

1 Ответ

7 голосов
/ 06 июня 2019

tl; dr: Я не думаю, что вы должны пытаться использовать для этого matplotlib, и это будет сложно и не очень хорошо работает. Я предлагаю использовать выделенную библиотеку vtk, либо vtk, либо более высокий уровень mayavi.mlab. Я подробно остановлюсь на этом.

Данные

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

# vtk DataFile Version 3.1
MCVE VTK file
ASCII
DATASET UNSTRUCTURED_GRID
POINTS      16 float
 0.   0.   0.
 0.   0.   3.
 0.   2.   0.
 0.   2.   3.
 4.   0.   0.
 4.   0.   3.
 4.   2.   0.
 4.   2.   3.
 5.   0.   0.
 5.   0.   3.
 5.   2.   0.
 5.   2.   3.
13.   0.   0.
13.   0.   3.
13.   2.   0.
13.   2.   3.

CELLS        3     27
 8    0   1   3   2   4   5   7   6
 8    4   5   7   6   8   9  11  10
 8    8   9  11  10  12  13  15  14

CELL_TYPES        3
          12          12          12

CELL_DATA        3
SCALARS elem_val float
LOOKUP_TABLE default
 1
 2
 3

Давайте обсудим, что представляет этот файл. Заголовок указывает, что это неструктурированная сетка. Это означает, что он может содержать точки, расположенные произвольным образом. В основном мешок очков. Вы можете найти некоторые пояснения по поводу формата файла здесь .

Первый блок, POINTS, содержит строки 16 float, каждая строка соответствует координатам точки в 3d, всего 16 точек.

Второй блок, CELLS, определяет 3 строки, каждая строка соответствует ячейке (меньшая единица, в данном случае объем), определенной в виде основанных на 0 индексов точек. Первое число (8) указывает количество вершин в данной ячейке, следующие числа являются индексами точек для соответствующих вершин. Все три ячейки в приведенном выше примере файла данных состоят из 8 вершин, поскольку каждый кубоид, который мы хотим нарисовать, имеет 8 вершин. Второе число в строке CELLS - это общее количество чисел в этом блоке, т. Е. 3 * (8+1), т. Е. 27.

Третий блок, CELL_TYPES, определяет тип ячейки для каждой из 3 ячеек. В этом случае все они имеют тип 12, что соответствует «шестигранникам». Информативная цифра заимствована из рис. 2 из уже связанных примеров : figure of cell types, 12 corresponds to hexahedrons Здесь перечислены основные типы типов ячеек и соответствующие им индексы.

Последний блок, SCALARS, содержит скаляр (число) для каждой ячейки, в соответствии с которым она будет окрашена позже. Скаляры от 1 до 3 будут отображены в цветовую карту, чтобы дать вам красно-синий переход, видимый на вашей фигуре.

Почему бы не matplotlib?

Я не знаком с meshio, но подозреваю, что он дает вам доступ к вышеупомянутым блокам в файле VTK. Атрибут mesh.cells, который вы показали, предполагает, что он распознает, что каждая ячейка является «шестигранником», и перечисляет каждую ячейку и соответствующие ей 8 индексов вершин. Атрибут mesh.points, вероятно, является массивом формы (n,3), и в этом случае mesh.points[cell_inds, :] дает вам (8,3) -образные координаты данной ячейки, определенной ее массивом из 8 длин cell_inds.

Как бы вы визуализировали это с помощью matplotlib? Во-первых, ваши фактические данные огромны, они содержат 84480 ячеек, хотя издалека они выглядят очень похоже на мои данные выше. Так что вам придется

  1. придумали способ превратить все эти координаты ячейки в поверхности, которые должны быть нанесены с помощью matplotlib, что было бы нелегко,
  2. затем осознайте, что 80k-поверхности приведут к огромным затратам памяти и процессора в matplotlib, наконец
  3. обратите внимание, что у matplotlib есть 2d рендерер, поэтому 3d визуализация сложных (читай: разъединяющих, сцепляющихся) поверхностей часто искажается .

Учитывая все вышесказанное, я бы определенно не пытался использовать для этого matplotlib.

Что тогда?

Используйте то, что ParaView использует под капотом: VTK! Вы по-прежнему можете использовать оборудование программно через модуль низкого уровня vtk или модуль высокого уровня (er) mayavi.mlab. Есть также mayavi -связанный модуль tvtk, который является своего рода средним уровнем (это все еще низкоуровневый VTK для этих целей, но с более дружественным для Python API), но я оставлю это как упражнение читателю.

1. vtk

Чтение и построение неструктурированной сетки с помощью vtk немного сложнее (как это всегда бывает с голым vtk, поскольку вы должны собрать конвейер самостоятельно), но управляемым с помощью этой древней вики-страницы плюс эти исправления, которые изменились с :

from vtk import (vtkUnstructuredGridReader, vtkDataSetMapper, vtkActor,
                 vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor)

file_name = "mesh_mcve.vtk"  # minimal example vtk file

# Read the source file.
reader = vtkUnstructuredGridReader()
reader.SetFileName(file_name)
reader.Update()  # Needed because of GetScalarRange
output = reader.GetOutput()
output_port = reader.GetOutputPort()
scalar_range = output.GetScalarRange()

# Create the mapper that corresponds the objects of the vtk file
# into graphics elements
mapper = vtkDataSetMapper()
mapper.SetInputConnection(output_port)
mapper.SetScalarRange(scalar_range)

# Create the Actor
actor = vtkActor()
actor.SetMapper(mapper)

# Create the Renderer
renderer = vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(1, 1, 1) # Set background to white

# Create the RendererWindow
renderer_window = vtkRenderWindow()
renderer_window.AddRenderer(renderer)

# Create the RendererWindowInteractor and display the vtk_file
interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(renderer_window)
interactor.Initialize()
interactor.Start()

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

output using vtk module, bar with red, green and blue stripe

Фактический цвет зависит от цветовой карты по умолчанию и масштабирования скаляров. Приведенное выше значение по умолчанию для модуля vtk, по-видимому, использует цветовую карту jet по умолчанию, и оно нормализует скаляры, так что значения отображаются в полный цветовой диапазон.

2. mayavi.mlab

Лично я считаю vtk огромной болью в использовании. Он включает в себя много поиска и чаще всего копание в лабиринте подмодулей и классов, определенных в библиотеке. Вот почему я всегда стараюсь использовать vtk через высокоуровневую функциональность mayavi.mlab. Этот модуль особенно полезен, когда вы не работаете с файлами VTK (например, когда пытаетесь визуализировать данные, которые определены в массивах numpy), но в данном случае это также избавляет нас от большой работы , обеспечивая при этом дополнительную функциональность. Вот та же визуализация с использованием mlab:

from mayavi import mlab
from mayavi.modules.surface import Surface

file_name = "mesh_mcve.vtk"  # minimal example vtk file

# create a new figure, grab the engine that's created with it
fig = mlab.figure()
engine = mlab.get_engine()

# open the vtk file, let mayavi figure it all out
vtk_file_reader = engine.open(file_name)

# plot surface corresponding to the data
surface = Surface()
engine.add_filter(surface, vtk_file_reader)

# block until figure is closed
mlab.show()

Гораздо меньше работы! Мы вытолкнули всю чудовищность разбора VTK на mayavi вместе с беспорядком картографов, актеров, рендеров и ...

Вот как это выглядит: output with mlab, similar three-coloured bar but the colours are in reverse order

Выше приведена минимальная визуализация с минимальными усилиями, но отсюда, конечно, вы можете начать изменять то, что вам нравится, чтобы оно соответствовало вашим потребностям. Вы можете изменить фон, изменить цветовую карту, манипулировать данными странным образом, вы называете это. Обратите внимание, что цвета здесь перевернуты по сравнению со случаем vtk, поскольку либо цветовая карта по умолчанию, либо отображение скаляров на цветовую карту (справочную таблицу) отличается. Чем больше вы отклоняетесь от высокоуровневого API mlab, тем грязнее оно становится (поскольку вы все ближе и ближе подходите к голому VTK под капотом), но обычно вы все равно можете сэкономить много работы и запутанный код с помощью mayavi.

Наконец, окно рисунков mayavi поддерживает все виды драгоценных камней: интерактивное изменение конвейера и сцены, аннотации, такие как оси координат, переключение ортогональных проекций и даже возможность записывать все, что вы изменяете в интерактивном режиме, в автоматически сгенерированном виде. скрипты на питоне. Я бы определенно предложил попробовать реализовать то, что вы хотите сделать, используя Mayavi. Если вы знаете, что будете делать с ParaView, довольно просто перенести его на mayavi, используя его интерактивную функцию записи сеансов.

...