メッシュとは?#

PyVistaのデータ型の基本を学び,一般的な3Dファイル形式を開いてデータを3Dで可視化する方法を紹介します.

Tip

チュートリアルのこのセクションは,PyVista ドキュメントのユーザーガイドの What is a mesh? の章から採用されています.

PyVistaでは,メッシュは空間的に参照される情報であり,通常は3 D空間内の表面またはボリュームのジオメトリ表現で構成されます.一般的に,空間的に参照されるデータセットはメッシュと呼ばれるため,メッシュ,グリッド,ボリュームの区別があいまいになることがありますが,PyVistaでは関係ありません.三角形のような2 Dジオメトリを持つ表面メッシュのデータセットがある場合はメッシュと呼び,ボクセル,4面体,6面体などの3 Dジオメトリのデータセットがある場合はメッシュと呼びます.なぜか? その方が簡単だからです.

空間的に参照されるすべてのデータセットには,基礎となるメッシュ構造 – セルを定義するノード間の接続またはジオメトリが存在します.これらのセルが2 Dであるか3 Dであるかは常に重要ではなく,ユーザがニュアンスにとらわれないように,いずれかのジオメトリまたは混合ジオメトリのデータセットでPyVistaを動作させるために私たちは懸命に努力してきました.

注釈

これは,PyVistaのデータ構造に慣れるための,PyVista APIの非常にハイレベルな概要です. データモデルの詳細,VTKデータモデルとの関係,独自のメッシュを作成する方法については, データモデルの詳細ガイド を参照してください.

ポイントとは?#

ポイントはメッシュの頂点,つまり基礎となる直交座標です.すべてのPyVistaデータセット (メッシュ!) にはポイントがあり,場合によっては,ポイントクラウドのようにポイントのみを持つメッシュを作成できます.

たとえば,1 Dおよび2 Dのセルタイプ(セルとは何か簡単に説明します)を持つメッシュ用に作成された pyvista.PolyData クラスを使用して,ポイントクラウドメッシュを作成できます.

ポイントクラウドから始めましょう – これは頂点のみを持つメッシュタイプです.作成するには,2 D配列の直交座標を次のように定義します.

import numpy as np
import pyvista as pv

points = np.random.rand(100, 3)
mesh = pv.PolyData(points)
mesh.plot(point_size=10, style='points', color='tan')
../../_images/index-2_00_001.png

しかし,ほとんどのメッシュは,この格子状のメッシュのように,点と点の間に何らかのつながりがあることに注意が必要です.

from pyvista import examples

mesh = examples.load_hexbeam()
cpos = [(6.20, 3.00, 7.50),
        (0.16, 0.13, 2.65),
        (-0.28, 0.94, -0.21)]

pl = pv.Plotter()
pl.add_mesh(mesh, show_edges=True, color='white')
pl.add_points(mesh.points, color='red', point_size=20)
pl.camera_position = cpos
pl.show()
../../_images/index-3_00_001.png

または,この三角形表面:

mesh = examples.download_bunny_coarse()

pl = pv.Plotter()
pl.add_mesh(mesh, show_edges=True, color='white')
pl.add_points(mesh.points, color='red', point_size=20)
pl.camera_position = [(0.02, 0.30, 0.73),
                      (0.02, 0.03, -0.022),
                      (-0.03, 0.94, -0.34)]
pl.show()
../../_images/index-4_00_00.png

セルとは?#

セルとは,メッシュの接続性またはトポロジーを定義する点間のジオメトリです.上記の例では,セルは線(黒で着色されたエッジ)と接続点(赤で着色された)によって定義されています.例えば,ビームの例におけるセルは,そのメッシュの8つの点の間の領域によって定義されるボクセルである.

mesh = examples.load_hexbeam()

pl = pv.Plotter()
pl.add_mesh(mesh, show_edges=True, color='white')
pl.add_points(mesh.points, color='red', point_size=20)

single_cell = mesh.extract_cells(mesh.n_cells - 1)
pl.add_mesh(single_cell, color='pink', edge_color='blue',
            line_width=5, show_edges=True)

pl.camera_position = [(6.20, 3.00, 7.50),
                      (0.16, 0.13, 2.65),
                      (-0.28, 0.94, -0.21)]
pl.show()
../../_images/index-5_00_001.png

セルはボクセルに限らず,3点間の三角形や2点間の線,あるいは1点をセルとすることもできます(ただし,これは特殊なケースです).

アトリビュートとは?#

アトリビュートは,メッシュのポイントまたはセルに存在するデータ値です.PyVistaでは,ポイントデータとセルデータの両方を処理し,データ辞書に簡単にアクセスして,メッシュのすべてのポイントまたはすべてのセルに存在するアトリビュートの配列を保持できます.これらの属性は,以下のようにアクセスできるPyVistaメッシュに付けられた辞書のような属性にアクセスできます.

ポイントデータ#

点データとは,メッシュの各点に存在する値(スカラー,ベクトルなど)の配列のことです.属性配列の各要素は,メッシュの各点に対応します.梁のメッシュの点データを作ってみましょう.プロットする場合,点間の値はセルをまたいで補間されます.

mesh.point_data['my point values'] = np.arange(mesh.n_points, dtype=float)
mesh.plot(scalars='my point values', cpos=cpos, show_edges=True)
../../_images/index-6_00_00.png

セルデータ#

セルデータは,メッシュの各セル全体に存在する値の配列(スカラー,ベクトルなど)を参照します.つまり,セル全体(2 D面または3 D体積)にそのアトリビュートの値が割り当てられます.

mesh.cell_data['my cell values'] = np.arange(mesh.n_cells)
mesh.plot(scalars='my cell values', cpos=cpos, show_edges=True)
../../_images/index-7_00_001.png

ここでは,点データとセルデータを比較し,色をマッピングするときに点データがセル間でどのように補間されるかを示します.これは,セルのドメイン全体で単一の値を持つセルデータとは異なります.

import pyvista as pv
from pyvista import examples
uni = examples.load_uniform()

pl = pv.Plotter(shape=(1, 2), border=False)
pl.add_mesh(uni, scalars='Spatial Point Data', show_edges=True)
pl.subplot(0, 1)
pl.add_mesh(uni, scalars='Spatial Cell Data', show_edges=True)
pl.show()
../../_images/index-8_00_00.png

フィールドデータ#

フィールドデータはポイントやセルとは直接関連していませんが,メッシュに添付する必要があります. これはメモを格納した文字列の配列であったり,あるいは Collision のインデックスであったりします.

スカラーをメッシュに割り当てる#

ここでは,セルの属性に値を割り当て,それをプロットする方法を紹介します. ここでは,6つの面を含む立方体を生成し,それぞれの面に range(6) から整数を割り当てて,それをプロットしています.

これは,各点にスカラーを割り当てるのとは異なることに注意してください.

cube = pv.Cube()
cube.cell_data['myscalars'] = range(6)

other_cube = cube.copy()
other_cube.point_data['myscalars'] = range(8)

pl = pv.Plotter(shape=(1, 2), border_width=1)
pl.add_mesh(cube, cmap='coolwarm')
pl.subplot(0, 1)
pl.add_mesh(other_cube, cmap='coolwarm')
pl.show()
../../_images/index-9_00_00.png

注釈

デフォルトでは,立方体はマージされていない面と重複したポイントで作成されるので,立方体の面をマージするために pyvista.PolyDataFilters.clean() を使用しています.

演習#

その他の例については, PyVista Examples Gallery のメッシュ作成セクションを参照してください.

レッスンの概要

Lesson Overview

やってみよう#

点群を作成

Create Point Cloud

均一グリッドを作成

Creating a Uniform Grid

三角形状のサーフェスを作成する

Create Triangulated Surface

解答#

点群を作成

Create Point Cloud

均一グリッドを作成

Creating a Uniform Grid

三角形状のサーフェスを作成する

Create Triangulated Surface

Sphinx-Galleryによるギャラリー